Pentest Günlükleri: Burp AT
Yazar: Alperen Keskin
İki günlük acil bir pentestte Burp AT'yi gerçek bir SQL Injection bulgusunu doğrulamak ve bir erişim kontrolü açığını keşfetmek için kullandım. Bu süreçte yaşadığım deneyimi anlatıyorum.
Elimde acil bir pentest vardı. Süre iki gün, kapsam kurumsal bir web uygulamasının tamamı. Kaynak koda sahibim, SAST çıktısı elimde, canlı hedefe erişim var ve ben tek başımayım. Bu işin normalde bir haftaya yayılması lazım. Bu sefer Burp AT'yi de işin içine kattım, ne kadar fark yarattığını görmek istedim.
Sahne
SAST çıktısında, bir repository sınıfındaki SQL injection bulgusu dikkatimi çekmişti. Tipik bir SAST çıktısı: metot adı, satır numarası, "kritik" etiketi, exploit edilebilirlik hakkında pek bir şey yok. Kodun kendisi şöyleydi (isimleri anonimleştirdim, mantık aynı kaldı):
sqlSelect.append(" and A.ID in (" + recordIds + ")");
Kaynak kodu Burp AT'ye verdim, ne düşündüğünü sordum. Burada bir şey itiraf etmem lazım. Bu ilk aşamada aldığım cevap özel bir şey değildi. String concatenation ile kurulan bir native SQL sorgusu zaten göze batıyor. Asıl mesele bundan sonra başladı.
"Garanti var diyorsun yani?"
Bulguyu kesinleştirmeden önce sordum: bu kod dışarıdan mı besleniyor yoksa dahili bir servisten mi geliyor. Verdiği ayrım hoşuma gitti. Kod seviyesinde bunun CWE-89 ile uyumlu olduğunu söyledi, ancak exploit edilebilirliğin çağrı zincirine bağlı olduğunu ekledi. Yani "garanti" demedi, "birlikte kanıtlayalım" dedi.
Kaynak kod zinciri kendim grep'ledim, ilgili metodu çağıran her yeri taradım. Çıkan zincir şöyleydi:

DTO'da bir List<String> alanı vardı, içeriği kısıtlayan herhangi bir validation bulunmuyordu. Gelen değer doğrudan sorguya eklendiği için tek tırnakla SQL ifadesinden çıkmak mümkün görünüyordu. Kullandığım PoC payload'ı kabaca şöyleydi:
{ "ids": ["' UNION SELECT ... FROM DUAL--"] }
DTO'dan repository'ye kadar izlediğim katmanların hiçbirinde liste alanının içeriğini sınırlandıran bir doğrulama bulunmuyordu. Buraya kadar yaptığım şey aslında sıradan bir kaynak kod incelemesi. Burp AT olmasa da biraz daha yavaş, yine aynı yere varırdım. Teoride zafiyet ortadaydı. Ama pentest raporuna koyacağım şey teori değil, çalışan bir PoC olmalıydı.
Burada bırakmadım, SAST çıktısını Burp AT'ye doğrulattım. Controller mapping'inden yola çıkıp endpoint'i site map üzerinde buldu ve scope içinde olduğunu teyit etti. PoC payload'ını Repeater üzerinden gönderdi, dönen yanıttaki farkı değerlendirdi ve zafiyeti canlı olarak doğruladı. Yani elimdeki teorik SAST bulgusu AT'nin oluşturup gönderdiği bu istekle canlı olarak doğrulanmış bir PoC'ye dönüştü.
Statik okuma tarafında pek fark yok fakat...
Bunu açık söyleyeyim çünkü çoğu tanıtım metni söylemiyor: sadece kaynak kod okuma tarafında Burp AT'nin Claude'a göre özel bir üstünlüğü yok. İkisi de aynı zafiyeti görüyor, ikisi de çağrı zincirini takip etmeni öneriyor. Bunu "devrim" diye satmak gerçeği yansıtmaz.
Dolaylı bir fark var yine de. Burp AT bunu boş bir sohbette değil, Burp projesindeki mevcut site map, trafik ve bulgularla birlikte çalışıyor; kodda bulduğunu projede zaten bilinenle çapraz kontrol edebiliyor. Sadece Claude'u kullandığım bir sohbette böyle bir kalıcı proje hafızası yok, her şeyi sana elle yapıştırman gerekiyor. Yani "daha iyi okuyor" değil, "daha bilgili bir bağlamda okuyor" demek daha doğru.
Asıl fark benim için kodu okuduktan sonra ortaya çıktı. Burp AT, Burp Suite'in içinde agent olarak çalışıyor. Hangi aracı kullanacağına karar veriyor, sonucu değerlendirip sıradaki adımı belirliyor, gerektiğinde işi parçalara ayırabiliyor. Bunu yaparken PortSwigger'ın pentest için hazırladığı skill'lerden de yararlanıyor (aşağıda ayrıca değineceğim). Repeater veya HTTP history'deki bir isteği alıp üzerinde değişiklik yapabiliyor, gönderip sonucu bir sonraki adıma taşıyor. Endpoint'i ve PoC'yi bulduktan sonra bu işi ona bıraktım, ben başka bir endpoint'e geçtim, o da bulduklarını Issue olarak kaydetti. İki ayrı yerde aynı anda ilerledik. Tek başıma olsaydı bu ikisini sırayla yapacaktım, iki günlük bir işte sıra beklemek zaman kaybı demek.
Mimari yapıyı şöyle düşünebiliriz:

Model karar verir, Burp yürütür.
Buna bir de şunu ekleyeyim: Burp AT'nin tasarımı belli bir modelin o anki kapasitesine bağımlı kalacak şekilde kurulmamış. PortSwigger'ın kendi ifadesiyle modeller zaman içinde gelişmeye devam edecek ve ürünün etrafındaki araçlar, skill kütüphanesi ve governance katmanı bu gelişmeden bağımsız olarak değerini koruyor. Bu bence önemli bir tasarım kararı, çünkü değeri "hangi LLM'i kullanıyorsun"a değil, Burp'ün araçlarına ve skill kütüphanesine bağlıyor.
Skills tarafı
Burp AT'deki asıl farklardan biri bence skills tarafında. PortSwigger Research'in geliştirdiği pentest yaklaşımları tekrar kullanılabilir skill'ler halinde sunuluyor. Content-discovery, limit-overrun-race-condition gibi skill'ler agent tarafından otomatik çağrılıyor. Claude'a aynı şeyi sorsam kendi genel bilgisinden bir yaklaşım kurar, bazen tutar bazen tutmaz. Burada genel amaçlı bir modelin sıfırdan metodoloji kurmasından ziyade, PortSwigger Research tarafından hazırlanmış bir yaklaşım devreye giriyor. Bu skill kütüphanesi zaman içinde genişletiliyor; benim ayrıca bunları tek tek oluşturup güncellememe gerek kalmıyor.
Gözden kaçanları görmek
İki günlük bir pentestte en büyük risk, gözden kaçan bir şeyi fark edememek. Dokunamadığım köşeler, sonraya bıraktığım şeyler. Burp AT'yi burada yanımda çalışan ikinci bir kişi gibi kullandım. Stratejiyi ben kurdum, o arka planda ilerledi; ben başka bir şeye baktığımda o benim atlayacağım noktaları kovaladı. Arada bir dönüp ne bulduğuna baktım.
PortSwigger'ın paylaştığı bir vaka çalışması bunu iyi anlatıyor. Orange Cyberdefense'ten bir pentester, dört günlük bir işte elle asla okuyamayacağı 66 bin satırlık minified JavaScript'i Burp AT'ye analiz ettirmiş, whistleblower raporlarının sadece altı karakterlik alfanümerik bir kodla korunduğunu bulmuş, sonra brute-force edip yıllardır orada duran bir açığı ortaya çıkarmış. Ama benim kendi işimde yaşadığım şey de küçük ölçekte benzerdi.
Frontend'in bundle edilmiş JS dosyası da birkaç bin satırdı, elimle satır satır taramaya kalksam yarıda bırakırdım. Burp AT dosyayı analiz etti ve UI'ın hiçbir yerinde linklenmeyen bir istek tanımına rastladı. Eski bir özellikten kalma kullanılmayan bir uç nokta gibi duruyordu.
Endpoint'i doğrudan GET ile denediğimde hiçbir şey dönmüyordu. İlk bakışta ölü bir route gibi görünüyordu, sıradan bir content-discovery taraması da muhtemelen bir şey bulmazdı. Ama Burp AT, JS'in içinde isteğin aslında POST olarak belirli bir body ile gönderildiğini gördü. İsteği tam o şekliyle, HTTP methodu ve body'siyle birlikte kurup gönderdi; endpoint ancak o zaman yanıt verdi. Normal kullanıcı akışında bu servise hiçbir yerden erişilmiyordu. Ama isteği doğru şekliyle kurunca endpoint'te ne kimlik doğrulama ne de yetkilendirme kontrolü bulunduğu ortaya çıktı. İstek doğrudan yanıt döndü ve yetkisiz erişilmemesi gereken bir veri kümesini geri getirdi. Broken Access Control, CWE-284. Bunu elle bulmam saatler sürerdi, iki günlük bir pentestte o saatleri ayıracak vaktim muhtemelen olmazdı.
Sınırları da var
Burp AT şu an Burp Pro kullanıcılarına public beta kapsamında sunuluyor, ancak kullanımı AI kredisiyle ölçülüyor ve kullandıkça bu kredi tüketiliyor. Benim kullanımımda PortSwigger'ın Burp Champion olarak sağladığı krediler sayesinde ayrıca kredi satın almam gerekmedi, ama bu benim özel durumum. Normal kullanımda bu, kullanım arttıkça büyüyen ayrı bir maliyet kalemi. Agent'ın "bu bulguyu doğruladım" demesi gerçekten doğrulandığı anlamına gelmiyor, rapor öncesi kontrolü yine kendim yapıyorum. Autonomous modda bırakırsan, Intruder gibi etkisi daha yüksek bir aracı da senin ayrıca onayını beklemeden kullanabilir, bu yüzden özellikle üretim hedeflerinde modu ve tool izinlerini bilinçli seçmek gerekiyor.
Sonuç
İki gün doldu ve elimde canlı olarak doğruladığım bir SQL Injection PoC'si ve JS analiziyle keşfettiğim, erişim kontrolü olmadığı ortaya çıkan bir uç nokta vardı. Tek başıma da büyük ihtimalle bir şeyler çıkarırdım, ama bu kadar derli toplu ve bu kadar erken değil. O endpoint'i de bu kadar hızlı bir pentestte muhtemelen bulamazdım. Fark büyük ölçüde şuradan geldi: birkaç iş aynı anda ilerledi, tek başıma atlayacağım yerleri o yakaladı.
Bu yazıyı "herkes için doğru cevap bu" demek için yazmadım. Ben iki günlük bir işte Burp AT'yi tercih ettim ve neden tercih ettiğimi anlatmaya çalıştım. Statik okumada fark yok, bunu abartmayalım. Ama benim işime kattığı şey zaten o değildi. Koddan zafiyeti çıkarmak başlı başına özel bir şey değil asıl fark, AT'nin buradan devam edip endpoint'i bulması, uygun payload'ı üretmesi, PoC isteğini kendisinin oluşturup göndermesi ve sonucu değerlendirerek bulguyu canlı olarak doğrulamasıydı. Aynı şekilde birkaç bin satırlık JavaScript'i analiz edip normal kullanıcı akışında görünmeyen bir endpoint'i ortaya çıkarması da benim için önemliydi. Burp projesindeki bağlamı doğrudan kullanması da bu süreçte önemli bir fark yarattı. Buna PortSwigger'ın araştırmasından gelen skill'leri ve agent'ın kendi başına karar verebilmesini de ekleyince, iki günlük bir işte bana ciddi bir zaman kazandırdığını gördüm. Araç bazlı izinler de bu çalışma şeklini kontrol altında tutmamı sağladı. Bana en somut geleni ise şuydu: Burp AT, stratejiyi benim belirlediğim, tekrar eden ve zaman alan araştırma işlerini devredebileceğim bir pentester ekip arkadaşı gibi çalıştı.
- Ürün sayfası: portswigger.net/burp/burp-at