/etc/shadowと同じ暗号化

/etc/shadowと同じ暗号化

私は、サーバー管理者がネットワーク全体でスクリプトの結果を分析できるように、Linux上でいくつかのマルウェア検出スクリプト用のGUIツールを作成しています。

/etc/shadowで使用されている暗号化が強力であることがわかっている限り、私のアプリケーションのルートに同じパスワードを使用し、/etc/shadowの変更を確認し、dbのルートパスワードを同期し、ルート資格情報を使用して管理します。管理者ログインを許可したい。 。

PHPを使って開発します。これが正確にどの暗号化を使用しているのか、そして人々がルート資格情報を使用してPHPから私のGUIにログインできるように、PHPで同じ機能を実装できるかどうか疑問に思います。

答え1

パスワードフィールドの値は、$XY$数字Xで始まるか、2つのDES(長さに応じて標準または拡張)のいずれかです。

DESはもはや安全ではなく、ほとんどサポートされていません。次の指定Yに従ってオプションです(2番目の項目以降)。X$

1:CRYPT_MD5(Ynull)
2:CRYPT_BLOWFISH(またはY可能性があります):CRYPT_SHA256:CRYPT_SHA512axy
56

最も一般的なの$6$は、計算がres = sha(res + salt)最初から繰り返し(標準5000回)の適用に基づいていることですres = password。別のラウンド数を指定してソルトの前に保存できない限り、ソルトは2番目$から3番目まで続きます。$

$6$salt$result
$6$rounds=N$salt$result

(最初は5000ラウンドを意味します)。

確かにこれを直接実装できますが、PHPのcryptが使用するアルゴリズム指定をサポートしているかどうかを確認するか、別の方法で呼び出しを見てみましょう(Ubuntuのパッケージなどmkpasswd)。whois


これがうまくいくことを考えると、HTTPSを介していなくてもrootアカウントとパスワードを使用しないことをお勧めします。 PHPが破損している場合は、システムのルートパスワードをスヌーピングするために何かを挿入するのは非常に簡単です。

答え2

人々はroot資格情報を使ってPHPから私のGUIにログインすることができますか?

GUIプロセスにルート資格情報があることを意味する場合は、そうです。 これは要件です。 passwdこれを行う他のものは次のとおりです。setuidビットルートが設定して所有します。 PHPを使用してこれを行う方法のガイドラインねえ

まず、パスワードの基本的な事実を明確にしてください。おそらくすでに知っていますが、パスワードいいえシステムに保存されます。一方向ハッシュは次のとおりです。一方向ハッシュは、暗号化アルゴリズムを使用してソース文字列(実際のパスワードなど)から生成できる文字列です。ハッシュからソースを再作成できません。

これは、誰かがパスワードを見つけても/etc/shadowユーザーのパスワードを再設定できないことを意味します。暗号化は方法なので、元に戻せません。しかし、文字列を取得して同じ方法で暗号化してハッシュと比較することができます。これがパスワードの確認方法です。

ハッシュ文字列の構造/etc/shadowは次のように記述されます。Antonの答えは素晴らしいです。。以下は、C言語で実装した基本的な認証プロセスです。 PHPは包装紙getpwnam()あるいは、/etc/shadow直接解析して保存することもできます。文字列が何をするのかを理解するにはcrypt()(Anthonが述べたように、これには使用されたアルゴリズムとハッシュを生成するために使用された「塩」の表示が含まれています)、次を参照してください。コメント -> Glibcコメント存在するman 3 cryptPHPcrypt()ドキュメントはあまり明確ではありませんが、同じように動作するようです。

唯一の重要な機能はおよびでありgetpwnam()crypt()他の機能は単なる基本的な入力、出力、および文字列操作です。

#define _XOPEN_SOURCE // Important.
#include <errno.h>
#include <crypt.h>
#include <shadow.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main (int argc, const char *argv[]) {
    if (argc < 2) {
        puts("Username required.");
        return 1;
    }

// Get shadow password.
    struct spwd *spw = getspnam(argv[1]);
    if (!spw) {
        if (errno == EACCES) puts("Permission denied.");
        else if (!errno) puts("No such user.");
        else puts(strerror(errno));
        return 1;
    }

// Read password from user.
    fprintf(stderr, "%s> ", argv[1]);
    char buffer[4096];
    int len = read(0, buffer, 4095);
    // Ditch the newline.
    buffer[len - 1] = '\0';

// Hash and report.
    char *hashed = crypt(buffer, spw->sp_pwdp);
    printf("%s\n%s\n", spw->sp_pwdp, hashed);
    if (!strcmp(spw->sp_pwdp, hashed)) puts("Password matched.");
    else puts("Password DID NOT match.");

    return 0;
} 

次のようにコンパイルできます。

gcc --std=c99 whatever.c -o testpw -lcrypt

ルートとして実行する必要があります。それ以外の場合は、「権限の拒否」というメッセージが表示されます。実際のユーザー名を指定する必要があります。

./testpw me

エコーは無効になっていないため、パスワードを入力するとパスワードが表示されます。

答え3

/etc/shadowの構造については、以下を参照してください。http://www.cyberciti.biz/faq/understanding-etcshadow-file/ 暗号化に関しては、LinuxがCryptアルゴリズムを使用していると確信しています。http://linux.die.net/man/3/cryptそしてhttp://php.net/manual/en/function.crypt.php)

答え4

パスワードは暗号化されません。彼らは塩でハッシュされます。

この形式は、文字列の一部としてアルゴリズム仕様を持つことによって、さまざまなハッシュアルゴリズムで使用またはサポートされています/etc/passwd/etc/shadowハッシュ文字列の生成と検証は、crypt入力文字列に基づいて適切なアルゴリズムを自動的に選択するこの関数を使用して行われます。

PHPには機能がありますが、cryptユースケースでは使用しないことをお勧めします。

root権限でWebサーバーでコードを実行するのは非常に危険です。 1つの小さなミスだけでも、システムが攻撃に対して脆弱になります。

代わりに、システムで標準のsuidユーティリティの1つを実行してPHPスクリプトにroot権限を取得することをお勧めします。このユーティリティは、rootパスワードが提供されたらroot権限を付与できます。このsuコマンドが最も適している可能性があります。

システムがハッシュされたルートパスワードをに保存するように設定されている場合、/etc/passwdスクリプトはそれを読み取り、cryptを使用してユーザーが入力したパスワードを確認できます。しかし、これを行う理由はあまりなく、/etc/shadow使用すると機能しません。代わりに、ユーザーが入力したパスワードを渡し、su応答でsuパスワードが正しいかどうかを確認してください。

関連情報