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個工具的套件:

  • haka.這是工具集中的主程序。這是一個守護進程,用于監控后臺中的數據包。Haka會根據指定的安全策略文件來分析和過濾這些數據包。例如,下面的配置樣本會要求Haka使用nfqueue模塊從接口eth0中捕捉數據包,并使用策略文件myrules.lua過濾這些數據包。這個腳本通常會加載用戶定義或內置的協議剝離器,并定義一系列的安全規則。另外,用戶可以選擇報警和報告模塊并設置一些特定的模塊選項:

    [general]
    # Select the haka configuration file to use
    configuration = "myrules.lua"
    
    # Optionally select the number of thread to use
    # By default, all system thread will be used
    #thread = 4
    
    [packet]
    # Select the capture model, nfqueue or pcap
    module = "packet/nfqueue"
    
    # Select the interfaces to listen to
    #interfaces = "any"
    interfaces = "eth0"
    
    # Select packet dumping for nfqueue
    #dump = yes
    #dump_input = "/tmp/input.pcap"
    #dump_output = "/tmp/output.pcap"
    
    [log]
    # Select the log module
    module = "log/syslog"
    
    # Set the default logging level
    #level = "info,packet=debug"
    
    [alert]
    # Select the alert module
    module = "alert/syslog"
    #module = "alert/file"
    #module = "alert/elasticsearch"
    
    # Disable alert on standard output
    #alert_on_stdout = no
    
  • hakactl. 這個工具允許控制一個運行的Haka守護進程。用戶可以實時分析捕捉到的數據包,檢查日志或簡單地關停/重啟守護進程。

  • hakapcap. 這個工具允許使用pcap模塊在數據包捕捉跟蹤上離線重現一個策略文件。例如,這樣對執行網絡分析非常有用。

  • hakabana.這個工具允許使用Kibana 和 Elasticsearch實時地可視化和監控網絡流量。Hakabana由一系列的自定義安全規則組成,這些規則會把流量信息通過Haka推送到一個elastisserach服務器,并讓這些流量能通過Kibana控制面板獲取到。另外一個控制板也可以可視化Haka警報。

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 鏈接


您的支持將鼓勵我們繼續創作!

[微信] 掃描二維碼打賞

[支付寶] 掃描二維碼打賞