diff --git a/CheckCert_BOF/CheckCertx64.o b/CheckCert_BOF/CheckCertx64.o deleted file mode 100644 index 727ff93..0000000 Binary files a/CheckCert_BOF/CheckCertx64.o and /dev/null differ diff --git a/CheckCert_BOF/src/CheckCert.c b/CheckCert_BOF/src/CheckCert.c index 483f8e9..c5d6ecc 100644 --- a/CheckCert_BOF/src/CheckCert.c +++ b/CheckCert_BOF/src/CheckCert.c @@ -24,6 +24,9 @@ void HTTPRequest(LPCWSTR http, INTERNET_PORT port, LPCWSTR referrer, LPCWSTR age WinHttpSendRequest_t pWinHttpSendRequest = (WinHttpSendRequest_t)GetProcAddress(hinst, "WinHttpSendRequest"); WinHttpQueryOption_t pWinHttpQueryOption = (WinHttpQueryOption_t)GetProcAddress(hinst, "WinHttpQueryOption"); WinHttpCloseHandle_t pWinHttpCloseHandle = (WinHttpCloseHandle_t)GetProcAddress(hinst, "WinHttpCloseHandle"); + WinHttpQueryHeaders_t pWinHttpQueryHeaders = (WinHttpQueryHeaders_t)GetProcAddress(hinst, "WinHttpQueryHeaders"); + WinHttpReceiveResponse_t pWinHttpReceiveResponse = (WinHttpReceiveResponse_t)GetProcAddress(hinst, "WinHttpReceiveResponse"); + //crypt32 - define pointers hinst = LoadLibrary("crypt32.dll"); @@ -35,7 +38,7 @@ void HTTPRequest(LPCWSTR http, INTERNET_PORT port, LPCWSTR referrer, LPCWSTR age //Begin HTTP request //Obtain a session handle - hSession = pWinHttpOpen(agent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + hSession = pWinHttpOpen(agent, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY , WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); //Set reasonable timout values pWinHttpSetTimeouts(hSession, 2000, 2000, 2000, 2000); @@ -57,14 +60,38 @@ void HTTPRequest(LPCWSTR http, INTERNET_PORT port, LPCWSTR referrer, LPCWSTR age else BeaconPrintf(CALLBACK_OUTPUT,"[!] Cannot connect to server.\n"); + + //Obtain the SSL certificate using WINHTTP_OPTION_SERVER_CERT_CONTEXT if (hResults) - hResults = pWinHttpQueryOption(hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCert, &dwLen); + { + + // get response code as well + DWORD dwStatusCode = 0; + DWORD dwSize = sizeof(dwStatusCode); + + pWinHttpReceiveResponse(hRequest, NULL); + pWinHttpQueryHeaders(hRequest, + WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, + NULL, + &dwStatusCode, &dwSize, NULL); + + BeaconPrintf(CALLBACK_OUTPUT,"Response Code: %d", dwStatusCode); + + hResults = pWinHttpQueryOption(hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCert, &dwLen); + if (!hResults) { + // length is probably not sufficient + pCert = (CERT_CONTEXT*)MSVCRT$malloc(dwLen); + hResults = pWinHttpQueryOption(hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCert, &dwLen); + } + } else BeaconPrintf(CALLBACK_OUTPUT,"[!] Unable to get SSL certificate.\n"); - + + //Begin parsing the SSL certificate context if (hResults) { + //Parse the SSL certificate context and obtain the CNAME/subject len = pCertNameToStrA(X509_ASN_ENCODING, &pCert->pCertInfo->Subject, CERT_X500_NAME_STR, NULL, 0); if (len) { @@ -93,6 +120,10 @@ void HTTPRequest(LPCWSTR http, INTERNET_PORT port, LPCWSTR referrer, LPCWSTR age pFileTimeToSystemTime(&expiryFt, &expirySt); pFileTimeToSystemTime(&effectiveDateFt, &effectiveSt); } + else { + BeaconPrintf(CALLBACK_OUTPUT,"[!] Unable to get HTTP response.\n"); + BeaconPrintf(CALLBACK_OUTPUT, "%X", KERNEL32$GetLastError()); + } //Name and issuer will be NULL if unable to obtain a SSL certificate if (name != NULL) @@ -112,7 +143,11 @@ void HTTPRequest(LPCWSTR http, INTERNET_PORT port, LPCWSTR referrer, LPCWSTR age void go(char* args, int length) { //Variables - char * target = MSVCRT$strtok(args, ","); + datap parser; + BeaconDataParse(&parser, args, length); + char * t = BeaconDataExtract(&parser, NULL); + + char* target = MSVCRT$strtok(t, ","); char* url = "/"; //set a default referrer of / as a referrer is required char* port = "443"; //set a default port of 443 LPCWSTR agent = L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"; diff --git a/CheckCert_BOF/src/CheckCert.h b/CheckCert_BOF/src/CheckCert.h index 5f77f97..f09b5fb 100644 --- a/CheckCert_BOF/src/CheckCert.h +++ b/CheckCert_BOF/src/CheckCert.h @@ -1,8 +1,13 @@ #include #include #include -#include +#ifdef __MINGW32__ +#include +#define _Frees_ptr_opt_ +#else +#include +#endif //#pragma comment(lib, "winhttp.lib") //#pragma comment(lib, "crypt32.lib") @@ -23,6 +28,7 @@ WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap(); WINBASEAPI void* WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE hHeap, DWORD dwFlags, _Frees_ptr_opt_ LPVOID lpMem); WINBASEAPI FARPROC WINAPI KERNEL32$GetProcAddress(HMODULE hModule, LPCSTR lpProcName); +WINBASEAPI DWORD KERNEL32$GetLastError(); //winhttp.dll typedef HINTERNET(WINAPI* WinHttpOpen_t)( @@ -79,6 +85,20 @@ typedef BOOL(WINAPI* WinHttpCloseHandle_t)( IN HINTERNET hInternet ); +typedef BOOL(WINAPI* WinHttpQueryHeaders_t)( + IN HINTERNET hRequest, + IN DWORD dwInfoLevel, + IN LPCWSTR pwszName, + OUT LPVOID lpBuffer, + LPDWORD lpdwBufferLength, + LPDWORD lpdwIndex +); + +typedef BOOL(WINAPI* WinHttpReceiveResponse_t)( + HINTERNET hRequest, + LPVOID lpReserved +); + //Crypt32.dll typedef DWORD(WINAPI* CertNameToStrA_t)( IN DWORD dwCertEncodingType, @@ -92,4 +112,4 @@ typedef DWORD(WINAPI* CertNameToStrA_t)( typedef BOOL(WINAPI* FileTimeToSystemTime_t)( IN const FILETIME* lpFileTime, OUT LPSYSTEMTIME lpSystemTime - ); \ No newline at end of file + ); diff --git a/CheckCert_BOF/src/CheckCert.x64.o b/CheckCert_BOF/src/CheckCert.x64.o new file mode 100644 index 0000000..ad188ea Binary files /dev/null and b/CheckCert_BOF/src/CheckCert.x64.o differ diff --git a/CheckCert_BOF/src/CheckCert.x86.o b/CheckCert_BOF/src/CheckCert.x86.o new file mode 100644 index 0000000..01347f3 Binary files /dev/null and b/CheckCert_BOF/src/CheckCert.x86.o differ diff --git a/CheckCert_BOF/src/Makefile b/CheckCert_BOF/src/Makefile new file mode 100644 index 0000000..06e2222 --- /dev/null +++ b/CheckCert_BOF/src/Makefile @@ -0,0 +1,7 @@ +BOFNAME := CheckCert +CC_x64 := x86_64-w64-mingw32-gcc +CC_x86 := i686-w64-mingw32-gcc + +all: + $(CC_x64) -o $(BOFNAME).x64.o -c $(BOFNAME).c + $(CC_x86) -o $(BOFNAME).x86.o -c $(BOFNAME).c diff --git a/CheckCert_BOF/src/check-cert.cna b/CheckCert_BOF/src/check-cert.cna new file mode 100644 index 0000000..4fd2900 --- /dev/null +++ b/CheckCert_BOF/src/check-cert.cna @@ -0,0 +1,28 @@ +beacon_command_register( +"check-cert", +"Fetch the certificate of a website", +"Synopsis: check-cert "); + + +alias check-cert { + local('$handle $data $args'); + + # figure out the arch of this session + $barch = barch($1); + + # read in the right BOF file + $handle = openf(script_resource("CheckCert. $+ $barch $+ .o")); + $data = readb($handle, -1); + closef($handle); + + + # pack our arguments + $args = bof_pack($1, "z", $2); + + btask($1, "CheckCert"); + + # execute it. + beacon_inline_execute($1, $data, "go", $args); +} + +