首页 网络安全 安全学院 查看内容

缓冲区溢出学习笔记

2009-6-27 11:18 694 0

摘要:   1。栈溢出介绍  缓冲区溢出主要是程序在设计时边界的限制不严格,导致缓冲区数据越出边界,覆盖掉旁边的数据,如果覆盖后的数据是经过精心设计的,那么就会存在严重的漏洞,可以通过此漏洞执行任意的程序代理...
关键词: nbsp shellcode 地址 函数 程序 管道 结构 一个 指令 攻击

  1。栈溢出介绍  缓冲区溢出主要是程序在设计时边界的限制不严格,导致缓冲区数据越出边界,覆盖掉旁边的数据,如果覆盖后的数据是经过精心设计的,那么就会存在严重的漏洞,可以通过此漏洞执行任意的程序代理。  主要的实现过程:  数据溢出后,此时通过计算程序返回地址,把一个JMP ESP的跳转指令地址(通用地址为0x7ffa4512)覆盖到返回地址上(也就是返回地址CS:IP上),那么此时CS:IP就跳到JMP ESP的指令上执行这条指令,而ESP的值正好指向返回地址的下一条指令,此时在返回地址后面覆盖上设计好的shellcode就可以放程序运行次程序,完成攻击.示意图如下:  NNNNNNNNN....RET(0X7FFA4512)  SHELLCODE  |                 |  jmp esp---------- |  补充:  有时SHELLCODE覆盖的数据区是不能读的,于是就会造成程序错误,与是还有一种办法就是把  shellcode调到前面,在返回地址后面不用shellcode覆盖,而是用一条JMP跳转指令跳转到前面的可读的数据区+shellcode,这样也可以执行SHELLCODE。  另外一种常用的溢出方法JMP EBX  通过对返回地址覆盖上一个不可读写的地址,造成程序错误,程序转入异常处理机制,这时找到处  理入口(0x7ffa1571 jmp ebx通用地址),计算返回地址与入口地址距离,然后他们之间覆盖上NOP直到入口前4个字节,前4个字节输入JMP 04,后面接着输入JMP EBX  接着shellcode(提示:JMP EBX就是跳转到自身地址的前4个字节)  NNNNNNNNNNN....  RET(造成异常地址)  NNNNNNNNNN  JMP 04   入口(JMP EBX)shellcode  |                                     |  |-------------------------------------|  (转入异常处理程序入口)  2.shellcode的编写  环境:VC++6。0  用汇编语言实现程序要的功能,然后编译没错后,F10开始调试,进入反汇编,复制机器码。OK  函数的调用是先把参数从右到左(视情况而顶)压栈,然后CALL 函数地址(call函数执行PUSH IP 然后JMP)。  | -------------  |    EBP    |     这部开始都是在函数内部执行,这条是保护原来的堆栈基址  | -------------  |     IP   |    这部之后程序指令调到API函数的入口  | -------------  |   第N个  |  |    参数    |      程序调用API时堆栈的结构  | -------------  |  第一个 |  |   参数    |  -------------  3.远程shellcode的编写  远程的SHELLCODE需要在攻击端打开一个SHELL,并实现shell命令在双方的传递与显示(IPC进程间通信),其中存在管道方式,事件,文件映射,邮槽。(目前了解下管道)  执行过成:  客户端建立连接之后,服务端监听到有连接进来,与是接受连接,建立管道(分为双管道,单管道  ,0管道),然后开启一个SHELL,他们之间用管道传递命令。  管道1(把命令传给CMD)  攻击端------------------------>被攻击端----------------------------------------------cmd.exe  ----------------------------------------------cmd.exe  管道2(把命令的结果回显)  以上为双管道  没执行一个命令,都把命令做为参数,从新开启一个新CMD  攻击端------------------------>被攻击端----------------------------------------------cmd.exe  管道1(传回显)  以上为单管道  0管道不用管道,直接通过SOCKET传命令,命令到达都立即执行  另一冲连接,反向的shellcode连接,由被攻击端主动来连接攻击端,可使用双管道,单管道等。  4.堆溢出(heap)  堆是一种程序在运行期间动态生成的一种内存结构,与堆栈的增长方向相反,是往高地址长。  堆结构:  8字节                8个字节各占4个(前指针4字节|后指针4字节)  ----------———---------------------------------------------  |堆管理 | 堆操作空间| 下一个空闲堆管理结构| 两个双链表 |  ———  ————------- -----------------------------------  堆结构  我们通过对数据以及链表等地方做覆盖,在链表上分为2个4字节的链表,当数据覆盖到双链表前4  个字节时就会出错,以及给下一个堆分配空间时也会出现错误而执行mov [ecx],eax,mov [eax+4],ecx.这2条指令  eax          ecx  --------------  ---------------  what=    |   where=    |双链表的结构,会执行上面2条命令,所以如果调用了ecx里面的函  shellcode   |    函数      |数入口地址指针,就会执行这个函数,我们还是在用mov[ecx],eax  地址     |   返回地址   |把函数入口地址指针(在ECX中的值是指向函数入口地址指针)  --------------  --------------  改成了shellcode的入口地址,于是运行函数就等于在帮我们执行们                        shellcode.(需要注意第二句指令会改变shellcode+4位置的代  码)在函数退出时调用也是好办法.  还有一种方法就是通过异常(SEH)调用  现在我们在定位shellcode的地址上没有很好的定位,现在我门来把他实现,把shellcode的地址用[esi+0x4c]来替代,由于[esi+0x4c]指向下一个堆管理结构,那么我们现在where里写上异常调用的地址指针,执行mov [ecx],eax后,把esi+0x4c的地址给异常函数第二句mov [eax+4],ecx 我们尽量使[eax+4]的内容不能写,产生错误,调用之前我们设计的异常(也就是shellcode地址)  5.shellcode的编码  如有些shellcode在编写完之后中间会出现一些不符合规定的字符,如在strcmp()函数中不允许有0x00,这回阻止程序的运行,因为程序以为0x00是字符串结尾,那么shellcode就需要编码来解决这个问题,让程序中不出现不符合规定的字符,这其中大体的思想是:  shellcode  +  一种编码方式(如xor,等) = enshellcode  而在如strcmp()等函数执行后,把shellcode反编码成原始shellcode,所以这也决定shellcode的编码方式必须是可逆的,shellcode编码结构:  enshellcode  ......  shellcode  这样shellcode就可以被解码.  shellcode的基本编码方式:  XOR方法  shellcode xor Key  =  enshellcode  enshellcode xor Key = shellcode  微调法  如果只是一二个地方需要改动,就改变指令的方式调整那一小部分  拆分法  把一个数拆分成几个数,如  Z = a + b  Z = a * b  直接替换法  就在shellcode中直接对XOR后的结果中还存在不符合的数据进行一种方式的直接替换  内寸搜索法  对那些shellcode地址长度有限制的程序,直接在后面接上搜索shellcode的代码+shellcode.  通常搜索代码都很小,不长,所以都能很好的执行,另外在shellcode中添加用于搜索的标记,方便搜索代码用来执行搜索shellcode地址的任务  6.shellcode高级编程(动态定位函数地址以及从高级语言提出shellcode代码)  由于在shellcode执行中,在个系统种的通用性是最重要的,而通用性需要解决的问题就是调用系统DLL提供的函数时的动态内存地址,所以解决了这个问题后  shellcode + 通用的JMP ESP等跳转地址 = 通用的shellcode  定位函数的内存地址又分为几步  1。定位kernel32.DLL程序基地址  2。在DLL中保存了各种它包含的函数的内存地址,通过搜索这个表查找函数GetprocAddress函数的地址,通过这个函数就可以查出其他函数的地址  至于shellcode的提取可以用直接内存复制,调试时内存复制.通过高级语言直接提取  介绍蠕虫与突破防火墙的方法  蠕虫会把本机做成一个TFTP或FTP或各种传输服务,通过在本地打开一个端口监听,另外同时还在  对网络上计算机进行漏洞扫描,查找到有漏洞计算机后,对它进行攻击,执行从本机的下载工作,把本机上准备的病毒程序传到网络计算机  突破防火墙  使用反向连接,被攻击者主动连接攻击者,而如果攻击者在内网,那么数据包无法到达目的地,须  借助二机本身建立的攻击连接.  还可以通过对放火墙允许连接的端口做复用突破限制.  7.漏洞的分析,发现与攻击  漏洞的分析与发现通常都是通过2种方法实现的  1黑盒测试Fuzzer  这种方法不需要对程序的内部结构,逻辑结构,内部运做有了解,就想是把程序当成一个不能打开  密封的盒子来做测试,主要通过输入数据,在程序的借口对程序做测试,如对字符边界,数组大小,程序输入长度,逻辑错误等做检测,以此发现漏洞  2白盒测试  需要对程序的结构,内部的运行过程等都要有了解。反逆向来进行对结构的认识,查找漏洞。  通常程序都是结合2种方法一起测试的.  注:介绍了一种脚本语言python进行对软件接口,输入等的测试,python是一种在测试中很强大方便的测试工具,实时,对字符串的构造,把大部分的网络协议进行了封装,方便使用.  -----------------------------------------------------------------------  由于本人技术很菜 ,如有理解错误处,请大牛门指教.
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部