看了@jinglingshu同学的利用asp/asp.net+IIS特性绕过防注入后,就一时兴起,看了他的防XSS的正则。下一面引用其中的核心部分代码:
$getfilter = "<[^>]*?=[^>]*?&#[^>]*?>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\()|[^>]*?\\b(onerror|onmousemove|onload|onclick|onmouseover)\\b[^>]*?>|^\\+\\/v(8|9)|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
先不透剧。先来试试看吧……首先,我们试着插入一个不会触发过滤规则的标签,像”<img src=x>”(如下图)
没有任何问题。因为在我们的query当中并没有出现黑名单成员。然后我们再试一下我们熟悉的”<img src=x onerror=write(1)>”(如下图)
和预料的一样我们被拦截了。问题出在哪儿了呢?从那一坨儿正则当中我们不难看出问题出现在了”>”上。因为程序员明白一个没有闭合的标签是不可能被 执行的。所以他在这里就机智了一把。说只要在”>”之前出现黑名单成员我们就干掉它。但是事情真的会像程序员想像的那样去发展么?在这里,让我们来 回顾一下在HTML的世界里尖括号是怎么配对的。写一段简单的代码:
<html> <body> <img src=www.baidu.com/1.jpg> </body> </html>
以上述代码中的<img为例,这个”<“会从当前位置向后查找离它最近的”>”来进行配对,这样一来在经过尖括号的配对 后,<img src=www.baidu.com/1.jpg>就成了一个完整的标签。那如果我们插入的标签没有闭合会怎样呢?比如说我们插入的是”< img src=x onerror=write(1)”,他就会变成:
<html> <body> <img src=x onerror=write(1)</body> </html>
和上面叙述的一样<img里面的”<“继续寻找当前位置向后离它最近的”>”来闭合这个标签,结果发现在body后面正好有一个”>”,结果就变成了:
<img src=”x” onerror=”write(1)</body”>
what??是的,我们的标签被闭合了。不过似乎有多余的东西参杂到了onerror里面来。需要我们去解决掉耍流氓的”</body”。一般有下面几种解决方案:
(1)注释掉后面的部分
<img src="x" onerror="write(1);//</body">
(2)把onerror的内容用双引号括起来
<img src="x" onerror="write(1)"</body>
(3)把onerror的内容用单引号括起来
<img src="x" onerror=‘write(1)’</body>
可以看到第一种方法的成本是会浪费三个字符”;//”。第二种第三种的方法会浪费2个字符(两个单引号或两个双引号)。这对于XSS来说明显太奢侈。那怎 么办呢?还记得属性和属性是怎么分开的么?对,用空格!所以我们只要在write(1)后面加上一个空格,那么”</body”就会被认为是属性名 称。这样我们就可以以一个字符的成本来解决这个问题了。最后我们的payload就会像这样:
<img src=x onerror=write(1)%20
再来试试看吧?
呵呵,我们绕过去了。是不是很简单呢?
ps:作者利用了未闭合的标签浏览器解析时会想办法闭合的思路成功绕过了360webscan,思路很好。同时学习到除了alert、prompt还可以用write来测试跨站。不明白的是:
<img src=x onerror=write(/bypass/) </body>
和代码
<img src=x onerror=write(/bypass/.source) </body>
有什么区别,.source的作用是什么?
转载请注明:jinglingshu的博客 » 绕过360webscan继续XSS