CTFZone Kualifikasi Penulisan 2019: Chicken

Meskipun penundaan konferensi OFFZONE 2020 , akan ada final CTFZone ! Tahun ini akan diadakan untuk pertama kalinya online dan akan disiarkan secara aktif di jejaring sosial.

Kami akan mengumumkan detailnya nanti, tetapi untuk saat ini, kami sarankan menjelajahi startup webtask dari tahap kualifikasi. Analisis solusi dikirim kepada kami oleh Devand MacLean dari Kanada. Khusus untuk Habr, kami telah menerjemahkan teks dari startup lokal dan kami mengundang Anda untuk mencari tahu rantai kerentanan yang ditemui peserta dan apa yang harus dilakukan ayam dengan itu.



informasi Umum


Penulis tugas: Pavel Sorokin
Poin: 470
Jumlah tim yang menyelesaikan tugas: 2

Tautan yang bermanfaat:




, - :


  • (/Home/Index);
  • (/Home/Hens);
  • (/Home/Contact);
  • (/Auth/Login).

,   , :


  • ;
  •  API ,   .


Halaman / Home / Hens berisi tautan untuk mengunduh "paspor" ayam.


Setelah decoding Base64, kami menemukan nama file parameter: 1.txt. Menggunakan CyberChef, kami menyandikan / etc / passwd di Base64 dan mengikuti tautan:

http://web-chicken.ctfz.one/File/Download?filename=L2V0Yy9wYXNzd2Q=

Isi file / etc / passwd di server dibuka di browser , yang berarti kami mendapatkan hak untuk membaca file sewenang-wenang dalam sistem.

Saat Anda mencoba menemukan file lain dalam sistem, Anda mungkin melihat kesalahan yang muncul setiap kali Anda meminta file yang tidak ada (atau file yang tidak dapat dibaca dengan hak pengguna aplikasi):


Setelah melihat bahwa kesalahan mengacu pada variabel lingkungan ASPNETCORE_ENVIRONMENT , kami mulai mempelajari tata letak aplikasi web ASP.NET Core. Dan kita melihat yang berikut ini:


Untuk mengonversi jalur dan nama file yang diperlukan dan mengekstraknya ke Base64, kami menulis skrip Python kecil ( fetch.py ):


Menggunakan pengetahuan ini tentang struktur aplikasi web MVC yang dibuat di ASP.NET Core, menggunakan fetch.py ​​kita mendapatkan kode sumber untuk file-file berikut:


  • ../Views/Shared/_Layout.cshtml
  • ../Views/Home/Index.cshtml
  • ../Views/Home/Contact.cshtml
  • ../Views/Home/Hens.cshtml
  • ../Views/Auth/Login.cshtml

Setelah melakukan ini dan mempelajari kode sumber setiap halaman, kami menemukan detail yang menarik di Hens.cshtml


Baris 1 berisi pernyataan inklusi @ using StackHenneryMVCAppProject, yang dalam ASP.NET berarti tautan ke file DLL.

Kami membuka ../StackHenneryMVCAppProject.dll - tetapi tidak melalui utilitas Python di Kali Linux, tetapi di browser pada Windows, karena kami akan mendekompilasi file ini di Windows. Melalui penggunaan URL seperti yang:

http://web-chicken.ctfz.one/File/Download?filename=Li4vU3RhY2tIZW5uZXJ5TVZDQXBwUHJvamVjdC5kbGw=

Membuka DLL-file dalam dnSpy (NET Decompiler), segera melihat bahwa dalam metode Initialize () kelas Config. Konfigurasi , yang berjalan ketika aplikasi web dimulai, membaca isi file chicken_domains_internal.txt . Menggunakan skrip Python, kami mengekstrak isi file ini:

web-chicken-flag
web-ayam-auth

The Initialize () metode menghubungkan ke  web-ayam-bendera melalui port 4321 dan menerima beberapa parameter: secret_token , RSA_key dan  bendera .

Sayangnya, tidak mungkin untuk memulai koneksi ke web-chicken-flag. Tetapi, ketika kami menetapkan catatan host DNS lokal untuk menerjemahkan web-chicken-auth ke alamat IP eksternal server ( 34.89.232.240 ), kami berhasil membuka http: // web-chicken-auth / dengan antarmuka Swagger UI yang digunakan untuk menggambarkan dan menjalankan perintah melalui REST API.


Saat menggali ke file DLL yang didekompilasi, Anda dapat melihat bahwa controller AuthController tidak hanya memiliki metode Login () , tetapi juga metode Change_Password_Test () :


Ketika kita pergi ke  / Auth / Change_Password_Test kita melihat formulir ini:


Saat mempelajari metode Change_Password_Test () , kami memahami bahwa ia memproses empat parameter tipe String melalui permintaan HTTP POST:


  • nama pengguna;
  • kata sandi baru;
  • password lama;
  • base_url.


Sedikit lebih rendah dalam metode Change_Password_Test () kita melihat: tanpa menerima nilai untuk base_url , metode ini mengambil nilai conf.auth_server , yaitu web-chicken-auth , dan kemudian menambahkan / auth / login ke akhir nilai base_url , menugaskan string yang dihasilkan ke variabel requestUri :


Di bagian penting berikutnya dari kode, nilai-nilai string dari parameter username dan  old_password dari permintaan HTTP POST, dan dengan mereka  secret_token dari konfigurasi, dimasukkan ke dalam string JSON. Kemudian, objek JSON StringContent dibuat dari data ini , yang dikirim sebagai data HTTP POST ke variabel requestURI yang dibuat pada langkah sebelumnya.


Sekarang server menunggu permintaan HTTP POST untuk meminta  Uri untuk mengembalikan objek JSON dengan parameter kode sama dengan 0. Jika ini tidak terjadi, kita masuk ke cabang kode yang dimulai dari baris 6 dan mengembalikan tampilan / Views / Auth / Login dengan kesalahan Login tidak valid / kata sandi .

Jika permintaan HTTP POST masih mengembalikan objek JSON dengan parameter kode sama dengan 0, kita pergi ke cabang kode dari baris 11. Kemudian variabel requestUri2 mendapatkan nilai http: // web-chicken-auth , objek JSON StringContent lain dibuatdengan parameter dari permintaan POST HTTP asli, seperti pada bagian sebelumnya, dan data ini dikirim ke alamat requestUri2  dalam permintaan HTTP PUT. Akhirnya, pesan Kata Sandi yang diubah dikembalikan ke klien .


Singkatnya: seluruh proses dimulai dengan permintaan HTTP POST ke  / Auth / Change_Password_Test , yang mengharapkan sejumlah parameter tertentu. Dibutuhkan nilai-nilai ini dan membuat objek JSON untuk mengirimkannya ke  <base_url> / auth / login melalui HTTP POST. Jika sebagai responsnya menerima JSON dengan parameter kode sama dengan 0, ia menciptakan objek JSON lain dan mengirimkan permintaan HTTP PUT ke  http: // web-chicken-auth / auth / change_password .

Ketika mempelajari REST API di UI Swagger, kita melihat bahwa dalam file DLL yang didekompilasi tidak hanya rute / auth / login dan  / auth / change_password , tetapi juga rute untuk / auth / password_recovery .


Rute API ini mengharapkan objek JSON dengan dua parameter: email dan  secret_token . Jika dia menerimanya, maka dia mengembalikan objek JSON dengan properti kode 0 dan string pesan dan  token .


Ternyata jika kita dengan paksa memaksa metode Check_Password_Test () untuk segera meminta rute / auth / password_recovery alih-alih / auth / login , maka untuk memasukkan cabang perubahan kata sandi itu akan cukup untuk memasukkan alamat email yang valid.

Kami lagi mempelajari bagian dari kode di mana metode Check_Password_Test () memberikan nilai requestUri dalam permintaan HTTP POST asli, dan kami memahami bahwa kami perlu mengirim nilai http: // web-chicken-auth / auth / password_recovery # sebagai parameter base_url, dan requestUri di final hasilnya adalah http: // web-chicken-auth / auth / password_recovery # / auth / login .

Karakter # dalam URL HTTP menunjukkan bahwa bagian dari alamat permintaan telah berakhir. Oleh karena itu, server yang menerima permintaan hanya akan mengabaikan bagian / auth / login .


Ini, tentu saja, bagus, tetapi kita hanya harus mencari tahu bagaimana titik akhir REST, di mana kita sekarang mengarahkan permintaan, akan menerima nilai email . Tanpa nilai ini, permintaan akan gagal, dan kami tidak akan melangkah lebih jauh.

Kami dengan cermat melihat bagaimana metode Check_Password_Test () membuat data JSON, dan kami melihat bahwa data input tidak dihapus sama sekali, yang berarti Anda dapat dengan mudah menerapkan parameter Anda. Cukup mengirim parameter berikut dalam permintaan POST HTTP:

username = admin
old_password = pwned "," email ":" admin@chicken.ctf.zone "," lol ":"
new_password = p0tat0
base_url = http: // web-chicken-auth / auth / password_recovery #

Objek JSON yang dihasilkan dikirim ke  / auth / password_recovery :


Dengan data JSON ini, kami memenuhi persyaratan bahwa / auth / password_recovery harus mengembalikan respons, setelah itu server akan memasukkan cabang perubahan kata sandi (objek JSON berisi properti email ). Sekarang kita tidak lagi membutuhkan nilai old_password . Di cabang kode ini, kami memberikan semua nilai yang diperlukan untuk mengubah kata sandi (properti nama pengguna adalah admin dan properti kata sandi adalah p0tat0 ). Permintaan selesai, dan kami mendapatkan Kata Sandi berubah sebagai tanggapan.


Tinggal memasukkan nama pengguna dan kata sandi baru di halaman login!


Dan ini adalah bendera kami:


All Articles