읽기를 사용하여 입력한 비밀번호를 스니핑하고 명령줄 인수로 전달합니다.

읽기를 사용하여 입력한 비밀번호를 스니핑하고 명령줄 인수로 전달합니다.

비밀번호를 입력하여 표시하고 싶습니다.read안전감이 없습니다.

이를 반현실적인 시나리오에 포함시키기 위해 사용자에게 비밀번호를 묻는 메시지를 표시하고 7z1이 다음 명령을 사용하여 암호화된 아카이브를 생성하도록 한다고 가정해 보겠습니다.

read -s -p "Enter password: " pass && 7z a test_file.zip test_file -p"$pass"; unset pass

비밀번호를 유출하려는 첫 번째 시도는 다음을 설정하는 것이었습니다.심사규칙:

auditctl -a always,exit -F path=/bin/7z -F perm=x

물론 readand 와 관련된 명령을 실행하면 7z실행 중에 로그 항목이 나타납니다 ausearch -f /bin/7z.

time->Thu Jan 23 18:37:06 2020
type=PROCTITLE msg=audit(1579801026.734:2688): proctitle=2F62696E2F7368002F7573722F62696E2F377A006100746573745F66696C652E7A697000746573745F66696C65002D7074686973206973207665727920736563726574
type=PATH msg=audit(1579801026.734:2688): item=2 name="/lib64/ld-linux-x86-64.so.2" inode=1969104 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=PATH msg=audit(1579801026.734:2688): item=1 name="/bin/sh" inode=1972625 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=PATH msg=audit(1579801026.734:2688): item=0 name="/usr/bin/7z" inode=1998961 dev=08:03 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0
type=CWD msg=audit(1579801026.734:2688): cwd="/home/mb/experiments"
type=EXECVE msg=audit(1579801026.734:2688): argc=6 a0="/bin/sh" a1="/usr/bin/7z" a2="a" a3="test_file.zip" a4="test_file" a5=2D7074686973206973207665727920736563726574
type=SYSCALL msg=audit(1579801026.734:2688): arch=c000003e syscall=59 success=yes exit=0 a0=563aa2479290 a1=563aa247d040 a2=563aa247fe10 a3=8 items=3 ppid=2690563 pid=2690868 auid=1000 uid=1000 gid=1000 euid=1000 suid=1000 fsuid=1000 egid=1000 sgid=1000 fsgid=1000 tty=pts17 ses=1 comm="7z" exe="/usr/bin/bash" key=(null)

이 라인이 가장 유망해 보입니다.

type=EXECVE msg=audit(1579801026.734:2688): argc=6 a0="/bin/sh" a1="/usr/bin/7z" a2="a" a3="test_file.zip" a4="test_file" a5=2D7074686973206973207665727920736563726574

그런데 그 문자열은 2D7074686973206973207665727920736563726574제가 입력한 비밀번호가 아닙니다.

내 질문은 두 가지입니다.

  • audit비밀번호를 얻는 데 적합한 도구 인가요 ? 그렇다면 중재 규칙을 변경해야 합니까?
  • audit이 외에 비밀번호를 쉽게 알 수 있는 방법이 있나요 ?

17z가 스스로 비밀번호를 묻는 메시지를 표시할 수 있다는 것을 알고 있습니다 .

답변1

read(2)안전하지 않은 것은 파일에서 데이터를 읽는 시스템 호출이 아닙니다 . 심지어는 그렇지 않습니다 read(1)(내장 쉘은 표준 입력에서 한 줄을 읽습니다). 안전하지 않은 것은 명령줄에 비밀번호를 전달하는 것입니다.

사용자가 셸이 읽는 콘텐츠를 입력하면 read해당 콘텐츠가 터미널과 셸 모두에 표시됩니다. 다른 사용자에게는 보이지 않습니다. 사용 중에는 read -s숄더 서퍼에게 보이지 않습니다.

명령줄에 전달된 문자열은 감사 로그에 표시됩니다. (문자열이 잘릴 수도 있습니다. 잘 모르겠지만, 그렇다면 비밀번호보다 훨씬 긴 문자열이 됩니다.) 공백과 같은 문자가 포함되면 hex 로 인코딩됩니다. 구문 분석하기가 불분명한 로그입니다.

$ echo 2D7074686973206973207665727920736563726574 | xxd -r -p; echo
-pthis is very secret
$ perl -l -e 'print pack "H*", @ARGV' 2D7074686973206973207665727920736563726574
-pthis is very secret

이것이 명령줄에서 비밀을 전달하면 안 되는 주된 이유는 아닙니다. 결국 감사 로그는 관리자만 볼 수 있어야 하며 관리자는 원하는 경우 모든 것을 볼 수 있습니다. 그러나 로그에 비밀을 유지하는 것은 더 많은 사람들이 나중에(예: 부적절한 보안 백업을 통해) 액세스할 수 있으므로 더 나쁩니다.

명령줄에서 비밀을 전달해서는 안 되는 주된 이유는 대부분의 시스템에서 명령줄이 다른 사용자에게도 표시되기 때문입니다. (일부 강화된 시스템은 그렇지 않지만 일반적으로 기본값은 아닙니다.) 비밀번호는 적시에 이나 ps유사한 유틸리티를 실행하는 사람이 볼 수 있습니다. 7z 프로그램은 시작 직후(내부 복사본을 만들 수 있게 되면) 비밀번호를 덮어쓰지만, 이는 위험 기간을 줄여줄 뿐 취약점을 제거하지는 않습니다.topcat /proc/*/cmdline

환경 변수에 비밀을 전달하는 것이 안전합니다. 해당 환경은 다른 사용자에게 표시되지 않습니다. 하지만 7z는 이것을 지원하지 않는다고 생각합니다. 명령줄을 통해 표시되지 않고 암호를 전달하려면 암호를 입력으로 전달하고 7z가 stdin이 아닌 터미널에서 읽어야 합니다. 당신은 그것을 사용할 수 있습니다expect이렇게 하세요(또는예상되는TCL보다 Python을 선호하는 경우 또는오후 예상Perl에서 또는expect루비 등). 테스트되지 않음:

read -s -p "Enter password: " pass
pass=$pass expect \
    -c 'spawn 7z a -p test_file.zip test_file' \
    -c 'expect "assword:" {send $::env(pass)}' \
    -c 'expect eof' -c 'catch wait result'
unset pass

관련 정보