How to read an opcode?

As a beginner, i'm usually confused about the generated shellcode by someone, sometimes i'm thinking what the mean of it, what is it a malicious or not. But after i've know the way how to read a shellcode, now i'm always try to read it before i'm using it.
For example i find a shellcode from here, they said that it's shellcode which will execute a /bin/sh, but i will check it by my self, i'm trying to read it in assembly language. We can learn the basic of assembly language from here.

 Ok, let's copy the opcode and paste it in a perl syntax like below
Syntax:
root@zombie:~# perl -e 'print "\x31\xc0\x89\xc2\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xc1\xb0\x0b\x52\x51\x53\x89\xe1\xcd\x80"'| ndisasm -u -


Now the opcode looked better than before ^_^ and then we can read it, so let's try to translate it.

xor eax,eax    # clear the eax register so the eax register become 0
mov edx,eax    # move data from reg eax to the edx (causes the eax is 0 then the edx become 0 too)
push eax    # add value of reg eax to the top of stack (here the value of eax is 0)
push dword 0x68732f6e # add the value which have data type dword to the top of stack (here the value is 0x68732f6e, it can translate become "hs/n")
push dword 0x69622f2f # add the value which have data type dword to the top of stack (here the value is 0x69622f2f, it can translate become "ib//")
mov ebx,esp    # move data from reg esp to the ebx (here the esp value is "0hs/nib//", in little-indien have mean "//bin/sh0")
mov ecx,eax    # move data from reg eax to the ecx (here the eax still 0 then the ecx become 0 too)
mov al,0xb    # move data 0xb (in decimal is 11) to the al (low 8-bit address of reg eax)
push edx    # add value of reg edx to the top of stack (here the value of edx is 0)
push ecx    # add value of reg ecx to the top of stack (here the value of ecx is 0)
push ebx    # add value of reg ebx to the top of stack (here the value of ebx is "0hs/nib//")
mov ecx,esp    # move data from reg esp to the ecx (here the esp value become "000hs/nib//", in little-indien have mean "//bin/sh000")
int 0x80    # calling a systemcall

Hem, the shellcode is calling system call, as we knew if the shellcode is calling system call then register eax is number of system call, and the other register is an argument to exec the system call which called.
Here the register eax have a value 11, in linux kernel 11 value of system call is have function to call a "sys_execve".
From a man page of execve we will find how to use the execve command, like below
int execve(const char *filename, char *const argv[], char *const envp[]);

The argument is :
int execve (for system call), in assembly declarated in eax
char *filename (address of filename which will execute), in assembly declarated in ebx
char *const argv[] (an address to an array of strings which starting with the address of the previously used filename and terminated with a null), in assembly declarated in ecx
char * envp[], in assembly declarated in edx

The value of register :
eax = 11
ebx = //bin/sh0
ecx = //bin/sh000
edx = 0
so the execve become execve(//bin/sh0, //bin/sh000, 0)

hem maybe in C language can be declarate like as below
char *val[2];
 val[0]="/bin/sh";
 val[1]="0";
execve(val[0], val, null)

The conclusion is the script will exec a "/bin/sh".

2 comments:

Manabu said...

nice article.. ^

KUMΞL said...

Ah lebay, actually you are better than me. (-_-")
I'm just newbie.

Post a Comment