新しいユーザーのパスワードを設定しようとして問題が発生しています。
mkpasswd -m sha-512 "my password here"
がuseradd -m -p "hashed and salted passwd" -s /bin/bash username
と組み合わせて使用できるソルトおよびハッシュされたパスワードを生成することを示すチュートリアルを見つけましたが、テストユーザーでこれを試しても、Incorrect Login
を受信し続けます。
Ubuntu 16.04を実行しており、mkpasswd
パッケージのwhois
を使用しています。
ここで何が間違っていますか?
1)apt update
2)apt install whois
3)mkpasswd -m sha-512 "my password here"
生成:$6$1FuuSdKgVke$bc8doOVGZhzomoeafvcQnpYhAxfR4aWdAuYvbxSHw6ZCFZ4NC5j9C762kmvs4Pc66bv4.LYTfrlknm5cWx65g.
4)useradd -m -p $6$1FuuSdKgVke$bc8doOVGZhzomoeafvcQnpYhAxfR4aWdAuYvbxSHw6ZCFZ4NC5j9C762kmvs4Pc66bv4.LYTfrlknm5cWx65g. -s /bin/bash testuser
5)login testuser
パスワードのプロンプト:
6)ここにパスワードを入力します
言う:Login incorrect
スペースを含まないパスワードで同じことを試み、mkpasswd
コマンドから引用符を省略したことを付け加えます。どちらも違いを生むようには見えませんでした。
また、ユーザーに-pフラグなし(パスワードを追加しないことを意味する)にして、ソルト/ハッシュされたパスワードを/etc/shadow
に手動でコピーしようとしました。
さらに興味深いことに、サブシェルを使用して値を入力すると、すべてが正常に動作するようです。
useradd -m -p $(mkpasswd -m sha-512 "my password") -s /bin/bash test
login test
タイプ:my password
正常にログインします!
さて、私は問題をロックダウンしました。 mkpassword
の出力は$id$salt$hash
になるため、これをコピーしてuseradd
コマンドに貼り付けると、bashは$
で変数置換を試行します。そのため、\$id\$salt\$hash
に文字列を追加する前にbashが変数置換を行わないように、/etc/shadow
を使用してこれらをエスケープする必要があります。
mkpasswd -m sha-512 "my password"
の結果
$6$5AfGzrQ9u$r6Q7Vt6h8f2rr4TuW4ZA22m6/eoQh9ciwUuMDtVBX31tR3Tb0o9EB1eBdZ2L9mvT.pX3dIEfxipMoQ0LtTR3V1
これをコピーしてuseradd
に貼り付け、各$
を\$
に置き換えます。
useradd -m -s /bin/bash -p \$6\$5AfGzrQ9u\$r6Q7Vt6h8f2rr4TuW4ZA22m6/eoQh9ciwUuMDtVBX31tR3Tb0o9EB1eBdZ2L9mvT.pX3dIEfxipMoQ0LtTR3V1
失敗する理由は、先頭に$
が付いたアイテムが変数として扱われ、useradd
に渡すときに引用符で囲まれないためです。
ハッシュの$6...
、$1...
、および$b...
部分は変数として扱われます。もちろん、障害はシェルにあります-シェルは、何かが実行される前に(単一引用符で囲まれていない限り)変数展開を実行します。また、これらの3つの変数は環境に存在しないため、useradd
に渡す文字列から消えます。
シェルが必要なすべての展開と置換の実行を完了し、それをexecve()
システムコールに渡した後に実行されるactualコマンドを見てみましょう。比較:
$ strace -e execve useradd -p $abra$cadabra newuser
execve("/usr/sbin/useradd", ["useradd", "-p", "newuser"], [/* 82 vars */]) = 0
$ strace -e trace=execve useradd -p '$abra$cadabra' newuser
execve("/usr/sbin/useradd", ["useradd", "-p", "$abra$cadabra", "newuser"], [/* 82 vars */]) = 0
最初の例では、$abra$cadabra
(これはハッシュが移動する場所です)が、システムによって実際に実行されるコマンドから消えます。対照的に、2番目の例の単一引用符で囲まれた$abra$cadabra
は、execve()
に渡される引数のリストに表示されます。
言い換えると、正しいハッシュを生成しましたが、Shellは引数としてuseradd
に完全に異なるものを渡します。これは最終的にシステムが実行するコマンドです。実際、ハッシュを例にとり、引用と非引用の2つのケースを比較してみましょう。
$ strace -e execve echo $6$1FuuSdKgVke$bc8doOVGZhzomoeafvcQnpYhAxfR4aWdAuYvbxSHw6ZCFZ4NC5j9C762kmvs4Pc66bv4.LYTfrlknm5cWx65g
execve("/bin/echo", ["echo", "FuuSdKgVke.LYTfrlknm5cWx65g"], [/* 82 vars */]) = 0
FuuSdKgVke.LYTfrlknm5cWx65g
+++ exited with 0 +++
シェルが変数の処理を完了した後にシステムが実際に見るものはFuuSdKgVke.LYTfrlknm5cWx65g
です。ただし、引用すると正しいハッシュが表示されます。
$ strace -e execve echo '$6$1FuuSdKgVke$bc8doOVGZhzomoeafvcQnpYhAxfR4aWdAuYvbxSHw6ZCFZ4NC5j9C762kmvs4Pc66bv4.LYTfrlknm5cWx65g'
execve("/bin/echo", ["echo", "$6$1FuuSdKgVke$bc8doOVGZhzomoeaf"...], [/* 82 vars */]) = 0
ただし、サブシェルは、置換が発生しないため機能します。変数はありません。また、引用も同じ理由で機能します。
以下にいくつかの方法を示します。
コマンド置換:
$ Sudo -p ">" useradd -m -s /bin/bash -p $(mkpasswd --hash=SHA-512 "123" ) newusr
>
$ su newusr
Password:
newusr@ubuntu1604:/home/admin$
シングルクォート(実際のハッシュは長すぎてフォーマットに適合しないため、実際のハッシュを削除しました):
$ Sudo -p ">" mkpasswd --hash=SHA-512 "112"
>
GVhvDY$vhw89D2X0bd2REQWE
$ Sudo -p ">" useradd -m -s /bin/sh -p 'GVhvDY$vhw89D2X0bd2REQWE' newusr2
>
$ su newusr2
Password:
$ echo $USER
newusr2
mkpasswd
のstdout
ストリームから出力を取得し、-I
フラグを付けてxargs
経由で渡します。
$ mkpasswd -m sha-512 'password1' | Sudo -p '>' xargs -I % useradd -p % newuser1
\
をすべての$
に追加します(OPは 彼らの答え で自分自身を見つけました)。 Georgeのコメント に従って、スクリプト化も可能です。
$ useradd -m -s /bin/bash -p \$6\$5AfGzrQ9u\$r6Q7Vt6h8f2rr4TuW4ZA22m6/eoQh9ciwUuMDtVBX31tR3Tb0o9EB1eBdZ2L9mvT.pX3dIEfxipMoQ0LtTR3V1 newuser