1

チャレンジ

他のプロセス (あらゆる種類のスクリプト: python、php、perl など) によって呼び出されるパスワード管理ツールが必要であり、アクセス制御を実行するために呼び出し元スクリプトを識別および検証できます。戻るか出る -1

現在の実装

さまざまなフレームワークを検討した結果、Keepass V1.X バックエンド データベース ファイルを処理し、独自のアクセス制御オーバーレイを構築できる を使用することにしましpythonkeepassdb(これは後でカスタマイズして、ユーザー/グループ アクセス用に LDAP に統合できるためです)。 . アクセス制御はnotes、各エントリのフィールドをオーバーロードして、パスワードへのアクセスが許可されている SHA-256 ハッシュのリストを含めることによって行われます。(これは、スクリプトが誰にも変更されていないことも検証することに注意してください)

パスワード マネージャーは-p、呼び出し先のスクリプト/アプリケーションの PID であるパラメーターを使用して呼び出され、次の手順を実行します。

  1. 自身の PID から開始して親を探して、再帰的に「上」に検索します。1呼び出し元の PIDは、親 0 のプロセスに到達する前に見つける必要がありinitます。これにより、誰がこのパスワード マネージャー インスタンスを呼び出したのかを確実に知ることができます。
  2. その (親) プロセスの完全なコマンド ラインを取得し、python、perl、php、bash、bat、groovy などを含むスクリプト言語を探して分析します (shlexこれには が使用されます)。
  3. スクリプトの絶対パスを特定し、その SHA を計算します
  4. これをデータベースの値と比較して、存在するかどうかを確認します。存在する場合、スクリプトは、stdout で標準形式で返されるパスワードを持つことが許可されます。そうでない場合は、-1 で終了します。

問題

上記の実装は正当なスクリプトに対してはうまく機能しますが、非常に混乱しやすいです。特定caller.pyのエントリへのアクセスが許可されているスクリプトにしますe。コマンドラインを実行すると、次のようになりpython /path/to/caller.py arg1 arg2ます。コマンド ラインを解析するコードは次のとおりです。

cmd = walk_ppids(pid)
lg.debug(cmd)
if cmd is False:
    lg.error("PID %s is not my parent process or not a process at all!" % pid)
    sys.exit(-1)

cmd_parts = shlex.split(cmd)
running_script = ""
for p in cmd_parts:
    if re.search("\.(php|py|pl|sh|groovy|bat)$", p, re.I):
        running_script = p
        break

if not running_script:
    lg.error("Cannot identify this script's name/path!")
    sys.exit(-1)

running_script = os.path.abspath(running_script)
lg.debug("Found "+running_script)

phash = hash_file(open(running_script, 'rb'), hashlib.sha256())

親プロセスのコマンドラインは、次を使用して取得されます。

os.popen("ps -p %s -o args=" % ppid).read().strip()

上記の関数を混同する最も簡単な方法は.sh、最初の引数としてcaller.py. sh はその引数を使用せず、代わりにエントリを照会するパスワード マネージャーを呼び出しますe。コマンドラインは次のようfake_sh ./caller.pyになり、上記のコードはパスを返します...これは間違ったことです。

質問

これは、プログラマーがパスをスクリプト/アプリにハードコーディングすることなく、ずっと前に解決された一般的な問題であると思われますが、数日間少し調査を行ったところ、同様の方法で機能するものを見つけることができなかったようです. この質問は自由回答であることを理解しているので、次の回答を受け入れます。

  • 私は車輪を再発明していますか?同様のことを行うフレームワーク/ソフトウェアはありますか?
  • これは、PID に依存する正しいアプローチですか? 別の方法はありますか?
  • 実装に関しては、投稿されたコードを改善してより堅牢にし、簡単に混乱しないようにすることはできますか? (shlex分析部分)
4

1 に答える 1

0

改善:ルールをより厳しくする

最初のステップは、正しい拡張機能が正しいインタープリターで実行されることを確認することでした。これは、 でcaller.py実行できないことを意味し/bin/bashます。

同様の脆弱性は、コマンドpython -W ./caller.py ./myUberHack.py. .pyインタープリターへの最初の引数を探すコマンドラインアナライザーは、それcaller.pyが実行されていると考えます...それはそうではありません。

すべてのインタープリターのすべての呼び出しルールを構築するのは時間がかかりすぎるため、前提条件をハードコーディングします。これらは に保存され、tuple各行は次のとおりです。

(file extension, positional argument, interpreter first letters)
exts = (
    (".py", 1, "python"), 
    (".php", 2, "php"),
    (".pl", 1, "perl"),
    (".sh", 1, "/bin/bash"), # Assumption, we accept only bash 
    (".groovy", 1, "groovy"),
    (".rb", 1, "ruby"),
)
"""Matching extensions to positional arguments and interpreters"""

検証コードは次のとおりです。

for i in exts:
    # Check the specified cmdline position and extension
    if cmd_parts[i[1]].strip().endswith(i[0]):
        lg.debug("Checking "+cmd_parts[i[1]])
        running_script = cmd_parts[i[1]]

        # Make sure that the interpretter matches the extension
        if running_script.endswith(i[0]) and not cmd_parts[0].startswith(i[2]):
            lg.error("Wrong interpretter... go away...")
            sys.exit(-1)

        break

今のところ他にいいのが思いつかない…

于 2015-12-20T13:43:24.140 に答える