[安洵杯 2019]easy_web&[WUSTCTF2020]朴实无华


概述

本文主要记录[安洵杯 2019]easy_web和[WUSTCTF2020]朴实无华的做题过程和相关思路

[安洵杯 2019]easy_web

打开题目,发现在url上有两个参数,分别是imgcmd,发现毫无思路,直接看源码进行审计
在这里插入图片描述
对于img的值其构成为大小写字母数字,符合Base64编码的特征,尝试对其进行Base64解码
注:由于TXpVek5UTTFNbVUzTURabE5qYz0的长度为27不满足4的倍数,需要在其后面添加=,使长度为28,再进行解码
在这里插入图片描述
解码后的结果同样满足Base64编码规则,再次进行解码
在这里插入图片描述
得到的结果为一串16进制,将其转换为字符串为555.png
在这里插入图片描述
尝试将555.png拼接到url进行访问,发现就是题目一开始所展示的那张图
在这里插入图片描述
在题目首页中查看该图片的加载方式,发现是通过Base64方式进行加载的
在这里插入图片描述
通过上面的分析,可以知道只要将需要读取的本地文件的文件名经过一次字符串转16进制,两次Base64编码,再传输到img参数中,即可在题目首页看到对应文件的Base64编码
那么首先尝试读取index.php
在这里插入图片描述
在这里插入图片描述

将上面的的Base64编码进行解码后可以得到index.php的源代码

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

?>
<html>
<style>
  body{
   background:url(./bj.png)  no-repeat center center;
   background-size:cover;
   background-attachment:fixed;
   background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>

那么现在看来img参数的作用应该就是帮助我们获取index.php源代码的,接下来的关键是cmd参数,通过查看源代码,发现对cmd参数的值进行了过滤,比如cattac等,并且下面还有更为重要的一段判断代码

if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
    echo `$cmd`;
} else {
    echo ("md5 is funny ~");
}

这里由于使用了string进行了强制转换,发现数组经string强制转换后的值都为"Array",不能满足!==,所以无法使用数组进行绕过
在这里插入图片描述
那么这里就要考虑使用md5强碰撞

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

注意,在使用hackbar发送post数据时会自动将数据进行一次url编码,所以我这里使用bp,由于没有过滤dir命令,那我就使用dir命令查看flag的位置
在这里插入图片描述
使用cat的命令直接读取flag的内容
在这里插入图片描述
注意,在查看其他师傅WP时发现有师傅有疑惑,说\为什么没有被检测到或者ca\t为什么可以绕过,我在本地测试了一下,有一些收获:
1.首先我们可以看到在preg_match函数的匹配模式$pattern中确实含有|\\|\\\\|,一眼看上去像是检测了\\\,其实不是,在php对于转义字符的说明中有一段话
在这里插入图片描述
由于preg_match函数的匹配模式为字符串,那么首先它应该被当作是字符串进行处理
在 /x|\\|\\\\|z/ 中三个高亮的反斜杠都是起到转义的作用,使得后面的反斜杠能够作为匹配模式中的内容
2.经过字符串的处理之后,实际上的匹配模式/x|\|\\|z/ ,而匹配模式中又是允许转义字符存在的,那么其中的\将再次发挥转义作用,即 /x|\|\\|z/ 中高亮的转义字符再次进行转义,最后实际的匹配模式为/x||\|z/,即匹配x|\z
以下是一个小案例:
不匹配\

在这里插入图片描述

匹配|\

在这里插入图片描述

[WUSTCTF2020]朴实无华

打开题目,只有一句话,看页面源代码也没有收获,直接用dirsearch,发现有robots.txt404.html

在这里插入图片描述

访问robots.txt发现提示有fAke_f1agggg.php

在这里插入图片描述
访问fAke_f1agggg.php说不是flag,而且页面源代码中也没有线索
在这里插入图片描述
查看fAke_f1agggg.php请求头响应头,发现在响应头中提示有fl4g.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("去非洲吧"); 
} 
?> 

第一关,其中涉及到intval函数,可以使用科学计数法表示进行绕过

  • intval('2e4')==>当遇到第一个非数字时停止,结果为2
  • intval('2e4'+1)==>2e4首先转换成20000再加1,结果为20001

在这里插入图片描述

第二关,是==弱类型比较

  • 0e215962017被看作是科学计数法0的21…次方,即为0
  • 0e291242476940776845150308577824被看作是科学计数法0的29…次方,也为0,故相等

在这里插入图片描述
第三关,!strstr($get_flag," ")会检测是否含有空格,有的话就会退出,str_ireplace("cat", "wctf2020", $get_flag)会将$get_flag中的ctf替换为wctf2020,那么这里就不能直接用cat命令,可以先用ls看看当前目前都有哪些文件,发现一个文件名很长的文件
在这里插入图片描述

使用tac来绕过cat检测和使用$IFS$9来绕过空格检测

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值