CTF, 워게임 문제 풀이/Hackerschool FTZ

Hackerschool FTZ: Level 9 문제 풀이

secumark 2023. 3. 9. 03:31
728x90

[level9@ftz level9]$ cat hint

/usr/bin/bof의 소스코드를 보여주고 있다.

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

main(){

  char buf2[10];
  char buf[10];

  printf("It can be overflow : ");
  fgets(buf,40,stdin);

  if ( strncmp(buf2, "go", 2) == 0 )
   {
        printf("Good Skill!\n");
        setreuid( 3010, 3010 );
        system("/bin/bash");
   }

}

 

이걸 이용해서 level10의 권한을 얻으면 된다.

일단 C언어 코드인 것 같고..

변수는 buf2, buf 이렇게 두개다. 

printf("It can be overflow :")라고 적혀있고..

fgets 함수로 40자까지의 문자열을 읽어올 수 있음.

buf 함수를 fgets 함수로 받는 듯 하다.

그리고 strncmp 함수는 (문자열1, 문자열2, 1과2를 비교할 문자열 길이) 이런식으로.. 문법 구성이 되어 있는데

즉 buf2가 go라는 글자와 같으면 0을 반환하는 듯하다.

그럼 setreuid(3010,3010)과 함께 /bin/bash까지 실행하는듯.

ruid랑 euid가 3010이라는.. 뜻일듯

 

대충 어떤식으로 하면 되냐면.. fgets를 넘어서 아래 if문 buf2까지 영향을 끼칠 수 있게 버퍼오버플로우 공격을 하면 된다.

 

 

/usr/bin/bof 파일을 실행하면 이렇게 값을 입력하도록 적혀있다.

 

disas main 명령어로 어셈블리 명령어들을 모두 확인했다.

 

(gdb) disas main
Dump of assembler code for function main:
0x08048420 <main+0>:    push   %ebp
0x08048421 <main+1>:    mov    %esp,%ebp
0x08048423 <main+3>:    sub    $0x28,%esp
0x08048426 <main+6>:    and    $0xfffffff0,%esp
0x08048429 <main+9>:    mov    $0x0,%eax
0x0804842e <main+14>:   sub    %eax,%esp
0x08048430 <main+16>:   sub    $0xc,%esp
0x08048433 <main+19>:   push   $0x8048554
0x08048438 <main+24>:   call   0x8048350 <printf>
0x0804843d <main+29>:   add    $0x10,%esp
0x08048440 <main+32>:   sub    $0x4,%esp
0x08048443 <main+35>:   pushl  0x8049698
0x08048449 <main+41>:   push   $0x28
0x0804844b <main+43>:   lea    0xffffffd8(%ebp),%eax
0x0804844e <main+46>:   push   %eax
0x0804844f <main+47>:   call   0x8048320 <fgets>
0x08048454 <main+52>:   add    $0x10,%esp
0x08048457 <main+55>:   sub    $0x4,%esp
0x0804845a <main+58>:   push   $0x2
0x0804845c <main+60>:   push   $0x804856a
0x08048461 <main+65>:   lea    0xffffffe8(%ebp),%eax
0x08048464 <main+68>:   push   %eax
---Type <return> to continue, or q <return> to quit---c
0x08048465 <main+69>:   call   0x8048330 <strncmp>
0x0804846a <main+74>:   add    $0x10,%esp
0x0804846d <main+77>:   test   %eax,%eax
0x0804846f <main+79>:   jne    0x80484a6 <main+134>
0x08048471 <main+81>:   sub    $0xc,%esp
0x08048474 <main+84>:   push   $0x804856d
0x08048479 <main+89>:   call   0x8048350 <printf>
0x0804847e <main+94>:   add    $0x10,%esp
0x08048481 <main+97>:   sub    $0x8,%esp
0x08048484 <main+100>:  push   $0xbc2
0x08048489 <main+105>:  push   $0xbc2
0x0804848e <main+110>:  call   0x8048360 <setreuid>
0x08048493 <main+115>:  add    $0x10,%esp
0x08048496 <main+118>:  sub    $0xc,%esp
0x08048499 <main+121>:  push   $0x804857a
0x0804849e <main+126>:  call   0x8048310 <system>
0x080484a3 <main+131>:  add    $0x10,%esp
0x080484a6 <main+134>:  leave
0x080484a7 <main+135>:  ret
End of assembler dump.

 

오랜만에 까먹었던 스택 구조를 다시 공부..

근데 뭐가 좀 안보여서 intel 구조로 바꿔봤다.

intel 구조로 바꾸는법: set disassembly-flavor intel

 

0x08048420 <main+0>:    push   ebp
0x08048421 <main+1>:    mov    ebp,esp
0x08048423 <main+3>:    sub    esp,0x28
0x08048426 <main+6>:    and    esp,0xfffffff0
0x08048429 <main+9>:    mov    eax,0x0
0x0804842e <main+14>:   sub    esp,eax
0x08048430 <main+16>:   sub    esp,0xc
0x08048433 <main+19>:   push   0x8048554
0x08048438 <main+24>:   call   0x8048350 <printf>
0x0804843d <main+29>:   add    esp,0x10
0x08048440 <main+32>:   sub    esp,0x4
0x08048443 <main+35>:   push   ds:0x8049698
0x08048449 <main+41>:   push   0x28
0x0804844b <main+43>:   lea    eax,[ebp-40] -> 이 부분이 buf를 할당하기 시작한? 부분인 것 같고,
0x0804844e <main+46>:   push   eax
0x0804844f <main+47>:   call   0x8048320 <fgets>
0x08048454 <main+52>:   add    esp,0x10
0x08048457 <main+55>:   sub    esp,0x4
0x0804845a <main+58>:   push   0x2
0x0804845c <main+60>:   push   0x804856a
0x08048461 <main+65>:   lea    eax,[ebp-24] -> 이 부분이 buf2를 할당한 부분인 것 같다. 
0x08048464 <main+68>:   push   eax

 

그러니까 .. 쉽게 얘기하면 ebp-40부터 buf가 시작돼서 -39, -38, -37,,,, 이런식으로 쭉 올라가다가 16만큼의 바이트를 채웠을 때 buf2에 도달한다는 뜻이다. 그리고 ebp-24부터 bo2가 시작되는 것.

이 뒤는 굳이 안봐도되는게

  printf("It can be overflow : ");
  fgets(buf,40,stdin);

  if ( strncmp(buf2, "go", 2) == 0 )
   {
        printf("Good Skill!\n");
        setreuid( 3010, 3010 );
        system("/bin/bash");
   }

}

buf에서 buf로 넘어간 후에 strncmp 함수로 buf2가 go 이 두글자만 만족시켜주면 되기 때문에

요렇게 아무 문자나 16개를 넣어주고, 뒤에 go를 입력해주면 if문 함수가 true가 되면서 level10으로 권한상승할 수 있게 된다.

 

 

권한을 획득했으니, my-pass를 확인하면 비밀번호까지 알 수 있다.

 

728x90