Saturday, June 9, 2012

Understanding Windows shellcode 2

Having read and understood Skapes paper on Windows shellcode I thought I'd better provide yet another explanation on how it works. Yesterday I explained finding kernel32.dll so today I will explain Skapes method of resolving symbols inside a dll.

Over at OpenRCE you can find a very useful PDF describing the structure of a PE file but I have drawn a diagram showing only the necessary elements:
Relevant parts of a PE file
All addresses inside the PE file are relative to the base address...they are NOT absolute.

Skapes 'find_function' function takes two arguments. The first being the base address of the dll to search and the second being a hash code of the name to find. Thus the stack upon entering the function looks like this:
Stack layout after having entered the function
First instruction (pushad) saves the value of all general purpose registers and a couple of others after which the stack looks like this:
Stack layout after having executed the 'pushad' instruction

The code begins by saving the registers and finding the export table (IMAGE_EXPORT_DIRECTORY). This is accomplished by the following instructions:

pushad                       ;Save registers
mov  ebp, [esp + 0x24]       ;Put first argument (dll base) into ebp
mov  eax, [ebp + 0x3c]       ;Put offset of PE header into eax
mov  edx, [ebp + eax + 0x78] ;Put offset of export directory into edx
add  edx, ebp                ;Offset + base = absolute address

Now EDX contains the absolute address in memory for the IMAGE_EXPORTS_DIRECTORY structure.
Next the number of names is put into ECX and the address of the names address table into EBX:

mov   ecx, [edx + 0x18]  ;Number of names
mov   ebx, [edx + 0x20]  ;Offset of names table
add   ebx, ebp           ;Adding EBP makes address absolute

Now ECX contains the number of exported symbols and EBX contains the address of the array of name offsets. Now we enter a loop which iterates backward through all exported names, hashing each name and comparing it to the requested value.

A C version of the hashing algorithm would look like this:

#define ROR(v,n) (((v)>>((n)%32))|((v)<<(32-((n)%32))))
char * name = "LoadLibraryA";
unsigned int hash = 0;
while (*name) {
    hash = ROR(hash, 13) + *name;

The code goes like this:

jecxz find_function_finished ;No more names, go to end
dec   ecx                    ;Decrement ECX
mov   esi, [ebx + ecx * 4]   ;Offset of next exported name
add   esi, ebp               ;Make it absolute

xor   edi, edi               ;EDI will contain calculated hash
xor   eax, eax               ;AL will contain top bits
cld                          ;Make lodsb increment esi

lodsb                        ;Put char at ESI into AL and increment ESI
test  al, al                 ;Reached end of string ?
jz    compute_hash_finished  ;Yes we did
                             ;End hashing and start comparing
ror   edi, 0xd               ;Right shift 13 bits
add   edi, eax               ;Add character
jmp   compute_hash_again     ;Again with next character

cmp   edi, [esp + 0x28]      ;Compare computed hash with second arg
jnz   find_function_loop     ;Not equal...try next name

mov   ebx, [edx + 0x24]      ;Found! Put offset of ordinals into EBX
add   ebx, ebp               ;Make it absolute
mov   cx, [ebx + 2 * ecx]    ;Put ordinal in CX
                             ;ECX contains index of name which
                             ;corresponds to the index into the ordinal
                             ;table. Each ordinal is two bytes long

mov   ebx, [edx + 0x1c]      ;Put offset of function table into EBX
add   ebx, ebp               ;Make it absolute
mov   eax, [ebx + 4 * ecx]   ;Use ordinal as index into function table
                             ;and put offset of function into EAX
add   eax, ebp               ;Make it absolute

mov   [esp + 0x1c], eax      ;Overwrite the saved EAX register
                             ;with the found address

popad                        ;Restore registers
ret                          ;Return with EAX=absolute address of function

The code is pretty clear when you can visualize the structures. With these two shellcodes you can build more or less anything since you can load any library on the target machine and utilize its functionality.


Wednesday, June 6, 2012

First post first blog post.

I had hoped to write about how awesome I am or some cool project I am working on, but no. All my projects need code which needs syntax highlighting and I cannot seem to get it working so instead I will write about how badly I am failing at making this work.

So, a code blog needs syntax highlighting and a Google query showed me that SyntaxHighlighter by Alex Gorbatchev is the way to go. It is using JavaScript/HTML and CSS for highlighting on the client so no server side code is needed. Cool.

And there is even lots of integration guides telling you how to make it work on many different blogging sites and CMSes so what can go wrong?

Well I succeeded in doing something ain't working.

Blogger has disabled the 'Edit HTML' button for editing the template for some reason. Another quick Google search offered me the solution, so I have added the CSS links and JavaScript source files that the many guides told me.

So I added a first (now deleted) blog post with some testing code:

<pre class="brush:c">
#include <stdio.h>

int main(int argc, const char * argv[]) {
    printf("Hello, World!\n");
    return 0;

But for some reason it didn't work. The code was just shown plain, simple and boring as with a normal <pre>. Why?

Viewing the source revealed that the scripts were in place. Pressing F12 in Google Chrome showed me that the files were in fact downloaded. A breakpoint on the JavaScript showed me that the code was run and the debugger tells me that no exceptions are thrown and everything is just fine. So why wasn't it working?

Well...apparently Blogger uses Ajax for retrieving the blog post text and then inserts it into the page. This happens AFTER the JavaScript has run so of course SyntaxHighlighter cannot format my code. It isn't there yet!

I press F12 again and run 'SyntaxHighlighter.all();'  from the console. Nothing happens!

Maybe SyntaxHighlighter doesn't like being called twice so I commented out the 'SyntaxHighlighter.all();' call from the template and ran it again manually. Still nothing!

Maybe there is an error in SyntaxHighlighter, so I create a static test page on my machine which loads all the files and contains a code snippet. To my dismay it looks fine and well highlighted.

This is where I am now. Failing!
Or maybe Blogger is...I really cannot tell but life must go on so I archive this issue in my "technical debt" tray for later. Code snippets will look like crap until I (or someone else) resolve this issue.

So much for looking cool in my first post.