在C可执行程序中嵌入安全信息(用户名和密码)

时间:2016-04-05 08:39:30

标签: c executable decoding

我已经将用户名和密码列表硬编码到C ++数组程序中,并将可执行程序交给每个人。用户解码可执行文件以获取实际的用户名和密码有多难?

用户名和密码非常长,猜测/暴力在计算上是不可行的。

我在安全编码方面没有背景,因此将用户名和密码硬编码在可执行程序中。黑客获取信息的唯一方法是解码可执行文件。我想知道这个过程有多难以及如何使其变得更加困难。

2 个答案:

答案 0 :(得分:3)

有多难?这只是一个命令。

strings path/to/executable

示例:

$ cat main.c
int main(void)
{
    char* foo = "zyxwvu";
    return 0;
}

$ gcc -o main main.c
$ strings main
zyxwvu

字符串保存在二进制文件.text / .data / .cstring(取决于二进制格式)部分,如下所示:

100000f8a:   7a 79                   jp     100001005 <_main+0x95>
100000f8c:   78 77                   js     100001005 <_main+0x95>
100000f8e:   76 75                   jbe    100001005 <_main+0x95>

0x7az0x79y等。

答案 1 :(得分:2)

在GNU工具中有一个命令,其名称为strings,确实如此:

  

GNU字符串打印可打印字符          长度至少为4个字符的序列(或者给出的数字          下面的选项),然后是一个不可打印的字符。通过          默认情况下,它只打印初始化和加载的字符串          目标文件的部分;对于其他类型的文件,它打印          整个文件中的字符串。

微软的世界中有相同的工具,而不是许多二进制(或十六进制编辑器)。

即使是好的旧vim也可以打开二进制文件,并允许将其视为字符和十六进制格式。

这意味着用户唯一的难点就是猜测用户名是什么字符串,密码是什么,哪些对应于哪些。但如果你把它们编码为2个阵列,那么很容易猜到。

从安全角度来看,将秘密存储在未加密的文件中是不好的。因此,正确的方法是使用不对称引擎,向每个用户询问其公钥,使用它加密密码并让用户使用其私钥对其进行解密。这样每个用户只能解码他的一组密码。

如果你不能这样做(设计过于复杂),你只会留下不好的安全解决方案,只会加强攻击者的任务,但如果风险低到中等就足够了。您可以尝试使用几个变量中的几乎无关紧要的算法(按位操作)构建主键,并使用该键使用对称算法对密码进行编码。这样,在可执行文件中没有任何键可以直接读取,并且您可以使用良好的algorythm来存储密码。但你仍然容易受到两次攻击:

  • 如果攻击者在调试器下执行程序,他可以很容易地猜出在使用它们时用户名和密码是什么 - 这可以通过确定程序是否在调试器下运行来部分缓解,但硬件调试器不能识别。
  • 如果攻击者读取正在运行的程序的内存,则密码或主键可以直接读取 - 这可以通过在计算密码后将内存重置为随机或零来缓解。

但无论如何,永远不要存储真正敏感的数据。

BTW,上面假设您确实需要程序中的实际密码,例如访问受您不希望与您自己的用户通信的用户名和密码保护的第三方数据。即使在这种情况下,如果相关,代理机制也会更安全。但是,如果您只需要根据用户名和密码的基础对用户进行身份验证,则只需存储哈希值。对于本地数据库,bcryp是一个不错的选择:

  • 它不是不可逆的
  • 这是非常耗时的,因此可以抵抗暴力攻击 - 具有可配置的强度