Systemhacking/FTZ

[FTZ] level14

レ(゚∀゚;)ヘ=З=З=З 2021. 5. 25. 19:34
728x90

level14

(password : what that nigga want?)

level14에 접속을 해서 'ls-l'를 통해 level15의 권한이 걸려 있는 'attackme'라는 setuid인 파일과 'hint' 파일이 존재하는 것을 확인하였다.

'cat' 명령어를 통해 'hint' 파일의 내용을 확인하였다.

 

더보기

 

'hint' 파일 해석

 

#include <stdio.h>
#include <unistd.h>

main()
{

  int crap;
  int check;
  char buf[20];                                   (1)
  fgets(buf,45,stdin);                            (2)
  if (check==0xdeadbeef)
   {
     setreuid(3095,3095);                       (3)
     system("/bin/sh");                          (4) 
   }
}

 

(1) 20byte 크기의 'buf' 변수 선언

(2) 'fgets()' 함수를 통해 40byte까지 사용자의 입력을 받음

(3) 'level15'의 'ruid', 'uid' 값으로 변경

(4) 'system()' 함수를 통해 쉘을 띄워줌

 

 

'buf'의 크기는 20byte이지만, 사용자에게서 입력받을 수 있는 크기는 45byte이다.

20byte보다 더 큰 값을 넣을 수 있으므로 'buffer overflow' 취약점이 존재한다.

이전 문제들과는 다르게 'if(check==0xdeadbeef)' 조건만 만족한다면 쉘을 획득할 수 있다.


'attackme' 파일을 './tmp'로 'level15.c'로 생성을 해 주고, 컴파일을 해 주었다.

그 다음 'gdb'로 열어서 main 함수를 디스어셈블 해보았다.

'fgets()' 함수에서 인자 값이 3개 이므로 이를 받기 위해 3번 push를 진행하게 된다.

push 중에 맨 마지막에 있는 것이 'buf'에 해당하는 부분이다.

즉, <main+27>에서 'fegts()'의 첫 번째 인자 값인 'buf'의 주소를 받기 위해 [ebp-56]의 주소값을 'eax' 에 넣어주므로 [ebp-56]에 20byte에 해당하는 buf가 존재한다.

<main+39>에서 if문에 해당하는 부분을 처리한다. 'check' 변수와 '0xdeadbeef'를 비교하므로, [ebp-16]에는 4byte에 해당하는 'check' 변수가 있다는 것을 알 수 있다.

결론을 내리자면, if문의 조건을 충족시키기 위해서는 buf값을 조작해서 check변수의 값을 '0xdeadbeef'로 변경해야하는데, 스택 구조가 밑의 표와 같이 되므로 이를 바탕으로 페이로드를 작성하였다.

check(4byte) -- [ebp-16]
dummy(20byte)
buf(20byte) -- [ebp-56]

스택 구조에 따라 앞 40byte에는 쓰레기 값을 넣고, 나머지 'check'에 해당하는 4byte에 '0xdeadbeef'로 채워주었다.

' (python -c 'print "A"*40+"\xef\xbe\ad\de"'; cat) | ./attackme '

위의 페이로드를 입력해주었다.

성공하였고, 'my-pass'를 통해 'level15'의 'password'인 'guess what"를 얻을 수 있었다.

'Systemhacking > FTZ' 카테고리의 다른 글

[FTZ] level13  (0) 2021.05.23
[FTZ] level12  (0) 2021.05.23
[FTZ] level 11  (0) 2021.05.17
[FTZ] level10  (0) 2021.05.17
[FTZ] level9  (0) 2021.05.06