0 前言
本文包含对shellcode开发技术及其特点的概述,了解了这些概念我们就可以编写自己的shellcode,而且我们还可以修改现有漏洞的shellcode来执行我们自定义的功能。
1 Shellcode介绍
维基百科中对shellcoed的介绍:
“在计算机安全中,shellcode 是一小段代码,用作利用软件漏洞的有效载荷。之所以称为“shellcode”,是因为它通常启动一个命令shell,攻击者可以从中控制受感染的机器,但任何执行类似任务的代码都可以称为 shellcode……Shellcode 通常用机器代码编写。”
假设:Internet Explorer或Flash Player中有一个可以打开calc.exe的有效漏洞利用程序。
在漏洞利用程序中,创建并打开计算器进程的那一部分代码就是shellcode。然而在黑客成功利用了漏洞后,打开计算器一定不是他们的目的,他们想要的是执行一些远程命令或执行其他有效的的功能。 既然shellcode在漏洞利用中如此重要,也就有了生成shellcode的工具:
http://shell-storm.org/shellcode/
https://www.offensive-security.com/metasploit-unleashed/msfvenom/
但是我们必须首先了解shellcode的基本原理才能更高的将其利用在漏洞中。
以C代码为例来看一下作为机器码的shellcode:
对应的汇编语言与机器码:
红框中的55 8B EC 68 00 B0 33 ...就是C代码对应的机器码。
2 在漏洞中利用shellcoed
以一个简单的基于堆栈缓冲区溢出漏洞为例:
利用此漏洞的主要思路如下:
1. 向应用程序发送一个大于20字节的字符串,其中还包含我们的shellcode
2. 堆栈中的缓冲区边界被破坏,我们的shellcode被放置于栈中
3. 发送的超长字符串(相对于缓冲区大小)将覆盖栈中的关键数据,如函数返回地址
4. 应用程序会从栈中跳转到我们的shellcode,并开始执行其中的机器码指令
如果我们能够成功利用此漏洞并运行shellcode,那么我们就可以对该漏洞做一些有价值的操作,而不仅仅是使程序崩溃。shellcode 可以打开 shell、下载和执行文件、重新启动计算机、启用 RDP 或任何其他操作。
3 Shellcoed特性
在编写shellcode时,也需要注意一些shellcode的特性:
1. 不能对字符串使用直接偏移量
2. 我们不知道函数的具体地址(如上述C代码中的printf)
3. 避免使用一些特定的字节(例如NULL字节)
4 Linux与Windows Shellcode的区别
Linux 上的“Hello, world”shellcode 需要以下步骤:
1. 指定系统调用(例如“write”)
2. 指定系统调用参数(例如stdout、“Hello,world”、长度)
3. 中断0x80执行系统调用
Windows上执行shellcode需要以下步骤:
1. 获取kernel32.dll基地址
2. 查找GetProcAddress函数地址
3. 使用GetProcAddress查找LoadLibrary函数的地址
4. 使用LoadLibarry加载DLL(例如user32.dll)
5. 使用GetProcessAddress查找函数的地址(例如user32.dll导出的MessageBox)
6. 指定函数参数
7. 调用函数