vulnerability in… WinCalc (Win7, x64)

I will never go out of business in this country. thanks to Microsoft. who would have thought that wincalcis vulnerable? I have not checked all systems yet, so this is my configuration: Windows 7 Ultimate SP1 x86-64, English.

1) run calc.exe;
2) press “Alt-2″ to go to “Scientistic” mode (“Programmer” mode works too);
3) type “1/255″ and press [ENTER] or [=]
4) press the button [F-E];

ops! shit happens!

I live in Reston, Virginia and would like to meet local hackers to analyze this crash and talk about possibilities of real exploitation of this bug. please, contact me: poldhiir#gmail^com

Problem signature:
Problem Event Name: APPCRASH
Application Name: calc.EXE
Application Version: 6.1.7600.16385
Application Timestamp: 4a5bc9d4
Fault Module Name: ntdll.dll
Fault Module Version: 6.1.7601.17725
Fault Module Timestamp: 4ec4aa8e
Exception Code: c00000fd
Exception Offset: 0000000000053560
OS Version: 6.1.7601.

wincalc crash

the bug was found by: Nuzhny


# faked Adobe PDF.SWF exploit on milw0rm

on July-23, milw0rm uploaded “Adobe Flash (Embedded in PDF) LIVE VIRUS/MALWARE Exploit” written by @hdmoore who states that it’s (I quote) “live exploit sample for the new Flash bug (embedded in PDF)“, which is far from the truth.

the truth is – it’s the old getIcon exploit having nothing to do with the new vulnerability in ActiveScript Virtual Machine. the real worms (described here ) uses PDF with two embedded SWF files, one – triggers the bug, another performs heap-spraying and generates the shell-code on the fly! yeah! it uses Active Script byte-code (which is not plain text like JavaScript, it’s more like Java byte-code) to generate the shell-code, so there is no unescape strings, so my shell-detector fails to find it (of course it fails, it does not support Active Script byte code, at least not yet).

I will write about the real SWF exploit tomorrow. today we’re going talk about that faked exploit. it’s pretty interested as well. the first thing we have to do is to decompress all streams. it’s easy. zlib support that format, we just should write PDF parser… should we?! oh, not really!!!

according to RFC-1950 a zlib stream has the following structure: CMF_FLG (more–>). so, we can just look for CMF_FLG header, trying to decompress every stream we meet – very useful universal decompressor, supporting now only PDF, but much more (HTTP streams for example).

FLG filed has 4 bits FCHECK checksum and the header itself is quite predicable, so it’s easy to find a potential ZLIB header inside a byte stream. how to defeat false positives? (2byte header is too short to be reliable enough). well, no problem guys! if we found something looks like CMF_FLG just try to unpack the first 512 bytes by zlib inflate() function. if it fails it means – false positive, otherwise we have to call it again to unpack the rest.

ok, all streams of hereEvil.pdf are decompressed. 15th stream is JavaScript with a large Array contains unescaped string. looks like a shell-code, but hell no! decode it with a simple deURI converter and… ops!!! another JavaScript!!! yes!!! exploit inside exploit, nested obfuscation. could you believe me?! I just improved my shell-code locator, adding recursive filtering support (zlib-decompror and unescape decoder – basically are external filters for the locator engine). I have not released the new version yet, just was testing in and… wow!!! I met the exploit that really uses the nested JavaScripts for better obfuscation! well, just in time, just in time…

NOTE: if you have no idea how to write deURI decoder, download ECMA-262.pdf (ECMAScript Language Specification) and go to section “B.2.2 unescape (string)“. there you will find unescape decoder, written in pseodo-code.

the second (underlined) layer is not interested. it’s just Array with uneascape string contains the real shell-code includes well-known ["doc"]["Collab"]["getIcon"]. do they look familiar?! of course they do!!! it’s the old getIcon exploit, just more obfuscated.

now, about the shell-code. it’s very simple, don’t even encrypted. this is what my shell-code locator said:

XOR key: 00 00 00 00 (00000000h)

ok, open the file with HIEW, go to 19h offset and see:

00000019: mov eax,[eax][0C]
0000001C: mov esi,[eax][1C]
0000001F: lodsd
00000020: mov eax,[eax][08]
00000023: jmps 00000002E —

yep, a typical KERNEL32 base address finder. what’s else?! the most interesting thing is — the shell-code has text strings. just look at them:

URLMON.DLL, URLDownloadToFileA, update.exe, crash.php,

wow!!! the domain name!!! I checked it and found out that is down, so I went to who is who service and… ops! surprise!!!

WHOIS information for
* Registration Service Provided By: DOMAIN NAMES REGISTRAR REG.RU LTD.
* Contact: +7.4955801111
* Domain Name: VIORFJOJ-2.COM

Private person
Dmitry Ostupin (
ul. Malaya Semenovskaya, d.5, kv. 28
g. Moskva
g. Moskva,107023
Tel. +7.4952240537

Creation Date: 08-Jul-2009
Expiration Date: 08-Jul-2010

Russian guy! that’s a deal! I have no idea whether he is the author of the exploit or maybe his server was used by another person, but I wonder… I wonder… going to give him a call tomorrow just out of curiosity.

well, maybe I should not public his contact info here because of etiquette, but… why not?! the exploit was taken from the public source, the hard-coded domain name was found, so… everyone can use the whois service to get this contact info.

well, what we’re going to do on ISP side? if you meet a packet from/to it means the host is infected and the packet should be blocked. well, since the server is down – obviously all major ISPs had blocked it already.

faked exploit on milw0rm - it has nothing to do with the real SWF security hole

faked exploit on milw0rm - it has nothing to do with the real SWF security hole


# weakness of PAGE_GUARD or new Windows bug (XP/Vista 32/64 SP1)

simple, but effective system independent anti-debug trick based on well-documented APIs and does not involve assembly inline (means: it could be implemented in pure C). also it works as anti-dump sensor.

caution: I would recommend do _not_ use this thick in production code, because it’s based on the bug (two bugs actually: one in Windows, another in OllyDbg), which could be fixed at any moment. however, noting terrible happens if the bug would be fixed – the application just could not detect debugger/dumper.

in passing: I found this bug working on the project for a spectrography cherry group, well, not a cherry actually, but I prefer to keep the real name if it under the mat, anyway it’s all about Ciscar Fon – my first love, a gothic type, very kinky and yet creative.

in a nutshell: the whole idea based on PAGE_GUARD attribute. SDK says: “any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE (80000001h) exception and turn off the guard page status… if a guard page exception occurs during a system service, the service typically returns a failure status indicator“. wow! how I like these words: “typically”, “usually”, “normally”… they say nothing, but at the same time they say everything!!! just read between the lines…

ReadProcessMemory: normally, /* I mean _normally_ */ ReadProcessMemory() returns error if it meet a page with PAGE_GUARD attribute. does it make sense? of course! but, _normally_ does not mean “every time”. Windows has a bug (I tested W2K SP4, XP SP3, Vista SP0 and Vista 64bit SP1 – they are all affected).

the bug: if PAGE_GUARD page is created by VirtualAlloc() call, ReadProcessMemory() turns off the guard page status without any exception and returns a failure status indicator. however, the second ReadProcessMemory() call returns a positive status (because PAGE_GUARD was turned off), so when the application will try to access to that page – there will be no exception (as it’s supposed to be), because there is no guard anymore.

the sensor: it’s easy to create a sensor to detect dumpers. allocate a page with PAGE_GUARD attribute and check it from time to time: just install SEH handler and read the content. no exception means we’re fucked, oh, sorry, dumped. I tested PE-TOOLS and other popular dumpers and they all were detected.

demo: to demonstrate the bug, I wrote two simple applications. one – “protected-like” application, another – dumper-like application. please download the sources and binaries.

“protected” application (PAGE_GUARD_BUG.c) is very simple, basically it just calls VirtualAlloc(,,,PAGE_READWRITE | PAGE_GUARD), displays the address/PID, waits for pressing ENTER and attempts to read the content of the allocated block. there is no SEH handler, so if an exception happens you will see the standard Windows message box.

p = VirtualAlloc(0, 0×1000, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD);
printf(“run turnoff.exe %d %d twice and press enter”, GetCurrentProcessId(), p);
gets(buf); printf(“result: %x\n”, *p);

and the “dumper” (turnoff.c ) just calls ReadProcessMemory() and displays the result:

h = OpenProcess(PROCESS_ALL_ACCESS, 0, atol(arg_id));
x = ReadProcessMemory(h, (void*)atol(arg_addr), &buf, 0×1, &n);

oh, here we go. follow me, please!

1) run the protected app (“$start PAGE_GUARD_BUG.exe“);
2) it displays ID/addr, like: id:1216 addr:4325376;
3) press right now;
4) ops! exception! this means: PAGE_GUARD works!!!
5) run the protected app again (“$start PAGE_GUARD_BUG.exe“);
6) it displays ID/addr, like: id:1212 addr:4325376;
7) run the dumper, passing ID and addr (“$turnoff.exe 1212 4325376“);
8) it says: “satus:0, bytes read: 0″ (means: ReadProcMem failed);
9) but! if you switch to PAGE_GUARD_BUG.exe and press ENTER you will see no exception (means: PAGE_GUARD was turned off);
10) if you run the dumper twice (of course without pressing ENTER) it will displays: “satus:1, bytes read: 1″ (means: there is no PAGE_GUARD anymore);

nice trick, it’s it? but actually it was just a little warming-up. the real tricks are coming.

NOTE: if PAGE_GUARD attribute is assigned by VirtualProtect(), Windows respects the attribute and ReadProcessMemory() fails, leaving PAGE_GUARD turned on.

debuggers: what happens if a debugger meet PAGE_GUARD page? the answer is: there will be no exception, the debugger just turns PAGE_GUARD off, processes the content and forgets to return PAGE_GUARD back.

demonstration: to demonstrate this nasty behavior I wrote a simple program PAGE_GUARD_DBG.c, download it, please. and follow me. the source code is easy to understand:

push 0×1000
push 0
call ds:[VirtualAlloc]
mov eax, [eax]

execute it step-by-step, make step over the VirtualAlloc() call and display the content of the allocated memory block (for example, in IDA-Pro press , eax, ENTER and to go back). continue tracing, and… ops! where is our exception?! there is no one!!!

OllyDbg is even worse. it automatically resolves memory references displaying the content in the right column, so we don’t need to go to the dump window nor pressing CTRL-G… just trace it and the debugger will be detected, since there will be no exception!!!

IDA-Pro: well, what about if we just run the program under debugger? just run, no trace! IDA-Pro triggers an exception: “401035: A page of memory that marks the end of a data structure such as a stack or an array has been accessed (exc. code 80000001, TID 1312)” and offers to pass the exception to the application. in this case the debugger will be _not_ detected.

OllyDbg: the standard de-facto debugger stops when the application accesses PAGE_GUARD, giving the message “Break-on-access when reading” in the status bar, but Olly does not offer us to pass the exception to the application. even we go to options->exceptions and add 0×80000001 (STATUS_GUARD_PAGE) exception to the list, Olly will ignore it! guess, PAGE_GUARD is just a part of “memory-breakpoint” engine, so no way to pass PAGE_GUARD exception to the application, so it’s easy to detect the debugger. (I tested OllyDbg 1.10).

Soft-Ice: it does not display the content of PAGE_GUARDED pages, so it could not be detected by this way. in other hand, keeping the impotent content under PAGE_GUARD makes debugging much harder. we can’t perform full memory search, we can’t find cross references… we’re blind.

the love triangle: PAGE_GUARD, Windows and OllyDbg: Windows has a bug, Olly has a bug, so... how were supposed to debug?!

the love triangle: PAGE_GUARD, Windows and OllyDbg: Windows has a bug, Olly has a bug, so... how we're supposed to debug?!


# how many forum members does it take to summon the evil who turns out to be a very sexy girl?

there is a well-known joke. “how many forum members does it take to change a light bulb?“. it’s funny, but it’s true. I would say the very true. instead of answer a question, people usually just piss off the topic starter.

what happened to me is: reading the article about San-Francisco, I met the ad, offering me to sell my soul for a fair price, just dial 1-800-666-EVIL. interesting… is it real?! well, I sold my soul twice (yep, do you think devils use computers? hell, no! everything they have is goose-quill and sheepskin! imagine, how large their database should be, and how long it takes to find out that they bought something that they have already paid for. ups, gays, if you read all this, please don’t be pissed of, nothing personal, business is business).

well, 1-800 is not toll-free for me (however, it’s quite cheap), so the first thing I did was… yeah, googling! after all it was just curiosity. ops! looks like it’s a popular question and people flood forums trying to find out the answer, but 99% replies were far from it. like, oh, come on, there is no Satan — the son of God, it’s just a phone. I do know it’s a phone, and it’s served not by Satan himself of course, but… what’s all about?! I wonder… I wonder…

eventually, I just dialed 8P101-800-666-3845, a woman with angel’ voice warned me that it’s not a toll-free number and I will be charged for an international call… beep-beep… and wow! it’s not Satan’s phone, it’s BDSM-sex pay phone, accepting VISA and Master-Card. $1 per minute. but it’s worth what it costs, especially if you’re tired of vanilla life.

well, if you’re going to San-Francisco… don’t forget your soul on a way back, because my soul is there.

dial it now or never!

dial it now or never!


# IDA-Pro steals RIP — introduction in relative addressing

intraarterial injection: i was involved into a project on design a software-level protection, based on anti-dbg tricks that should work in 32- and 64-bit environment causing no conflict with legal apps. also, my shell-code locator has to learn how to recognize x86-64 exploits, so… I took a deep breath and dived into 64-bit word. well, I’m not newbit here, but digging up the anti-dbg tricks working everywhere sounds like a challenge. ok, anti-dbg tricks, shell-codes… good point to begin with.

kotal: x86 does not allow to address EIP register directly (PDP-11 does), but supports relative addressing in the flow control commands (“the” means “all”), for example: CALL L1 it’s a relative call. in the machine representation it looks like: E8 61 06 00 00, where E8h is opcode of CALL and 61 06 00 00 – a relative 32bit signed offset of the target, calculated from the _end_ of the CALL.

it’s very important for shell-codes, because it gives them ability to work being loaded at any offset. for protections it’s useful well. to prevent dumping – just allocate the memory on the heap and copy your procedure there. no dumper is able to create a workable PE image out of heap!

drawbacks: aside of benefits of relative addressing it has its own disadvantages. guess, what happens if we copy our function which calls the function we can’t copy (for example, API). the delta between CALL and the target will be changed, forcing us to recalculate all relative addresses, or… (turn your mind on) start to use absolute addressing, for example: mov eax, offset API_func/CALL eax;

home and dry: x86-64 does not allow to use RIP (former EIP) as a general purpose register (MOV RAX, RIP does not work), but it supports relative addressing almost everywhere (let me to quite the Intel manuals:”RIP-relative addressing allows specific ModR/M modes to address memory relative to
the 64-bit RIP using a signed 32-bit displacement. This provides an offset range of -/+2GB from the RIP
“). what it does mean?! for shell-code writers it means a lot!!! from now on we don’t need in GetPC subroutine (usually, CALL L1/L1:POP r32) and can use RIP directly. and this is the part where we meet the problem of the stolen RIP.

anaphylactic shock: please, consider the following code. this is how IDA-Pro 5.5 disassembles it. remember: it’s a piece of a real shell-code, so, concentrate your mind into fuming acid and do not miss the point (see the picture bellow as well):

.code:0000000000401000 start proc near
.code:0000000000401000 mov ecx, 69h
.code:0000000000401005 jmp short loc_40100C
.code:0000000000401007 loc_401007:
.code:0000000000401007 nop
.code:0000000000401008 xor [eax+ecx], cl
.code:000000000040100C loc_40100C:
.code:000000000040100C lea rax, loc_401013
.code:0000000000401013 loc_401013:
.code:0000000000401013 loop loc_401007
.code:0000000000401015 mov r9d, 0

how do you like it?! ok, let me to be more specific. how do you like the line: “lea rax, loc_401013″?! what?! did you say: “looks clear!” hello no!!! look closely!!! Option -> Text representation -> Number of opcode bytes -> 9. do you see _now_ what IDA-Pro hides from us?!

.code:000000000040100C 48 8D 05 00 00 00 00 lea rax, loc_401013
.code:0000000000401013 loc_401013:

oh, my unholy cow!!! “LEA RAX, loc_401013” turns out to be “LEA RAX, [RIP]“, thus we’re dealing with position-independent code. in a way, IDA-Pro is correct. she is just calculates RIP on the fly and replaces it by the effective offset. but, we – hackers – want to know if the code is position independent or not!!!

breakdown: HIEW also replaces RIP by effective offset. please consider the following line: 0040100C: 488D05000000001 LEA RAX, [000401013]

ok, do you want to get high? well, let’s do it, ppl!

00000000: 488D0500000000 lea rax,[7]
00000007: 488D0500000000 lea rax,[00000000E]
0000000E: 488D0500000000 lea rax,[000000015]

the same opcodes produce different targets, how funny!!! of course, it’s an opcode of LEA RAX, [RIP] command and I would like to have an option which enables/disables showing RIP, because I do need in very much!!!

updated: Igor Skochinsky pointed out (see his comment below) that IDA-Pro allows us to show RIP (Options -> Analysis options -> Processor specific analysis options -> Explicit RIP-addressing). ok, lets enable it and see what happens:

.code:000000000040100C loc_40100C: ; CODE XREF: start+5j
.code:000000000040100C lea rax, [rip+0]

well, say hello to “RIP”! it’s explicated now, but… the rest of the code is almost damaged and unvoyageable (means: inconvenient for navigation):

.code:000000000040101B lea r8, [rip+0FDEh] ; “x86-64 program!”
.code:0000000000401022 lea rdx, [rip+0FEEh] ; “hello world!”
.code:0000000000401029 mov rcx, 0 ; hWnd
.code:0000000000401030 call qword ptr [rip+2016h]
.code:0000000000401036 mov ecx, eax ; uExitCode

we see relative offsets like 0FDEh, 0FEEh, 2016h, etc. they’re red colored (means: IDA-Pro does not recognize these offsets) and if we move cursor to the constant – we can’t jump by ENTER and we need to calculate the target address manually. so, the problem is still unsolved.

in passing: look at the encoder again. don’t you think that it damages the loop?! ok, lets trace the code with any debugger or with our own mind if we have no 64-bit debugger under our hands.

“loop loc_401007″ has E2h F2h opcode. in binary representation F2h is “011110010″, so the lowest bit is zero, thus, when ECX = = 1, the target of loop will change from 401007h to 401008h (401007h ^ 1 = 401008h). as result – NOP will be skipped. of course, it might be INC EBX (opcode 43h) – in that case, EBX would be increased not by ECX (as it’s expected), but by (ECX – 1). how interesting…

well, when ECX = = 0, LOOP just does not pass the control to the target, so everything works fine.

updated: Sol_Ksacap (from pointed out that (let me to quote him): “the target of loop will indeed change, but there won’t be any loop – “loop” instruction first decreases RCX, and only then checks if it’s zero“. and he is definitely right. this post was written in hurry. sorry for the mistakes I made and big thanks all guys who pointed it out.

off the record: in normal shell-codes you probably meet something like LEA EAX, [RIP-1] (opcode: 8B05FFFFFFFF), since commands with the positive offsets have zeros in opcodes and shell-codes do not like zeros very much (because of ASCIIZ, where Zero is a string terminator).

updated on:
Wed, Juli-15: enable-RIP option in IDA-Pro, loop patching bugs;

an example of real 64bit shell-code with hidden RIP

an example of real 64bit shell-code with hidden RIP


# MS DirectShow MPEG2 (msvidctl.dll) worm was fired out!

Internet is under attack, the Chinese worm hits, disease is spreading fast, the number of infected machines is grown rapidly. it’s a new outbreak!

Let me let you in on a little inside info. McAfee has a solution, but due to the size of the company does not apply it. as a part of the former Endeavor Security Team I’m working on the shell-code locator. this is my own project here and some modules were integrated into Active Malware Protection commercial product, now renamed to NTR. and it works!!! it did catch the worm giving the green flag (means: 99% chances of invasion).

long before McAfee exposed the interest to it, the locator was demonstrated to NDS company (Jerusalem, Israel), Sec++ Group (Tel-Aviv, Israel), Sense-Post company (Pretoria, South Africa), Soft-Forum (Seoul, South Korea) and many other hackers, so, basically, it’s a collective solution. it’s not only about me and my ideas… yeah, it was my idea from the beginning, but it has been improved over the discussions, and of course it was discussed inside our company, big thanks to Alice Chang, Kun Luo, Zheng Bu, Yichong Lin, Vitaly Zaytsev and many others.

ok, lets take the shell-code locator, feed the worm to it and check out what the heuristic module says:

$shell-codes_locator_v3.exe stream.bin
+DETECTED FSTENV-based encoder @ 000002ABh
XOR key: B9 8E A9 13 (13A98EB9h)

in fast, there is an encoder and the rest of the worm is encrypted, but it does not help the worm to escape. my shell-code locator was designed to perform heuristic search inside encrypted steams, without decrypting them, without emulation and of course without brute forcing because we should care about resources and we just don’t have enough CPU power for virtualization of any kind.

well, lets load the worm into HIEW and see the encoder with your own eyes (the picture bellow). wow! indeed, the encoder is located at the same address, but… it uses another key. just look at the following code (taken from the encoder) “XOR D, [EBX+13], 0A98EB913” and compare the key with my shell-code locator outputs: 13A98EB9h.

is my locator wrong?! not at all! because A98EB913h and 13A98EB9h is the same key, just rotated by 8bit. since, XOR is a stream operation, no matter which byte is first and which is the second if the offset is given. if we apply A98EB913h at 318h offset – we get the same result.

it proofs that my shell-code locator does not look for “XOR” in order to extract the immediate DWORD, (the plain key). my shell-code locator does need in it at all. if the encoder is missed or not recognized – never mind! isn’t impressive?

however, at this moment URI decoder (Chinese worm keeps the shell-code inside an unescaped string) is still under construction (pre-pre alpha stage of development), so the worm was caught by the internal version of the shell-code locator, but it inspires me to continue working on it.

FSTENV-based encoder recognized by my shell-code locator

FSTENV-based encoder recognized by my shell-code locator


# IDA-Pro//BOCHSDBG plug-in bug: lack of 16bit support

16bit code is obsolete today, it’s nearing the end of its exile, the rogue’s march is playing despite the fast that 16bit programs are alive and millions users continue using them, being scared by the fact that x86-64 does not support 16bit anymore and even 32bit NT/XP has a very feeble DPMI host.

ok, let’s get down to business. some people want to debug 16bit applications for different reasons. IDA-Pro supports 16bit MS-DOS/DPMI applications quite well, and states that BOCHSDBG Plug-in support them too. (NOTE: IDA 5.3 and lower supports only win32 Debugging Engine, thus, you can’t debug 16bit apps with it).

the problem is: BOCHSDBG Plug-in does not support neither 16-bit MS-DOS/EXE nor 16bit code snippets. whether it’s 32bit or 16bit segment, BOCHSDBG plug-in threats it as 32bit, executing code in 32bit mode. not wonder that we get an unexpected result. for example, PUSH 1234h decreases ESP by four(!) instead of two! the worst thing is: 16bit and 32bit modes are very different. 8Bh 00h is “mov eax, [eax]” in 32bit mode and “mov ax, [bx][si]” in 16bit!

in the mean time: BOCHSDBG supports 16bit code well by itself. just to prepare an image, load in into BOCHSDBG and you the integrated debugger (a simple console one, kind of gdb). don’t touch IDA-Pro! you don’t need at all for this particular operation (IDA-Pro team is going to support 16bit code snippets, but it’s going to take time, the next version will probably just check the segment size and refuse to debug it with BOCHSDBG Plug-in if it’s 16bit).

if you’re not familiar with GDB or want to know more about debugging 16-bit apps with BOCHSDBG just leave me a comment and I will write a special post about it, sharing my own BOCHS image with all necessary tools installed (free and legal).

closing remarks: 16bit code became a quite strong anti-debug trick by itself, because the modern hacker tools do not support it at all :(

an attempt to debug 16bit code with IDA-Pro 5.5/BOCHSDBG Plug-in

an attempt to debug 16bit code with IDA-Pro 5.5/BOCHSDBG Plug-in


# Xcon2009: passive non-resident root-kits

I was invited to Xcon 2009 Security Conference (Beijing, China, 18th-19th August 2009) where I’m going to talk about a new generation of passive non-resident win32/Linux root-kits. the brief introduction is followed bellow:.

In the dark…
…I heard your voice: “hey, you on the other side! In this dark and rainy night, we come out of the shadows just to finish what we began a thousand years ago. my gun is pumping, you’re down on your knees. a closer step to death. I think I’m coming, are you ready to receive? I spray you full with my killer disease! now life is death and light is dark!

there is a full-scale subterranean war been raged for every shred of information, there are things that go bump in the night, everybody knows about it and nobody says anything about it. they don’t intend to upset the balance of the war. I will. I wlll open a portal… and awaken the Ogdru Jahad. behind this door, a dark entity. evil, ancient and hungry.

The Seven Gods of Chaos turn out to be a new kind of root-kits. non-resident passive Ring-3 Root-Kits affect Windows and Linux. sounds boring, doesn’t it? but hold a candle to the sun and listen. they’re coming inside to break you down, they hide exe/dll modules, using only well-documented win32 APIs, working _everywhere_ from 9x to Vista, they don’t request administrator rights and every known AV fails to find the hidden modules as well as to detect the root-kits, because there is nothing to detect — thanks to the passive non-resident nature of them! your favorite tool — the manual detection (“hands-n-brain”) fails to detect them as well! soft-ice, syser, and root-kit finders show us nothing! what the hell is this — science or black magic?! I don’t know, I just hear how your PC box is crying: what’s happening to me? everything is so cold! everything is so dark! what is this pain I feel, why does it hurt? please no, let me die… let me die… let me die… hey! don’t you know it is supposed to work? you always get what you deserve! there is no cure. there is no solution. in death and dark we are all alone.

facts: This is not something absolutely new. this is what the hacker community started to talk about a year ago. it was a part of my Reverse Engineering Course lectured to Sec++ Group (Israel) Sense Post company (South Africa) and many others. at that moment we considered it as a win32 bug, allowing us to infect running EXEs and loaded DLLs.
Discussing this stuff with the Apple Panda and Soft Forum guys (Seoul, South Korea) suddenly we realized — this is much more than just infection, the same trick might be used for hiding and there is no way to find the coffined modules. it was supposed to be a part of my speech on CodeGate-2009 conference, but for some reasons this topic was removed and suspended for a while.
There were some (just a few) internal reports that I sent to my company (McAfee, Avert Labs), but the wide public had no idea about what was going on till now, and from now till doomsday you will know for sure what this is all about. this is a new threat, spotlighting maladjustment of three major Windows engines – file system, virtual memory manager and object manager. Linux boxes are not affected. well, in fact, they’re affected, but for them there is a solution — a cure. but not for Windows! we’re all waiting for an official patch, fixing the problem.

/* snippets from New Rose Hotel, Queen Of The Damned, Hell-boy, BlutEngel, Pain were used */

updated on: Jul-09, grammar fix (thanks to Ben Layer, McAfee)

new generation of passive non-resident win32/Linux root-kits

Xcon - one of the most authoritative and famous information security conference in China


# die Vista, die or why DEADDEEF is alive?

intraarterial injection: fixing old bugs in Vista ms-guys inevitably add new ones. don’t ask me for proofs unless you want to hurt your face-painting wretched system. do you know the system I’m talking about? good! the following code has no impact on NT, W2K, XP, but… it freezes malformed Vista. it just hangs the system up! (I tested Vista SP0). download the binary or compile the file by yourself.


get off the subject: remember a simple anti-dbg trick with closing a non-existing handler? something like CloseHandle(0xBADC0DE) or CloseHandle(0xBADC0DE). if we’re under a debugger – OS generates C0000008h (INVALID HANDLE) exception. no debugger means no exception. the problem is: how to close an assuredly invalid handler? if you didn’t open it, any system DLL might opened it. of course, you can use GetHandleInformation() to check: if the handler has been opened, but… it’s too obvious (for hackers) and too trivial to be interested for us. there is another way — our way.

flowing well: has it never come in upon your mind how OS assigns handlers? a handler is DWORD, right? but it’s impossible to get all values busy. some values will be taken, but some of them should be free, because it’s impossible to open all of 4,294,967,296 possible handlers. it’s out of the limit! so, lets perform a fast research of system internals. what we’re going to do is: to consume all handlers until CreateFile() says: “no more handlers, I give up“. well, time to call GetHandleInformation() and check: is there any predictable template? which handlers are taken and which are not?

dead marines: holly cow!!! just look at it!!! wow! this is the very template we looked for! handlers 0h .. 02h are taken, handler 07h is taken as well, but… the rest of them fits the following equation: (((h – 0×12) % 04). so, it’s easy to determine handlers that will be not taken whatever happens to them, thus these handlers will definitely raise an exception on the close attempt. the point is: closing a handler like 1Bh looks reasonable from hacker’ point of view, but it’s just a way to generate an exception under debugger.

HANDLE: 00h is invalid
HANDLE: 01h is invalid
HANDLE: 02h is invalid
HANDLE: 03h is valid
HANDLE: 04h is valid
HANDLE: 05h is valid
HANDLE: 06h is valid
HANDLE: 07h is invalid
HANDLE: 08h is valid
HANDLE: 09h is valid
HANDLE: 0Ah is valid
HANDLE: 0Bh is valid
HANDLE: 0Ch is valid
HANDLE: 0Dh is valid
HANDLE: 0Eh is valid
HANDLE: 0Fh is valid
HANDLE: 10h is valid
HANDLE: 11h is valid
HANDLE: 12h is valid
HANDLE: 13h is invalid
HANDLE: 14h is valid
HANDLE: 15h is valid
HANDLE: 16h is valid
HANDLE: 17h is invalid
HANDLE: 18h is valid
HANDLE: 19h is valid
HANDLE: 1Ah is valid
HANDLE: 1Bh is invalid
HANDLE: 1Ch is valid
HANDLE: 1Dh is valid
HANDLE: 1Eh is valid

Achilles’ spear: so, you got it! we have the magic formula allowing us to check any arbitrary value. take 0xBADC0DEh for example. download the sources of IsInvalid.c and call IsHandlerInvalid(0xBADC0DE) or simile run IsInvalid.exe. as you can see, 0xBADC0DE could not be taken, so it’s a good choice to cause an exception.

ok, another try — 0xDEADBEEF. just pass the value to our magic function and… ops! it says: “HANDLE: DEADBEEFh is possibly valid“, so it’s potentially unsafe to use CloseHanlde(0xDEADBEEF). oh, come on! fat chance to close a file, opened by system or custom DLL, but… it’s still possible. btw, VMProtect uses CloseHanle(0xBADC0DE), which is safe. coincidence? or… anyway, Dermatolog (Иван Пермяков, Екатеринбург –the geek who created it) is a very wise guy and his protector is one of the best. it’s stuffed by anti-dbg tricks and it was a pleasure for me to dig them up. what’s about you?

handler consuming leads to consume kernel memory as well (handler_explorer.exe is running), sorry for the Russian screen-shoot, will appreciate your help, if somebody send me eng one (info # re - lab . org )

handler consuming leads to consume kernel memory as well (handler_explorer.exe is running), sorry for the Russian screen-shoot, will appreciate your help, if somebody send me eng one (info # re - lab . org )


# IDA-Pro 5.5 has been updated, fixed — Bochs plug-in unaligned PE bug

in a nutshell: IDA-Pro has been updated on July-01/2009 in order to fix a bug in BOCHSDBG plug-in. from now on it supports unaligned PE files (see definition below). if you want to get the updated version, send your identification (the ida.key) to

nude statement: I don’t like IDA-Pro Debugger. it’s very limited, devilish uncomfortable and embarrassing. it has its own benefits, none the less, but for me OllyDbg is much better. every man has his taste – opinions differ.

death notice: OllyDbg/Soft-Ice (like any other x86 debugger) is very limited. it could be detected, it could be broken. it does not support tracing of a self-traced program and there is no workaround — no script nor plug-in to fix it. it’s nature of x86 CPU. the same story with DRx registers. virtualization and emulation is the only way to hack strong protections (oh, come on! as if you can’t break an emulator, whose behavior is pretty different from native CPU).

brutal facts: what do we have?! is there any decent emulator?! well, x86emu (plug-in for IDA-Pro) is extremely limited. BOCHSDBG is good enough to debug MBR or OS loader, but… how we’re supposed to debug applications/drivers, working _below_ the Operation System?! the same story with VMWare/WinDbg and QEMU/GDB. so, in essence there is no decent emulators, except for internal products like McAfee EDebug (very good tool, but only for home consumption, “home” means “McAfee”).

beam of hope: IDA-Pro debugger had been significantly improved since 5.4 and the most dramatical change is BOCHSDBG plug-in supporting win32 PE debugging. what does it mean and how it works? well, to answer the first question: we got what we were waiting for a looong time. yeah, there was BOCHS, but it’s impossible to debug code snippets directly into BOCHS. the only way to do it – create an image of a tiny operation system and put a snippet there. CPU starts in real 16 bits mode, while win32 programs expect to see 32-bit protected mode with flat address space – the minimum requirements to debug code snippets, but it’s not enough to hack real applications!

the next step is to create win32-like environment. at least we need to emulate fundamental system structures (like PEB) and engines (SEH for example) not mention basic API set. it has been hell of a job (or, may be, a job in hell). and this job has been done by Elias Bachaalany, he is our hell-guy – very talented brick from the eastern shore of the Mediterranean Sea. not wonder that he is a clever cat!

a mint of intrigue: it was excitement from the first sight when I read Ilfak’ post “Bochs Emulator and IDA?“. it was just awesome! at that moment my company provided me a license for IDA-Pro 5.3, but it was too old to be updated for a free, so I kicked up my heels. McAfee provided me a license as well (Danke schön to the director of IPS research of Avert Labs, it was very kind of him and maybe I will find myself in his team based in Santa-Clara). but… it was IDA-Pro 5.3 – the original CD, shipped to Moscow McAfee office, hosted in the biggest building in Europe – Naberezhnaya Towers, but I was unable to get the updates because of security policies of McAfee. I had no access to the internal network and the sardonic Firewall did not allow to go outside. what’s a piggishly! only when IDA-Pro 5.5 has been released, I got the updates directly from, sitting in Macrovision office and thinking that even in my village Internet is faster (I own 10 Mbytes link, but an average speed is 2 Mbytes, but it’s more that enough to fit my needs).

collapse of plans: I started testing the new plug-in, trying to debug programs (malware mostly) that I was unable to debug with OllyDbg and the old IDA-Pro debugger. the first impression was: wow! it’s cool! it’s easy to trace self-tracing code, “software” breakpoints do not changed the content… well, I felt like I reached the golden gates (or it was Golden Bridge?) and was about to dine with Mohammed, happy hunting ground – Elias made the best of both worlds, but… better to reign in hell than serve in heaven. BOCHSDBG plug-in is a great tool, yet it’s all wrong. the whole design is wrong. it’s easy to break the debugger.

for example: it traces programs by BOCHS virtual CPU engine. the very engine is used by the debugged program, so… no problem to detect the debugger, yet it’s harder than beat a non-virtual one. (now I’m working on anti-debugging tricks some of them will be posted here, some – for commercial purposes).

the facts: when you choose Loader Type -> PE in BOCHS configuration message box, the plug-in prepares a virtual image and loads PE file there. so, we should expect a lot of problems, because it’s almost impossible to design a decent 3rd party PE Loader. the problem is: MS PE Specification is not accurate and MS does not follow it. take Section Alignment for example. according to MS PE specification, the minimal Section Alignment == PAGE_SIZE, but win/32 supports much smaller values as well (win/64 does not) and the smallest alignment, supported by standard MS Linker, is 10h. lets come to terms to call these files “unaligned PE” – it’s not a good term, because the files are still aligned, yet the align value is much smaller than the specification requires, but it’s just a term :-)

IDA-Pro BOCHSDBG Plug-in does not support unaligned PE files, and generates an exception on any writing attempt, even if the section is writable (in fact, even the section is not writable, the system PE loader makes _all_ sections writable, regardless of the attributes – but I will keep this feature to another post). just a few people have a chance to meet an unaligned PE, because these files are not common for commercial applications, but malware use this trick quite often in order to be smaller, and I met the problem on the second day of using IDA-Pro BOCHSDBG Plug-in.

in the can: to demonstrate the problem I created a very simple file. download it or see the source below:

int mem; char *txt=”[OK]“;
__declspec(naked) nezumi()
__asm{ mov [mem], eax }
MessageBox(0, txt, txt, 0); ExitProcess(0);

to make it, run “nmake make” or use the following command lines:

$cl.exe /c /Ox ida-bug_bochsdbg-16.c
$Link.exe ida-bug_bochsdbg-16.obj /ALIGN:16 /ENTRY:nezumi /SUBSYSTEM:WINDOWS KERNEL32.lib USER32.lib

ignore the linker warning “LiLNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run” — image works fine on 32-bits editions of NT, W2K, XP, S2K3/S2K8, Vista (64-bits editions probably will not run it, but I have not checked it by myself, if you have 64-bits editions of Windows under your hand, please test it and post your comment here, thanks!)

as you can see, unaligned exe works fine, OllyDbg and local IDA-Pro debugger have no problem with it, but… go to Debugger menu, click “Switch Debugger”, select “Local Bochs debugger” and run it by F9 or try to trace step-by-step.

ops!!! an exception on a write attempt (see the pic below), accessing “mem” variable, which belongs to .data section, which is writable. remove “/ALIGN:16” key from the linker arguments, rebuild the program and try to debug it again. now it works fine! but… we can’t rebuild closed source program!!! so, it’s a problem and now it’s fixed. just ask the support for the updated version.

updated on: Sun, July 05, 04:44: grammar fix

IDA-Pro, BOCHSDBG, unaligned pe, impact area

IDA-Pro, BOCHSDBG, unaligned pe, impact area