Hackerschool FTZ: Level 9 문제 풀이
[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를 확인하면 비밀번호까지 알 수 있다.