2014 Plaid CTF Ezhp
힙알못이라 난이도가 쉬운편인 문제들부터 서서히 풀기로 했다.
아무것도 안걸려있다ㅋㅋ.
IDA로 main 함수를 보면 이렇게 5개의 메뉴가 보인다.
Change 함수에 있는 이 부분에서 취약점이 생기는데 사이즈 조절을 안해놔서 사이즈를 마음대로 크게 정해놓고 read로 그 사이즈만큼 받아서 overflow를 일으킬 수 있다. 그래서 청크의 헤더와 fd, bk 를 조작해서 unlink 시킬 수 있다.
그래서 나는 exit 함수 got에 쉘 코드를 집어넣었다.
문제가 신기한게 할당을 하기도 전에 힙 영역을 보면 fd 와 bk가 있다 ㄷㄷ..
그래서 free를 하지 않아도 fd 와 bk가 있다.
시나리오를 설명하자면
(Line 33 ~ 41)청크 3개를 할당한 다음에 0번 청크를 1번 청크의 fd(2번 청크)까지 오버플로우 시켜고 0번을 출력시켜서
1번 청크의 fd(2번 청크) 를 구한다.
이 fd는 나중에 공격에 사용된다.
(Line 42) 0번 청크를 다시 overflow 시켜서 prev_size와 size를 -1(\xff\xff\xff\xff) 로 바꿔주고 exit_got-4 를 넣어준다.
이 문제는 custom malloc&free 라서 일반 unlink와 다르게 unlink 될 때 다르게 돼서 -8 이 아닌 -4를 해준다.
(원래 unlink는 bk+8 에 fd를 넣어줌 그래서 bk -8을 해줘야 되는데 custom이라서 bk+4 에 fd를 넣어줌 그래서 bk-4 다 그래서 exit_got에 -8이 아닌 -4를 해준다.)
위에 있는 사진이 ezhp의 unlink 부분이다.
(Line 43)chunk 2의 값을 NOP(\x90)과 shellcode로 채워준다.
그리고 익스코드에는 안적었는데 free(1)을 하고 exit함수를 실행시키면 쉘이 따진다.
왜냐하면 unlink가 되면서 exit_got가 쉘코드가 있는 청크 2의 주소를 가리켜서 exit가 실행되지 않고 쉘코드가 실행돼서
쉘이 따진다.
-의식의 흐름 끝-
문제를 풀 때 취약점을 찾고 어떤 기법으로 풀어야 될지는 알았는데 무엇을 unlink 시켜야하는지 파악을 못했다.
그래도 이 문제를 풀면서 힙 공부에 도움이 많이 된 것 같았다. :)
'CTF' 카테고리의 다른 글
2016 Hitcon secret holder (0) | 2018.01.21 |
---|---|
2017 Codegate messenger (0) | 2018.01.06 |
tuCTF guest_book (2) | 2017.12.03 |
tuCTF vuln-chat2 (0) | 2017.11.29 |
tuCTF vuln-chat (0) | 2017.11.28 |
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
fastbin_dup & fastbin_dup_into_stack
포너블을 한다면 무조건 거처야 한다는 shellphish의 how2heap..
평소에 다른 걸 공부하면 전에 공부했던 걸 까먹어서 이것만 보면 바로 기억나게 만드는 용으로 만들 것이다.
그러니 입문보다는 복습이다.
fastbin_dup 코드는 여기서 보면 된다 -> Link 출처 [https://github.com/shellphish]
fastbin_dup_into_stack은 여기서 -> Link 출처 [https://github.com/shellphish]
fastbin_dup gdb로 까서 상세하게 설명이 되어있는 곳 -> Link 출처 [http://banjjak23.tistory.com/]
fastbin_dup : 청크 A 를 연속으로 2번 free 하는 것은 필터링에 걸리기 때문에 이를 우회하기 위해
A를 한 번 free 하고 다른 청크 B를 free하면 다시 A청크를 free 할 수 있게되는 것이다.
fastbin_dup_into_stack : fastbin 청크가 A,B,C 이렇게 4개가 주어진 상황이라고 가정한다. (gdb 로 shellphish 코드를 까본다면
8만 할당을 할텐데 fastbin 은 최소가 32만큼 할당이 돼서 청크 사이즈를 보면 0x21이라고 뜰 것이다.
32 + 1(prev_inuse) = 33 = 0x20 + 0x1 = 0x21) 그리고 fastbin_dup를 이용해서 A B A 순으로 free를 한다.
다음에 malloc를 할 때 순서가 A B A로 될 것이다. A 와 B 를 재할당하면 A만 남게 된다.
이제 A에 *d = (unsigned long long) (((char*)&stack_var) - sizeof(d)) 를 넣어준다.
(청크의 데이터 구조가 prev_size size data 이렇게 되어있으면 이 data 에서 fd bk 가 만들어진다. 그러니까 이 데이터를 fd 로 인식하게 시키는 것이다.
그러면 이 청크의 fd가 내가 넣어준 *d = (unsigned long long) (((char*)&stack_var) - sizeof(d))
로 될 것이다.)
그리고 이제 다시 할당을 하면 A 에 할당이 될 것이다. 근데 이 A 에 데이터를 보면 fd 영역에 *d = (unsigned long long) (((char*)&stack_var) - sizeof(d)) 이 들어있을 것이다. 그래서 다음에 malloc 를 하면 fd가
스택 주소니까 스택 주소에 할당되는 것이다.
끝!
'Documents > how2heap' 카테고리의 다른 글
how2heap house_of_force (0) | 2018.02.20 |
---|---|
how2heap unsorted_bin_attack (0) | 2018.01.17 |
how2heap poison_null_byte (0) | 2018.01.16 |
house_of_einherjar (0) | 2018.01.15 |
first_fit & unsafe unlink (0) | 2018.01.08 |
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
Protostar Heap3
코드를 보자
32만 할당하니까 우선 fastbin이라는 것을 알 수 있다. fast는 다른 bin 과 free될 때 다른 bin들과 다르다.
그리고 strcpy를 이용하여 fd와 bk를 마음대로 조작할 수 있다.
fake chunk 생성이 가능하다는 것이다. 첫번 째 청크를 조작하여 2번 째 청크의 prev_size와 size fd bk를 조작하여
b청크가 free 될 때 unlink가 되게하여 printf(실제로는 puts함수가 쓰인다.)에 winner의 주소가 들어가게 할 것이다.
처음에 문제 풀 때 내 우분투 환경에서 풀려고 했으나 이상하게 안되서 시간을 엄청 낭비하고 결국 포기하고 protostar iso를 다운받아서 풀었다...
쉘코드식으로 넣어줘야 풀리기 때문에 push하고 ret를 찾아서 winner함수에 붙였다.
Unlink 가 될 때 현재 청크의 fd+12에 bk 주소를 넣기 때문에 puts_got - 12를 해줘야 한다.
그래서 나중에 unlink가 될 때 puts_got - 12 + 12 == puts_got가 돼서 puts_got에 winner가 들어갈 수 있는 것이다.
이렇게 넣어주면
성공하게 된다. 아까운 내 시간....깝치지 말고 걍 할걸..
'Wargame > Protostar' 카테고리의 다른 글
Protostar Heap2 (0) | 2018.01.01 |
---|---|
Protostar Heap1 (0) | 2017.12.31 |
Protostar Heap0 (0) | 2017.12.31 |
Protostar Stack7 (0) | 2017.04.06 |
Protostar Stack6 (0) | 2017.04.05 |
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
Protostar Heap2
문제 코드를 보자
if 문이 엄청 많지만 auth->auth 과 strdup 부분을 보면 될 것 같다.
auth 구조체에 auth 값이 0이 아니여야 성공인 것 같다.
gdb로 보면 service 를 사용하면 auth 부분을 덮을 수 있다는 걸 알 수 있다.
service 로 값을 많이 넣어주면 로그인이 됐다고 뜬다.
이렇게 쉽게 말했지만 C 코드를 보고 엄청 이해가 안가서 힘들었다.
그래서 풀이를 봤더니 gdb로 주소의 위치 차이를 보고 문제를 푸는 걸 보고
gdb의 대단함을 한번 더 깨달았다. gdb를 생활화해야 되는데;;
'Wargame > Protostar' 카테고리의 다른 글
Protostar Heap3 (0) | 2018.01.02 |
---|---|
Protostar Heap1 (0) | 2017.12.31 |
Protostar Heap0 (0) | 2017.12.31 |
Protostar Stack7 (0) | 2017.04.06 |
Protostar Stack6 (0) | 2017.04.05 |
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.
Protostar Heap1
먼저 문제 코드를 보면
구조체를 보면 priority와 name 이라는 변수들을 선언한다.
그리고 priority 에 1과 2라는 값을 넣어주고 포인터 변수인 name 을 이용하여 할당을 해준다.
그리고 strcpy로 name에 할당한 곳에 입력한 값을 복사한다.
11은 사이즈 1과 2는 priority 변수에 넣어준 값 1,2 그리고 그 옆에는 name으로 malloc한 주소다.
그리고 aaaa(0x41414141) bbbb(0x42424242) 는 내가 넣은 값이다. 그런데 보면 0x41414141(AAAA) 부분을 보면 overwrite 해서
0x0804b038 를 overwrite해서 다른 주소로 조작할 수 있을 것 같다. 나는 GOT overwrite를 할 것이다.
puts 함수의 got를 알아와서 그 인자로 winner 함수의 주소를 넣어서 공격할 생각이다.
puts_got 와 winner의 주소를 알아냈다.
성공!
'Wargame > Protostar' 카테고리의 다른 글
Protostar Heap3 (0) | 2018.01.02 |
---|---|
Protostar Heap2 (0) | 2018.01.01 |
Protostar Heap0 (0) | 2017.12.31 |
Protostar Stack7 (0) | 2017.04.06 |
Protostar Stack6 (0) | 2017.04.05 |
Protostar Heap0
SECCON Tinypad를 풀면서 내가 Heap에 대한 기본적인 지식이 많이 부족한 것 같음을 많이 느끼고 반성했다. 그래서 Protostar부터 how2heap, 다른 CTF 문제들을 풀어나가면서 Heap을 다시 차근히 공부할 생각이다.
우선 C 코드를 보자.
data 라는 구조체에 name이라는 64byte 짜리 버퍼를 생성한다. 그리고 fp 라는 구조체에는 함수 포인터를 만든다.
여기서부터 약간 냄새가 난다 ㅋㅋㅋ
그리고 malloc를 이용해여 이 구조체 포인터들을 이용하여 구조체들을 할당해주고 함수 포인터가 있는 구조체를 이용하여
nowinner을 가리킨다. 그리고 출력문 다음에 strcpy를 이용하여 버퍼가 있는 구조체에 입력받은 값을 복사한다.
그리고 함수포인터에 있는 함수를 실행시키는데 힙 오버플로우를 하여 함수 포인터를 조작해 nowinner 함수를 winner 함수로 조작시키는 문제일 것이다.
a(61)를 넣고 strcpy 까지 진행시켰을 때의 힙 상황이다. 0x400607 이 nowinner함수 주소인 걸 확인할 수 있다.
a를 80개 넣으면 함수포인터를 조작할 수 있을 것 같다. name[64] + 16(dummy) 여서 80개를 넣어야 하는 것 같다.(32bit 컴파일이 아니라 64bit 컴파일 환경이다.)
winner 함수의 주소는 0x4005f6 이다 a를 80개 넣고 리틀엔디안 방식으로 winner 의 주소를 넣어주면 level pessed 가 뜰 것이다.
예상대로 성공했다!
'Wargame > Protostar' 카테고리의 다른 글
Protostar Heap2 (0) | 2018.01.01 |
---|---|
Protostar Heap1 (0) | 2017.12.31 |
Protostar Stack7 (0) | 2017.04.06 |
Protostar Stack6 (0) | 2017.04.05 |
Protostar Stack5 (0) | 2017.04.05 |