如何在二进制读取完成后覆盖内存以避免obash源码泄露?
解决obash内存源码泄露的内存覆盖实现方案
obash的核心问题是解密后的明文脚本会留在内存中,核心转储会完整导出这块内存区域。要解决这个问题,需要在解密执行脚本后立即覆盖存储明文的内存,同时可以配合禁用核心转储作为额外防护。
1. 定位并覆盖明文内存区域
修改obash的源码,找到解密后存储明文脚本的内存块,在脚本执行完成后用无意义数据覆盖该区域:
- 首先定位obash中处理OpenSSL解密的代码段,找到保存明文脚本的变量(比如堆分配的
char*缓冲区或栈上数组)。 - 在脚本执行完成(比如通过
system()、execve()调用bash执行脚本后),调用memset()将该内存区域填充为0或随机字节,彻底清除明文内容。 - 如果是堆分配的内存,覆盖后要及时释放并将指针置空,避免悬空指针残留。
示例代码修改(假设解密后明文存在decrypted_script缓冲区):
// 解密逻辑:获取decrypted_script和script_len char* decrypted_script = malloc(script_len); // 执行OpenSSL解密操作填充decrypted_script... // 调用bash执行解密后的脚本 pid_t pid = fork(); if (pid == 0) { // 子进程执行脚本 execl("/bin/bash", "bash", "-c", decrypted_script, (char*)NULL); exit(1); } else if (pid > 0) { // 父进程等待子进程执行完成 waitpid(pid, NULL, 0); // 覆盖并释放内存 memset(decrypted_script, 0, script_len); free(decrypted_script); decrypted_script = NULL; }
2. 禁用核心转储作为额外防护
在obash程序启动时,通过系统调用限制核心转储的大小,从根源上阻止核心文件生成:
#include <sys/resource.h> int main(int argc, char** argv) { struct rlimit core_limit; // 限制核心转储大小为0 core_limit.rlim_cur = 0; core_limit.rlim_max = 0; setrlimit(RLIMIT_CORE, &core_limit); // 原obash的初始化、解密等逻辑... }
关于Ubuntu 18.04 LTS的差异
你之前在该系统上生成的二进制无此问题,大概率是因为当时系统默认禁用了核心转储(比如由apport处理核心文件且默认不保存),或者使用的obash旧版本自带了内存清理逻辑。
额外建议(长期方案)
如果obash无人维护的现状带来隐患,可考虑将bash脚本转为C程序包装后编译:将脚本内容作为字符串嵌入C代码,通过system()或execvp()调用执行,编译为二进制后内存中仅保留编译后的机器码,而非明文脚本。
内容的提问来源于stack exchange,提问作者Erikli
相关产品推荐
相关产品推荐

