프로세스 교체 시 민감한 데이터

프로세스 교체 시 민감한 데이터

내가 이렇게 한다고 가정해보자:

#!/bin/bash
content="foo"
pass="secret-password"
echo $content | ccrypt -f -k <(echo -n $pass)  

프로세스 대체 파일에 설정된 권한을 신뢰하여 /dev/fd/*해당 기간 동안 비밀번호를 안전하게 유지할 수 있습니까 ccrypt?

답변1

분석해 보겠습니다.

content=$(cat -)

이는 와 동일합니다 content=$(cat). 사용되는 것명령 대체파이프를 사용 bash합니다. 파이프의 한쪽 끝에는 cat표준 입력에서 읽은 내용이 기록됩니다. bash다른 쪽 끝은 그것을 읽고 $content.

그러나 그렇게 하기 전에 후행 개행 문자를 제거하고 NUL 문자에 대한 차단도 제거합니다. 임의의 데이터를 변수에 저장할 수 있으려면 를 사용할 수 없으며 다음과 같은 작업을 bash수행해야 합니다 .zsh

content=$(cat; echo .); content=${content%.}

개행 제거 문제를 해결합니다.

저장할 데이터는 $content스크립트의 표준 입력을 통해 입력됩니다. 이것은 (Linux에서) 파이프로 복사되므로 에서도 /proc/pid-of-your-script/fd/0사용할 수 있습니다 ./proc/pid-of-cat/fd/0catbash/proc/pid-of-cat/fd/1/proc/pid-of-script/fd/fd-to-the-other-end-of-the-pipe

어쨌든 콘텐츠는 한 번만 사용하므로 $content중간 단계를 수행할 필요가 없습니다.


pass=$1

여기서 당신은 비밀에 대해 이야기하고 있습니다열쇠스크립트의 첫 번째 매개변수에서 가져옵니다.

비밀 데이터를 명령줄 인수로 전달할 수 없습니다. 명령줄 매개변수는 비밀이 아닙니다. 의 출력에 나타납니다 ps -efwww. Linux에서는 /proc/pid/cmdline해당 파일이 포함된 파일을 누구나 읽을 수 있습니다. 기본적으로 Linux에서는 /proc/pid관리상 동일한 euid를 가진 프로세스로 액세스를 제한할 수 있지만 동작이나 ps기타 문제에 영향을 미치기 때문에 거의 수행되지 않습니다.

일부 시스템에서는 일부 프로세스 계정/감사 메커니즘을 통해 기록될 수도 있습니다.


echo $content오류에는 여러 가지 이유가 있습니다.

  • echo임의의 데이터와 함께 사용할 수 없습니다. 환경에 따라 , ...와 -n같은 인수 및 백슬래시와 같은 항목에서는 제대로 작동하지 않습니다 .-neneneene
  • 따옴표가 없으면 $content원하지 않는 분할+glob 연산자를 호출하는 것을 의미하며 와일드카드 문자를 $content포함 하면 $IFS문제가 발생할 수 있습니다 .
  • 추가 개행 문자를 추가합니다.

당신이 원하는 것:

printf %s "$content"

그리고 후행 개행 문자가 너무 일찍 제거되지 않도록 하세요.

파이프의 일부 이기 때문에 printf하위 프로세스에서 실행되며 표준 출력은 파이프가 됩니다. Linux에서는 /proc/pid-of-that-child-process/fd/1콘텐츠에 대한 액세스가 허용됩니다. 그럴 것이다 /proc/pid-of-ccript/0.


존재하다

ccrypt -f -k <(echo -n $pass)

echo과 인용되지 않은 질문이 다시 발생합니다 $pass.

echo(하위 프로세스에서 다시 실행) 파이프에 비밀번호를 씁니다. 파이프의 다른 쪽 끝은 fd에서 사용할 수 있습니다.Nccrypt은 또는 과 같은 것으로 <(...)확장됩니다 . 파일을 열고(새 fd에서) 해당 파일(Linux에서)을 다시 사용할 수 있습니다 ./dev/fd/n/proc/self/fd/nccrypt/proc/pid-of-ccrypt/fd/that-fd/proc/pid-of-ccrypt/fd/n/proc/pid-of-echo/fd/1


이제 코드의 주요 문제는 프로세스 대체나 다른 파이프가 아니라 암호가 명령(여기 스크립트)에 대한 명령줄 인수로 제공된다는 사실입니다.

프로세스 대체 에는 $(...)명령 대체 및 |. /dev/fd/x그러나 동일한 euid(또는 루트)로 실행되는 다른 프로세스는 어쨌든 해당 프로세스의 메모리를 읽고(디버거가 수행하는 것처럼) 해당 비밀번호를 복구할 수 있습니다(또는 동일한 소스에서 비밀번호를 가져올 수도 있음).

Linux에는 기호 링크 와 동적 기호 링크 /dev/fd가 있습니다 . 기본적으로 동일한 euid를 가진 프로세스는 읽을 수 있습니다(더 많은 제한 사항이 추가될 수 있지만 프로세스에 디버거를 연결할 수 있는 사람을 제한하는 것과 동일합니다)./proc/self/fd/proc/self/proc/the-pid/proc/pid/fd

파이프를 가리키는 fd의 경우 /proc/pid/fd/that-fd명명된 파이프처럼 작동합니다. 따라서 다른 프로세스(다시 동일한 euid 또는 루트로 실행)가 파이프의 내용을 훔칠 수 있습니다. 하지만 어쨌든 그렇게 할 수 있다면 프로세스 메모리의 내용을 직접 읽을 수도 있으므로 이를 방지하려고 노력할 필요가 없습니다.


명령줄에서 비밀번호를 전달하는 대신 환경 변수를 통해 비밀번호를 전달할 수 있습니다. 환경은 매개변수 목록보다 더 비공개적입니다. Linux에서는 /proc/pid/environ동일한 euid(또는 euid )를 가진 root프로세스에서만 읽을 수 있습니다.

따라서 스크립트는 다음과 같을 수 있습니다.

#! /bin/sh -
exec ccrypt -f -E PASSWORD

그리고 전화해

PASSWORD=secret-phrase the-script < data-to-encrypt 

관련 정보