60 saniyede bulut IAM saldırı yolları

Bulut IAM mimarisi, hangi kimliklerin (principals) hangi kaynaklar üzerinde hangi eylemleri gerçekleştirebileceğine karar verir. Bir yetki yükseltme (privilege escalation) yolu, tek tek bakıldığında son derece makul görünen birden fazla iznin bir araya gelerek tek bir kimliğe hiç kimsenin amaçlamadığı bir güç vermesiyle ortaya çıkar. Bu nedenle politikaları tek tek incelemek asıl saldırı yolunu tamamen gözden kaçırabilir.

Bulut güvenlik değerlendirmelerinden tertemiz çıkan raporlar beni her zaman daha çok endişelendirir. Ortamın kesinlikle güvensiz olduğunu düşündüğüm için değil; temiz bir taramanın gerçekte neyi ölçtüğünü bildiğim için. Bir CSPM (Cloud Security Posture Management) aracı, her IAM politikasını bir kural kümesine göre, her seferinde tek bir politika olacak şekilde puanlar. Yetki yükseltme ise tek bir politika değildir. Birden fazla politikanın arasından geçen bir saldırı yoludur ve bu politikaların neredeyse tamamı tek başlarına tamamen savunulabilirdir.

Tarayıcı izinleri okur. Saldırı ise izinlerin arasındaki boşluklardan inşa edilir.

Identity vs Resource: Kimsenin okumadığı tersine çevirme

IAM’de “bu kimlik bu işlemi yapabilir” demenin iki yolu vardır. Herkesin okuduğu yol identity policy’dir; yani kullanıcıya veya role eklenen ve neleri yapabileceğini listeleyen doküman. Herkesin gözden kaçırdığı yol ise resource policy’dir; yani bucket’a, kuyruğa veya role eklenen ve kendisine kimlerin dokunabileceğini listeleyen doküman.

Bunlar sadece farklı görünmekle kalmaz; birbirinin tam zıddı yönleri işaret ederler.

Bir identity policy “bu rol şu rolü devralabilir (assume edebilir)” der. Hedef roldeki güven politikası (trust policy) olan resource policy ise “şu kimlik beni devralabilir” der. Erişim, bu iki politikanın kesişimidir. Üstelik bunlardan biri kimliğin sahibi olan ekip tarafından değil, kaynağın sahibi olan ekip tarafından yazılır. Yetki yükseltmenin saklandığı yer tam olarak bu ayrımdır; çünkü kimliğin politikasını puanlayan bir CSPM aracı, sorunun diğer yarısını sormak için kaynağın politikasını asla açıp bakmaz.

Bu durum Kerberos delegasyon notundaki yapıyla birebir aynıdır: İzin hedef üzerinde saklanır ve kararı hedef verir. Bir dizinde bunu bir nesneye kimin yazabileceğini sorarak bulursunuz. Bir bulut hesabında ise bunu güven politikalarında, kaynak politikalarında ve hiç envanterini çıkarmadığınız KMS anahtar politikalarında kimlerin adının geçtiğini sorarak bulursunuz.

Politika taramasından sağ çıkan zincirler

Bir tarayıcı * üzerinde * yetkisi tanımlayan bir politikayı anında işaretler. Oysa gerçek bir hesapta neredeyse hiçbir şey bu kadar kaba değildir. Asıl tehlikeli yetkiler dar kapsamlı, sıradan ve sıkıcıdır; yalnızca sırayla okunduklarında ilgi çekici hale gelirler.

iam:CreatePolicyVersion. Kimlik, müşteri tarafından yönetilen bir politikanın (customer-managed policy) yeni bir sürümünü yayınlayabilir. Eğer bu politika daha üst düzey bir role bağlıysa, kimlik o üst düzey rolün ne yapmaya yetkili olduğunu tamamen yeniden yazabilir — hem de o role, rolün güven politikasına veya tarayıcının baktığı herhangi bir şeye hiç dokunmadan. Versiyonlama özelliği tam da politikaların güncellenebilmesi için vardır; bu yüzden bu izni içeren bir tanımlama rutin bir sistem yönetimi gibi görünür.

iam:UpdateAssumeRolePolicy. Güven politikasına (trust policy) yazma erişimi, kimin o role dönüşebileceğini doğrudan kontrol etmek demektir. PassRole iznine bile ihtiyaç duymaz. Kimlik, güven dokümanını kendisini hedef gösterecek şekilde yeniden yazar, rolü devralır ve artık o rolün sahip olduğu tüm yetkilere kavuşur. Rolün kendi izin politikası hiçbir zaman değiştirilmediği için, üretilecek herhangi bir uyarı kimsenin izlemediği önemsiz bir kimliğe yazılır.

Hesaplar arası (cross-account) güven üzerinden sts:AssumeRole. Buluttaki en güvenilir pivot noktası ve işaretlenme olasılığı en düşük olanıdır; çünkü bu güven ilişkisi bilerek ve isteyerek kurulmuştur. A hesabındaki bir rol, B hesabındaki bir kimliğe güvenir. B hesabını ele geçirdiğinizde A hesabına giden yol zaten açılmış, belgelenmiş ve onaylanmıştır. Tarayıcı buna yanlış diyemez; sistem bizzat bu şekilde tasarlanmıştır.

Tersten okunan iam:PassRole. PassRole herkesin bildiği bir izindir ve herkes bildiği için genellikle kontrol kuralı mevcuttur. Taramalardan sağ çıkan sürüm ise dolaylı olanıdır: Bir role politika bağlayabilen (attach) ve ardından o rolü bir servise devredebilen (pass) bir kimlik. İki izin de tek başına tehlikeli değildir. Ancak bir araya geldiklerinde saldırgan tarafından yazılmış bir politikaya sahip bir rol üretirler. İki ifade asla aynı politika dokümanında yer almadığından, tekil politika denetimlerinin hiçbiri bu ikisini bir arada göremez.

TARAYICININ GÖRDÜĞÜ — DÖRT AYRI İZİN, HER BİRİ TESTİ GEÇİYOR düşük yetkili rol CreatePolicyVersion admin görevi — GEÇTİ managed policy yüksek yetkili role bağlı versiyonlama — GEÇTİ yüksek yetkili rol B hesabına güveniyor cross-account — GEÇTİ SALDIRGANIN GÖRDÜĞÜ — DÖRDÜNDEN GEÇEN TEK BİR YOL politikayı yeniden yaz → rolü devral → güven ilişkisini aş → servise devret (pass) hiçbiri tek bir dokümanda değil, bu yüzden tekil politika denetimleri zinciri asla göremez HER ADIM SAVUNULABİLİR — ASIL BULGU İZİNLER DEĞİL, SALDIRI YOLUNUN KENDİSİDİR
Dört iznin her biri kendi başına temiz puan alır ve her biri geçerli bir gerekçeyle verilmiştir. Yetki yükseltme tek bir izin değildir; bir kimliğin dördüne birden dokunabilmesidir ve mevcut araçların hiçbiri bu soruyu sormaz.

Tarayıcı neden bunu göremiyor?

Bir CSPM anlık görüntü (snapshot) aracıdır. Tek bir politikayı açar, tek bir kuralı uygular ve tek bir karar üretir. Bir yetki yükseltme zinciri ise bir çizge (graph) problemidir — BloodHound bağlantı ömrü notundaki argümanın aynısıdır; ancak buradaki bağlantılar (edges) ACL’ler yerine güven ilişkileridir ve çizge tek bir dizin yerine hesaplar arasına yayılır.

Bir principal mapper tam olarak bu boşluğu doldurur. Çizgeyi oluşturur (kim neyi devralabilir, hangi güven politikasında kimin adı geçiyor, her rol neyi bağlayabilir ve devredebilir) ve ardından BloodHound’un bir Active Directory domain’inde gezindiği gibi çizgeyi analiz eder:

# Mevcut kimlik bilgilerinden hesabın principal çizgesini oluşturun.
$ pmapper graph create --config config.json

# Bir CSPM'in asla sormadığı soru: Bu spesifik kimlik gerçekte nereye ulaşabilir?
$ pmapper query "who can do s3:GetObject with admin"
$ pmapper query "preset privesc *"

privesc önayarı işin asıl değerli yarısıdır. Aşırı izin verilmiş politikaları listelemez. Zincirleri listeler; bir kimliği bulunduğu yerden olmaması gereken yere taşıyan izin dizilimlerini gösterir. Farklı belgelerdeki iki ifadenin bir AssumeRole ile birbirine bağlanması, politika puanlama raporlarında asla görünmeyen ancak bir çizge sorgusunda tek adımda ortaya çıkan tipik bir örnektir.

Anlık görüntü yerine bir yol olarak test etmek

Verimli bir bulut testi * aramasıyla başlamaz. Belirli bir kimlikten (saldırganın ilk adımda ele geçirebileceği makul bir rolden) başlar ve o kimliğin yalnızca kalıcı izinleri kullanarak adım adım neye dönüşebileceğini sorgular.

# Hesaptaki her güven politikasını listeleyin — çoğu taramanın atladığı kaynak tarafı.
$ aws iam list-roles --query 'Roles[].{Role:RoleName,Trust:AssumeRolePolicyDocument}'

# Ardından tek bir hesabın taramasının dışında yaşayan hesaplar arası (cross-account) yüzey.
$ aws organizations list-accounts --query 'Accounts[].Id'

Hesaplar arası soru, tek hesaplı bir CSPM’in yapısal olarak yanıtlayamayacağı bir sorudur. A hesabından B hesabına olan güven A’da saklanır ancak yarattığı risk B’de yaşar. B ile sınırlandırılmış hiçbir araç A’da yaşayan bir politikayı asla işaretlemez. Biri tüm organizasyon genelinde doğrudan güven çizgesini sorgulamak zorundadır; aksi takdirde ortamdaki en güvenilir pivot noktası yapısal olarak görünmez kalır.

Kanıt matrisi (Evidence matrix)

SinyalNeyi kanıtlarNegatif kontrolSavunucu doğrulaması
Kimlik izni ve hedef güven/kaynak politikası geçişe izin veriyorKimlik sınırı aşabilir; iki doküman da bunu tek başına kanıtlayamazBir test rolünde bir tarafı kaldırın ve rol devralmanın reddedildiğini teyit edinİlişkinin her iki tarafına karşı Access Analyzer ve politika simülasyonu kullanın
AssumeRole sonrasında kapsamı daraltılmış zararsız bir eylem başarılı oluyorSaldırı yolu başlangıç kimliğinden itibaren fiilen yürütülebilmektedirAynı eylemi reddetmesi gereken bir sınır (boundary) veya koşul ekleyip tekrarlayınCloudTrail’de STS ve sonraki API olaylarını birbiriyle ilişkilendirin
PassRole ve servis oluşturma/güncelleme hakları aynı rolde kesişiyorAyrı ifadeler üzerinden servisle ilişkili bir ayrıcalık yolu mevcutturiam:PassedToService veya rol kaynağını kısıtlayın ve zincirin kırıldığını teyit edinHem rolü devredebilen hem de ilgili servisi çağırabilen kimlikleri sorgulayın
Hesaplar arası geçiş, hedef taramanın dışındaki bir hesaptan başlıyorYetki yükseltme çizgesi idari mülkiyet sınırlarını aşmaktadırHarici güveni iptal edin veya koşula bağlayın ve aynı kaynaktan testi tekrarlayınExternal ID’ler ve principal koşulları dahil tüm organizasyon kapsamında güven çizgesini çıkarın

Sıkça karşılaştığım ortak örüntü

Bu zincirlerdeki her tehlikeli izin, verildiği anda tamamen doğru olan bir gerekçeyle tanımlanmıştır. Bir dağıtım rolünün bir değişikliği yayınlamak için bir politikayı güncellemesi gerekiyordu, bu yüzden CreatePolicyVersion aldı. Bir tedarikçinin bir rolü devralması gerekiyordu, bu yüzden hesaplar arası güven oluşturuldu. Bir servisin bir role ihtiyacı vardı, bu yüzden biri aynı kimliğin önce bir politika bağlayabileceğini fark etmeden PassRole tanımladı.

Hiçbiri ilk bakışta yanlış görünmez. Bunlar sıradan sistem yönetimi adımlarıdır ve kural tabanlı bir tarayıcının bunları ortaya çıkaramamasının tam nedeni de budur: Ortada işaret edilecek tek bir yanlış yapılandırma yoktur, yalnızca kimsenin baştan sona sırayla okumadığı bir kararlar dizisi vardır.

Bir sertifika yetkilisini iki ekibin arasında kaldığı için denetimsiz bırakan dinamik neyse; bulut güven ilişkilerini de iki hesabın arasında kaldığı için denetimsiz bırakan dinamik odur. Kimlik ekibi kullanıcının sahibidir, platform ekibi rolün sahibidir ve hiçbiri saldırı yolunun sahibi değildir.

Savunuculara teslim edilmesi gerekenler

Politikayı değil, saldırı yolunu gösterin. Belirli kimliği, yürüyebileceği izin dizilimini ve kaldırıldığında zinciri kıran en erken tekil adımı belirtin. “IAM aşırı yetkilendirilmiş” diyen bir rapor genel bir temizlik projesi başlatır. “Bu servis rolü yeni bir politika sürümü yayınlayabilir, yönetici rolünü devralabilir ve canlı ortama geçebilir” diyen bir rapor ise doğrudan somut bir bilet açılmasını sağlar.

Kimliği kaynaktan ayırın. Her güven politikası, kaynak politikası ve KMS anahtar politikası taramanın yanlış tarafında yaşayan birer erişim kararıdır. Bunları açıkça envantere alın; çünkü kimlik tarafındaki araçlar bunu sizin yerinize asla yapmaz.

Hesaplar arası güveni haritalandırın. Organizasyon genelindeki principal haritası, hesaplar arası pivotları yakalayan tek çıktıdır ve çoğu kurum bunu bugüne kadar hiç çıkarmamıştır. Bunu bir kez kurun ve düzenli olarak çalıştırın; çünkü güven ilişkileri de tıpkı izinler gibi zamanla birikir: Yeni bir tedarikçi, yeni bir hesap, yeni bir “geçici” tanımlama.

Tarayıcı yanılmıyor. Yalnızca saldırganın sorduğu sorudan tamamen farklı bir soruyu yanıtlıyor.

Kaynaklar ve güncellik

Bu teknik not ne kadar güncel?

Kontrol edilen kaynaklar14 Ağustos 2025

En son kaynak incelemesi, içerik güncellemesi veya yayın tarihi gösterilmektedir.

İnceleme DurumuYazar incelemesi tamamlandı

Yazar teknik incelemeyi tamamladı. Bu etiket tek başına laboratuvar yeniden üretimi iddiası taşımaz.