PDA

View Full Version : rekindled hope (maybe)


BanMe
07-14-2009, 09:26 PM
I really don't like to give up on things..
I want Allocate a console from a Native Mode Application..

I tried dynamic calling of the function and it succeeds but nothing is displayed, because I we are running in Session 0.. This can be bypassed..I know it can..

Elicz did it in w32asap with user32 api..and a crafted call to CreateProcess..

So In my fishing of the net, I found a question about "Starting a process on the winlogon desktop in session >0" by andrewb (#1) .. and his question gave me a idea..

If I can obtain the token of explorer.exe I can use it in my call to specially recrafted AllocConsole and hopefully get the Window to show up...I've got a clear view of the solution now.. hopefully i can implement it ;] and if I cant implement it this way the backup plan is to hijack my own token to make my window show up..but after that I think I might be outta gas..except for spawning from the client.

(#1)
http://www.eggheadcafe.com/software/aspnet/30999838/starting-a-process-on-the.aspx

regards BanMe

BanMe
07-14-2009, 10:49 PM
Code:

enum { OB_TYPE_UNKNOWN = 0, OB_TYPE_TYPE = 1, OB_TYPE_DIRECTORY,
OB_TYPE_SYMBOLIC_LINK, OB_TYPE_TOKEN, OB_TYPE_PROCESS,
OB_TYPE_THREAD, /*OB_TYPE_UNKNOWN_7,*/ OB_TYPE_EVENT,
OB_TYPE_EVENT_PAIR, OB_TYPE_MUTANT, //OB_TYPE_UNKNOWN_11,
OB_TYPE_SEMAPHORE, OB_TYPE_TIMER, OB_TYPE_PROFILE,
OB_TYPE_WINDOW_STATION, OB_TYPE_DESKTOP, OB_TYPE_SECTION,
OB_TYPE_KEY, OB_TYPE_PORT, OB_TYPE_WAITABLE_PORT,
/*OB_TYPE_UNKNOWN_21, OB_TYPE_UNKNOWN_22, OB_TYPE_UNKNOWN_23,
OB_TYPE_UNKNOWN_24,*/ OB_TYPE_JOB, //22 on Whistler
//OB_TYPE_CONTROLLER, OB_TYPE_DEVICE, OB_TYPE_DRIVER,
OB_TYPE_IO_COMPLETION, OB_TYPE_FILE, OB_TYPE_WMI_GUID,
};


the methodology now to do this is to Pole the Real HandleTable for "explorer.exe", then duplicate out all the handles I need...
ep_x0ff wrote about using the handle table to bypass the protections of a AV..

located here http://www.rootkit.com/board.php?did=edge778&closed=1&lastx=15

It was a delphi implementation of using the handle table..I translated it to C++ and repurposed it to work genericly ( I posted that code ).. so that is what I am going to use as the base.. just a little restructuring and hopefully this method will work..as a sufficient way to get the handles I need without calling "suspicious" API's

regards BanMe

Kayaker
07-15-2009, 11:44 PM
I'm just curious BanMe, which I know is a dangerous thing, but what are you going to use the console window for? To inform the user, yes, but is it to allow user interaction? i.e. are you going to be able to pause Windows booting if something "of interest" happens and get user input?

If it's only for informational purposes, wouldn't NtDisplayString on the boot screen work? Or, just log all the info to a buffer and spit it out when you can create a legit console.

I know it's more fun to force a console "when I want it dammit"

A thought, if you get a console showing, will it always be visible to the user (stay topmost) throughout the boot process, through to the desktop appearing?

Cheers,
Kayaker

BanMe
07-16-2009, 09:04 AM
Idea is to have a "interface" that can take user input. this interface will also be used for output. the "input" will be for directing the "client" to do specific actions(ie load plugins, send code, so forth..

NtDisplayString will only work on the "boot screen" and this will not work directly after the call to SmSsContinue..as there is no more boot screen

Im not sure about "topmost" always and it wont be started until after the "boot" process is done and explorer is "loaded". because in order to get a handle to the window station and desktop i have to pole the System HandleTable for "explorer.exe" albeit the "test" just before I run Native_Server in the "new" code.

hope this help

regards BanMe

BanMe
07-16-2009, 08:37 PM
Heres how I'm gonna search for explorer..I updated the code for this cause it was not to my liking...still more modifications to do to this but Ill post this and explain how im gonna use it to wait for a process

*removed buggy code*

So apparently this is "not" a good method cause it never obtains the right amount of memory to "write" the handle table into. resulting in a infinite loop of allocating and releasing memory..and the hated "low virtual memory" message from windows.

so to combat this Im going to just allocate 10 pages 0x40960 of memory and skip the "proper" way to do it..also thanks to Kayaker for showing me how to "setup windbg in vmware" in one of his earliar postings I think in the "server thread recycling" thread..the only thing I can add to that is if SIN32 is running as a "subsystem" you should use NtGlobal program to allow debugging of the subsystem

The New Code for this little bit will be up soon as well as Im adding OBJ_TYPE_WINDOW_STATION and OBJ_TYPE_DESKTOP to the object types available to be queried with this function,
Currently It only works with OBJ_TYPE_PROCESS and OBJ_TYPE_THREAD (5 and 6) respectivly.

Hope you enjoy

regards BanMe

BanMe
07-17-2009, 04:18 PM
this code should work properly

Code:

HANDLE Native_DuplicateHandleInProcess(wchar_t *pName,ULONG HandleType)
{
THREAD_BASIC_INFORMATION tbi = {0};
POBJECT_NAME_INFORMATION oni = {0};
CLIENT_ID Cid = {0};
OBJECT_ATTRIBUTES oa = {0};
PSYSTEM_HANDLE_INFORMATION_EX buf = {0};
PUNICODE_STRING pnb = 0;
HANDLE hCProcess = INVALID_HANDLE_VALUE,TempHandle = INVALID_HANDLE_VALUE;
NTSTATUS Status = 0;
ULONG Reusable = 0x40960;
BOOLEAN test = 0;
InitializeObjectAttributes(&oa,0,0,0,0);
__try
{
SzMismatch:
buf = (PSYSTEM_HANDLE_INFORMATION_EX)RtlAllocateHeap(RtlProcessHeap(),HEAP_ZERO_MEMORY |HEAP_GROWABLE,Reusable);
Status = NtQuerySystemInformation(SystemHandleInformation,buf,Reusable,&Reusable);
if(Status == 0xC0000004 )
{
if(RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf))
{
__asm jmp SzMismatch;
}
}
if(!NT_SUCCESS(Status))
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
return INVALID_HANDLE_VALUE;
}
for(Reusable = 0;Reusable < buf->NumberOfHandles;Reusable++)
{
if(buf->Information[Reusable].ProcessId != 4)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_PROCESS)
{
Cid.UniqueProcess = (PVOID)buf->Information[Reusable].ProcessId;
Cid.UniqueThread = 0;
Status = NtOpenProcess(&hCProcess,PROCESS_ALL_ACCESS,&oa,&Cid);
if(hCProcess != INVALID_HANDLE_VALUE)
{
pnb = (PUNICODE_STRING)RtlAllocateHeap(RtlProcessHeap(),HEAP_ZERO_MEMORY|HEAP_GROWABLE,0x1024);
Status = NtQueryInformationProcess(hCProcess,ProcessImageFileName,(PVOID)pnb,0x1024,0);
if(pnb->Buffer != NULL)
{
PWCHAR cpn = (PWCHAR)pnb->Buffer;
USHORT cln = pnb->Length;
do
{
cpn++;
if(wcscmp(pName,cpn)== 0)
{
switch(HandleType)
{
case OB_TYPE_PROCESS:
test = RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
test = RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
return hCProcess;
case OB_TYPE_THREAD :
Reusable = 0;
do
{
if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_THREAD)
{
Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
Status = NtQueryInformationThread(TempHandle,ThreadBasicInformation,&tbi,sizeof(tbi),0);
if(tbi.ClientId.UniqueProcess == (PVOID)Cid.UniqueProcess)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
NtClose(hCProcess);
return TempHandle;
}
}
}
Reusable++;
}while(Reusable != buf->NumberOfHandles);
case OB_TYPE_WINDOW_STATION:
Reusable = 0;
do
{
if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_WINDOW_STATION)
{
Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
if(TempHandle != INVALID_HANDLE_VALUE)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
NtClose(hCProcess);
return TempHandle;
}
}
}
Reusable++;
}while(Reusable != buf->NumberOfHandles);
case OB_TYPE_DESKTOP:
Reusable = 0;
do
{
if(buf->Information[Reusable].ProcessId == (USHORT)Cid.UniqueProcess)
{
if(buf->Information[Reusable].ObjectTypeNumber == OB_TYPE_DESKTOP)
{
Status = NtDuplicateObject(hCProcess,(PHANDLE)buf->Information[Reusable].Handle,NtCurrentProcess(),&TempHandle,0,0,DUPLICATE_SAME_ACCESS);
if(TempHandle != INVALID_HANDLE_VALUE)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
NtClose(hCProcess);
return TempHandle;
}
}
}
Reusable++;
}while(Reusable != buf->NumberOfHandles);
default :
return INVALID_HANDLE_VALUE;
}
}
cln--;
}while(cln);
}
}
}
}
}
if(pnb)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
}
if(buf)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
}
if(hCProcess)
{
NtClose(hCProcess);
}
if(TempHandle)
{
NtClose(TempHandle);
}
}
__except(1)
{
if(pnb)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)pnb);
}
if(buf)
{
RtlFreeHeap(RtlProcessHeap(),0,(PVOID)buf);
}
if(hCProcess)
{
NtClose(hCProcess);
}
if(TempHandle)
{
NtClose(TempHandle);
}
}
return INVALID_HANDLE_VALUE;
}


added the previously described features and bugfixes and "debugged" it a few times, I also added Handle Leak Prevention and buffer clean up.

regards BanMe

BanMe
07-17-2009, 07:18 PM
Ok so that didn't solve it either, but the code works "If" Initialization has ended and the handle table isnt growing every millisecond..so I have a few options left to consider to solve this..

First one is using NtDelayExecution after the call to SmSsContinue..Otherwise it just waits at the boot screen..
this is not a good solution because system boot times vary from system to system.

Second option is to wait for a client to Connects to do the call described above..
The 2nd option has the added benefit of being "reliable behavior" on slower systems..
and the benefit of not trying to get the handletable, when handles are being added to it constantly.. so the 2nd one it is

regards BanMe

BanMe
07-19-2009, 04:57 AM
BBQ ?

wtf i forget about most basic IPC when deving a complex one..I forgot about named pipes and the first thing I code used them..(it was in perl and wsc format..Telnet.TelnetAdmin..might be out there still...)..but damn basic IO..not good .. :[ losing my mind ]: or have i lost it already? hmm...

regards BanMe