Подход в порядке и является таким же безопасным, как и передача пароля в оболочке <<<"myPassword" veracrypt
.
- Нет пароля в выводе
ps
.
- Пароль хранится только во временных буферах.
- Я думаю, что злоумышленник все еще может получить пароль, используя некоторые атаки по побочным каналам, если он знает достаточно о вашем приложении / исходном коде.
Ваш код вообще не защищен.
- Вы не проверяете возвращаемое значение malloc
- Вы не проверяете возвращаемое значение popen
- Вы не проверяете возвращаемое значение getpass
- Вы переполняете выделенную память для
cc
. Вы не выделяли место для завершающего нулевого символа. Вы можете использовать asnprintf
и позволить библиотеке GNU делать всю работу за вас.
- Поскольку вы не передаете должным образом
argv[i]
и argv[i+1]
, очень просто атаковать любой компьютер с помощью вашей программы, например: ./your_program "; sudo rm -rf <some_file>" "; echo I can run any shell script here"
.
Является ли этот подход хорошей идеей вообще? (Securitywise)
Подход в порядке, как вы подошли, не в порядке. Ваша программа теряет память и не проверяет никаких возвращаемых значений и не контролирует строки, переданные в popen
, что просто небезопасно. Использование system(sudo echo -n)
также небезопасно. Что касается approuch, было бы лучше обнулить буфер после его последнего использования memset(buffer, 0, strlen(buffer) + 1)
(может быть, несколько раз, например, 5), а затем free(buffer)
.
В свете последних атак, таких как Meltdown, Spectre и других, новые версии ssh шифруют пароль длинным ключом (я думаю, с RSA, не уверен) сразу после получения его от пользователя и дешифруют каждый раз при использовании. Ключ достаточно длинный, чтобы сделать атаки такими методами маловероятными или слишком длинными. Я не думаю, что есть потребность в легком небольшом приложении, чтобы реализовать такой метод. источник .
Как значение буфера передается в veracrypt с помощью 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()
также позволит вам отправлять сигналы и обрабатывать возвращаемое значение дочернего элемента.
Буфер считывается непосредственно из своего местоположения или копируется и поэтому может оставаться где-то в памяти?
Да, и да, и да. Он читается непосредственно из его местоположения внутри fprintf
вызова. Копируется во внутренний FILE*
буфер. Поэтому он может оставаться где-то в памяти.