SLAE x86 Exam - Assignment 5 - Part 1
Assignment #5 - Analyzing shellcode
Student ID: PA-7854
The assignment indications are as follows:
- Take up at least 3 shellcode samples from Metasploit for linux/x86
- Use GDB/Ndisasm/Libemu to dissect them
The code is available at my github repo
I will shortly describe what are we going to do. First, we need to choose 3 different payloads, so I have chosen these three:
linux/x86/exec
linux/x86/chmod
linux/x86/read_file
We will generate payloads with msfvenom
which is the newer tool that replaces msfpayload
and msfencode
, both deprecated. Let’s start with the first one:
linux/x86/exec
I generate the shellcode as follows:
# msfvenom -p linux/x86/exec CMD=whoami -f raw --platform linux -a x86 -o /tmp/exec-whoami.txt
No encoder or badchars specified, outputting raw payload
Payload size: 42 bytes
Saved as: /tmp/exec-whoami.txt
We dissect the generated file with ndisasm
:
# ndisasm -u /tmp/exec-whoami.txt
00000000 6A0B push byte +0xb
00000002 58 pop eax
00000003 99 cdq
00000004 52 push edx
00000005 66682D63 push word 0x632d
00000009 89E7 mov edi,esp
0000000B 682F736800 push dword 0x68732f
00000010 682F62696E push dword 0x6e69622f
00000015 89E3 mov ebx,esp
00000017 52 push edx
00000018 E807000000 call 0x24
0000001D 7768 ja 0x87
0000001F 6F outsd
00000020 61 popa
00000021 6D insd
00000022 6900575389E1 imul eax,[eax],dword 0xe1895357
00000028 CD80 int 0x80
Let’s analyze it line by line
00000000 6A0B push byte +0xb
We push the value 0xb (11 in decimal) which corresponds to the syscall execve
.
00000002 58 pop eax
Here we pop out that value and assign it to EAX.
00000003 99 cdq
Convert Double Quad. This is like a xor edx, edx
, it copies the sign bit (+ or -, bit 31) of the value in EAX into every bit of the EDX register.
If you remember from previous assignments, the way execve
function parameters are:
int execve(const char *filename, char *const argv[], char *const envp[]);
Which we usually push a sequence like:
[command][NULL][*address of command][NULL]
, let’s see how this is being implemented.
00000004 52 push edx
Save the value of EDX (which are NULL bytes), string delimiter, in stack.
00000005 66682D63 push word 0x632d
Save the value ‘-c’ in stack, which stands for command (see below).
00000009 89E7 mov edi,esp
Save the pointer which ESP holds (-c) in EDI.
0000000B 682F736800 push dword 0x68732f
00000010 682F62696E push dword 0x6e69622f
These two lines save in stack the string hs/nib/
(remember little endian?) which is the primary command we will execute.
00000015 89E3 mov ebx,esp
Save the pointer which ESP holds (/bin/sh) in EBX, first parameter of execve
function.
00000017 52 push edx
Save the value of EDX (which are NULL bytes), string delimiter, in stack.
00000018 E807000000 call 0x24
Call function located at address 0x24.
This is a technique so that the next instruction’s address is saved in stack (push edi
in this case). Next 4 lines are ambiguous.
Call address location, which is 0x018, +0x4 (holds 4 bytes) + 0x1 should be the address holding the next instruction, which starts right below at 0x1f.
We can confirm this with xxd
:
# echo 77686f616d6900 | xxd -r -p
whoami
That’s the command previously entered in msfvenom
. Let’s keep analyzing, by skipping the first 36 characters, until the NULL byte after whoami
command, so that ndisasm
shows the instructions correctly:
# ndisasm -u -e 36 /tmp/exec-whoami.txt
00000000 57 push edi
00000001 53 push ebx
00000002 89E1 mov ecx,esp
00000004 CD80 int 0x80
00000000 57 push edi
EDI holds the pointer to ESP (-c) so we push that to stack.
00000001 53 push ebx
EBX holds the primary command, /bin/sh
.
00000002 89E1 mov ecx,esp
This sets ECX to the list of arguments (argv).
00000004 CD80 int 0x80
This instruction should be familiar, makes an interrupt and executes the syscall.
Basically the syscall contains: execve(“/bin/sh, [“bin/sh, “-c”, “whoami”], \0)