<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/11009

            http://thisissecurity.net/2015/11/23/hackers-do-the-haka-part-1/

            Haka是一種開源的以網絡安全為導向的語言,可以用于編寫安全規則和協議剝離器。在這一部分中,我們的重點是編寫安全規則。

            0x00 什么是Haka


            Haka是一種開源的以網絡安全為導向的語言,可以在捕捉到的活動流量上指定和應用安全策略。Haka基于Lua。這是一種簡單、輕量(~200 kB)且快速的(有一個可用的JiT編譯器)腳本語言。

            Haka的使用范圍有兩種。首先,Haka能允許指定安全規則來過濾掉不想要的流并報告惡意活動。Haka提供了一個簡單的API用于操作高級數據包和流。用戶可以投放數據包,或創建新的數據包,并注入數據包。Haka還支持修改運行中的數據包。這是Haka的主要功能之一,因為用戶可以看到所有的復雜任務,比如調整數據包的大小,設置正確的序列號。這些都是現場完成的,根本不需要代理。

            其次,Haka還附帶有一種語法,允許協議規范及其底層的狀態機。Haka支持兩種類型的協議:基于二進制的協議(如,dns)和基于文本的協議(如,http)。這種規范包括了基于數據包的協議(如ip)以及基于流的協議(如http)。

            Haka內嵌到了一個模塊化框架中,其中包括幾個數據包捕捉模塊(pcap, nfqueue),能允許終端用戶在實時捕捉到的流量上應用自己的安全策略,或者是在一個數據包跟蹤文件上重現這個安全策略。這個框架還提供了記錄(syslog)和報警模塊(syslog,elasticsearch)。報警遵循了一種類似IDMED的格式。最后,這個框架還具有附屬模塊,比如模式匹配引擎和一個指令反匯編模塊。這些模塊允許編寫精密的安全規則來檢測經過混淆的木馬。因為Haka是按照模塊方式設計的,所以用戶可以通過額外的模塊來擴展其功能。

            p1

            0x01 Haka工具套件


            Haka提供了一個包含有4個工具的套件:

            p2

            p3

            0x02 編寫安全規則


            Haka提供了一種簡單的方式來編寫安全規則,從而過濾,修改,創建,注入數據包和流。當檢測到一個惡意流后,用戶可以報告一個警報或放棄這個流。用戶可以定義更多復雜的方案來應對某次攻擊所造成的影響。例如,用戶可以報警http請求,強制舊版瀏覽器更新或偽造特定的數據包來欺騙端口掃描工具。

            0x03 數據包過濾


            下面的這個規則是一個基礎的數據包過濾規則,能夠攔截所有到某個網絡地址的連接。

            local ipv4 = require("protocol/ipv4")
            local tcp = require("protocol/tcp_connection")  
            
            local net = ipv4.network("192.168.101.0/24")    
            
            haka.rule{
                hook = tcp.events.new_connection,
                eval = function (flow, pkt)
                    haka.log("tcp connection %s:%i -> %s:%i",
                        flow.srcip, flow.srcport,
                        flow.dstip, flow.dstport)   
            
                    if net:contains(flow.dstip) then
                        haka.alert{
                            severity = "low",
                            description = "connection refused",
                            start_time = pkt.ip.raw.timestamp
                        }
                        flow:drop()
                    end
                end
            }
            

            第一行會加載需要的協議剝離器,也就是ipv4和tcp連接剝離器。前者是處理ipv4數據包。后者是一個狀態性的tcp剝離器,這個剝離器會維持一個連接表并管理tcp流。下一行,定義了必須要攔截的網絡地址。

            這種安全規則是通過haka.rule關鍵字定義的。一個安全規則由一個hook和一個評估函數eval組成。這個hook是一個會觸發安全規則評估的事件。在這個例子中,在每次嘗試創建一個tcp連接時,這個安全規則就會被評估。傳遞到評估函數的參數會根據事件來確定。以new_connection事件為例,eval會獲取兩個參數:flow和pkt。第一個參數中會有關于連接的詳細信息,另一個參數一個包含有所有tcp(以及下層)數據包字段的表。

            在安全規則的核心中,我們首先記錄(haka.log)了一些關于當前連接的信息。然后,我們檢查了源地址是否屬于先前定義的非授權IP地址范圍。如果測試成功,我們就會發出警報(haka.alert)并放棄連接。注意,我們只在警報中報告了少量的一些細節。用戶可以添加更多信息,比如來源和目標服務。

            我們使用hakapcap工具在一個pcap追蹤文件filter.pcap上,測試了我們的規則filter.lua

            $ hakapcap filter.lua filter.pcap
            

            從這里往下就是Haka的輸出,Haka轉儲了一些關于已加載剝離器和已注冊規則的信息。這個輸出顯示Haka成功攔截了目標地址192.168.101.62的連接:

            p4

            在上面的例子中,我們已經定義了一個單獨的規則來攔截連接。用戶可以用關鍵字haka.group寫一個類似于防火墻一樣的完整規則集。以這個配置為例,如果沒有任何安全規則能認證流量,用戶可以選擇一種默認行為(如攔截所有的連接)。

            0x04 數據包注入


            在Haka中,用戶可以創建新的數據包并注入這些數據包。下面的這個規則會制作一個RST數據包,用于欺騙Xmas nmap掃描。最終,nmap會認為目標端上的所有端口都是關閉的。

            raw = require("protocol/raw")
            ipv4 = require("protocol/ipv4")
            tcp = require("protocol/tcp")
            
            haka.rule {
                hook = tcp.events.receive_packet,
                eval = function(pkt)
                    local flags = pkt.flags
                    -- test for xmas nmap scans
                    if flags.fin and flags.psh and flags.urg then
                        -- raw packet
                        local rstpkt = raw.create()
            
                        -- ip packet
                        rstpkt = ipv4.create(rstpkt)
                        rstpkt.ttl = pkt.ip.ttl
                        rstpkt.dst = pkt.ip.src
                        rstpkt.src = pkt.ip.dst
            
                        -- tcp packet
                        rstpkt = tcp.create(rstpkt)
                        rstpkt.srcport = pkt.dstport
                        rstpkt.dstport = pkt.srcport
                        rstpkt.flags.rst = true
                        rstpkt.flags.ack = true
                        rstpkt.ack_seq = pkt.seq + 1
            
                        -- inject forged packet and
                        -- drop malicious scanning packet
                        rstpkt:send()
                        pkt:drop()
                    end
                end
            }
            

            0x05 數據包警報


            數據包修改是Haka中最高級的功能之一。Haka會在流和數據包層級上自動處理所有的內部修改:重新設置數據包大小和分段,重置序列號等。下面的例子證明了訪問和修改協議字段有多么容易。這個規則會修改一些http協議的標頭。更準確的說, user-agent標頭會被修改(如果沒有設置,添加至標頭列表),并移除accept-encoding標頭。

            local http = require("protocol/http")
            
            http.install_tcp_rule(80)
            
            haka.rule{
                hook = http.events.request,
                eval = function (flow, request)
                    request.headers["User-Agent"] = "HAKA User Agent"
                    request.headers["Accept-Encoding"] = nil
                end
            }
            

            blurring-the-webinject_ponies是非常有意思的腳本,會通過修改http響應流量來分別模糊和污染(注入垃圾)被請求的web頁面:

            p5

            0x06 流過濾


            在講解流過濾前,我們首先要說明的是Haka如何在內部管理數據包和流。在Haka中,所有的數據包和流都會用虛擬緩沖區(見下圖)來表示。虛擬緩沖區是一種非相鄰內存塊的統一視圖。這些虛擬緩沖區能允許簡單和有效的修改內存數據。虛擬緩沖區使用分散列表來表示非相鄰數據塊,避免分配和復制不必要的內存塊。Haka提供了迭代器來導航通過這些內存塊。這些迭代器可以通過攔截讓停用一些函數,然后,比如當流上有更多可用的數據時,透明地恢復這些函數的執行。

            p6

            下面的規則會收集http流,并在stdout上轉儲這些流。這個規則等同于Wireshark的follow tcp stream”功能。

            local ipv4 = require('protocol/ipv4')
            local tcp_connection = require('protocol/tcp_connection')
            
            haka.rule{
                hook = tcp_connection.events.receive_data,
                    options = {
                        streamed = true
                    },
                eval = function (flow, iter, dir)
                    local data = flow.ccdata or {}
                    flow.ccdata = data
            
                    while iter:wait() do
                        data[#data+1] = iter:sub('available'):asstring()
                    end
                    haka.log("%s -> %s:\n", flow.srcip, flow.dstip)
                    io.write(table.concat(data))
                 end
            }
            

            0x07 交互式數據包過濾


            這是我最喜歡的Haka功能。這個功能允許檢查每個數據包的流量包。下面的規則會提示每個HTTP POST請求。

            local http = require("protocol/http")
            
            http.install_tcp_rule(80)
            
            haka.rule {
                hook = http.events.request_data,
                eval = function (http, data)
                    haka.interactive_rule("interactive mode")(http, data)
                end
            }
            
            haka.rule {
                hook = http.events.request,
                eval = function (http, request)
                    http:enable_data_modification()
                end
            }
            

            這個shell能夠提供到完整Haka API的訪問,以便處理數據包內容:讀寫和修改數據包字段,刪除數據包,記錄可疑的事件,警告等。Lua控制板支持自動補齊,因此,是深入Haka API的一個好的開始。

            在下面的數據中,Haka會破解第一個POST請求。HTTP數據可以通過可用的輸入來獲取。在這個例子中,我們在運行中修改了用戶憑據。

            p7

            注意,最好在pcap文件上使用交互規則,因為修改會造成額外的延遲。

            0x08 高級流過濾


            Haka還有一個模式匹配引擎和一些反匯編模塊。這兩個模塊都是基于流的模塊,能讓我們檢測到分散在多個數據包中的惡意有效載荷。下面的規則使用了一個常規表達來檢測nop sled。我們啟用了流選項,也就是說,匹配函數會攔截和等待可用的數據來進行匹配。如果檢測到nop sled,我們就會發出警告,并轉儲shellcode指令。注意,模式匹配函數會更新迭代器的位置,之后會指向shellcode。

            local tcp = require("protocol/tcp_connection")
            
            local rem = require("regexp/pcre")
            local re = rem.re:compile("%x90{100,}")
            
            local asm = require("misc/asm")
            local dasm = asm.new_disassembler("x86", "32")
            
            haka.rule{
                hook = tcp.events.receive_data,
                    options = {
                        streamed = true,
                },
                eval = function (flow, iter, direction)
                    if re:match(iter, false) then
                        -- raise an alert
                        haka.alert{
                            description = "nop sled detected",
                        }
                        -- dump instructions following nop sled
                        dasm:dump_instructions(iter)
                    end
                end
            }
            

            我們在著名的網絡分析挑戰上重播了這條規則,并得到了下面的輸出。關于網絡流量反匯編為指令的詳細信息都可以在這里獲得。

            p8

            未完待續…

            0x09 鏈接


            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线