日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文涉及的實(shí)操——實(shí)驗(yàn):php反序列化漏洞實(shí)驗(yàn)(合天網(wǎng)安實(shí)驗(yàn)室)https://www.hetianlab.com/expc.do?ec=ECID172.19.104.182016010714511600001&pk_campaign=toutiao-wemedia

通過本次實(shí)驗(yàn),大家將會明白什么是反序列化漏洞,反序列化漏洞的成因以及如何挖掘和預(yù)防此類漏洞。

前言

php反序列化的字符逃逸算是比較難理解的一個(gè)知識點(diǎn),在最近的好幾場比賽中都出現(xiàn)了相關(guān)的題,于是下定決心徹底理解透徹這個(gè)知識點(diǎn),于是便有了這篇文章。

基礎(chǔ)知識理解

字符逃逸在理解之后就能夠明白,這是一種閉合的思想,它類似SQL中的萬能密碼,理解這種原理之后會變得特別容易。

在SQL注入中,我們常用'、"來對注入點(diǎn)進(jìn)行一些閉合或者一些試探,從而進(jìn)行各種姿勢的注入,反序列化時(shí),序列化的值是以;作為字段的分隔,在結(jié)尾是以}結(jié)束,我們稍微了解一下,

<?php
 class people{
    public $name = 'Tom';
    public $sex = 'boy';
    public $age = '12';
 }
 $a = new people();
 print_r(serialize($a));O:6:"people":3:{s:4:"name";s:3:"Tom";s:3:"sex";s:3:"boy";s:3:"age";s:2:"12";}

反序列化的過程就是碰到;}與最前面的{配對后,便停止反序列化。我們可以將上面的序列化的值稍作改變:

O:6:"people":3:{s:4:"name";s:3:"Tom";s:3:"sex";s:3:"boy";s:3:"age";s:2:"12";}123123
細(xì)說php反序列化字符逃逸

 

可以看到,并沒有報(bào)錯(cuò),而且也順利將這個(gè)對象反序列化出來了,恰好說明了我們以上所說的閉合的問題,與此同時(shí),修改一些序列化出來的值可以反序列化出我們所知道的對象中里沒有的值,在學(xué)習(xí)繞過__wakeup就能過知道了,這里可以自己去做一些嘗試,去理解。

接下來就是要說到報(bào)錯(cuò)的時(shí)候了,當(dāng)你的字符串長度與所描述的長度不一樣時(shí),便會報(bào)錯(cuò),比如上圖中s:3:"Tom"變成s:4:"Tom"或s:2:"Tom"便會報(bào)錯(cuò),為的就是解決這種報(bào)錯(cuò),所以在字符逃逸中分為兩類:

  1. 字符變多
  2. 字符減少

關(guān)鍵字符增多

在題目中,往往對一些關(guān)鍵字會進(jìn)行一些過濾,使用的手段通常替換關(guān)鍵字,使得一些關(guān)鍵字增多,簡單認(rèn)識一下,正常序列化查看結(jié)果

細(xì)說php反序列化字符逃逸

 

這里,我們對序列化后的字符串進(jìn)行了替換,使得后來的反序列化報(bào)錯(cuò),那我們就需要在Tom這里面的字符串做手腳,在username之后只有一個(gè)age,所以在雙引號里面可以構(gòu)造我需要的username之后參數(shù)的值,這里修改age的值,我們這里將Tom替換為Tom";s:3:"age";s:2:"35";}然后進(jìn)行反序列化,這里指的是在對username傳參的時(shí)候進(jìn)行修改,也就是我們寫鏈子的時(shí)候進(jìn)行的操作

細(xì)說php反序列化字符逃逸

 

可以看到構(gòu)造出來的序列化字符串長度為25,而在上面的反序列化過程中,他會將一個(gè)o變成兩個(gè),oo,那么得到的應(yīng)該就是s:25:"Toom"我們要做的就是讓這個(gè)雙引號里面的字符串在過濾替換之后真的有描述的這么長,讓他不要報(bào)錯(cuò),再配合反序列化的特點(diǎn),(反序列化的過程就是碰到;}與最前面的{配對后,便停止反序列化)閉合后忽略后面的age:13的字符串成功使得age被修改為35。

age的修改需要前面的字符串username的值長度與描述的一樣,這需要我們精確的計(jì)算,這里是將一個(gè)o變成兩個(gè),以下就只寫o不寫Tom,效果一致,我們需要知道我們除了雙引號以內(nèi)的,所構(gòu)造的字符串長度為多少,即";s:3:"age";s:2:"35";}的長度22,那就需要22個(gè)o,

總的來說就是22個(gè)o加上后面的字符串長度22,總長度就為44,在被過濾替換后,光o就有44個(gè),符合描述的字符串長度。下面就說明(為什么叫做逃逸

細(xì)說php反序列化字符逃逸

 

這里特意寫了"將一大串o進(jìn)行與前面的"閉合了,如果直接反序列化,在序列化出來的值中就包含了";s:3:"age";s:2:"35";}。

反序列的過程中,所描述的字符串長度(這里為44),而后面雙引號包裹的字符串長度(這里為22)不夠所描述的長度,那么他將會向后吞噬,他會將后雙引號吞噬,直至足夠所描述的長度,在一切吞噬結(jié)束之后,序列化出來的字符串如果不滿足反序列化的字符串的格式,就會報(bào)錯(cuò)。我們這里是他吞噬結(jié)束后,還滿足這個(gè)格式,所以不報(bào)錯(cuò)。

在這個(gè)例子中,我們利用他對序列化后的值,進(jìn)行增加字符串長度的過濾,讓他填充雙引號內(nèi)的字符串達(dá)到所描述的44這么長,使得后面的s:3:"age";s:2:"35";不被吞噬,讓這部分代碼逃逸出吞噬,又讓他提前遇到}忽略后面的一些不需要的字符串,結(jié)束反序列化。

細(xì)說php反序列化字符逃逸

 

可以看到,我們構(gòu)造的payload是成功修改了age,這里是數(shù)組,在對對象操作時(shí)也是一樣的。

剛剛說到吞噬,在增加字符串的題目中,我們是利用題中的增加操作,阻止他進(jìn)行向后吞噬我們構(gòu)造的代碼,而在字符減少的過程中,我們也是利用這個(gè)操作。

關(guān)鍵字符減少

有了前面”吞噬“的一種解釋,那么字符串減少就很好說了 ,同樣的也是因?yàn)樘鎿Q的問題,使得參數(shù)可以讓我們構(gòu)造payload

細(xì)說php反序列化字符逃逸

 

這里的錯(cuò)誤是因?yàn)閟:5:"zddo"長度不夠,他向后吞噬了一個(gè)雙引號,導(dǎo)致反序列化格式錯(cuò)誤,從而報(bào)錯(cuò),我們要做的就是讓他往后去吞噬一些我們構(gòu)造的一些代碼。以下將具體實(shí)施。

同樣的,我們這里以修改age為例,不同的是與增加字符串傳值的地方有些許不同,我們構(gòu)造的值是有一部分讓他吞噬的

先正常傳遞值序列化出我們需要修改的值,我們需要的是將age:13改為35

細(xì)說php反序列化字符逃逸

 

取出";s:3:"age";s:2:"35";}這就是我們需要構(gòu)造的,接著繼續(xù)將這部分內(nèi)容重新傳播,序列化出來,得到下面的結(jié)果

細(xì)說php反序列化字符逃逸

 

選中部分就是我們構(gòu)造出來,他需要吞噬的代碼,s:22:""這個(gè)雙引號里面我們還有操作的空間,用來補(bǔ)齊字符串長度,接著就是計(jì)算我們自己所需要吃掉的字符串長度為18,根據(jù)過濾,他是將兩個(gè)o變成一個(gè),也就是每吃掉一個(gè)字符,就需要有一個(gè)oo,那我們需要吃掉的是18個(gè)長度,那么我們就需要18個(gè)oo,在吞噬結(jié)束之后我們的格式又恢復(fù)正確,使得真正的字符s:3:"age";s:2:"35";逃逸出來,成功加入反序列化

細(xì)說php反序列化字符逃逸

 

這就是我們最終的payload,可以看到下圖成功修改了

細(xì)說php反序列化字符逃逸

 

例題

有了以上基礎(chǔ),就可以做題了,簡單的開始入手

安恒四月(字符減少)

<?php
show_source("index.php");
function write($data) {
    return str_replace(chr(0) . '*' . chr(0), '', $data);
}

function read($data) {
    return str_replace('', chr(0) . '*' . chr(0), $data);
}

class A{
    public $username;
    public $password;
    function __construct($a, $b){
        $this->username = $a;
        $this->password = $b;
    }
}

class B{
    public $b = 'gqy';
    function __destruct(){
        $c = 'a'.$this->b;
        echo $c;
    }
}

class C{
    public $c;
    function __toString(){
        echo file_get_contents($this->c);
        return 'nice';
    }
}

$a = new A($_GET['a'],$_GET['b']);
//省略了存儲序列化數(shù)據(jù)的過程,下面是取出來并反序列化的操作
$b = unserialize(read(write(serialize($a))));

看到上面的代碼,很明顯,我們需要利用file_get_contents();讀取文件,將flag讀取出來,但是他是個(gè)__toString()方法,我們就要讓他觸發(fā)這個(gè)方法,當(dāng)反序列化出對象后,被當(dāng)作字符串使用時(shí),就可以觸發(fā),那我們就需要寫一個(gè)鏈,與此同時(shí)我們也要知道字符串被刪減了幾個(gè)字符

function write($data) {
    return str_replace(chr(0) . '*' . chr(0), '', $data);
}

function read($data) {
    return str_replace('', chr(0) . '*' . chr(0), $data);
}

看這一部分即可了解到,如果發(fā)現(xiàn)不可見字符*不可見字符,字符串就會增多,接著又將的6個(gè)字符變成3個(gè)字符不可見字符*不可見字符,我們自己是不會去寫入不可見字符的在這道題中,相反可以故意寫入使得字符串減少,通過計(jì)算逃逸字符,讀取flag文件

題目中序列化的是對象$a,里面有兩個(gè)參數(shù),username和password,我們要傳入的也是這兩個(gè)參數(shù)的值,所以我們構(gòu)造的payload,應(yīng)該是往password傳我們構(gòu)造好的字符,而在username傳入的為計(jì)算好的個(gè)數(shù),

按照流程來,先寫一個(gè)鏈子,某些參數(shù)先隨便寫

細(xì)說php反序列化字符逃逸

 

";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:5:"/flag";}}}

選中部分就是我們需要重新傳參的地方,我們傳進(jìn)password,再次序列化看看效果

細(xì)說php反序列化字符逃逸

 

我所選擇的地方就是需要被吞噬的部分,然后才能使得后邊的代碼全部逃逸,長度為23,計(jì)算后發(fā)現(xiàn)需要8個(gè),但8個(gè)這樣的符號會吞噬24個(gè)字符,因此我們可以在s:70:""雙引號里面可以隨意補(bǔ)一個(gè)字符讓它吞噬。

因此我們最終在password里面?zhèn)鲄⒌膽?yīng)該是:

i";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:5:"/flag";}}}

而在username中傳的就是8個(gè):

最終payload:

?a=&b=i";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:5:"/flag";}}}
細(xì)說php反序列化字符逃逸

 

0CTF piapiapia(字符增加)

掃描目錄發(fā)現(xiàn)www.zip,下載后開始,審計(jì)源碼

我們根據(jù)他的網(wǎng)頁一步步看源碼,首先他要我們登陸,我們先注冊一個(gè)賬號進(jìn)行登陸

細(xì)說php反序列化字符逃逸

 

看到上圖的界面,這時(shí)我們看到update.php,都是一些對參數(shù)的白名單按要求寫即可,圖片也隨便傳一個(gè)符合大小的即可,但是注意nickname是我們要操作的地方,稍后講解,然后有個(gè)序列化數(shù)組的過程

$user->update_profile($username, serialize($profile));

在上傳成功后,他會到profile.php,我們看到profile.php,有這么一段東西

$profile = unserialize($profile);
$phone = $profile['phone'];
$email = $profile['email'];
$nickname = $profile['nickname'];
$photo = base64_encode(file_get_contents($profile['photo']));

這里告訴我們,他反序列化的是profile這個(gè)數(shù)組序列化后的值,讀取的是鍵名為photo里面的文件名,而flag在config.php也就是說我們需要構(gòu)造的就是數(shù)組中$profile['photo']='config.php'

那么怎樣才能讓他讀這個(gè)config.php呢

我們看到class.php,看到父類MySQL中:

public function filter($string) {
        $escape = array(''', '\\');
        $escape = '/' . implode('|', $escape) . '/';
        $string = preg_replace($escape, '_', $string);

        $safe = array('select', 'insert', 'update', 'delete', 'where');
        $safe = '/' . implode('|', $safe) . '/i';
        return preg_replace($safe, 'hacker', $string);
    }

發(fā)現(xiàn)序列化的值他會傳遞給user中的方法update_profile,接著update_profile又將這個(gè)值傳遞給了父類方法filter,顯而易見,就是一種過濾,防止sql注入,但是可以發(fā)現(xiàn),他是以替換的方式給返回值,在過濾的字符串中,只有where變成hacker,由5個(gè)字符變成6個(gè),所以是字符增加的逃逸方式,接著開始構(gòu)造

細(xì)說php反序列化字符逃逸

 

選擇部分是需要傳入的,在phone和email都是白名單,傳入的格式受限制,只有nickname是黑名單,所以我們要繞過這個(gè)黑名單,bp抓包

細(xì)說php反序列化字符逃逸

 

他使用的是strlen()所以這里有個(gè)方式,這個(gè)函數(shù)如果參數(shù)是字符串,那么數(shù)出來的就是字符串個(gè)數(shù),如果是數(shù)組,那么數(shù)出來的就是數(shù)組元素的個(gè)數(shù)

將nickname改成nickname[]然后傳參

傳的參數(shù)我們需要構(gòu)造,需要計(jì)算,上面分析了我們需要構(gòu)造的字符串";}s:5:"photo";s:10:"config.php";},但是他是字符增多,我們就需要知道需要逃逸的字符有多少個(gè),計(jì)算了一下為34個(gè),(這里因?yàn)楦臑榱藬?shù)組,而數(shù)組的序列化格式結(jié)束后是一個(gè)大括號,所以我們在一開始的”;后面增加了一個(gè)花括號)所以需要34個(gè)where幫助我們逃逸這部分代碼,上傳成功,根據(jù)這個(gè)修改放包即可

細(xì)說php反序列化字符逃逸

 

返回網(wǎng)頁點(diǎn)擊

細(xì)說php反序列化字符逃逸

 

之后可以看到一張顯示不出來的圖片,因?yàn)槭褂胋ase64編碼了,右擊查看圖片信息

細(xì)說php反序列化字符逃逸

 

解碼即可看到flag

細(xì)說php反序列化字符逃逸

 

分享到:
標(biāo)簽:php
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定