在this essay的底部是一个关于打败密码的怪异方式的评论。扫描用户的整个硬盘驱动器,包括死区,交换空间等,然后尝试看起来可能是密码的所有内容。
问题:第1部分,是否有任何工具(例如现场CD)将扫描未安装的文件系统并将所有可能的内容归零? (注意我不试图找到密码)
这包括:
该工具(除了最后一种情况)不会修改任何可以通过文件系统API检测到的内容。我不正在寻找一个块设备查找/替换,而是只是擦除不属于文件的所有内容。
第2部分,这样的程序有多实用?写作有多难?文件格式包含未初始化数据的常见程度如何?
执行此操作的一种(风险且成本高昂)方法是使用文件系统感知备份工具(仅复制实际数据)备份整个磁盘,擦除它然后将其还原。
答案 0 :(得分:1)
我不明白你的第一个问题(你想修改文件系统吗?为什么?这个死空间不是你想看的地方吗?)
无论如何,here's an example of such a tool:
#include <stdio.h>
#include <alloca.h>
#include <string.h>
#include <ctype.h>
/* Number of bytes we read at once, >2*maxlen */
#define BUFSIZE (1024*1024)
/* Replace this with a function that tests the passwort consisting of the first len bytes of pw */
int testPassword(const char* pw, int len) {
/*char* buf = alloca(len+1);
memcpy(buf, pw,len);
buf[len] = '\0';
printf("Testing %s\n", buf);*/
int rightLen = strlen("secret");
return len == rightLen && memcmp(pw, "secret", len) == 0;
}
int main(int argc, char* argv[]) {
int minlen = 5; /* We know the password is at least 5 characters long */
int maxlen = 7; /* ... and at most 7. Modify to find longer ones */
int avlen = 0; /* available length - The number of bytes we already tested and think could belong to a password */
int i;
char* curstart;
char* curp;
FILE* f;
size_t bytes_read;
char* buf = alloca(BUFSIZE+maxlen);
if (argc != 2) {
printf ("Usage: %s disk-file\n", argv[0]);
return 1;
}
f = fopen(argv[1], "rb");
if (f == NULL) {
printf("Couldn't open %s\n", argv[1]);
return 2;
}
for(;;) {
/* Copy the rest of the buffer to the front */
memcpy(buf, buf+BUFSIZE, maxlen);
bytes_read = fread(buf+maxlen, 1, BUFSIZE, f);
if (bytes_read == 0) {
/* Read the whole file */
break;
}
for (curstart = buf;curstart < buf+bytes_read;) {
for (curp = curstart+avlen;curp < curstart + maxlen;curp++) {
/* Let's assume the password just contains letters and digits. Use isprint() otherwise. */
if (!isalnum(*curp)) {
curstart = curp + 1;
break;
}
}
avlen = curp - curstart;
if (avlen < minlen) {
/* Nothing to test here, move along */
curstart = curp+1;
avlen = 0;
continue;
}
for (i = minlen;i <= avlen;i++) {
if (testPassword(curstart, i)) {
char* found = alloca(i+1);
memcpy(found, curstart, i);
found[i] = '\0';
printf("Found password: %s\n", found);
}
}
avlen--;
curstart++;
}
}
fclose(f);
return 0;
}
安装:
hddpass.c
su || sudo -s
#让你成为root用户,以便你可以访问硬盘apt-get install -y gcc
#安装gcc
gcc -o hddpass hddpass.c
#Compile。./hddpass /dev/
YOURDISK #磁盘通常是sda
,hda
在旧系统上Test(以root用户身份复制到控制台):
gcc -o hddpass hddpass.c
</dev/zero head -c 10000000 >testdisk # Create an empty 10MB file
mkfs.ext2 -F testdisk # Create a file system
rm -rf mountpoint; mkdir -p mountpoint
mount -o loop testdisk mountpoint # needs root rights
</dev/urandom head -c 5000000 >mountpoint/f # Write stuff to the disk
echo asddsasecretads >> mountpoint/f # Write password in our pagefile
# On some file systems, you could even remove the file.
umount testdisk
./hdpass testdisk # prints secret
在Ubuntu Live CD上自行测试:
# Start a console and type:
wget http://phihag.de/2009/so/hddpass-testscript.sh
sh hddpass-testscript.sh
因此,它相对容易。当我发现自己时,ext2(我使用的文件系统)会覆盖已删除的文件。但是,我很确定某些文件系统没有。页面文件也一样。
答案 1 :(得分:1)
文件格式包含未初始化数据的常见程度是多少?
越来越不常见,我会想到的。经典的“罪犯”是旧版MS Office应用程序(基本上)将内存转储到磁盘上作为其“quicksave”格式。没有序列化,没有选择要转储的内容以及没有将新分配的内存页面归零的内存分配器。这不仅导致文档以前版本的多汁内容(因此用户可以使用撤销),而且还会导致其他应用程序的多汁片段。
写作有多难?
清除未分配的磁盘块的东西不应该那么难。它需要离线运行或作为内核模块运行,以免干扰正常的文件系统操作,但大多数文件系统都有一个“已分配”/“未分配”的结构,这种结构相当简单。解析。交换更难,但只要您在启动(或关闭)时清除它就可以了,这并不是太棘手。清除尾部块比较棘手,绝对不是我想要在线尝试的东西,但它不应该太难以使其适用于离线清洁。
这样的程序有多实用?
真的,取决于你的威胁模型。我会说,在一端,它根本不会给你太多,但另一方面,它是一个明确的帮助,以防止信息从错误的手中。但我不能给出一个坚定而快速的答案,
答案 2 :(得分:1)
好吧,如果我要为启动CD编写代码,我会做这样的事情:
效率不高,需要进行调整以确保您不会尝试复制文件中的第一个(以及完整的)群集。否则,如果没有足够的可用空间,你将陷入缓慢和失败。
有哪些工具可以有效地开源?