概述
冰蠍是一款新型動態二進制加密網站工具。目前已經有6個版本。對於webshell的網絡流量側檢測,主要有三個思路。一:webshell上傳過程中文件還原進行樣本分析,檢測靜態文件是否報毒。二:webshell上線或建立連接過程的數據通信流量。三:webshell已連接后執行遠程控制命令過程的數據通信流量。本文通過分析多個歷史冰蠍版本及五種腳本(asp|aspx|jsp|jspx|php),結合第二點檢測冰蠍上線的靜態特征,並總結部分snort規則。
冰蠍通訊原理
冰蠍采用AES加密,很多文章已有介紹,並有對應解密腳本,這里不再贅述。
冰蠍上線數據包
V1.0版本冰蠍連接
抓取到的通信流量如下:
Content-Type: application/octet-stream表示以二進制流傳輸數據。GET請求體返回16位大小寫字母或數字。
V1.1版本冰蠍連接
冰蠍工具從V1.1開始(包含V1.1)新增隨機UserAgent支持,每次會話會從17種常見UserAgent中隨機選取。這個版本的pass 與其他版本不同,pass(密碼) 后跟10位數字。
V2.0.1版本冰蠍連接
php shell上線數據包
asp shell 上線數據包
特殊的數據包
特殊包類型一
僅在php shell 上線時發現。測試版本 V2.0和V2.0.1
php shell上線時會產生兩個POST請求和響應。第一個POST 響應無響應體,第二個POST響應有響應體。這里需要額外寫snort判斷。用flowbits 設置多包聯合檢測。
第一個POST響應
第二個POST響應
特殊包類型二
有兩條很久以前抓的冰蠍包,寫的snort一直匹配不上,忘了是哪個版本。仔細一看,居然沒有Content-Length字段。php shell 上線,GET響應居然無強特征 ”Content-Length: 16,查資料說如果是 chunked 加密的,可能就不顯示這個content-length字段了。這個特殊類型我選擇性忽視。
下面也是php GET響應 無強特征 “Content-Length: 16″,看上去多了幾個字符,是顯示的問題,其實並沒有多。
靜態特征
弱特征1:密鑰傳遞時URL參數
"\.(php|jsp|asp|jspx|aspx)\?\w{1,8}=\d{1,10}HTTP/1\.1"
這里 \w{1,8} 表示密碼的長度,可根據實際需求及探針性能調整。\d{1,10} 表示密碼后面跟的數字長度,為了兼容V1.0和V1.1,用1-10。如果只檢測V2.1版本,可以調整為 \d{2,3}。
弱特征2:加密時的URL參數
在加密通訊過程中,沒有URL參數。是的,沒有參數本身也是一種特征。
"\.(php|jsp|asp|jspx|aspx) HTTP/1.1"
本文暫未使用此特征。
強特征3:Accept字段(可繞過)
Accept是HTTP協議常用的字段,但冰蠍默認Accept字段的值卻很特殊,這個特征存在於冰蠍的任何一個通訊階段。
Accept: text/html,image/gif, image/jpeg, *; q=.2, */*;q=.2
冰蠍支持自定義HTTP Header,因此該特征可以被繞過。
可以針對此特征做專門的檢測,因為大多數人都沒有修改Accept 習慣。
本文暫未使用此特征。
強特征4:UserAgent字段(可繞過)
冰蠍工具從V1.1開始(包含V1.1)新增隨機UserAgent支持,每次會話會從17種常見(較老)UserAgent中隨機選取。
如果發現歷史流量中同一個源IP訪問某個URL時,命中了以下列表(下載地址)中多個UserAgent,那基本確認就是冰蠍了。
大多數人都沒有修改Accept 習慣。但冰蠍支持自定義UA,該特征可以被繞過。
本文暫未使用此特征。
強特征5:傳遞的密鑰
加密所用密鑰是長度為16的隨機字符串,大小寫字母+數字組成。密鑰傳遞階段,密鑰存在於get請求的響應體中。需要划重點的是,不管哪種冰蠍腳本的shell,上線過程客戶端都是要與服務器商量2次密碼的,也就是會發2個get請求,並返回2次 16位的key。
因此密鑰特征如下:
"\r\n\r\n[A-Za-z0-9]{16}$"
還有一個特征,get請求響應體長度一定是16位的。
"Content-Length: 16"
弱特征6:加密數據上行
jsp|php|jspx 加密數據上行特征如下:
“\r\n\r\n[a-zA-Z\d\+\/]{10,}\/[a-zA-Z\d\/]{50}"
數字50表示至少出現50字符才匹配,可根據IDS設備實際情況及需求調整。
jsp加密流量上行
php加密流量上行
jspx加密流量上行
aspx 加密上行流量獨有。為減少誤報,建議檢查加密上行和下行,此特征同樣適用aspx加密流量下行。
數據包中的 “.” 其實是不可見字符。
”[^\w\s><=\-'"\:\;\,\!\(\)\{\}]”
asp加密流量上行
aspx加密流量上行
弱特征7:加密數據下行
jsp加密流量下行
" [^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}"
[^\w\s><=\-'"\:\;\,\!\(\)\{\}] 表示不可見字符
[\w]{2} 表示特殊符號前至少有2個字符,經過大量對比分析,發現可以匹配的字符串例如:
“不可見字符”+”VO?ES”
“不可見字符”+”Fl#fB”
“不可見字符”+”9w+rv”
“不可見字符”+”6G/SW”
“不可見字符”+”mN]ss”
“不可見字符”+”ss[ss”
“不可見字符”+”gV|05”
“不可見字符”+”Iz\8o”
......
且返回狀態碼 200 OK
另外對於 php|jsp|asp|aspx,響應的Type特征還有
"Content-Type: text/html"
jspx稍有特殊。
jspx加密流量下行
"Content-Type:text/xml"
弱特征8:長連接(可繞過)
冰蠍通訊默認使用長連接,避免了頻繁的握手造成的資源開銷。因此默認情況下,請求頭和響應頭里都會帶有:
Connection: Keep-Alive
這個特征存在於冰蠍的任何一個通訊階段。
本文暫未使用此特征。
冰蠍snort規則檢測思路
一.從建立連接的第一個GET請求的響應體開始檢測,
1.響應體必chujian0定為16位大小寫字母或數字,
2.返回狀態碼200 OK
可以作為IDS的入口正則,防止接入過多流量影響IDS性能。
二.之后檢測第二個GET請求,
1.滿足上面提取的GET請求弱特征
三.檢測第二個GET響應體特征,特征與步驟一一致,但應滿足遞進關系。
四.這里分為2種情況,
第一種情況,
1.檢測POST請求通用特征
2.檢測POST響應特征,匹配到則判定為冰蠍 asp|jsp|aspx|php 上線。
第二種情況(不滿足第一種情況),
1.檢測POST請求 jspx 特征
2.檢測POST響應 jspx 特征
冰蠍snort規則總結
綜上
alert http any any -> any any(msg:"MALWARE-BACKDOOR Behinder webshell online detected"; flow:established,to_client; pcre: "/\r\n\r\n[A-Za-z0-9]{16}$/”; content:”200 OK”; content: “Content-Length: 16″; fast_pattern;nocase; flowbits: set, bx_first_get_resp; noalert; classtype:web-attack;sid:3000021; rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)
alert http any any -> any any(msg:”MALWARE-BACKDOOR Behinder webshell online detected”; flow:established,to_server; content:”GET”; http_method; pcre:”/\.(php|jsp|asp|jspx|aspx)\?\w{1,8}=\d{1,10} HTTP/1\.1/”;flowbits:isset, bx_first_get_resp; flowbits:set, bx_second_get_req; noalert;classtype:web-attack; sid:3000022; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)
alert http any any -> any any(msg:”MALWARE-BACKDOOR Behinder webshell online detected”; flow:established,to_client; pcre: “/\r\n\r\n[A-Za-z0-9]{16}$/”; content:”Content-Length: 16″; fast_pattern; nocase; flowbits: isset,bx_second_get_req; flowbits:set, bx_second_get_resp; noalert;classtype:web-attack; sid:3000023; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)
alert http any any -> any any(msg:”MALWARE-BACKDOOR Behinder webshell online detected”; flow:established,to_server; content:”POST”; http_method; pcre:”/\.(php|jsp|asp|jspx|aspx) HTTP/1\.1/”; flowbits:isset, bx_second_get_resp;flowbits:set, bx_first_post_req; noalert; classtype:web-attack; sid:3000024;rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)
alert http any any -> any any(msg:”MALWARE-BACKDOOR Behinder webshell online detected”; flow:established,to_client; pcre: “/[^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}/”;content: “200 OK”; content: “Content-Type: text/html”;flowbits: isset, bx_first_post_req; classtype:web-attack; sid:3000025; rev:1;metadata:created_at 2019_11_20, updated_at 2019_11_20;)
alert http any any -> any any(msg:”MALWARE-BACKDOOR Behinder webshell-jspx online”; flow:established,to_server; pcre:”/\r\n\r\n[a-zA-Z\d\+\/]{10,}\/[a-zA-Z\d\/]{50}/”; content:”Content-Type: application/octet-stream”; fast_pattern; flowbits:isset, bx_second_get_resp; flowbits: set, bx_req_jspx; noalert;classtype:web-attack; sid:3000026; rev:1; metadata:created_at 2019_11_20,updated_at 2019_11_20;)
alert http any any -> any any(msg:”MALWARE-BACKDOOR Behinder webshell-jspx online”; flow:established,to_client; pcre:”/[^\w\s><=\-'"\:\;\,\!\(\)\{\}][\w]{2}[^\w\s><=\-'"\.\:\;\,\!\(\)\{\}][a-zA-Z\d]{2}/”;content: “200 OK”; content: “Content-Type: text/xml”;fast_pattern; flowbits: isset, bx_req_jspx; classtype:web-attack; sid:3000027;rev:1; metadata:created_at 2019_11_20, updated_at 2019_11_20;)