【发布时间】:2012-05-27 21:01:47
【问题描述】:
在here 的讨论之后,如果你想有一个安全类用于在内存中存储敏感信息(例如密码),你必须:
- memset/clear the memory before free it
- 重新分配也必须遵循相同的规则 - 而不是使用 realloc,而是使用 malloc 创建一个新的内存区域,将旧内存复制到新内存,然后在最终释放之前 memset/clear 旧内存
所以这听起来不错,我创建了一个测试类来看看它是否有效。所以我做了一个简单的测试用例,我不断添加单词“LOL”和“WUT”,然后在这个安全缓冲区类中添加一个数字大约一千次,销毁该对象,然后最终执行导致核心转储的操作。
由于该类应该在销毁之前安全地清除内存,因此我不应该能够在 coredump 上找到“LOLWUT”。但是,我还是设法找到了它们,并想知道我的实现是否只是错误。但是,我使用 CryptoPP 库的 SecByteBlock 尝试了同样的事情:
#include <cryptopp/osrng.h>
#include <cryptopp/dh.h>
#include <cryptopp/sha.h>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <cryptopp/filters.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(){
{
CryptoPP::SecByteBlock moo;
int i;
for(i = 0; i < 234; i++){
moo += (CryptoPP::SecByteBlock((byte*)"LOL", 3));
moo += (CryptoPP::SecByteBlock((byte*)"WUT", 3));
char buffer[33];
sprintf(buffer, "%d", i);
string thenumber (buffer);
moo += (CryptoPP::SecByteBlock((byte*)thenumber.c_str(), thenumber.size()));
}
moo.CleanNew(0);
}
sleep(1);
*((int*)NULL) = 1;
return 0;
}
然后编译使用:
g++ clearer.cpp -lcryptopp -O0
然后启用核心转储
ulimit -c 99999999
然后,启用核心转储并运行它
./a.out ; grep LOLWUT core ; echo hello
给出以下输出
Segmentation fault (core dumped)
Binary file core matches
hello
这是什么原因造成的?由于 SecByteBlock 的 append 引起的重新分配,应用程序的整个内存区域是否重新分配?
另外,This is SecByteBlock's Documentation
edit:使用 vim 检查核心转储后,我得到了这个: http://imgur.com/owkaw
edit2:更新了代码,使其更易于编译,以及编译说明
final edit3:看起来 memcpy 是罪魁祸首。请参阅 Rasmus 的mymemcpy 实现,了解他的回答。
【问题讨论】:
-
我认为这不是您所看到的原因,但您确实知道在某些内存上调用
memset并不能阻止某些交换文件中仍然存在它的副本某处?通常,memset的结果不需要穿透所有缓存层,但我提到交换文件,因为它是最持久的,因此对于敏感数据来说是最危险的地方。 -
@SteveJessop 嗯,这可能就是为什么 windows 有 SecureZeroMemory 或类似的东西。我想知道 linux/posix 的等价物是什么……如果有的话。
-
一个足够积极的优化器可能会将
memset删除到不再被读取的块中。SecureZeroMemory是有原因的! -
那么我的王国需要一个 posix/linux/iOS 版本的securezeromemory!
-
@kamziro:我很确定 Linux 和 iOS 都会在让另一个进程看到之前为您清除内存。如果不是,那是因为你在编译内核时关闭了某些东西:-)最终你要争夺的是攻击者可以通过引发和读取核心转储来查看内存内容的窗口的持续时间,直接检查 RAM 等。无论您做什么,该窗口要么存在,要么不存在,因为攻击者通常没有理由在之后你清除它而不是之前这样做。
标签: c++ security memory cryptography passwords