自上一篇博客介紹瀏覽器通信以來已經(jīng)過去將近兩個月了,兜兜轉轉挖了不少坑,也走了很多彎路。期間研究saml2.0和單點登錄等技術都最后無疾而終。
只有xss框架這部分堅持了下來,這個框架還有很多事情需要完善,不過總算是有了一點小成果,很開心~~~
代碼放到了這里對照著看效果更好
https://github.com/littleworldwar/pybeef

0x00web服務器設計

(1)tornado處理請求和Application類
要編寫一個Tornado應用中最多的工作是定義類繼承Tornado的RequestHandler類,主要用于將特定的url對應到不同的類。
通過在類中定義get和post函數(shù)處理對應的請求,self.write()用于將內(nèi)容輸出到返回流中。
self.render()將特定的文件內(nèi)容渲染后作為輸出,指定文件名即可。
self.get_argument()獲取請求的參數(shù)
self.set_header()設置HTTP返回頭
如果碰到復雜的服務器需求需要重寫Application類,在__init__函數(shù)中定義handlers和setting。Handlers主要是將所有的url路徑和對應的handler類對應起來,Setting中設置了template_path 設置模板路徑主要用于self.render()函數(shù)查找文件路徑。

(2)控制臺登錄設計
為了處理登錄表單和配置文件中的用戶名密碼進行校驗,先要定義一個LoginPageHandler類,處理登錄的post請求取出用戶名密碼等參數(shù),將參數(shù)與用configparser解析配置文件的數(shù)據(jù)進行對比,一致則通過認證。
同時還有cookie的設計為了在已經(jīng)登錄過的情況下直接使用get方法就能進入控制臺頁面。

(3)提供給受害瀏覽器執(zhí)行的js文件
處理xss漏洞產(chǎn)生的get請求,將hook.js作為請求的響應。同時生成32位隨機數(shù),在hook瀏覽器中設置cookie,設置hook_id作為hook瀏覽器的唯一標識。

(4)控制臺請求hook瀏覽器的數(shù)據(jù)
連接數(shù)據(jù)庫查詢?yōu)g覽器的數(shù)據(jù),使用pymongo模塊連接本地數(shù)據(jù)庫。
將信息組織成json結構,由于mongodb默認插入的_id值屬于Object不能放到輸入流中,我們刪除了_id這一項。并將這些信息按照順序標好。
由于控制臺使用AJAX跨域請求,需要設置返回頭Access-Control-Allow-Orign,將其設置為通配符* 也就是匹配一切地址。否則瀏覽器不能讀取返回的數(shù)據(jù)。

(5)hook瀏覽器的輪詢處理
Hook瀏覽器執(zhí)行了hook.js后臺post方法發(fā)送瀏覽器信息,同時要帶上在cookie中設置的hook_id來標識瀏覽器。要讓AJAX請求同時攜帶cookie,在后臺設置返回頭 Access-Control-Allow-Credentials為true。
將收集的信息存入數(shù)據(jù)庫,如果hook_id存在不會重復插入數(shù)據(jù)。

0x01hook瀏覽器的信息收集設計

(1)收集瀏覽器的user-agent(用戶代理)
瀏覽器的user-agent是瀏覽器的身份標識,簡稱UA。每次向服務器發(fā)出請求的時候都會在請求頭中帶上UA參數(shù)。例如 Mozilla/5.0 (X11; Linux x86_64;) Gecko/20100101 Firefox/45.0。包含了瀏覽器的版本,操作系統(tǒng)的類型,瀏覽器的渲染引擎等信息

(2)收集瀏覽器版本
即便在UA中可以獲取到部分瀏覽器的版本,但是UA是可以人為修改的,判斷瀏覽器版本不能全依賴UA。而且例如IE edge瀏覽器的UA是 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393??梢钥闯銎渲型瑯影薈hrome和Safari瀏覽器的信息,依靠UA并不能準確判斷瀏覽器版本。瀏覽器中一般擴展了自己獨特的方法,例如window.chrome window.opera這種與瀏覽器相關性很強的特性 。利用這樣的特性可以幫助我們縮小范圍。跟蹤瀏覽器每一個版本的更新特性,在判斷的時候甚至可以脫離UA。在判斷IE瀏覽器的時候完全沒有借助UA,只是將各種特性合在一起判斷瀏覽器版本。

(3)獲取受害者的ip地址和內(nèi)網(wǎng)地址
我們采用了webrtc技術,webrtc是一種用于方便創(chuàng)建在線聊天web應用的技術,被內(nèi)置在Firefox和Chrome瀏覽器中。webRTC(Web Real-Time Communications)是一種讓web應用和網(wǎng)站在瀏覽器之間交換數(shù)據(jù)的技術,建立了一系列的標準可以實現(xiàn)點對點的數(shù)據(jù)交換不需要用戶安裝插件或者其他第三方應用。要想讓兩個瀏覽器通信就要獲取真實的ip地址,我們只用這一部分的技術。

1, 首先判斷瀏覽器是否支持webrtc
!!window.mozRTCPeerConnection || !!window.webkitRTCPeerConnection

2,webrtc的接口介紹:
RTCPeerConnection
表示一個在本地電腦和外部節(jié)點的WebRTC連接,用于處理節(jié)點間的數(shù)據(jù)流

RTCIceCandidate
表示一個為了創(chuàng)建節(jié)點連接的服務器

rtc.onicecandidate = eventHandler;
指定一個函數(shù)當rtc中出現(xiàn)icecandidate事件時響應當本地的ICE客戶端需要通過信號服務器給另一個節(jié)點發(fā)送信息時。需要ICE客戶端和遠程節(jié)點協(xié)商,瀏覽器不知道信號如何處理,簡單使用這個方法將ice證書發(fā)送給遠程節(jié)點

rtc.createOffer(successCallBack,errorCallBack[,options])
初始創(chuàng)建一個sdp offer 包含了 ICEagent已經(jīng)收集到的candidate 用于信道內(nèi)發(fā)送請求連接或者升級已存在鏈接的配置successCallback 將會傳遞一個RTCSessionDescription對象描述新建的offer

sdp (session describe procotol) 會話描述協(xié)議,是描述點對點連接標準,sdp包含編碼,源地址,和視頻語音的時間。Sdp信息就包含在RTCSessionDescription中,RTCSessionDescription.sdp取得sdp。

rtc.setLocalDescription(sessionDescription)方法 改變本地連接的描述信息正在運行的連接會改變
圖4代表探測出的相關sdp信息,再利用正則表達式過濾出ip地址即可。

電腦培訓,計算機培訓,平面設計培訓,網(wǎng)頁設計培訓,美工培訓,Web培訓,Web前端開發(fā)培訓

0x03控制臺頁面的設計

在控制臺頁面中主要是顯示收集的信息,采用的樹形結構使用了ztree框架顯示受控的主機瀏覽器同時用其第一個ip地址來作為特征標識。為了頁面的美觀采用了bootstrap3這一款css框架,主要是通過對常見的html元素添加標簽來改變頁面的樣式。Ztree框架同樣用json數(shù)據(jù)來定義樹形文檔,面對的主要需求是點擊樹中的不同瀏覽器要動態(tài)改變頁面的內(nèi)容,顯示與之對應的信息。
主要思路就是使用AJAX請求將節(jié)點部分的信息替換成收集的瀏覽器信息,因為得到的是json數(shù)據(jù)這里我們采用Jquery庫中的
$.getJSON(url,function(data))
前一個參數(shù)代表請求的地址,后一個參數(shù)是一個處理得到的數(shù)據(jù)的函數(shù),其中data就存儲著返回的數(shù)據(jù)。所以我們把所有關于ztree的操作都放在這個函數(shù)中。
定義樹形結構json 定義zTreeNodes name 是要顯示的名字,open 代表初始狀態(tài)是打開的 children 代表下面的節(jié)點部分 定義在[]框中可以定義多個。

        zTreeNodes =[
            {"name":"online",open:true, children:[//              { "name":data.hook0.host, "url":"http://g.cn", "target":"_blank"},
                ]
            }
        ];

使用得到的data數(shù)據(jù)向tree中添加節(jié)點,將hook+i 設為了treeId 是為了在onclick回調(diào)函數(shù)中繼續(xù)操作data

        for(var i=0;i<JSONLength(data);i++){
    zTreeNodes[0].children.push({"name":data["hook"+String(i)].IP.split(" or ")[0],                "url":"","treeId":"hook"+String(i),
            });
        }

在ztree框架可以捕捉各種樣式的瀏覽器事件,我們要響應單擊這個事件并制定對應的回調(diào)函數(shù)處理單擊事件。

            callback:{                onClick: zTreeOnClick
            },

接著定義zTreeOnClick函數(shù),這個函數(shù)傳遞了三個變量我們只用到了treeNode

function zTreeOnClick(event, treeId, treeNode) {
TreeNode就是瀏覽器節(jié)點信息
要在這個函數(shù)中改變頁面的信息,使用Jquery選擇器動態(tài)改變頁面信息例如,
$("#ua").html(data[treeNode.treeId].ua);
選擇id為ua的元素改變其中的html,treeNode后的treeId不是函數(shù)的參數(shù)而是在節(jié)點中定義的treeId 值為hook+數(shù)字。
電腦培訓,計算機培訓,平面設計培訓,網(wǎng)頁設計培訓,美工培訓,Web培訓,Web前端開發(fā)培訓

0x04網(wǎng)絡拓補圖的動態(tài)繪制設計

這一塊沒有使用框架,只是利用html5的canvas標簽大致畫了一個拓補圖,展示一下hook瀏覽器所處的網(wǎng)絡環(huán)境。我們在外部定義了兩個點(point_x,point_y)表示畫筆所在的位置,例如畫了一張圖片以后將點的位置移動到接下來劃線的開始位置,同理劃線之后也一樣。但是在畫分支的時候我們提取了分支點的坐標,讓每一個分支都從同一點出發(fā)。
Canvas畫圖只有等到頁面渲染完會使用到指定的canvas標簽,否則會出現(xiàn)找不到canvas標簽的錯誤,所以我們將所有操作放在以下函數(shù)中 代表所有dom結構渲染完畢后需要進行的操作。
$(document).ready(function(){
先要指定標簽,并取得context(上下文)context指定畫圖的形式為2d

        var canvas_tag =document.getElementById("net_map");        var ctx = canvas_tag.getContext("2d");

基本的canvas操作:
添加圖片操作 :drawImage函數(shù)中pic是圖片元素,start_pic_x,y是開始節(jié)點的坐標,后兩個是圖片的寬和高

            var pic =new Image();
            pic.src ="static/img/"+pic_name;
            pic.onload =function(){
                ctx.drawImage(pic,start_pic_x,start_pic_y,50,50);
            }

添加文字操作:font設置文字大小和字體,textAlign設置文字對齊方式 fillText(字符串)

                ctx.font ="12px sans-serif";
                ctx.textAlign ="start";
                ctx.fillText(text,start_pic_x,start_pic_y+62);

劃線操作:moveTo代表移動光標,lineTo則是劃線到目標點,stroke代表正式將線畫在上面,如果缺失就沒有線段。

            ctx.beginPath();            ctx.moveTo(start_line_x,start_line_y);            ctx.lineTo(start_line_x+80,end_line_y);            ctx.stroke();



標簽: xsspython安全工具