Concourse Enumeration & Attacks
Concourse Numaralandırma ve Saldırılar
Kullanıcı Roller ve İzinler
Concourse, beş rolle birlikte gelir:
Concourse Yönetici: Bu rol, ana takıma (varsayılan başlangıç concourse takımı) sahip olanlara verilir. Yöneticiler, diğer takımları yapılandırabilir (örneğin:
fly set-team
,fly destroy-team
...). Bu rolün izinleri RBAC tarafından etkilenemez.sahip: Takım sahipleri takım içindeki her şeyi değiştirebilir.
üye: Takım üyeleri, takım ayarlarını değiştiremezler ancak takım varlıkları içinde okuma ve yazma yapabilirler.
pipeline-operator: Pipeline operatörleri, yapılandırmaları güncelleyemezler ancak yapılandırmaları tetikleme ve kaynakları sabitleme gibi pipeline işlemleri gerçekleştirebilirler.
görüntüleyici: Takım görüntüleyicileri, bir takıma ve onun pipeline'larına "salt okunur" erişime sahiptir.
Ayrıca, sahip, üye, pipeline-operator ve görüntüleyici rollerinin izinleri RBAC'yi yapılandırarak değiştirilebilir (daha spesifik olarak eylemlerini yapılandırarak). Daha fazlasını okumak için: https://concourse-ci.org/user-roles.html
Unutmayın ki Concourse, pipeline'ları Takımlar içinde gruplandırır. Bu nedenle, bir Takıma ait olan kullanıcılar bu pipeline'ları yönetebilir ve birçok Takım olabilir. Bir kullanıcı birçok Takıma ait olabilir ve her birinde farklı izinlere sahip olabilir.
Vars ve Kimlik Bilgisi Yöneticisi
YAML yapılandırmalarında, değerleri ((_kaynak-adı_:_gizli-yol_._gizli-alan_))
sözdizimi kullanarak yapılandırabilirsiniz.
Dökümantasyondan: kaynak-adı isteğe bağlıdır ve atlanırsa, küme genelindeki kimlik bilgisi yöneticisi kullanılacak veya değer statik olarak sağlanabilir.
İsteğe bağlı olan gizli-alan belirtilen gizli alandan okunacak. Atlanırsa, kimlik bilgisi yöneticisi, alanda varsa alınan kimlik bilgisinden 'varsayılan alanı' okumayı seçebilir.
Ayrıca, gizli-yol ve gizli-alan nokta .
ve :
gibi özel karakterler içeriyorsa çift tırnaklar "..."
ile çevrilebilir. Örneğin, ((kaynak:"benim.gizli"."alan:1"))
gizli-yol'u benim.gizli
olarak ve gizli-alan'ı alan:1
olarak ayarlar.
Statik Vars
Statik vars, görev adımlarında belirtilebilir:
Veya aşağıdaki fly
argümanlarını kullanarak:
-v
veya--var
NAME=VALUE
,VALUE
değeriniNAME
değişkeninin değeri olarak ayarlar.-y
veya--yaml-var
NAME=VALUE
,VALUE
'yi YAML olarak ayrıştırır veNAME
değişkeninin değeri olarak ayarlar.-i
veya--instance-var
NAME=VALUE
,VALUE
'yi YAML olarak ayrıştırır veNAME
örneği değişkeninin değeri olarak ayarlar. Daha fazla bilgi için Gruplama Boruları sayfasına bakın.-l
veya--load-vars-from
FILE
,FILE
adlı, değişken adlarını değerlere eşleyen bir YAML belgesini yükler ve hepsini ayarlar.
Kimlik Bilgisi Yönetimi
Bir boruda Kimlik Bilgisi Yöneticisi nasıl belirtileceği farklı şekillerde olabilir, bunu https://concourse-ci.org/creds.html sayfasında okuyun. Ayrıca, Concourse farklı kimlik bilgisi yöneticilerini destekler:
Unutmayın ki, bir şekilde Concourse'a yazma erişiminiz varsa, Concourse'un bunlara erişebilmesi için gizli bilgileri dışarı çıkarmak için işler oluşturabilirsiniz.
Concourse Saptama
Bir Concourse ortamını saptamak için öncelikle geçerli kimlik bilgilerini toplamanız veya muhtemelen bir .flyrc
yapılandırma dosyasında kimlik doğrulama belirteci bulmanız gerekir.
Giriş ve Geçerli Kullanıcı saptama
Giriş yapmak için uç nokta, takım adı (varsayılan olarak
main
) ve kullanıcının ait olduğu bir takım bilmeniz gerekmektedir:fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]
Yapılandırılmış hedefleri alın:
fly targets
Yapılandırılmış hedef bağlantısının geçerli olup olmadığını alın:
fly -t <target> status
Kullanıcının belirtilen hedefe karşı rolünü alın:
fly -t <target> userinfo
API belirtecinin varsayılan olarak $HOME/.flyrc
'ye kaydedildiğini unutmayın, bir makineyi yağmaladığınızda orada kimlik bilgilerini bulabilirsiniz.
Takımlar ve Kullanıcılar
Takımların bir listesini alın
fly -t <target> teams
Takım içindeki rolleri alın
fly -t <target> get-team -n <team-name>
Kullanıcıların bir listesini alın
fly -t <target> active-users
Borular
Boruları listele:
fly -t <target> pipelines -a
Boru YAML'sini alın (hassas bilgiler tanımda bulunabilir):
fly -t <target> get-pipeline -p <pipeline-name>
Tüm boru yapılandırma değişkenlerini alın
for pipename in $(fly -t <target> pipelines | grep -Ev "^id" | awk '{print $2}'); do echo $pipename; fly -t <target> get-pipeline -p $pipename -j | grep -Eo '"vars":[^}]+'; done
Kullanılan tüm boru gizli adlarını alın (bir iş oluşturabilir veya bir konteyneri ele geçirebilirseniz bunları dışarı çıkarabilirsiniz):
Konteynerler ve İşçiler
İşçileri listele:
fly -t <hedef> workers
Konteynerleri listele:
fly -t <hedef> containers
Çalışan yapıları görmek için yapıları listele:
fly -t <hedef> builds
Concourse Saldırıları
Kimlik Bilgileri Kaba Kuvvet
admin:admin
test:test
Gizli Bilgiler ve parametrelerin sıralanması
Önceki bölümde, boru hattı tarafından kullanılan tüm gizli adlarını ve değişkenleri nasıl alabileceğinizi gördük. Değişkenler, hassas bilgiler içerebilir ve gizli adlarının daha sonra çalmak için kullanışlı olacaktır.
Çalışan veya yakın zamanda çalışan bir konteyner içinde oturum açma
Yeterli ayrıcalığa sahipseniz (üye rolü veya daha fazlası), boru hattını ve rolleri listelemeniz ve sadece <boru hattı>/<iş>
konteyneri içinde bir oturum açmanız mümkün olacaktır. Bunun için:
Bu izinlerle şunları yapabilirsiniz:
Konteyner içindeki sırları çalmak
Düğüme kaçmaya çalışmak
Bulut meta veri uç noktasını (mümkünse pod ve düğümden) numaralandırmak/istismar etmek
Pipeline Oluşturma/Değiştirme
Yeterli ayrıcalığa sahipseniz (üye rolü veya daha fazlası), yeni pipeline'lar oluşturabilir/değiştirebilirsiniz. Aşağıdaki örneği kontrol edin:
Yeni bir pipeline'ın değiştirilmesi/yaratılmasıyla şunları yapabilirsiniz:
Sırları çalmak (onları yankılayarak veya konteynere girip
env
komutunu çalıştırarak)Node'a kaçmak (yeterli ayrıcalıkları vererek -
privileged: true
)Bulut meta veri uç noktasını (pod ve noddan) sıralamak/kötüye kullanmak
Oluşturulan pipeline'ı silmek
Özel Görevi Yürüt
Bu, önceki yönteme benzer, ancak tamamen yeni bir pipeline yerine sadece özel bir görevi yürütebilirsiniz (bu muhtemelen çok daha gizli olacaktır):
Yetkili görevden nod'a kaçış
Önceki bölümlerde, concourse ile yetkili bir görevin nasıl yürütüleceğini gördük. Bu, bir docker konteynerindeki ayrıcalıklı bayrağa tam olarak aynı erişimi sağlamaz. Örneğin, /dev içinde düğüm dosya sistemi cihazını görmeyeceksiniz, bu yüzden kaçış daha "karmaşık" olabilir.
Aşağıdaki PoC'de, release_agent'i bazı küçük değişikliklerle kullanarak kaçış yapacağız:
Gözlemlemiş olabileceğiniz gibi, bu sadece bir düzenli release_agent kaçışı ve düğümdeki cmd yolunun değiştirilmesiyle yapılır.
Bir İşçi konteynerinden düğüme kaçış
Bunun için biraz değiştirilmiş bir düzenli release_agent kaçışı yeterlidir:
Web konteynırından düğüme kaçış
Web konteynırının bazı savunmaları devre dışı bırakılmış olsa bile, bu konteynır bir sıradan ayrıcalıklı konteynır olarak çalışmıyor (örneğin, bağlama yapamazsınız ve yetenekler oldukça sınırlıdır, bu yüzden konteynırdan kaçmak için kolay yollar işe yaramaz).
Ancak, yerel kimlik bilgilerini açık metin olarak saklar:
Web sunucusuna karşı oturum açmak ve ayrıcalıklı bir konteyner oluşturarak düğüme kaçmak için bu kimlik bilgilerini kullanabilirsiniz.
Ortamda, Concourse'un kullandığı postgresql örneğine erişmek için bilgileri bulabilirsiniz (adres, kullanıcı adı, şifre ve diğer bilgiler arasında veritabanı):
Garden Servisi Kötüye Kullanma - Gerçek Bir Saldırı Değil
Bu sadece servis hakkında ilginç notlar, ancak yalnızca yerel ana bilgisayarda dinlendiği için bu notlar daha önce zaten sömürdüğümüz bir etki sunmuyor.
Varsayılan olarak, her bir Concourse işçisi, port 7777'de bir Garden servisi çalıştıracaktır. Bu servis, Web yöneticisinin işçiye neyi yürütmesi gerektiğini (görüntüyü indirip her görevi çalıştırma) belirtmek için kullanılır. Bu bir saldırgan için oldukça iyi görünüyor, ancak bazı güzel korumalar var:
Yalnızca yerel olarak (127.0.0.1) açığa çıkarılır ve işçi, özel SSH servisiyle Web'e kimlik doğrulama yaptığında, her işçi içindeki Garden servisiyle iletişim kurmak için bir tünel oluşturulur.
Web sunucusu, çalışan konteynerleri her birkaç saniyede bir izler ve beklenmeyen konteynerler silinir. Bu nedenle, özel bir konteyner çalıştırmak istiyorsanız, web sunucusu ile garden servisi arasındaki iletişimi manipüle etmeniz gerekir.
Concourse işçileri yüksek konteyner ayrıcalıklarıyla çalışır:
Ancak, düğümün /dev cihazını veya release_agent'i bağlama gibi teknikler çalışmayacaktır (çünkü düğümün dosya sistemiyle gerçek cihaza erişilemez, sadece sanal bir cihaz vardır). Düğümün işlemlerine erişemiyoruz, bu yüzden çekirdek açıkları olmadan düğümden kaçmak karmaşık hale gelir.
Önceki bölümde, ayrıcalıklı bir konteynerden nasıl kaçılacağını gördük, bu yüzden geçerli işçi tarafından oluşturulan bir ayrıcalıklı konteynerde komutları çalıştırabiliyorsak, düğümden kaçabiliriz.
Concourse ile oynarken fark ettim ki bir şeyi çalıştırmak için yeni bir konteyner oluşturulduğunda, konteyner işlemleri işçi konteynerinden erişilebilir, bu yüzden içinde yeni bir konteyner oluşturan bir konteyner gibi çalışır.
Çalışan bir ayrıcalıklı konteynere giriş yapma
Yeni bir ayrıcalıklı konteyner oluşturma
Çok kolay bir şekilde yeni bir konteyner oluşturabilirsiniz (yalnızca rastgele bir UID çalıştırın) ve üzerinde bir şeyler çalıştırabilirsiniz:
Ancak, web sunucusu çalışan konteynerleri her birkaç saniyede bir kontrol ediyor ve beklenmeyen bir tane bulunursa siliniyor. İletişim HTTP üzerinden gerçekleştiği için, beklenmeyen konteynerlerin silinmesini önlemek için iletişimi bozabilirsiniz:
Referanslar
https://concourse-ci.org/vars.html
Last updated