ss-panel 在梯子站里用的也比较多吧,无意间发现了个反射型 XSS,不过有点鸡肋。
根据项目描述,它是基于自己写的框架 LightFish,而 LightFish 又是基于 slim 写的。
其 ORM 用的是 Eloquent
,简单看了下没什么问题,
而 View 用的是 Twig
(实际上用的是 Smarty
),默认不进行 HTML 转义,也没发现有用到 htmlspecialchars
,cookie 也没设置 http-only
。
所以有用户可控输出的地方很可能就存在 XSS。
以邀请码处的反射型 XSS 为例:
https://github.com/orvice/ss-panel/blob/master/app/Controllers/AuthController.php#L88
public function register($request, $response, $args)
{
$ary = $request->getQueryParams();
$code = "";
if (isset($ary['code'])) {
$code = $ary['code'];
}
$requireEmailVerification = Config::get('emailVerifyEnabled');
return $this->view()->assign('code', $code)->assign('requireEmailVerification', $requireEmailVerification)->display('auth/register.tpl');
}
很明显直接把 code
输出到了页面上,
访问 http://victim.com/auth/register?code="><svg/onload=alert(1)>
即可触发:
但可惜登陆过的用户访问此页面时会被 302 直接跳转到 /user
页面,所以无法直接打 cookie。
一个思路是写个网页,先将已登陆用户登出,如插个不可见图片:<img src="http://victim.com/user/logout" visibility: hidden>
然后伪造登陆框截获用户名和密码。
其他可能存在 XSS 的地方还有 注册用户名
和 修改 Shadowsocks 密码
处,
另外修改 Shadowsocks 密码处还存在 CSRF
。
于是又有两个思路:
- 注册一个用户名为 XSS Payload 的账号,等管理员在后台查看用户信息时打他的 cookie。
- Self-XSS 加 CSRF,把用户的 Shadowsocks 密码改成攻击者的 XSS Payload,当他发现上不了网查看密码时中招。
关于 Smarty 的 XSS 问题,有两个解决办法:
- 使用 default_modifiers,如
$smarty->default_modifiers = array('escape:"htmlall"')
,会自动对所有变量进行 HTML 转义。 - 在模板中使用
{{$var|escape:"html"}}
。