Log in

View Full Version : Current QuickLPC Server Implementation


BanMe
June 19th, 2009, 16:26
Curret Server Source 1.03bv1

to be updated...

BanMe
July 7th, 2009, 15:23
*Change\BugFix Log*

version 1.02bv2
bug fixes:
Event DACL's added so Client can open events in "subsystem".
connection\communication synchronization fixed so no dealocks can occur hopefully...

Changes:
Native_UpdateHandleState
Native_DeleteHandle

dELTA
July 7th, 2009, 18:29

Looks good.

BanMe
July 15th, 2009, 22:07
*1.03bv1* update\change log

added alot of code to server from "client"
fixed Native_OpenObjectInProcess()
fixed a few small logic bugs..
did a ton of reorganization..
enjoy..Client will be up tommorow after I complete the integrations..

regards BanMe

OHPen
July 19th, 2009, 04:01
Hi,

sorry to ask a stupid question, but for what can i use it. Could you give an example.

Thx,
OHPen

BanMe
July 19th, 2009, 04:43
dynamorio comes to mind as example of some of the things that this will be capable of doing..
picture a reversing minded subsystem that can "activate" on specific processes..and from there most things become possible its just getting "there" thats the fun part ..

maybe I can explain it a "new" way by explaining how a process comes into actually executing its code..

LdrpInitialize is called by apc after initialial Kernel process object creation this does all sorts of things before "OEP" is actually executed..calls also occur to LdrpGetExecutionOptions and LdrInitializeProcess and LdrInitializeThread set's up the basic calling context of the Main Thread the initial_teb and CONTEXT and other stuff..
all these function eventually lead to BaseProcessStartThunk and BaseThreadStartThunk IF it's a WIN32 (subsystem windows or console) process..now BaseProcessStartThunk is pretty lame but BaseThreadStartThunk is very interesting.. cause as we all know threads do the "real" code execution..so by placing hooks at these key locations we can then analyze or modify the process or thread in order to accomplish ones desired result..

Currently its not so useful but I am Almost to Plugable subsystem behaviors..still yet a few hurdles to jump.. I need feed back and thoughts and questions to really get this stuff off the ground..cause I may be a somewhat good developer\and not so bad reverser, but I know I do not know everything...I go crazy with the amount I already know and understand now..but with help from others I know this can have robust and varied features that can be implemented inside "protected\rootkited" processes from a aspect they will cannot expect.. nor hopefully in the end detect..

I hope that clears some of this whole mess up

regards BanMe

OHPen
July 20th, 2009, 08:08
Thx for clearing that

BanMe
July 22nd, 2009, 18:47
1.04bv1 of server coming soon

*dELTA or JMI or woodmann can you remove the d/l in the upper thread for me.. cant seem to edit it o0*

Kayaker
July 22nd, 2009, 18:59
Quote:
[Originally Posted by BanMe;82022].. cant seem to edit it o0*


That's because there's a forum limit of 30 days that a user can edit their old posts. I have changed that limit to 60 days - think that will keep you for a while?

BanMe
July 22nd, 2009, 19:03
Thank you Kayaker.. 60 days..yes that should be sufficient and something that I will have to remember.

regards BanMe

BanMe
July 25th, 2009, 20:36
Then Again with code that looks like this... 60 days might be cutting it.. o0
Im tryinG as hard as I can.. ;D

Sample of 1 Function now o0
Code:

#include "SIN32.h"
//#define __NATIVE__ //if you want to test the Native Application.
//#define __DEBUG__ //if you want Debug Output to be printed in Native or Win32 mode..
//NtProcessStartup is the Native equivelent of int Main or void Main..
//it's where a Native Application Start Execution
void NtProcessStartup(PSTARTUP_ARGUMENT Argument)
{
//Zero'd Parameters..
UNICODE_STRING Unicode = {0};
OBJECT_ATTRIBUTES oa = {0};
void* ServerHandleTable = 0;
SIN32_HANDLE_TABLE_ENTRY *HandleEntry = {0};
HANDLE Event0 = INVALID_HANDLE_VALUE;
HANDLE Event1 = INVALID_HANDLE_VALUE;
HANDLE Reusable = INVALID_HANDLE_VALUE;
PORT_MESSAGE *Message = {0};
NTSTATUS Status = 0;
BOOLEAN Enabled = 0;
bool Recycler = false;
CLIENT_ID ClientId = {0};
SECURITY_DESCRIPTOR SecDesc = {0};
//End Zero'd Parameters
//Start Initializing Non-Zero Data
SIZE_T SizeRegion = 0x4096;
RtlInitUnicodeString(&Unicode,LpcEventName);
oa.Length = sizeof(OBJECT_ATTRIBUTES);

//if Preprocessor _NATIVE_ is defined make a Permanent Object,
//This cannot be compiled If the application is not Native,
//unless you can aquire the SeMakePermantObject Privilege in some way..
//Again hmm..Token Swapping with the 'Server'??
//also apparently I cannot open handles from other applications unless
//I specificlly alter the dacl..passing 0 does not work here..
//If running as a normal application passing 0 works fine..
#ifdef __NATIVE__
Status = RtlCreateSecurityDescriptor(&SecDesc,1);
Status = RtlSetDaclSecurityDescriptor(&SecDesc,true,(PACL)NULL,false);
InitializeObjectAttributes(&oa,&Unicode,OBJ_PERMANENT|OBJ_KERNEL_HANDLE,0,&SecDesc);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Correcting Dacl UnSuccessful";
DbgOutput(&Unicode,Status);
#endif
return;
}
else
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Correcting Dacl UnSuccessful";
DbgOutput(&Unicode,Status);
#endif
}
#else
//Else where not running in Native Mode and we are just debugging in Win32 Mode..
InitializeObjectAttributes(&oa,&Unicode,OBJ_KERNEL_HANDLE,0,0);
#endif
__try
{
//Get all Supporting Api that 'have' to be Dynamically loaded..
//although I could sig_seek them..hmm maybe next time..
if(!Native_GetSupportAPI())
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Failed Acquiring Support Functions";
DbgOutput(&Unicode,STATUS_UNSUCCESSFUL);
#endif
return;
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Succeed in Getting Support Api";
DbgOutput(&Unicode,0);
#endif
#ifdef __NATIVE__
//We Cannot obtain the privilege in Win32 mode even as administrator
//But we can as "System" in Native Mode
Status = RtlAdjustPrivilege(16L,true,false,&Enabled);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Acquiring Privilege UnSuccessful";
DbgOutput(&Unicode,Status);
#endif
return;
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Acquiring Privilege Successful";
DbgOutput(&Unicode,Status);
#endif
#endif
//Create The Event That is signaled when a Thread needs
Status = NtCreateEvent(&Event0,EVENT_ALL_ACCESS,&oa,SynchronizationEvent,TRUE);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"NtCreateEvent Status:";
DbgOutput(&Unicode,Status);
#endif
return;
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"NtCreateEvent Status:";
DbgOutput(&Unicode,Status);
#endif
RtlInitUnicodeString(&Unicode,LpcCommEvent);
#ifdef __NATIVE__
InitializeObjectAttributes(&oa,&Unicode,OBJ_PERMANENT|OBJ_KERNEL_HANDLE,0,&SecDesc);
#else
InitializeObjectAttributes(&oa,&Unicode,OBJ_KERNEL_HANDLE,0,0);
#endif
//Create The Event that can be signaled from User Mode in order to Initiate
//and Synchronize Communication.
Status = NtCreateEvent(&Event1,EVENT_ALL_ACCESS,&oa,NotificationEvent,TRUE);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"NtCreateEvent Status:";
DbgOutput(&Unicode,Status);
#endif
return;
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"NtCreateEvent Success:";
DbgOutput(&Unicode,Status);
#endif
#ifdef __NATIVE__
//Disable the Privilege if we are in "Native" Mode.
Status = RtlAdjustPrivilege(16L,false,false,&Enabled);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Failing removing Privilege..w.e. ";
DbgOutput(&Unicode,Status);
#endif
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Successful Privilege Removal";
DbgOutput(&Unicode,Status);
#endif
#endif
//Create a section of memory for the HandleTable
ServerHandleTable = Native_CreateHeap(0);
if(ServerHandleTable)
{
//Initialize the HandleTable
if(Native_InitHandleTable((RTL_HANDLE_TABLE*)ServerHandleTable))
{
//Added Entry for Capture Event
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Event0,ObEvent_Sync,ObSignaled,HandleEn try);//0
//Added Entry for CommEvent
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Event1,ObEvent_Comm,ObSignaled,HandleEn try);//1
//Added Entry for the dedicated "Listener" Thread I added it
//by Id rather then NtCurrentThread() because that returns
//a psuedo handle. And if I need to do work on it or with it the
//handle to the current thread wont help, but its ThreadId will.
//So I add a unique entry for the this thread so it wont get
//Changed by UpdateHandleState..
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,NtCurrentTeb()->ClientId.UniqueThread,ObThread,ObPRunning,HandleEntry);//2
//Create A Suspended Thread pointing to CallOutRecaptureRoutine,
//as it seems impossible to redirect the EIP,without direct code modification (a hook),
//this only applies if the ThreadStart Address ZwSetInformationThread
//with information class 9.. as seen in BaseThreadStartThunk,
//which Internally calls BaseThreadStart..
Status = RtlCreateUserThread(NtCurrentProcess(),0,true,0,0,0x4096,(PUSER_THREAD_START_ROUTINE)CallOutRecaptur eRoutine,0,&Reusable,&ClientId);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Failed Creating a CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Successful Creation of CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif

//add entry for the thread
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Reusable,ObThread,ObTSuspended,HandleEn try);//3
Status = RtlCreateUserThread(NtCurrentProcess(),0,true,0,0,0x4096,(PUSER_THREAD_START_ROUTINE)CallOutRecaptur eRoutine,0,&Reusable,&ClientId);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Failed Creating a CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Successful Creation of CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Reusable,ObThread,ObTSuspended,HandleEn try);//4
//tell the Server the Recycler and Handle Table are functional.
Recycler = true;
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Successful Initialization";
DbgOutput(&Unicode,Status);
#endif
}
}
else
{
//failed. try to repeat a different way..
if(!Native_DestroyHeap((void*)ServerHandleTable))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Failed Destroying Heap During Init";
DbgOutput(&Unicode,STATUS_UNSUCCESSFUL);
#endif
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Success Destroying Heap During Init";
DbgOutput(&Unicode,STATUS_UNSUCCESSFUL);
#endif
Status = NtAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&ServerHandleTable,0,&SizeRegion,MEM_COMMIT | MEM_TOP_DOWN,PAGE_READWRITE);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"NtAllocateVirtualMemory Status:";
DbgOutput(&Unicode,Status);
#endif
__asm
{
jmp NoRecycler
}
}
if(ServerHandleTable)
{
if(Native_InitHandleTable((RTL_HANDLE_TABLE*)ServerHandleTable))
{
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Event0,ObEvent_Sync,ObSignaled,HandleEn try);//0
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Event1,ObEvent_Comm,ObSignaled,HandleEn try);//1
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,NtCurrentTeb()->ClientId.UniqueThread,ObThread,ObPRunning,HandleEntry);//2
Status = RtlCreateUserThread(NtCurrentProcess(),0,true,0,0,0,(PUSER_THREAD_START_ROUTINE)CallOutRecaptureRout ine,0,&Reusable,&ClientId);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Failed Creating a CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Successful Creation of CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Reusable,ObThread,ObTSuspended,HandleEn try);//3
Status = RtlCreateUserThread(NtCurrentProcess(),0,true,0,0,0,(PUSER_THREAD_START_ROUTINE)CallOutRecaptureRout ine,0,&Reusable,&ClientId);
if(!NT_SUCCESS(Status))
{
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Failed Creating a CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif
}
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Successful Creation of CallOutRecapture Thread";
DbgOutput(&Unicode,Status);
#endif
HandleEntry = (SIN32_HANDLE_TABLE_ENTRY*)Native_AddEntry(ServerHandleTable,Reusable,ObThread,ObTSuspended,HandleEn try);//4
Recycler = true;
#ifdef __DEBUG__
RtlInitUnicodeString(&Unicode,L"Successful Alternate Initialization";
DbgOutput(&Unicode,Status);
#endif
}
}
}
NoRecycler:
//Continue to Win32 Mode by connecting to smss
Status = SmSsContinue();
if(NT_SUCCESS(Status))
{
//Start the Server
Native_Server(Recycler,ServerHandleTable,HandleEntry);
}
}
__except(1)
{
if(Event0)
{
NtClose(Event0);
}
if(Event1)
{
NtClose(Event1);
}
if(ServerHandleTable)
{
Native_DestroyHandleTable(ServerHandleTable);
}
}
NtTerminateProcess(NtCurrentProcess(),0);
}


HolyFather Above ?
right..anyone? a smart cookie that one.. :-(
hope he is o.k. wherever he is..

here is a sample debug log I hope to get more of these in the future

'SIN32.exe': Loaded 'C:\Documents and Settings\BanMe\My Documents\Visual Studio 2005\Projects\ProcessProfiler\SIN32\Debug\SIN32.exe', Symbols loaded.
'SIN32.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', Symbols loaded (source information stripped).
'SIN32.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', Symbols loaded (source information stripped).
Succeed in Getting Support Api 0
NtCreateEvent Status: 0
NtCreateEvent Success: 0
Successful Creation of CallOutRecapture Thread 0
Successful Creation of CallOutRecapture Thread 0
Successful Initialization 0
Success Allocating UniqueId 0
Successful SmSsContinue 0
NtCreateSection Status: 0
NtCreatePort Status: 0
NtResetPort Status: 0
NtListenPort Status: 0
Dispatcher Status: 0
First-chance exception at 0x004057b3 in SIN32.exe: 0xC0000005: Access violation reading location 0x00180014.
(null) c0000005NtListenPort Status: 0
SIN32.exe has triggered a breakpoint


these can now be saved from DbgPrint or from a Windbg or even the Visual Studio Debugger as is above example..
So I made it as easy as I possibly could for me to identify bugs and come up with solutions..And hopefully for you as well

regards BanMe