如何防止用户读取存储在二进制文件中的字符串?

时间:2012-03-11 08:32:28

标签: c++ c linux string elf

这是一个最小的测试用例:

#include <stdio.h>
#include <stdlib.h>

int main ( int argc , char **argv )
{
        const char abc [15] = "abcdefg\0";
        printf ("%s\n" , abc);
        return 0;
}

你做strings test,你应该看到abcdefg,因为它存储在只读区域。

那么,使用“strings”命令阻止用户读取此字符串的最佳方法是什么,例如我不希望用户知道我的SQL短语

3 个答案:

答案 0 :(得分:11)

一种解决方案是编写另一个以另一个用户身份运行的程序,并从要保护凭据的用户无法访问的位置读取凭据。该程序将公开一个API(通过TCP / IP或任何消息传递接口或远程过程调用),它不需要直接连接到数据库,而只响应您感兴趣的请求。

另一种方法是在您的程序上设置setuid 位,并从用户没有读取权限的位置读取凭据。使用chown为程序提供允许读取包含查询的文件的所有者。执行时,程序将获得读取文件的权限。

就像Nawaz的回答(和Binyamin Sharet)中说的那样,您可以使用混淆技术来使查询更难(特别是,它不再适用于strings),但要记住某人拥有更多知识将能够使用反汇编程序或调试程序查找字符串,或者只需在strace中运行程序即可。 它使这种方法不适合存储敏感信息,例如连接凭证:只要二进制文件可以连接,它包含凭据,任何具有计算机安全知识的人都知道并且可以对程序进行反向工程以检索你的密码。

作为一般准则,如果您需要保护执行程序的用户的信息,请不要将此信息提供给程序。这是确保无法阅读的唯一方法。

答案 1 :(得分:4)

您可以使用一些常量缓冲区存储XORed字符串,并在使用过程中恢复原始字符串。虽然不是那么容易维护......

例如,字符串“hello”,与0x55 XORed为:

hello:  0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x00
0x55:   0x55, 0x55, 0x55, 0x55, 0x55, 0x55
result: 0x3D, 0x30, 0x39, 0x39, 0x3A, 0x55

所以我们存储缓冲区:

char enc_str[] = { 0x3D, 0x30, 0x39, 0x39, 0x3A, 0x55 };

这是我们的解密功能(简化):

#define DEC_STR(X, Y) getDecryptedStr(X, Y sizeof(Y))
void getDecryptedStr(char * dec_str, char * enc_str, size_t size) {
    int i;
    for (i = 0; i < size; ++i) {
        dec_str[i] = enc_str[i] ^ 0x55;
    }
}

这就是我们使用它的方式:

char clear_str[sizeof(enc_str)];
DEC_STR(clear_str, enc_str);

答案 2 :(得分:1)

根据您的要求和可行性,您可以这样做:

  • 一种方法可能涉及以二进制格式将所有字符串存储在文件中,因此无法读取它,并且当您需要字符串时,可以从文件中读取它。您可以在文件中存储字符串时使用键值,在检索文件时,您可以使用来读取相关字符串。

  • 其他方法可能涉及某种形式的加密。将加密的字符串存储在程序本身中,并在需要时将其解密,然后再使用它。