gpt4 book ai didi

c - 使用 popen() 将密码短语传输到 Veracrypt - 它安全吗?

转载 作者:太空狗 更新时间:2023-10-29 11:40:27 26 4
gpt4 key购买 nike

我试图在 Linux 命令行上使用相同的密码更方便地挂载多个 Veracrypt 卷。由于 Veracrypt 仅支持 GUI 模式下的密码缓存,因此我编写了以下代码来为我完成这项工作:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<time.h>

int main(int argc, char* argv[]){
if(argc > 1 && argc%2==1){
srand(time(0));

//prevent veracrypt from asking for user's passphrase
system("sudo echo -n");

char *buffer = getpass("Veracrypt Password:");

for(int i = 1; i<argc; i+=2){
char* cc;
cc = (char *) malloc(57+strlen(argv[i])+1+strlen(argv[i+1]));
strcpy(cc, "veracrypt -t --protect-hidden=no --keyfiles=\"\" --pim=123 ");
strcat(cc, argv[i]);
strcat(cc, " ");
strcat(cc, argv[i+1]);

FILE* fChild = popen(cc, "w");
fprintf(fChild, "%s", buffer);
pclose(fChild);

free(cc);
}
for(int i = 0; i<strlen(buffer); i++)
buffer[i] = rand();
}
return 0;
}

代码有效,但我想知道密码是否在执行后从内存中正确删除。如上面的代码所示,密码短语首先被读入字符数组缓冲区,最后替换为随机值。

我的两个问题是:

  • 这种方法到底是不是个好主意? (安全方面)

  • buffer 的值是如何通过 popen() 传递给 veracrypt 的?/buffer 是直接从其位置读取还是被复制并因此可以保留在内存中的某个位置?

最佳答案

该方法是可行的,并且与在 shell 中通过管道传递密码一样安全 <<<"myPassword" veracrypt .

  1. ps 中没有密码输出。
  2. 密码仅存储在临时缓冲区中。
  3. 我认为如果攻击者对您的应用程序/源代码有足够的了解,他仍然可以使用一些侧 channel 攻击来获取密码。

您的代码根本不安全。

  1. 你不检查malloc的返回值
  2. 你不检查popen的返回值
  3. 你不检查getpass的返回值
  4. 您溢出了为 cc 分配的内存.您没有为终止空字符分配位置。你可以使用 asnprintf让 GNU 库为您完成这项工作。
  5. 因为你没有正确传递 argv[i]argv[i+1]使用您的程序攻击任何 PC 非常简单,例如:./your_program "; sudo rm -rf <some_file>" "; echo I can run any shell script here" .

Is this approach a good idea at all? (securitywise)

方法是好的,你如何接近它是不对的。您的程序泄漏内存并且不检查任何返回值并且无法控制传递给 popen 的字符串,这是不安全的。使用 system(sudo echo -n)也没有安全感。至于方法,最好在最后一次使用后将缓冲区清零 memset(buffer, 0, strlen(buffer) + 1) (可能多次,比如 5 次),然后是 free(buffer) .

鉴于最近的 Meltdown 和 Spectre 等攻击,较新的 ssh 版本在从用户收到密码后立即使用长 key (我认为使用 RSA,不确定)加密密码,并在每次使用时解密。 key 足够长,使得使用此类方法的攻击不太可能或太长。我认为不需要简单的小应用程序来实现这种方法。 source .

How is the value of buffer piped to veracrypt by popen()?

因为你使用 fprintf ,缓冲区被复制到内部 FILE*缓冲区,然后在换行符上刷新。默认 FILE*流在换行符上被缓冲和刷新。您可以使用 setvbuf 指定行为,但是,我认为它根本不安全,因为密码将保留在 FILE* 中。缓冲一段时间。然后 fprintf调用写入内部的内容FILE*使用 FILE* 将换行符缓冲到关联的管道文件描述符指针。然后内核将数据从管道的输入传递到命令的标准输入。更安全一点的方法(因为你根本不需要 printf 实用程序,你只是 "%s" ...),可能是使用 setvbuf(fChild, NULL, _IONBF, 0)然后使用 fwrite(buffer, strlen(buffer), 1, fChild) .

正确的方法是删除 FILE*并使用正确的 pipe() + fork() + exec()并使用 write() 将密码直接传输到管道中打电话,所以你不使用FILE*内部缓冲。 fork()还将允许您发送信号并处理子项的返回值。

Is buffer read directly from its location or is it copied and can therefore remain somewhere in memory?

是的,是的,是的。它直接从它在 fprintf 中的位置读取。称呼。它被复制到内部 FILE*缓冲。因此它可以保留在内存中的某个位置。

关于c - 使用 popen() 将密码短语传输到 Veracrypt - 它安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56821662/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com