二開背景suricata是一款高性能的開源網絡入侵檢測防禦引擎,旨在檢測、預防和應對網絡中的惡意活動和攻擊。 suricata引擎使用多線程技術,能夠快速、準確地分析網絡流量並識別潛在的安全威脅,是眾多IDS和IPS廠商的底層規則檢測模塊。
前段時間搭了個suricata引擎播包測試流量規則,發現原生的suricata引擎並不能獲取規則匹配的位置、命中的字符串等信息。因suricata引擎並不會輸出命中的信息,遂修改源碼,改了命中詳情(下文簡稱高亮)出來,今天想跟大家分享一下修改和使用的過程。
1、suricat編譯安裝參考官方文檔https://docs.suricata.io/en/suricata-6.0.0/install.html#install-advanced
先裝庫,裝rust支持,裝make
然後下載源碼make
編譯後的二進製程序在/src/.libs/suricata查看依賴庫,然後補齊到默認so庫目錄中即可運行。
2、vscode+gdb調試suricata環境搭建然後就是裝插件,除了必備的c語言插件全家桶之外還需要裝GDB Debug這個插件。
接著任意新建一個運行配置。
修改lauch.json為:
{ //Use IntelliSense to learn about possible attributes. //Hover to view descriptions of existing attributes. //For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 'version': '0.2.0', 'configurations': [ { 'name': '(gdb) Launch', 'type': 'cppdbg', 'request': 'launch', 'program': '${fileDirname}/./src/.libs/suricata', //以下為監聽網卡模式。 //'args': [ //'-i', 'ens33', '-c', '/home/lalala/Desktop/suricata/6/suricata.yaml', '-v', '-l','/home/lalala/Desktop/suricata/6/log6/','--runmode', 'single' //], //以下為讀包模式。 'args': [ '-r', '/home/lalala/Desktop/suricata/6/6-27/48040.pcap', '-c', '/home/lalala/Desktop/suricata/6/suricata.yaml', '-v', '-l','/home/lalala/Desktop/suricata/6/log6/','--runmode', 'single' ], 'stopAtEntry': true, 'cwd': '${fileDirname}', 'environment': [], 'externalConsole': false, 'MIMode': 'gdb', 'setupCommands': [ { 'description': 'Enable pretty-printing for gdb', 'text': '-enable-pretty-printing', 'ignoreFailures': true }, { 'description': 'Set Disassembly Flavor to Intel', 'text': '-gdb-set disassembly-flavor intel', 'ignoreFailures': true } ] }, ]}選擇配置好的配置運行,看到斷在入口,調試環境完成。
3、suricata流程分析,尋找關鍵位置流程過於復雜,簡單理解就是匹配和記錄日誌的地方是分在不同線程,但是又有結構體可以從匹配帶到那裡。
4、關鍵位置代碼分析,獲取高亮內容根據流程,在初始化後慢慢摸索找到關鍵函數DetectEngineContentInspection
smd為傳入規則,根據type的不同走不同的代碼塊兒匹配。本次加高亮重點關注CONTENT和PCRE這兩個最常用的類型。
CONTENT代碼塊裡,重點在於這個found。分析得出最後兩個else裡都是命中。
根據原字符串,偏移,長度即可組合出高亮字符串。
f為flow結構體也就是會帶到打印日誌那邊的結構體,在結構體中新加一個字符串,即可達成帶數據到日誌流程的目的。
高亮函數代碼:
staticintGet_gaoliang(constchar*data,u_int32_tend,u_int32_tlen,char*res){
chartmp[1024]='';
if(len1024)
{
memcpy(tmp,data+end-len,len);
}else{
memcpy(tmp,data+end-len,1024);
}
strncat(res,tmp,4096);
strncat(res,'\n\0',4096);
return1;}
pcre同理,在命中流程中加入寫高亮字符串即可。
5、高亮加到日誌高亮字符已經寫入到了flow結構體。下一步就是在打印日誌的時候讀到,寫出來。
最優先的當然是fastlog,因為fastlog本就是觸發規則會進行輸出的日誌,且沒有其他干擾。
從Packet結構體找到flow結構體找到其中的gaoliang字符串,打印即可。
最終效果,fastlog會在正常展示命中的同時,講高亮內容展示。
6、修改匯總匯總代碼放在github 上鍊接https://github.com/webraybtl/suricata_gaoliang
修改文件詳情:
alert-fastlog.c加打印
修改AlertFastLogger
添加如下代碼:
PrintBufferData(alert_buffer,size,MAX_FASTLOG_ALERT_SIZE,'=========ruleid:%'PRIu32'高亮字段展示=======:\n%s====================================\n',pa-s-id,p-flow-gaoliang);
detect-engine-content-inspection.c加Get_gaoliang函數
修改DetectEngineContentInspection函數加入寫入高亮字符串邏輯。
static int Get_gaoliang(const char* data,u_int32_t end, u_int32_t len,char* res){ char tmp[1024]=''; if (len1024) { memcpy(tmp, data + end-len, len); }else{ memcpy(tmp, data + end-len, 1024); } strncat(res, tmp,4096); strncat(res, '\n\0',4096); return 1; } int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode) { . if (found==NULL !(cd-flags DETECT_CONTENT_NEGATED)) { if ((cd-flags (DETECT_CONTENT_DISTANCE|DETECT_CONTENT_WITHIN))==0) { /* independent match from previous matches, so failure is fatal */det_ctx-discontinue_matching=1; } goto no_match; } else if (found==NULL (cd-flags DETECT_CONTENT_NEGATED)) { goto match; } else if (found !=NULL (cd-flags DETECT_CONTENT_NEGATED)) { if(f){ Get_gaoliang((char*)buffer,match_offset,cd-content_len,f-gaoliang); } SCLogInfo('content %'PRIu32' matched at offset %'PRIu32', but negated so no match', cd-id, match_offset); /* don't bother carrying recursive matches now, for preceding * relative keywords */if (DETECT_CONTENT_IS_SINGLE(cd)) det_ctx-discontinue_matching=1; goto no_match; } else { match_offset=(uint32_t)((found - buffer) + cd-content_len); if(f){ Get_gaoliang((char*)buffer,match_offset,cd-content_len,f-gaoliang); } .
flow.hflow結構體加一個gaoliang字符串成員。
typedefstructFlow_{
.
.
.
chargaoliang[4096];
}Flow;
遺留問題1、因只開闢了4096字節存高亮字符,會有溢出。
2、直接按字符串打印展示出來的,對十六進制展示不理想,00會導致打印不全。
原文鏈接
Recommended Comments