Jump to content

二開背景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庫目錄中即可運行。

0624-1.png2、vscode+gdb調試suricata環境搭建然後就是裝插件,除了必備的c語言插件全家桶之外還需要裝GDB Debug這個插件。

接著任意新建一個運行配置。

0624-2.png

修改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 } ] }, ]}選擇配置好的配置運行,看到斷在入口,調試環境完成。

QQ截图20240624140810.png

3、suricata流程分析,尋找關鍵位置QQ截图20240624140851.png流程過於復雜,簡單理解就是匹配和記錄日誌的地方是分在不同線程,但是又有結構體可以從匹配帶到那裡。

4、關鍵位置代碼分析,獲取高亮內容根據流程,在初始化後慢慢摸索找到關鍵函數DetectEngineContentInspection

smd為傳入規則,根據type的不同走不同的代碼塊兒匹配。本次加高亮重點關注CONTENT和PCRE這兩個最常用的類型。

QQ截图20240624140911.png

CONTENT代碼塊裡,重點在於這個found。分析得出最後兩個else裡都是命中。

QQ截图20240624140933.png

根據原字符串,偏移,長度即可組合出高亮字符串。

QQ截图20240624140954.png

f為flow結構體也就是會帶到打印日誌那邊的結構體,在結構體中新加一個字符串,即可達成帶數據到日誌流程的目的。

QQ截图20240624141026.png

高亮函數代碼:

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同理,在命中流程中加入寫高亮字符串即可。

QQ截图20240624141101.png

5、高亮加到日誌高亮字符已經寫入到了flow結構體。下一步就是在打印日誌的時候讀到,寫出來。

最優先的當然是fastlog,因為fastlog本就是觸發規則會進行輸出的日誌,且沒有其他干擾。

從Packet結構體找到flow結構體找到其中的gaoliang字符串,打印即可。

QQ截图20240624141126.png

最終效果,fastlog會在正常展示命中的同時,講高亮內容展示。

QQ截图20240624141250.png

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會導致打印不全。

原文鏈接

0 Comments

Recommended Comments

There are no comments to display.

Guest
Add a comment...