char阵列C++无法删除|使用过程黑客仍然可以使用转储
我想实现安全的解决方案,这将在使用后阻止内存中倾倒密码。我尝试了几个解决方案,但是即使我使用了所有解决方案,我仍然可以倾倒应该从内存中删除的密码。我的代码:
char str[49] = "This is a string literal. See the double quotes?";
// cout << "Secret variable is: " << str << " with length: " << strlen(str) << endl;
cleanse(str, sizeof(str));
memset(str, 0, sizeof(str));
SecureZeroMemory(str, sizeof(str));
OPENSSL_cleanse(str, sizeof(str));
即使一次使用所有这些函数 - 在内存转储中,我的秘密变量出现
我的编译参数:
-s -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -fuse-ld=lld -Wl,--gc-sections -fstack-protector
这就是我使用Process Hacker倾倒内存的方式,然后我使用>字符串
从内存中提取所有字符串,这里是:
在这里永远不应该出现的值,我在做什么错?
I want to implement secure solution, which would prevent dumping password from memory after it usage. I tried few solutions, but even when i used all of them, i still can dump my password which should be erased from memory. My code:
char str[49] = "This is a string literal. See the double quotes?";
// cout << "Secret variable is: " << str << " with length: " << strlen(str) << endl;
cleanse(str, sizeof(str));
memset(str, 0, sizeof(str));
SecureZeroMemory(str, sizeof(str));
OPENSSL_cleanse(str, sizeof(str));
Even after using all of those functions at one time - in memory dump my secret variable appear
My compile params:
-s -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -fuse-ld=lld -Wl,--gc-sections -fstack-protector
That's how i dumping memory using Process Hacker, then i'm using strings
to extract all strings from memory and here it is:
Value which should never appear here, what i'm doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在
c ++
中,字符串文字具有类型const char [n]
,其中n
是字符串的大小,包括终止null字符。行的效果是将字符串文字复制到程序启动时的
str
数组。这将在str
array中创建密码的A 复制;原始的字符串文字保持不变。正是strings
应用程序找到的原始字符串文字。为了解决这个问题,您可以从用户输入时在运行时初始化
str
数组。但是,如果您使用库例程(例如fgets
)来执行此操作,则无法控制它的作用;就我所知,它可能会保存内部某个地方的输入行的副本。因此,如果strings
仍然在内存中找到您的密码,则必须实现自己的角色输入处理。顺便说一句,您通过指定
str
数组的大小来为自己创建问题;如果字符串长度发生变化,您的代码将无法编译(或更糟)。更简单,更好的是具有相同的效果。
In
C++
, string literals have typeconst char[N]
, whereN
is the size of the string including the terminating null character. The effect of your lineis to copy the string literal into the
str
array at program startup. This creates a copy of your password in thestr
array; the original string literal remains unchanged. And it is this original string literal that is found by thestrings
app.To get round this, you could initialise the
str
array at runtime, from user input. But if you use a library routine likefgets
to do this, you have no control over what it does; for all I know, it might save a copy of the input line somewhere internally. So ifstrings
still finds your password somewhere in memory, you will have to implement your own character input handling.By the way, you are creating problems for yourself by specifying the size of the
str
array; if the string length ever changes, your code will fail to compile (or worse). Simpler and better iswhich has the same effect.
调用函数时,该过程需要能够初始化该字符串。即使清除了存储在堆栈上的值,它仍将保留在加载的二进制中。您了解:
无论我们在代码中添加什么,都不足以阻止专业网络安全工程师在二进制中找到或生成的密码,而无需添加单独的密钥。
我们将密码的内存归零,因为该密码在程序开始之前不存在,因此我们可以最大程度地减少其保留在内存中的时间。没有安全的方法将密码存储在二进制中,但是我们可以做一些技巧来更难找到。我们可以通过存储密码的编码版本来假装具有安全性。但是,仍然很难以一种防止编译器将密码重新优化为纯文本表单的方式存储。
理想情况下,密码(或私钥)只能存储在受信任的系统上。该二进制文件将传递给不受信任的系统,这些系统必须将请求发送到受信任的系统。然后,受信任的系统代表他们采取行动,同时忽略了恶意或畸形的请求。
旁注:这个问题可能是 xy问题的结果。您为什么要存储密码?您实际想做什么?您的问题可能会有更简单的答案,不需要将密码存储在二进制中。
The process needs to be able to initialize that string when the function is called. Even if the value stored on the stack is cleared, it will still remain present in binary that was loaded. It is very important that you understand:
No matter what we add in the code, it won't be enough to stop a professional cybersecurity engineer from finding a password stored or generated within a binary without the addition of a separate key.
We zero the memory of a password because it did not exist prior to the start of the program so we can minimize the time it is held in memory. There is no safe way to store a password in the binary, but we can do some tricks to make it harder to find. We can pretend to have security by storing an encoded version of the password. However, it will still be difficult to store it in a way that prevents the compiler from optimizing the password back into its plain text form.
Ideally the password (or private key) would only be stored on a trusted system. This binary would be passed to untrusted systems which must send requests to the trusted system. The trusted system then acts on their behalf while ignoring malicious or malformed requests.
Side Note: This question may be the result of the XY problem. Why are you attempting to store the password? What do you actually want to do? There may be a simpler answer to your problem which does not require storing the password in a binary.