Archive for the ‘bugs’ Category

# zombie slam

back in the old days (UNIX, big iron) zombies were a real headache. what’s a zombie? it’s an orphan child – process without parents. how it might happen? well, guess, a mother process creates a children process and dies leaving the child alone in the dark. does it make a problem? for GUI apps – no problem, but console apps – are very different.

in general console apps share the same console. if we run cmd.exe from Explorer it creates a new console, but when we run format.com from cmd.exe – format.com uses the same console. it’s oblivious. oh, really?! NT is not MS-DOS!!! creating a new process (format.com) does not suspend the parent (cmd.exe). so, cmd.exe is still running. it would make a mess, if cmd.exe did not wait for finishing of format.com.

if you guys developed console shell you probably know that CreateProcess follows by WaitForSingleObject(hHandle,,) where hHandle – is handle of the created process. now, guess, the child process creates a sub-child and dies. WaitForSingleObject() returns control, but the sub-child is running and shares the same console!!!

consider the following code or download sources and binary:

// if it’s child process – output message to the console
if (c > 1) while(1) printf(“\rI’m a zombie [%c]$”, x[++c % sizeof(x) - 1]), Sleep(69);

// creating a child and terminating itself
memset(&pi, 0, sizeof(pi)); memset(&si, 0, sizeof(si)); si.cb = sizeof(si);
if (!CreateProcess(v[0], “Im zombie”, 0, 0, 0, 0, 0, 0, &si, &pi)) return printf(“-ERR:create_proc\n”);

run cmd.exe and type “zombie_bug.exe” (with extension!). wow!!! a very modern command prompt with a rotating fan! you can type cmd’ commands and they will be executed, but the rotating fan is working!!! now, start FAR manager and run zombie_bug.exe. ops! FAR has the same bug and our zombie is working again!!!

what’s it good for? fist of all we can create “resident” programs living in foreign consoles (use console API to output text into desired positions). another idea – zombie can intercept all input and if zombie output nothing to the console – nobody notices it!!! a good stealth spy.

what we’re going to do? does anybody want to send a bug report to Microsoft and FAR manager team?

zombie - alone in the dark

zombie - alone in the dark

 

# Process Explorer – bloody hell of indefinite waiting bugs

long time ago I found a bug in Process Explorer pointing out that it uses wrong algorithm of retrieving Thread Start Address. all threads created with CreateRemoteThread has Thread Start Address pointing to KERNEL32.DLL. it’s true, but help- and sense-less. I sent my bug report to Mark, but got no answer and posted it on my old blog: “bug in Process Explorer (a gift for malware)

it means that Process Explorer is not reliable enough, we can’t trust it anymore and yesterday I found more bugs. they’re very common and almost _every_ application has numerous bugs like this. are you intrigued? well, lets begin!!!

download to_attach_ldr.exe (anti-attach trick, based on damaged PEB=>PPEB_LDR_DATA – read this post for more info), run it and… ask Process Explorer to display properties of “to_attach_ldr.ex” process (yeah! “ex”, not “exe” – another bug?!). now, go to “Threads” tab and…

ops!!! Process Explorer freezes falling into infinitive loop with 100% CPU load. ~60% is to_attach_ldr.exe and ~40% is CSRSS.EXE. ok, close to_attach_ldr.exe and Process Explorer immediately wakes up. this means it just was waiting the even that was not going to happen.

ok, another example. download to_attach_33.exe (anti-attach based on intercepted NtRequestWaitReplyPort, described here ). run it and ask Process Explorer to show properties, go to “Threads” tab and… you know what will happens in the next moment. freezing!!!

freezing Process Explorer

freezing Process Explorer

we just found out how buggy Process Explorer is. but why? what’s the issue? the answer: NT has numerous functions like WaitForSingleObject, WaitForDebugEvent, etc. they all take dwMilliseconds argument specifies time to wait for an event. if the parameter is INFINITE, the function does not return until an event has occurred. the problem is – almost every programmer uses INFINITE and does not handles time out error. admit, you did this too?

Ilfak does for sure and I pointed out it before (“another EnableTracing() bug“).

ok, we got two points. first – never use INFINITE unless you’re 100% sure it works. the second point: if malware creates a malicious thread inside a trusted application – anti-attach tricks help it to survive. many anti-viruses are unable to enumerate threads in this case and some of them just freezes. very effective DoS attack against pro-active protections!!!

note: I tested Process Explorer 11.4 under W2K SP4, not tested other versions yet, but guess the bug is there.

 

# NtRequestWaitReplyPort abuses IDA-Pro

good news first. my simple anti-anti-attaching plug-in is coming soon and it works very well. meanwhile, I’m experimenting with different anti-attaching technologies and wish to share a few new (old?) tricks with you.

well, the method based on NTDLL!DbgBreakPoint (see “try to attach to me: if you can!” ) is not good enough to hurt IDA-Pro. like Ilfak said – just set “Stop on debugging start” checkbox in the debugger options to stop IDA-Pro _before_ NTDLL!DbgBreakPoint. how it’s going to help?! nothing! but we will try. press F7 several times. go to Debug\Open subviews\Open threads. do you see two threads there? one is the main thread of the app, another – the system tread, created by DebugActiveProcess() API. the point is – we don’t need the system thread anymore. we should kill it. why? the debugged application might inject bad code into it. but IDA-Pro does not allow us to kill treats.

OllyDbg does. ok, run Olly, go to Options\Debugging options\Events\Break on new thread [x]. Attach to the to_attach_31.exe. ok, OllyDbg has been stopped. now, View\Threads. do you see two threads there? current thread is the system thread. kill it! (context menu\kill thread). um, the thread does not want to die. don’t worry it’s almost dead. now, click another thread (the main), context menu, actualize it and start tracing the main thread step-by-step or just press F9 to run. the system thread is disappeared. there was injected code displaying “shit happens”, but since the thread has been killed – no shit!!! everything is just fine!!!

this is universal technology. I tested it on large malware/protectors collection and it works well! at least for Olly. for IDA-Pro we need to write a script or plug-in, killing unwanted threads.

ok, forget about NTDLL!DbgBreakPoint. back to IDA-Pro. “Stop on debugging start” is set, IDA-Pro attaches to the process (any process you want) and stops. where it stops? let me see…

NTDLL!77F88B6C ZwRequestWaitReplyPort proc near
NTDLL!77F88B6C mov eax, 0B0h ; NtRequestWaitReplyPort
NTDLL!77F88B71 lea edx, [esp+arg_0]
NTDLL!77F88B75 int 2Eh
NTDLL!77F88B77 retn 0Ch ; << here NTDLL!77F88B77 ZwRequestWaitReplyPort endp

so, IDA-Pro stops at NTDLL!77F88B77, when NtRequestWaitReplyPort NTCALL has been executed, so NtRequestWaitReplyPort (called by CsrClientCallServer) is executed _before_ stop. thus, if we intercept NtRequestWaitReplyPort – it will be easy for us to abuse IDA-Pro or do something unexpected. and IDA-Pro has nothing to do this it.

the problem is: NtRequestWaitReplyPort is very popular function and it’s used not only by debugger. so, we can’t just intercept it. we have to check the caller – the thread ID.

for example:

mov eax, fs:[18h] ; // *TIB
mov eax, [eax+24h] ; // CurrentThreadId
sub eax, [our_tid] ; // ?another Thread
jz to_old ; // => no dbg

; // perform stack overflow
die: push eax
jmp die

; // all ok, passing control to the old func
to_old: jmp ds:[old_NtRequestWaitReplyPort]

I wrote a simple POC, abusing IDA-Pro and OllyDbg. download it, run exe. do you see message – “attach to me”? well, ask Olly to attach. Olly attaches without any problems, but… the string changes to “debugger is detected” and the process is still running. wow!!! of course, we can stop the process and continue tracing, but… the point is – the debugger has been detected. how? I just injected my code into NtRequestWaitReplyPort to set global flag if we’re under debugger. the main thread checks this flag and changes its behavior if we’re under debugger. of course, in this simple case we can fix it after attaching, but imagine what happens if the injected code will wipe out all code of the app or destroy the critical structures or just free a few memory blocks cause random crashes?

OllyDbg stops too late. our code injected into NtRequestWaitReplyPort executes before, and debugger has no control under it. what’s about IDA-Pro? try to attach to to_attach_33.exe (all check box in debug options are set). what do we see? the protection tell us “debugger is detected”, the process is running, but IDA-Pro‚Ķ freezes. what she is waiting for? and how to save our database? we don’t want to kill IDA-Pro, don’t we? right! kill to_attach_33.exe with Process Explorer. IDA-Pro will return from dead to alive.

IDA-Pro 5.3 fails to attach

IDA-Pro 5.3 fails to attach

well, who will break this simple crack me? who will find the way how to attach to the process do not disturbing the protection?

 

# attach to me… if you can (part II)

the previous post describes how to intercept attaching, but that way does not prevent attaching itself. as it happens there is a simple and elegant way to block any attaching attempts. just wipe out PEB=>PPEB_LDR_DATA field. the application is running well, the process is present in the processes list of Task Manager/Process Explore, but… it’s not listed in the Olly 1.10/Olly 2.00i attach windows!!!

to_attach_ldr.exe is not present in the attach windows!

to_attach_ldr.exe is not present in the attach windows!

ok, guys another plan! load the file directly into OllyDbg 1.10 in order to debug it. can we debug it? well, yes, but… no. OllyDbg 1.10 does not show us the module list (so, how we’re supposed to set breakpoints on API?) and the map window is empty as well. OllyDbg 2.00i and IDA-Pro 5.3 have no such problem.

IDA-Pro 5.3 can’t attach to the process as well, she just freezes!!! and there is nothing to do but terminate IDA-Pro with all changes we have made. a very nasty bug!

the source code is extreme simple. see it bellow or download.

__asm{
mov eax, fs:[30h] ; // PEB
mov [eax + 0xC], eax ; // damage LdrData to prevent attaching
}
// do something
while(1) printf(“\rattach to me [%c]“,x[++a % (sizeof(x)-1)]), Sleep(100);
}

so, you get it. any ideas how to hack it? does anybody know the way how to attach to the process?

note: Elias Bachaalany checked IDA-Pro 5.4 (both with WinDbg plug-in and build-in win32 debugger). it does not freeze, but attached is code crashed inside NTDLL.DLL and IDA catches a lot of exceptions, so this trick works for IDA-Pro 5.4 as well. it’s not IDA-Pro bug! and IDA-Pro has nothing to do to fix it.

 

# self-overwritten REP STOS/MOVS, IDA-Pro 5.4 and Ko

once upon a time was MS-DOS and ancient debuggers like Turbo-Debugger, Soft-Ice and many others. and there were anti-debug tricks. one of them was based on self-overwritten REP STOS/MOVS instruction. it worked great against all existing debuggers, including CUP 386 (exe unpacker with build-in CPU emulator).

I used this tricks for years. I would almost forget about if Silviocesare not posted “Anti-debugging prefetch tricks and single stepping through a rep stos/movs” article on his blog (very nice blog, btw).

I was interested: what’s about modern debuggers? what’s about emulators like BOCHS? what’s about IDA-Pro 5.4 with BOCHS-based debugger? imagine, how surprised I was when I found out that IDA-Pro 5.3, Olly 1.10 and Soft-Ice not only can be detected this way, but also lost the control during step over tracing! debugged code just escapes out of the debugger!!! IDA-Pro 5.4 with BOCHS module fails to emulate the self-overwritten REP STOS/MOVS instruction (so it can be detected as well) and lost control on Step Over tracing. only Olly 2.00i recognizes attempts to espace and blocks them, however it can be detected the same way.

for testing reasons I wrote a simple program with self-overwritten REP STOSB command (see source bellow).

std
xor ebx, ebx
mov al, 43h ; // INC EBX
mov edi, offset end_of
mov ecx, 6
REP STOSB
NOP
NOP
NOP
end_of: NOP
cld

download it, load into IDA-Pro 5.3 and start tracing REP STOSB instruction (F7 hot key). what do we see? REP STOSB changes NOP to INC EBX, overwrites four commands and overwrites itself (STOSB). since, during tracing CPU generates a single step exception every iteration, REP STOSB becomes REP INC EBX and as far as we all know, REP works only with string commands, so REP INC EBX is not executed and REP loop finishes with ECX = 1.

now, run the program without tracing. CPU pipelines REP STOSB and executes it until ECX > 0. REP STOSB modifies only data cache, while the instruction is executed on the pipeline and CPU does not recognizes modification of the code, so REP loop finishes with ECX = 0.

Olly 1.10/200i and Soft-Ice also fails to trace self-overwritten REP STOSB instruction. of course, if we trace the program with our hands, it’s easy to set a breakpoint _after_ it and run the code without tracing, but!!! many plug-ins use trace engine for their needs, so the trace engine should work fine and it’s possible to fix debuggers – just before executing REP STOS/MOVS we have to perform some checks and if the command overwrites itself we either set a breakpoint either emulate CPU behavior.

ok, run the program under BOCHS (IDA-Pro 5.4 support a special plug-in, allowing us to debug code on the fly). regardless of whether we trace program or not, the REP loop finishes with ECX = 1. well-known x86-emu plug-in gives us the same result, and this result is definitely wrong.

by the way, did I hear a question: how long CPU is executing overwritten REP STOS/MOVS command? there is no universal answer. it depends on CPU internal behavior and external evens like interrupts. when an interrupt is generated, CPU stops executing overwritten REP STOS/MOVS. a good way to create a pseudo-random generator! I’m going to write about it in the next post.

meanwhile, some CPU have a bug. they executes CLD commands _before_ overwritten REP STOS/MOVS will be stopped or finishes. as result, REP STOS/MOVS changes the direction and hits the memory not supposed to be written. I’m investigating this case now, will publish the result soon.

well, let’s return to our muttons. load the program into IDA-Pro 5.3/5.4 and perform Step Over tracing. move cursor to REP STOSB, press F8 and… the debugger lost the control!!! why? the answer is: to gain control back after REP STOSB command IDA-Pro sets a software breakpoint on the next command. we all know that a software breakpoint it’s just INT 03 (CCh) instruction and in our case this instruction is overwritten by REP STOSB. thus the breakpoint is wiped out and the process is executed until another breakpoint will be triggered. if there is no other breakpoints – the debugged code escapes out of the debugger!

what’s about Olly 1.10 and Soft-Ice?! fast check shows us like they do not lost the control and stop after REP STOSB. but… how they do it? well, they just use hardware breakpoints!!! and if all four hardware breakpoints are in use, the debuggers set a software breakpoint like IDA-Pro does, so they lost control as well. not good!

Olly 2.00i (didn’t check other versions) is the only debugger who is able to detect that the breakpoint was wiped out. if it happens we have a warning message. impressive! Olly 2.00 is a great debugger doubtless!!!

 

# IDA-Pro 5.4: old bugs on the new streets (was: to download or to not download)

IDA-Pro 5.4 has been released. aside of many positive changes it’s just a huge bug-fix. take the old bug with zero-based PE-files for example. I reported it to Ilfak long before 5.3. now it’s fixed and following pictures taken by Elias Bachaalany (the clever guy working for hex-rays) proves it.
not good for me, coz I was going to talk about it (and many other IDA-Pro bugs) on Code Gate 2009 security conference in South Korea . well, never mind. I have enough time to redesign my syllabus

dead bug

dead bug

TLS flooding bug (also discovered by nezumi) has not been fixed yet. um, going to write a short article how to fix it with _your_ hands.

 

# FreeLibrary bug becomes a PE packers bug

there is a way to find out if a program was packed or not. XP/S2K3 has a bug that has to be taken into account unless a packer wants to crash a packed program.

FreeLibrary() does not unload statically linked libraries, but frees dynamically linked ones. consider the following code. it should work. at least it works on XP/S2K3 (W2K is a bug free):

// get USER32 module handle
HANDLE h; h = GetModuleHandle(“USER32.DLL”);

// free the library (3 times just to guarantee the reference count is zero)
FreeLibrary(h); FreeLibrary(h); FreeLibrary(h);

// time to unload
Sleep(3000);

// call any function from statically linked USER32
MessageBox(0,”:-)”,”[x]“,0);

ok, now remove USER32 from the import table and load it on the fly.

// load USER32 and get the module handle
HANDLE h; h = LoadLibrary(“USER32.DLL”);

// free the library (3 times just to guarantee the reference count is zero)
FreeLibrary(h); FreeLibrary(h);FreeLibrary(h);

// time to unload
Sleep(3000);

// call any function from dynamically linked USER32
(int (WINAPI *)(int, char*, char*, int)) GetProcAddress(h,”MessageBoxA”)(0, “:-)”, “[x]“, 0);

wow! the program crashes!!! interesting… but… it has nothing to do with packers! um, actually it has. some packers (and especially protectors) leaves only KERNEL32.DLL there and loads the rest on the fly.

guess, we have a file with statically linked libraries. guess, the program frees one or more libraries doing it deliberately or maybe there is a bug. this bug does not appear, coz FreeLibrary not unloads statically linked DLLs. imagine what happens if we pack the file by packer removes all DLL from the import table? the answer: the program will crash!!!

download the POC (original exe and file packed by RLPack) and test your packer/protector collection.

 

# MS VC – challenge for PE packers

blackd0t () started working on his own PE packer and reached the moment where everything is fine, but MSVC++ 2005 floating point files refuse to work and end up with the runtime error: “R6002: floating point not loaded error” . it’s a common problem. many commercial packers meet the same bug.

well, let’s find out what’s this bug all about! first of all I wrote a simple floating-point program and translated it with Microsoft Visual C++ 2008 (Express). the source code is followed (if don’t have MS VC under your hands, just download the archive):

int a; double x = 1.2f;
for (a = 0; a < 10; a++) x += sin(x); cout << x; return 0;

ok. run it and get 3.14159. the program runs fine! now, we’re going to make “.rdata” writable. why? blackd0t mentioned what he already found out: if “.rdata” is writable, we get the error. the question is why?! maybe there is a bug: if .rdata section is writable – floating point library damages critical data, maybe not, who knows?

open exe with HIEW, press ENTER to go to hex-mode, F8 to call PE-header, F6 for ObjTable, move cursor to “.rdata”, F3 to edit, find “Attributes” there, F3 to edit, change the highest bit from 0 to 1 and press F9 twice to save changes. ESC (twice) to exit.

ops! now we see:

$R6002bug-demo.exe
runtime error R6002
- floating point support not loaded

ok. run HIEW and restore the attributes back. everything works fine as before. load exe into OllyDbg, View -> Memory, find “.rdata” and set memory breakpoint on write. run the program. the program runs fine, nobody tries to write something to “.rdata” section. hm… strange…

ok, ask HIEW to make “.rdata” writable again, reload the file into OllyDbg and run it (with memory breakpoint). the program does not work (the same error), but our breakpoint has been not triggered. what’s a helll?!

make “.rdata” non-writable, reload the file into OllyDbg, View -> Memory and change access of “.rdata” section to RW. run the file. no error! the program works fine.

ok. we got it!!! the floating point library checks not access attributes themselves, but verifies PE-header. go to dump windows (in Olly). press CTRL-G and type the address of the header (400000h in this case). find “.rdata” there and move cursor to 40 00 00 40 (the last DWORD before “.data”). set hardware breakpoint on access and press F9 to run the program, the breakpoint is triggered!!!
how do you like this:

.text:0040E780 __IsNonwritableInCurrentImage proc near
.text:0040E780
.text:0040E782 push ebp
.text:0040E783 mov ebp, esp

.text:0040E7C1 call __ValidateImageBase

.text:0040E7D6 push 400000h
.text:0040E7DB call __FindPESection
.text:0040E7E0 add esp, 8
.text:0040E7E3 test eax, eax
.text:0040E7E5 jz short loc_40E822
.text:0040E7E7 mov eax, [eax+24h] ; !!! breakpoint is triggered here !!!
.text:0040E7EA shr eax, 1Fh

_IsNonwritableInCurrentImage() reads PE-header in order to checks – if its argument belongs to non-writable section.

so, packers are obligated to keep original PE sections layout (or restore only PE header in memory) unless they want to crash floating point applications translated with MS VC and maybe other compilers.

thanks blackd0t for the interesting question!

I wonder: how may packers/protectors will be unable to process this file? going to find out. plz, test all packers/protectors you only have under your hands and leave comments. time to send bug reports :-)

first of all it’s bug of MS RTL – bitch should check real page attributes, not just PE-header!

second of all: numerous packers/protectors do not restore PE-header or damage it to prevent dumping or… disables all PE-header pages (PAGE_NO ACCESS)

 

# chilly suspicions of new win32 bug

wandering over Windows kernel nezumi found very screwy code – another loophole to bypass DEP. W2K SP4 gives PEB/TEB r-w-x attributes, so, PEB and TEB are executable! easy to check it with OllyDbg (View -> Memory).

W2K SP4 gives PEB/TEB r-w-x attributes

W2K SP4 gives PEB/TEB r-w-x attributes

XP SP3 and S2K3 SP1 come without this bug, but what’s about other systems? let’s found out! please, download a simple system info collector (it comes with full sources), run it and send the result to info#re-lab.org or leave your comment here. it’s absolute safe for your system. no harm, no fault.
thanks in advance!

results:
W2K SP4: PEB/TEB are executable;
XP SP3: PEB/TEB are _not_ executable;
S2K3 SP1: PEB/TEB are _not_ executable;

 

# 3 lines C-prog hurts MS VC

do you trust your compiler? do you complete “secondhand” sources? yeah, we all do that. but do you know that evil sources might hurt your compiler and sometimes even abuse your host OS (if compiler works inside guest VM Ware/Virtual PC environment). no MS specific extension! just pure ANSI C!

well, try this…

#include “stdio.h”
#include “limits.h”
int hack[INT_MAX] = {1,2,3};
main(){
printf(“hello world!\n”); return hack[INT_MAX-1];
}

what happened? oh… trying to create a very big array (2Gb!) complier fed up all memory and end up with error. if you don’t have enough physical memory and page file is not disabled – OS is hunting hdd for a long time, slowing down the whole system.

the same trick works with some assemblers – just define a huge array (TASM and MASM are affected).

I wonder: how many translators have this bug? please, download the source code, try to compile it and mail result to info#re-lab.org or leave your comment here. please, test every translator you have under your hands. not only C/C++ but DELPHI/Pascal/ASM as well. thanks!