hacktricks/linux-hardening/bypass-bash-restrictions/bypass-fs-protections-read-only-no-exec-distroless/ddexec.md
2024-02-10 18:14:16 +00:00

7.3 KiB
Raw Blame History

DDexec / EverythingExec

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

HackTricks'ı desteklemenin diğer yolları:

Bağlam

Linux'ta bir programı çalıştırmak için, dosya olarak var olmalı ve dosya sistemi hiyerarşisi üzerinden bir şekilde erişilebilir olmalıdır (bu sadece execve() işlevinin çalışma şeklidir). Bu dosya diskte veya ram'de (tmpfs, memfd) bulunabilir, ancak bir dosya yolu gereklidir. Bu, Linux sistemde çalıştırılan şeyi kontrol etmeyi çok kolay hale getirir, tehditleri ve saldırgan araçlarını tespit etmeyi veya onların hiçbir şeyini çalıştırmalarına izin vermemeyi kolaylaştırır (örneğin, ayrıcalığı olmayan kullanıcıların yürütülebilir dosyaları herhangi bir yere yerleştirmelerine izin vermemek).

Ancak bu teknik, tüm bunları değiştirmek için burada. İstediğiniz süreci başlatamazsanız... zaten var olan bir süreci ele geçirirsiniz.

Bu teknik, salt okunur, noexec, dosya adı beyaz listeleme, hash beyaz listeleme gibi yaygın koruma tekniklerini atlamak için kullanılabilir.

Bağımlılıklar

Son komut dosyasının çalışması için aşağıdaki araçlara bağımlılığı vardır, saldırdığınız sistemde erişilebilir olmaları gerekmektedir (varsayılan olarak hepsini her yerde bulabilirsiniz):

dd
bash | zsh | ash (busybox)
head
tail
cut
grep
od
readlink
wc
tr
base64

Teknik

Bir sürecin belleğini keyfi olarak değiştirebiliyorsanız, onu ele geçirebilirsiniz. Bu, zaten var olan bir süreci ele geçirmek ve başka bir programla değiştirmek için kullanılabilir. Bunun için ya ptrace() sistem çağrısını kullanarak (sistemde syscalls çalıştırma yeteneğine veya gdb'nin sistemde bulunmasına ihtiyaç duyar) veya daha ilginç olanı, /proc/$pid/mem dosyasına yazarak başarabiliriz.

/proc/$pid/mem dosyası, bir sürecin tüm adres alanının (örn. x86-64'te 0x0000000000000000 ile 0x7ffffffffffff000 arasında) birbirine eşleştirilmesidir. Bu, bir ofset x ile bu dosyadan okuma veya yazma, sanal adres x'teki içeriği okuma veya değiştirmeyle aynıdır.

Şimdi, üstesinden gelmemiz gereken dört temel sorunumuz var:

  • Genel olarak, yalnızca kök ve dosyanın program sahibi tarafından değiştirilebilir.
  • ASLR.
  • Programın adres alanında eşlenmemiş bir adrese okuma veya yazma denememiz durumunda bir G/Ç hatası alırız.

Bu sorunların, mükemmel olmasa da iyi çözümleri vardır:

  • Çoğu kabuk yorumlayıcısı, ardından çocuk süreçler tarafından devralınacak dosya tanımlayıcılarının oluşturulmasına izin verir. Yazma izinleriyle kabuğun mem dosyasına işaret eden bir fd oluşturabiliriz... böylece bu fd'yi kullanan çocuk süreçler, kabuğun belleğini değiştirebilecektir.
  • ASLR bile bir sorun değil, programın adres alanı hakkında bilgi edinmek için kabuğun maps dosyasını veya procfs'ten başka bir dosyayı kontrol edebiliriz.
  • Bu yüzden dosya üzerinde lseek() yapmamız gerekiyor. Kabuktan bu yapılamaz, ancak kötü şöhretli dd kullanılarak yapılabilir.

Daha detaylı olarak

Adımlar oldukça kolaydır ve bunları anlamak için herhangi bir uzmanlık gerektirmez:

  • Çalıştırmak istediğimiz ikili ve yükleyiciyi analiz edin ve hangi eşlemelere ihtiyaç duyduklarını bulun. Ardından, her bir execve() çağrısında çekirdeğin yaptığı adımların genel olarak aynısını gerçekleştirecek bir "shell" kodu oluşturun:
  • Söz konusu eşlemeleri oluşturun.
  • İkili dosyaları bunlara okuyun.
  • İzinleri ayarlayın.
  • Son olarak, programın argümanları için yığını başlatın ve yükleyici tarafından gereken yardımcı vektörü yerleştirin.
  • Yükleyiciye atlayın ve gerisini ona bırakın (program tarafından gereken kütüphaneleri yükleyin).
  • İşlem tarafından gerçekleştirilen sistem çağrısından sonra döneceği adresi syscall dosyasından alın.
  • Bu, yazılabilir olmayan sayfaları mem aracılığıyla değiştirebileceğimiz bir yer olan, yürütülebilir olan yere kendi shell kodumuzu üzerine yazın.
  • Çalıştırmak istediğimiz programı sürecin stdin'ine geçirin (söz konusu "shell" kodu tarafından read() edilecektir).
  • Bu noktada, programımız için gerekli kütüphaneleri yüklemek ve ona atlamak yükleyiciye bağlıdır.

Araç için https://github.com/arget13/DDexec adresine bakın

EverythingExec

dd'ye alternatif olarak birkaç seçenek vardır, bunlardan biri olan tail, mem dosyası üzerinde lseek() yapmak için şu anda varsayılan olarak kullanılan programdır (dd kullanmanın tek amacı buydu). Söz konusu alternatifler şunlardır:

tail
hexdump
cmp
xxd

Değişken SEEKER'ı ayarlayarak kullanılan arayıcıyı değiştirebilirsiniz, örneğin:

SEEKER=cmp bash ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Eğer betikte uygulanmamış başka geçerli bir arayıcı bulursanız, SEEKER_ARGS değişkenini ayarlayarak hala kullanabilirsiniz:

SEEKER=xxd SEEKER_ARGS='-s $offset' zsh ddexec.sh ls -l <<< $(base64 -w0 /bin/ls)

Engelleyin bunu, EDR'lar.

Referanslar

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

HackTricks'i desteklemenin diğer yolları: