XSS编码剖析
作者 0xExploit
0×00 引言
很多不了解html、js编码的童鞋挖掘xss漏洞时,都是一顿乱插,姿势对了,就能获得快感,姿势不对,就么反应。另外在freebuf里,有很多文章介绍过跨站编码,有兴趣的,可以搜索下。
本文介绍常见的编码方法,能力不足,如有其他意见,请指正。
0×01 常用编码
URL编码:一个百分号和该字符的ASCII编码所对应的2位十六进制数字,例如“/”的URL编码为%2F(一般大写,但不强求)
HTML实体编码:
命名实体:以&开头,分号结尾的,例如“<”的编码是“<”
字符编码:十进制、十六进制ASCII码或unicode字符编码,样式为“&#数值;”,例如“<”可以编码为“<”和“<”
JS编码:js提供了四种字符编码的策略,
1、三个八进制数字,如果不够个数,前面补0,例如“e”编码为“145”
2、两个十六进制数字,如果不够个数,前面补0,例如“e”编码为“x65”
3、四个十六进制数字,如果不够个数,前面补0,例如“e”编码为“u0065”
4、对于一些控制字符,使用特殊的C类型的转义风格(例如n和r)
CSS编码:用一个反斜线()后面跟1~6位的十六进制数字,例如e可以编码为“65”或“65”或“00065”
复合编码:
所谓复合编码,也就是说输出的内容输出在多个环境中,例如
<td onclick=”openUrl(add.do?userName=’<%=value%>’);”>11</td>
value的内容首先出现在一个URL中,这个URL在一段javascript总,而javascript代码又是html的一部分。所以解码的顺序就是HTML解码–>js解码–>url解码,那么正确的编码顺序就应该是url编码–>js编码–>html编码。
0×02基本概念
HTML解析器能识别在文本节点和参数值里的实体编码,并在内存里创建文档树的表现形式时,透明的对这些编码进行解码。
例如以下两种写法的功能是一样的(忽略里面的空格。。鄙视下这个编辑器):
<img src="http://www.example.com"><img src="ht&# x74;p://www.example.com">
而下面的两个例子,实际上却没法真的加载图片,因为这种编码干扰了标签本身的结构。
<img src&# x3d;"http://www.example.com"><img s&# x72;c="http://www.example.com">
下面了解下浏览器解析HTML的步骤:浏览器收到从服务器发送来的HTML内容,会从头解析,当遇到<script></script>时,会调用javascript脚本解析器解析javascript,并执行脚本,然后继续解析其他的HTML内容,对于一些需要触发才能执行的事件,当触发事件发送时,脚本解析器才会解析其中的脚本,在事件触发之前,它是HTML的一部分。
0×03实例剖析
3.1 HTML–>js编码
代码如下:
<?php
function htmlencode($str){
if(empty($str)) return;
if($str == "") return;
$str = str_ireplace("<","",$str);
$str = str_ireplace(">","",$str);
$str = str_ireplace("script","",$str);
$str = str_ireplace("img","",$str);
$str = str_ireplace(":","",$str);
$str = str_ireplace("javascript","",$str);
return $str;}
if(!array_key_exists ("name",$_GET) || $_GET['name'] == NULL || $_GET['name'] == ''){
$isempty = true;
} else {
$html .= '<pre>';
$html .= '<a onclick=" ' .htmlencode($_GET['name']).'">click this url</a>';
$html .= '</pre>'; }?>
<html><script> </script></html>
可以看到,过滤了尖角号,script等标签,当输入javascript:alert(/xss/)时,系统返回的为:
我们现在分析一下$name的环境,$name先在html环境中,然后在javascript环境(onclick事件)中,浏览器解析的顺序是html解码–>js解码,所以我们将javascript:alert(/xss/)进行html编码,从而可以绕过限制(当然此处代码还有其他好几种绕过的方式,此处只是简单说明编码问题),因为在javascript解码时,$name已经被html解码了,那么处在javascript中的$name变量就是正常的js代码。
源代码为:
3.2 js–>html编码
代码如下:
<?php
if(!array_key_exists ("name",$_GET) || $_GET['name'] == NULL || $_GET['name'] == ''){
$isempty = true; } else { $value = $_GET['name']; $html .= '<pre>'; $html .= "Your Name is :
<div id='a'></div>
<script>
document.getElementById('a').innerHTML= "."'".htmlspecialchars($value)."'".";
</script>
"; $html .= '</pre>'; } ?>
可以看到,$value使用了htmlspecialchars进行了编码,htmlspecialchars会对&、’、”、<、>进行html编码,当输入<img src=1 onerror=alert(/xss/)>时,系统不会弹框,因为特殊符号被html编码了。
我们现在分析下$value的环境,$value先在javascript中,然后在html环境中(通过innerHTML操作html),所以浏览器解码顺序为js解码–>html解码,所以我们可以对$value进行js编码,绕过htmlspecialchars限制,因为$value在html解码时,已经是正常的html代码了。
3.3 URL编码
此外,如果&等符号被过滤的话,可以对其进行URL编码,然后测试。
0×04 Tips:
1、DOM:只有使用合规的完整闭合的HTML区块对每个innerHTML节点进行赋值,因为这样才不会改变被重写段落之外的文档层级结构。如果格式不对,在重写发生之前输入的数据会先按照规定的语法进行强制转换。
即通过DOM操作HTML时,可以使用<script>alert(/xss/)来代替<script>alert(/xss/)</script>,因为DOM会自动补全。
2、innerHTML只能使用<img src=1onerror=alert(1)>这种方式来触发JS。而不能以<script>alert(1)</script>来触发,因为这种压根不会执行<script>..</script>之间的内容。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- struts2(一)---编写第一个struts2项目
- Struts2(二)---将页面表单中的数据提交给Action
- 03 . Shell数组和函数
- Shell百宝箱(后续会不断更新)
- 09 . Prometheus监控tomcat+jvm
- 09 . Kubernetes之pv、pvc及使用nfs网络存储应用
- 10 . Kubernetes之Configmap,Secret
- struts2(三)---使用EL表达式,显示Action中的数据
- 02 . 分布式存储之FastDFS 高可用集群部署
- 11 . KubernetesRBAC认证及ServiceAccount、Dashboard
- 12 . Kubernetes之Statefulset 和 Operator
- 01 . SaltStack部署配置及简单应用
- 02 . SaltStack高级用法(Python API)
- 小加载动画
- 日志收集工具简单对比