binee::
[TU CTF 2016] WoO & WoO2 & woO2-fixed write up 본문
TU CTF 2016라고 처음 참가해보는 대회인데,
개인적으로 실력에 알맞았던 대회였다.
딱 대학교 동아리가 참가하기 좋은 난이도 였던 것 같다.
CTF 준비하는 팀원들도 적당한 난이도에 재미를 느끼면서 풀었던 것 같다.
배점이 큰 500점 2문제를 모두 풀어서 만족스러운 대회였다.
팀원들이 맘잡고 했으면 10위권 안에 들었을거 같은데,
끝까지 하지 않았던 점이 아쉽다...
위에는 푼 문제들이고, 나는 pwn과 rev만 풀었다.
pwn과 rev 문제 중에서 영양가 있는 문제만 풀이를 쓸 예정이다.
먼저 Wo0부터 문제 풀이를 할건데,
Wo0는 총 3문제로 나뉘어져있다.
동일 소스코드지만, 취약점이 발생하는 소스가 조금씩 다르다.
점수가 올라 갈수록 exploit 하기 쉬운 취약점을 수정하여,
다른 취약점을 활용해야하는 문제인데,
나는.. 50점짜리 문제 풀려다가 250점 문제를 풀 때 쓰는 취약점으로 풀어서
한 번에 3문제가 다 풀려버렸다..
그래서 솔직히 각 3 문제가 어떤 차이점 있는지 지금도 모른다..
write up은 마지막 250점 짜리 풀이기준으로 작성 할 것이다.
Binary 분석
503b8ee65d7e768e81ee95b7ce14b2a903abb5c7 바이너리를 확인 해보면
503b8ee65d7e768e81ee95b7ce14b2a903abb5c7: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=cb34b38d6ea9b2fb44d74378dba149ab584bb5a6, not stripped
64bit elf 파일이고 특이한 점은 없다.
아 그리고 스트립 안 되어 있어서 분석하기 쉬웠다.
Program Logic 분석
.
아래는 main함수의 hex-xay 결과다.
main 함수가 심플하다.
printWelcom 과 printMenu는 함수 이름대로 환영메시지와 메뉴를 출력한다.
메뉴는 동적 실행그림으로 대체한다.
모험하는데 동물을 선택하라는 것 같다.
동물 종류는 3종류이고, 사자, 호랑이, 곰이고
각 동물마다 몇개의 종을 가지고 있다.
선택하고 나면 동물의 이름을 지을 수 있다.
4번을 선택하면 이전에 선택한 동물을 지운다.
솔직히 이정도 쯤 오면 감이 온다.
Delete? free? 아 Use after free 겠구나?
이거 보는 순간 Use after Free 해야되겠다는 생각 밖에 안 들었다.
실제로 Delete 부분에 free를 하는지 확인해봤다.
역시나 free한다.
그렇다면 use after free를 초점으로 잡고 exploit 할 수 있는지
살펴보기 위해서 다른걸 찾아 보려고 했는데,
문제에서 대놓고 pwnMe 라고 알려준다.
메뉴 선택시 4919를 입력하면 pwnMe가 실행된다.
문제를 살펴보면,
함수 포인터 변수를 사용해서 호출하는 부분이 있는 것을 확인 할 수 있다.
함수포인트 변수를 overwrite를 해서 exploit하라는 말 같다.
그렇다면 nx-bit가 걸려 있으므로, RTL를 해야되는데,
그럴려면 infomation leak을 통해서 libc의 base주소를 구해야된다.
leak할 방법을 강구해야된다.
이때까지만 해도 50점짜리 문제치고는 귀찮은 문제라고 생각했다.
문제 출제자님이 천사인지, 아예 flag를 읽을 수 있는 함수를 소스코드에 넣어줬다.
그럼 걍 함수포인트를 overwrite하면 된다.
Exploit
pwnMe 함수에서 함수포인터를 실행시키기 위한 조건으로
bearOffset이 -1이면 안된다.
그리고 pointers + bearOffset값의 주소 +20 의 값이 3이여야한다.
그렇다면 bearOffset이 뭐하는 전역변수인지 확인하고,
어떻게 하면 pointers + bearOffset값의 주소 +20 값에 3을 넣을 수 있는지 확인한다.
총 24바이트 메모리를 할당하고 앞에서부터 20바이트는 name으로 사용하고,
20이후로는 pickLionType함수에서 반환되는 값을 이용한다.
pickLionType 함수를 확인해보면,
동물의 종를 고르는 함수인 것을 알 수 있다.
종을 고르면 그 종의 번호를 return한다.
따라서
pointers + bearOffset값의 주소 +20 값은 종의 번호이다.
종의 번호가 3을 입력하는 값이 있는지 확인해보면
Tiger함수에서 선택 할 수 있다.
그렇다면 남은 bearOffset 값은 bear함수에서 찾아봤다.
bearOffset에 next값을 대입한다.
총 종합해보면,
bearoffset값이 -1이 아니여하고,
함수포인터변수와 함께 타입값이 3인 조건을 만족하게 use after free를 하면 된다.
1. bearoffset값이 -1이 아니게, next값을 증가시키기위해서 아무 동물을 만든다.
2. bear 동물을 만들어서 bearOffset값을 다른 값으로 변경한다.
3. bear 동물을 delete한다.
4. lion 동물을 만들어서 type을 3으로 생성한다. 이때 이름값에 flag값을 읽는 함수 주소를 넣어준다.
5. 메뉴선택에서 4919를 입력해서 pwnMe함수를 실행시킨다.
'CTF' 카테고리의 다른 글
[Defcon CTF 2016] baby-re write up (1) | 2016.05.26 |
---|---|
[Plaid CTF 2016] unix_time_formatter write up (0) | 2016.04.23 |
[Plaid CTF 2016] butterfly write up (1) | 2016.04.21 |
[sCTF 2016] pwn3 write up (0) | 2016.04.21 |
[sCTF 2016] pwn2 write up (0) | 2016.04.19 |