Linux x86 Reverse Engineering Basic guide of Shellcode Disassembling
Harsh N. Daftary Sr. Security Researcher at CSPF Security Consultant at Trunkoz Technologies info@securityLabs.in
Abstract:-- Basic idea about encryption and x86 structure is required. Most of the Windows as well as Linux based programs contains bugs or security holes and/or errors. These bugs or error in program can General Registers : be exploited in order to crash the program or make system do 32 bits : EAX EBX ECX EDX unwanted stuff 16 bits : AX BX CX DX 8 bits : AH AL BH BL CH CL DH Exploit usually attacks the program on Memory Corruption, Segmentation Dump, format string, Buffer overflow or something EAX,AX,AH,AL : else. Called the Accumulator register. It is used for I/O port access, arithmetic, interrupt calls. In computer security, a shellcode is a small piece of code used as the payload in the exploitation of a software vulnerability. It is called Segment Registers : "shellcode" because it typically starts a command shell from which CS DS ES FS GS SS the attacker can control the compromised machine. Segment registers hold the segment address of various items It is just a basic guide, not for l33t reverse engineers :) Index and Pointers: ESI EDI EBP EIP ESP Introduction:- idexes and pointer and the offset part of and address. They Shellcode are not responsible for exploiting but to create a shell have various uses but each register has a specific function. or execute something on victim system after exploiting the bug. Test System Specification : Shellcode can execute almost all the functions that a Linux Ubuntu 10.04 independent program could. Execution of this code takes place Intel i3 after exploiting vulnerability.(usually) System Architecture: x86- 32 bit NASM assembled shellcode Importance : By just looking at shellcode we cannot say what it does, As In this paper I would discuss Reverse Engineering of Two hackers often uses various shellcodes along with their programs. respective exploits
1. Simple program that reades /etc/passwd file We just believe what description of shellcode says and are ready to run it but, How can we trust it. It can do many other 2. XOR encrypted shellcode that launches new shell ksh with functions apart from what its description say and it can end up setreuid (0,0) in compromising our own system, or create backdoor for shellcode author
So the reverse Engineering Helps us to to get idea of working
of the code.
so we create breakpoint at this pointer and run so at point we hit our breakpoint that time we disassemble the
program 1. Simple program that reads
/etc/passwd file Debugger Output: Shellcode: ( Download Link given in the end ) 0x0804a040 <+0>: xor eax,eax --- > It will xor eax with eax, it is used to make eax register 0
0x0804a044 <+4>: push 0x7461632f Now we create a simple program that will execute this code 0x0804a049 <+9>: push 0x7461632f = tac/ and Compile it using 0x0804a04e <+14>: mov ebx,esp
gcc –fno-stack-protector -z execstack code.c –o shellcode --- > Copies the data stored into esp into ebx It will compile our code and program should work without any hindrance. 0x0804a050 <+16>: push edx 0x0804a051 <+17>: push 0x64777373 0x0804a056 <+22>: push 0x61702f2f 0x0804a05b <+27>: push 0x6374652f 0x0804a060 <+32>: mov ecx,esp 0x0804a062 <+34>: mov al,0xb
--- > Makes a syscall by interrupt 80 Lets load our Program into Debugger Now we set the disassembling structure to intel. 0x0804a06b <+43>: add BYTE PTR [eax],al So now we have to stop just before execution so we create breakpoint at a place where program makes a syscall i.e. at address: 0x0804a069 Interrupt 80 makes a syscall with syscall number stored in eax register, as we can see by code: print /x $eax -->> $eax = 11 We need to find function that will start at syscall number 11
so under x86 structure we open : /usr/src/your linux header/arch/x86/include/asm/unistd_32.h
Looking at our source code file we can find that the name of pointer in which we stored our shellcode is "code"
2. XOR enecrypted shellcode thats launches new shell ksh with setreuid (0,0) Shellcode : "\xeb\x0d\x5e\x31\xc9\xb1\x21\x80\x36\x7c\x46\xe2\xfa\xeb\ x05\xe8\xee\xff\xff\xff\x16\x3a\x24\x4d\xa7\x4d\xb5\xb1\xfc \x4d\xae\x16\x77\x24\x2e\x14\x53\x17\x0f\x14\x14\x53\x1e\x 15\x12\xf5\x9f\x2e\x2f\xf5\x9d\xb1\xfc"
Now we create a simple prorgam that will execute this code and Compile it using This file contains list of functions against their syscall numbers gcc –fno-stackp-protector -z execstack code.c –o shellcode Importance of this code it to compile our code without any So at 11th number we understand that program is calling hindrance. "execve" Manual of execve :
Lets load our Program into Debugger Now lets examine values stored in other 32 bit registers Looking at our source code file we can find that the name of
pointer in which we stored our shellcode is "code" creating breakpoint and analyzing
ebx i.e. Second argument contains a hex number which converted into string as /bin/cat cat is Linux bash command used to read a file 3rd argument i.e. ecx register stores a location of file which "/bin/cat" will read so file is 0xbffff3d0: "/etc//passwd" Program will read /etc/passwd file and then will exit.
Here this lines of code will xor decrypt all the commands till end with 0x7c and then will jump to 0x804a054 So now we create break point just after XOR decryption finishes and before it jumps to another memory location for further execution
Syscall Number is 70 And Arguments are 0,0 /usr/src/your linux header/arch/x86/include/asm/unistd_32.h
As we can compare disassembly output to the previous one, we can understand all the instructions after 0x0804a04d are now decrypted So basically XOR decryption is finished, Now we look at EIP +27 we see that Interrupt 80 is being called for syscall so we new create our new breakpoint there
Just as Before EAX register contains Syscall Number EBX and ECX register contains Argument
Here again we Have Syscall Number 11 that is execve function as we saw that last time. And EBX register contains hex data which we convert into string so we get /bin/ksh
So it means This shellcode is going to first decode it self,
then will try open another shell (KSH) located at /bin/ksh So Here 1st argument sets uid and 2nd argument sets gid with root access Which in our case both are 0
Means the program here is trying to get the root access If you find anything missing or have any suggestions feel over system. free to contact me :)
Now lets create breakpoint where program calls interrupt ~Regards, 80 to make a syscall Harsh
PS : 1. Data associated with PUSH can be directly analyzed by converting hex into string, but that data/string will be Right- to-Left. 2. Location of unistd_32.h may be different. Using locate