HanJeouk의 개인공부 블로그

2014 Plaid CTF Ezhp

CTF2018. 1. 4. 19:34

힙알못이라 난이도가 쉬운편인 문제들부터 서서히 풀기로 했다.

아무것도 안걸려있다ㅋㅋ.

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

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

포너블을 한다면 무조건 거처야 한다는 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로 될 것이다. AB 를 재할당하면 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))

로 될 것이다.)

그리고 이제 다시 할당을 하면 에 할당이 될 것이다. 근데 이  데이터를 보면 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

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

코드를 보자


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

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

확인

문제 코드를 보자

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

Wargame/Protostar2017. 12. 31. 23:23

먼저 문제 코드를 보면

구조체를 보면 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

Wargame/Protostar2017. 12. 31. 21:09

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