shellcode开发
shellcode的基本原理
shellcode通常使用机器语言编写,是一段用于利用软件漏洞而执行的代码,因其目的常常是让攻击者获得目标机器的命令行shell而得名。
shellcode根据它是让攻击者控制它所运行的机器,还是通过网络控制另一台机器,可以分为本地和远程两种类型。本地shellcode通常用于提权,攻击者攻击高权限程序中的漏洞(例如缓冲区溢出),获得与目标进程相同的权限。远程shellcode则用于攻击网络上的另一台机器,通过TCP/IP套接字为攻击者提供shell访问。根据连接的方式不同,可分为反向shell(由shellcode建立与攻击者机器的连接)、绑定shell(shellcode绑定到端口,由攻击者发起连接)和套接字重用shell(重用exploit所建立的连接,从而绕过防火墙)。
有时,攻击者注入目标进程中的字节数是被限制的,因此可以将shellcode分阶段执行,由前一阶段比较简短的shellcode将后一阶段复杂的shellcode(或者可执行文件)下载并执行,这是恶意程序常见的一种操作。但有时攻击者并不能确切的知道后一阶段的shellcode在内存种的具体位置,因此就出现了egg-hunt shellcode,这段代码会在内存里进行搜索,直到找到后一阶段的shellcode(所谓的egg)并执行。
编写简单的shellcode
前篇一律,所谓的shellcode就是一段脚本(只不过是由汇编语言编写而成)。
例子:做PWN题时书写的shellcode
这些代码体现在内存中就是一条一条的汇编指令
shellcode变形
大多数shellcode都是专用的,与特定的处理器、操作系统、目标程序以及要实现的功能紧密相关,几乎没有一套全平台通用的shellcode。有时,被注入进程的shellcode会限制使用某些字符,例如不能有NULL、只能由字母和数字等可见字符、ASCII和Unicode编码转换等,因此需要做一些特殊处理。
NUll-free shellcode不能包含NULL字符,因此NULL会将字符串操作函数截断,这样注入或者执行的shellcode就只剩下NULL前面的那一段。为了避免NULL字符的出现,可以用其他相似功能的指令替代。
替换前:
B8 01000000 MOV EAX,1 //Set the register EAX to 0x000000001
替换后:
33C0 XOR EAX,EAX //Set the register EAX to 0x00000000
40 INC EAX //Increase EAX to 0x000000001
对于限制了只能使用可见字符字母,也就是字母和数字结合的情况,可以采用自修复(self-modifying)代码的方法,将原始shellcode的字符进行编码,使其符合限制条件。相应地,需要在shellcode中加入解码器,在代码执行前将原始shellcode还原出来。