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)> 即可触发:

sp170301_104241.png

但可惜登陆过的用户访问此页面时会被 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 问题,有两个解决办法:

  1. 使用 default_modifiers,如 $smarty->default_modifiers = array('escape:"htmlall"'),会自动对所有变量进行 HTML 转义。
  2. 在模板中使用 {{$var|escape:"html"}}