A partir deste artigo, apresentarei sucessivamente através de vários artigos que, no processo de operação de segurança real, criarei uma ferramenta de análise de ameaças de tráfego para analistas de segurança baseada em wireshark, que ajudará os analistas de segurança a obter análises e análises forenses de pacotes de dados de rede. o dobro do resultado com metade do esforço. Este documento apresenta o uso do iwreshark para analisar os pacotes de dados e exibir os dados de alarme do suricata na IU.
Wireshark é a ferramenta de análise de pacotes mais comum. A vantagem do wireshark é que ele fornece os recursos de análise de protocolo mais abrangentes. A Figura 1 abaixo mostra os tipos de protocolos suportados pelo wireshark: Figura
1
Pode-se ver que os tipos de protocolos suportados são tão altos quanto 2000+. O Wireshark pode analisar o protocolo com precisão, mas não tem capacidade de determinar se há um problema em cada campo do protocolo e se um determinado processo de sessão é normal. Para os analistas de segurança, eles geralmente se concentram em fazer julgamentos sobre as seguintes informações:
- Se o IP de destino e o IP de origem são normais, como ativos do invasor
- Se há riscos em URLs em HTTP, como se há riscos como execução de comandos, injeção e travessia de diretório
- Se o nome de domínio de acesso é normal, como se é um nome de domínio recém-registrado
- Se o certificado TLS é normal, como se é um certificado digital aplicado por uma organização maliciosa
- Se os arquivos transmitidos por HTTP, FTP, SMB e outros protocolos são normais, como se um arquivo de vírus está sendo transmitido
- Existem riscos no protocolo SMB, como exploits psexec?
Talvez analistas experientes possam julgar ataques WEB comuns com base em recursos de texto em protocolos como HTTP, como ameaças como várias injeções, execução de comandos e uploads de arquivos. No entanto, se há risco no endereço IP, propriedade do nome de domínio, se o certificado é normal, se o arquivo em transmissão é malicioso, se há vulnerabilidades como o Eternal Blue no protocolo SMB, para a grande maioria das questões de segurança analistas, eles só podem confiar na detecção de dispositivos de segurança. No entanto, os recursos de cada dispositivo de segurança são desiguais e, ao mesmo tempo, falsos alarmes precisam ser levados em consideração, portanto, os recursos não podem ser muito agressivos.
Portanto, para analistas de segurança, por um lado, construir uma ferramenta de análise de segurança local para verificação secundária de pacotes de dados de alarme de dispositivos de segurança, enriquecer a identificação de diferentes pontos de detecção para pacotes de dados de alarme e aprimorar a confirmação de ameaças. Por outro lado, para alguns pacotes de dados que precisam ser investigados, é muito útil usar ferramentas de segurança local para analisar e descobrir possíveis ameaças.
Para a investigação e coleta de evidências de pacotes de dados, o mais importante é ser capaz de decodificar pacotes de dados. Os recursos avançados de análise de protocolo do Wireshark são a primeira escolha. Para detecção de ameaças, os mecanismos de detecção de ameaças de software livre no campo de pacote de dados incluem suricata, snort e zeek. Para o uso desses três mecanismos, consulte aqui . Para os analistas de segurança, o que precisa ser feito é combinar a capacidade de análise de protocolo do wireshark com a capacidade de análise de ameaças do suricata. A ideia geral é muito simples. Use o recurso de plug-in do wireshark para integrar os resultados da análise suricata dos pacotes de dados, conforme mostrado na Figura 2 abaixo:
Figura 2
Pode-se ver que o resultado do alarme de suricata pode ser usado como a camada superior de toda a hierarquia do pacote de dados. A essência é explicar os métodos de ataque, tipos de ameaças e níveis de ameaças existentes no pacote de dados, para que os analistas possam ser o primeiro a analisar e alterar o tráfego. Hora de entender o contexto do ataque. O código do plug-in correspondente é o seguinte ou acesse este link para fazer o download:
local ok, json = pcall(require, "cjson")
if not ok then
json = require("dkjson")
end
--注册需要在wireshark UI上显示suricata eve文件中的信息,包括alert告警和主要协议信息
if (gui_enabled()) then
local suri_proto = Proto("suricata", "Suricata Analysis")
local suri_sid = ProtoField.string("suricata.alert.sid", "SID", FT_INTEGER)
local suri_msg = ProtoField.string("suricata.alert.msg", "Message", FT_STRING)
local suri_category = ProtoField.string("suricata.alert.category", "Category", FT_INTEGER)
local suri_severity = ProtoField.string("suricata.alert.severity", "Severity", FT_INTEGER)
local suri_tls_subject = ProtoField.string("suricata.tls.subject", "TLS subject", FT_STRING)
local suri_tls_issuerdn = ProtoField.string("suricata.tls.issuerdn", "TLS issuer DN", FT_STRING)
local suri_tls_fingerprint = ProtoField.string("suricata.tls.fingerprint", "TLS fingerprint", FT_STRING)
local suri_tls_version = ProtoField.string("suricata.tls.version", "TLS version", FT_STRING)
local suri_ssh_client_version = ProtoField.string("suricata.ssh.client.version", "SSH client version", FT_STRING)
local suri_ssh_client_proto = ProtoField.string("suricata.ssh.client.proto", "SSH client protocol", FT_STRING)
local suri_ssh_server_version = ProtoField.string("suricata.ssh.server.version", "SSH server version", FT_STRING)
local suri_ssh_server_proto = ProtoField.string("suricata.ssh.server.proto", "SSH server protocol", FT_STRING)
local suri_fileinfo_filename = ProtoField.string("suricata.fileinfo.filename", "Fileinfo filename", FT_STRING)
local suri_fileinfo_magic = ProtoField.string("suricata.fileinfo.magic", "Fileinfo magic", FT_STRING)
local suri_fileinfo_md5 = ProtoField.string("suricata.fileinfo.md5", "Fileinfo md5", FT_STRING)
local suri_fileinfo_sha1 = ProtoField.string("suricata.fileinfo.sha1", "Fileinfo sha1", FT_STRING)
local suri_fileinfo_sha256 = ProtoField.string("suricata.fileinfo.sha256", "Fileinfo sha256", FT_STRING)
local suri_fileinfo_size = ProtoField.string("suricata.fileinfo.size", "Fileinfo size", FT_INTEGER)
local suri_fileinfo_stored = ProtoField.string("suricata.fileinfo.stored", "Fileinfo stored", FT_STRING)
local suri_http_url = ProtoField.string("suricata.http.url", "HTTP URL", FT_STRING)
local suri_http_hostname = ProtoField.string("suricata.http.hostname", "HTTP hostname", FT_STRING)
local suri_http_user_agent = ProtoField.string("suricata.http.user_agent", "HTTP user agent", FT_STRING)
local suri_http_content_type = ProtoField.string("suricata.http.content_type", "HTTP Content Type", FT_STRING)
local suri_http_method = ProtoField.string("suricata.http.method", "HTTP Method", FT_STRING)
local suri_http_protocol = ProtoField.string("suricata.http.protocol", "HTTP Protocol", FT_STRING)
local suri_http_status = ProtoField.string("suricata.http.status", "HTTP Status", FT_STRING)
local suri_http_length = ProtoField.string("suricata.http.length", "HTTP Length", FT_STRING)
local suri_http_referer = ProtoField.string("suricata.http.referer", "HTTP Referer", FT_STRING)
local suri_smb_command = ProtoField.string("suricata.smb.command", "SMB Command", FT_STRING)
local suri_smb_filename = ProtoField.string("suricata.smb.filename", "SMB Filename", FT_STRING)
local suri_smb_share = ProtoField.string("suricata.smb.share", "SMB Share", FT_STRING)
local suri_smb_status = ProtoField.string("suricata.smb.status", "SMB Status", FT_STRING)
local suri_prefs = suri_proto.prefs
local suri_running = false
local suri_alerts = {
}
local suricata_alert_expert_info = ProtoExpert.new("suricata.alert.expert","Suricata Alerts",expert.group.MALFORMED,expert.severity.WARN)
local suricata_proto_expert_info = ProtoExpert.new("suricata.proto.expert","Suricata Proto Info",expert.group.DEBUG,expert.severity.NOTE)
--注册分析下的专家信息
suri_proto.experts = {
suricata_alert_expert_info,suricata_proto_expert_info}
suri_prefs.alert_file = Pref.string("EVE file", "/var/log/suricata/eve.json",
"EVE file containing information about pcap")
suri_proto.fields = {
suri_sid, suri_msg, suri_category, suri_severity, suri_tls_subject, suri_tls_issuerdn, suri_tls_fingerprint, suri_tls_version,
suri_ssh_client_version, suri_ssh_client_proto, suri_ssh_server_version, suri_ssh_server_proto,
suri_fileinfo_filename, suri_fileinfo_magic, suri_fileinfo_md5, suri_fileinfo_sha1, suri_fileinfo_sha256,
suri_fileinfo_size, suri_fileinfo_stored,
suri_http_url, suri_http_hostname, suri_http_user_agent,
suri_http_content_type, suri_http_method, suri_http_protocol, suri_http_status, suri_http_length, suri_http_referer,
suri_smb_command, suri_smb_filename, suri_smb_share, suri_smb_status
}
--在解析每个数据包的同时,将已经解析的eve log数据按照数据包的序号为索引填充到已经注册的字段中
function suri_proto.dissector(buffer,pinfo,tree)
if not(suri_alerts[pinfo.number] == nil) then
for i, val in ipairs(suri_alerts[pinfo.number]) do
if val['sid'] then
--print(val['sid'])
subtree = tree:add(suri_proto,
"Suricata alert: "..val['sid'].." ("..val['msg']..")")
subtree:add(suri_sid, val['sid'])
subtree:add(suri_msg, val['msg'])
subtree:add(suri_category, val['category'])
subtree:add(suri_severity, val['severity'])
subtree:add_proto_expert_info(suricata_alert_expert_info, val['msg'])
end
if val['tls_subject'] then
subtree = tree:add(suri_proto, "Suricata TLS Info")
subtree:add(suri_tls_subject, val['tls_subject'])
subtree:add(suri_tls_issuerdn, val['tls_issuerdn'])
subtree:add(suri_tls_fingerprint, val['tls_fingerprint'])
subtree:add(suri_tls_version, val['tls_version'])
subtree:add_proto_expert_info(suricata_proto_expert_info, "TLS info")
end
if val['ssh_client_version'] then
subtree = tree:add(suri_proto, "Suricata SSH Info")
subtree:add(suri_ssh_client_version, val['ssh_client_version'])
subtree:add(suri_ssh_client_proto, val['ssh_client_proto'])
subtree:add(suri_ssh_server_version, val['ssh_server_version'])
subtree:add(suri_ssh_server_proto, val['ssh_server_proto'])
subtree:add_proto_expert_info(suricata_proto_expert_info, "SSH info")
end
if val['fileinfo_filename'] then
subtree = tree:add(suri_proto, "Suricata File Info")
subtree:add(suri_fileinfo_filename, val['fileinfo_filename'])
if val['fileinfo_magic'] then
subtree:add(suri_fileinfo_magic, val['fileinfo_magic'])
end
if val['fileinfo_md5'] then
subtree:add(suri_fileinfo_md5, val['fileinfo_md5'])
end
if val['fileinfo_sha1'] then
subtree:add(suri_fileinfo_sha1, val['fileinfo_sha1'])
end
if val['fileinfo_sha256'] then
subtree:add(suri_fileinfo_sha256, val['fileinfo_sha256'])
end
subtree:add(suri_fileinfo_size, val['fileinfo_size'])
if val['fileinfo_stored'] then
subtree:add(suri_fileinfo_stored, val['fileinfo_stored'])
end
subtree:add_proto_expert_info(suricata_proto_expert_info, "File info")
end
if val['http_url'] then
--print(val['http_url'])
subtree = tree:add(suri_proto, "Suricata HTTP Info")
-- add protocol fields to subtree
subtree:add(suri_http_url, val['http_url'])
if val['http_hostname'] then
subtree:add(suri_http_hostname, val['http_hostname'])
end
if val['http_user_agent'] then
subtree:add(suri_http_user_agent, val['http_user_agent'])
end
if val['http_content_type'] then
subtree:add(suri_http_content_type, val['http_content_type'])
end
if val['http_method'] then
subtree:add(suri_http_method, val['http_method'])
end
if val['http_protocol'] then
subtree:add(suri_http_protocol, val['http_protocol'])
end
if val['http_status'] then
subtree:add(suri_http_status, val['http_status'])
end
if val['http_length'] then
subtree:add(suri_http_length, val['http_length'])
end
if val['http_referer'] then
subtree:add(suri_http_referer, val['http_referer'])
end
subtree:add_proto_expert_info(suricata_proto_expert_info, "HTTP info")
end
if val['smb_command'] then
subtree = tree:add(suri_proto, "Suricata SMB Info")
subtree:add(suri_smb_command, val['smb_command'])
if val['smb_filename'] then
subtree:add(suri_smb_filename, val['smb_filename'])
end
if val['smb_share'] then
subtree:add(suri_smb_share, val['smb_share'])
end
if val['smb_status'] then
subtree:add(suri_smb_status, val['smb_status'])
end
subtree:add_proto_expert_info(suricata_proto_expert_info, "SMB info")
end
end
end
end
function suri_proto.init()
end
-- 解析suricata eve log日志
function ids_load_log(eve_file)
function suricata_eve_log_parser(file)
local event
local id = 0
local s_text = ""
suri_alerts = {
}
for s_text in io.lines(file) do
event = json.decode(s_text)
id = event["pcap_cnt"]
if not (id == nil) then
if event["event_type"] == "alert" then
if suri_alerts[id] == nil then
suri_alerts[id] = {
}
end
table.insert(suri_alerts[id],
{
category = event["alert"]["category"], sid = tonumber(event["alert"]["signature_id"]),
severity = tonumber(event["alert"]["severity"]), msg = event["alert"]["signature"]})
elseif event["event_type"] == "tls" then
if suri_alerts[id] == nil then
suri_alerts[id] = {
}
end
table.insert(suri_alerts[id],
{
tls_subject = event["tls"]["subject"], tls_issuerdn = event["tls"]["issuerdn"],
tls_fingerprint = event["tls"]["fingerprint"], tls_version = event["tls"]["version"]})
elseif event["event_type"] == "ssh" then
if suri_alerts[id] == nil then
suri_alerts[id] = {
}
end
table.insert(suri_alerts[id],
{
ssh_client_version = event["ssh"]["client"]["software_version"],
ssh_client_proto = event["ssh"]["client"]["proto_version"],
ssh_server_version = event["ssh"]["server"]["software_version"],
ssh_server_proto = event["ssh"]["server"]["proto_version"],
})
elseif event["event_type"] == "fileinfo" then
if suri_alerts[id] == nil then
suri_alerts[id] = {
}
end
table.insert(suri_alerts[id],
{
fileinfo_filename = event["fileinfo"]["filename"],
fileinfo_magic = event["fileinfo"]["magic"],
fileinfo_md5 = event["fileinfo"]["md5"],
fileinfo_sha1 = event["fileinfo"]["sha1"],
fileinfo_sha256 = event["fileinfo"]["sha256"],
fileinfo_size = tonumber(event["fileinfo"]["size"]),
fileinfo_stored = tostring(event["fileinfo"]["stored"]),
})
elseif event["event_type"] == "http" then
if suri_alerts[id] == nil then
suri_alerts[id] = {
}
end
table.insert(suri_alerts[id],
{
http_url = event["http"]["url"],
http_hostname = event["http"]["hostname"],
http_user_agent = event["http"]["http_user_agent"],
http_content_type = event["http"]["http_content_type"],
http_method = event["http"]["http_method"],
http_protocol = event["http"]["protocol"],
http_status = event["http"]["status"],
http_length = event["http"]["length"],
http_referer = event["http"]["http_refer"]
})
elseif event["event_type"] == "smb" then
if suri_alerts[id] == nil then
suri_alerts[id] = {
}
end
table.insert(suri_alerts[id],
{
smb_command = event["smb"]["command"],
smb_filename = event["smb"]["filename"],
smb_share = event["smb"]["share"],
smb_status = event["smb"]["status"],
})
end
end
end
end
function suriwire_register(file)
if file == "" then
file = suri_prefs.alert_file
end
local filehandle = io.open(file, "r")
if not (filehandle == nil) then
filehandle:close()
-- parse suricata log file
suricata_eve_log_parser(file)
-- register protocol dissector
if suri_running == false then
register_postdissector(suri_proto)
suri_running = true
end
reload()
else
new_dialog("Unable to open '" .. file
.. "'. Choose another alert file",
suriwire_register,
"Choose file (Linux default:" .. suri_prefs.alert_file..")")
end
end
-- run suricata
-- set input file
if eve_file then
suriwire_register(eve_file)
else
new_dialog("Choose alert file",
suriwire_register,
"Choose file (Linux default:" .. suri_prefs.alert_file..")")
end
end
function wireshark_page()
browser_open_url("https://blog.csdn.net/javajiawei/category_9583097.html")
end
register_menu("导入入侵检测日志/导入Suricata日志", ids_load_log, MENU_TOOLS_UNSORTED)
register_menu("Wireshark使用技巧", wireshark_page, MENU_TOOLS_UNSORTED)
local eve_file = os.getenv("SURIWIRE_EVE_FILE")
if eve_file then
ids_load_log(eve_file)
end
end
Deve-se observar que, como o script lua de dkjson é referenciado no script, o script Lua precisa ser baixado primeiro no diretório wireshark local, o endereço de download é aqui . Ou acesse o download do github correspondente, aqui .
A maneira de carregar o plug-in Lua é usar a linha de comando para abrir o wireshark, conforme a seguir:
wireshark -r test.pcap -X lua_script:suricata.lua
Ou configure o script modificado no init.lua para inicialização automática e adicione a seguinte configuração ao init.lua:
disable_lua = false--开启Lua解析
dofile(DATA_DIR.."suricata.lua")
Depois de iniciar o wireshark, você precisa carregar o arquivo de log do suricata, conforme mostrado na Figura 3 abaixo para importar o log do suricata:
Após o carregamento do log de véspera correspondente na Figura 3 , a análise das informações de alarme correspondentes será gerada nas informações do especialista, conforme Figura 4 abaixo:
Figura 4
A Figura 4 mostra todas as informações do pacote de dados que acionam um alarme, e você pode pular para o pacote de dados correspondente selecionando o alarme correspondente. Na Figura 3, você pode ver que o arquivo que precisa ser inserido é um arquivo no formato suricata eve. O exemplo é o seguinte:
{"timestamp":"2019-10-15T06:54:14.857081+0000","flow_id":1511806696075679,"pcap_cnt":351,"event_type":"alert","src_ip":"1.1.141.169","src_port":17725,"dest_ip":"1.2.61.25","dest_port":53,"proto":"TCP","alert":{"action":"allowed","gid":1,"signature_id":2030524,"rev":1,"signature":"ET INFO Possible NOP Sled Observed in Large DNS over TCP Packet M1","category":"Attempted Administrator Privilege Gain","severity":1,"metadata":{"affected_product":["Windows_DNS_server"],"created_at":["2020_07_15"],"former_category":["INFO"],"performance_impact":["Significant"],"signature_severity":["Informational"],"updated_at":["2020_07_15"]}},"flow":{"pkts_toserver":3,"pkts_toclient":1,"bytes_toserver":1638,"bytes_toclient":62,"start":"2019-10-15T06:54:14.700831+0000"}}
{"timestamp":"2019-10-15T06:54:14.872549+0000","flow_id":535741018300164,"pcap_cnt":372,"event_type":"dcerpc","src_ip":"1.1.171.176","src_port":7018,"dest_ip":"1.2.34.235","dest_port":6502,"proto":"TCP","dcerpc":{"request":"BIND","interfaces":[{"uuid":"62b93df0-8b02-11ce-876c-00805f842837","version":"1.0","ack_result":0}],"response":"BINDACK","call_id":0,"rpc_version":"5.0"}}
{"timestamp":"2019-10-15T06:54:14.902033+0000","flow_id":1632151679679309,"pcap_cnt":386,"event_type":"anomaly","src_ip":"1.2.33.242","src_port":80,"dest_ip":"1.1.30.100","dest_port":46189,"proto":"TCP","tx_id":0,"anomaly":{"app_proto":"http","type":"applayer","event":"INVALID_REQUEST_CHUNK_LEN","layer":"proto_parser"}}
{"timestamp":"2019-10-15T06:54:14.902033+0000","flow_id":1632151679679309,"pcap_cnt":386,"event_type":"http","src_ip":"1.1.30.100","src_port":46189,"dest_ip":"1.2.33.242","dest_port":80,"proto":"TCP","tx_id":0,"http":{"hostname":"pdfyoocaugsebmnhamlz","url":"/","http_method":"GET","protocol":"HTTP/1.1","length":0}}
{"timestamp":"2019-10-15T06:54:14.914528+0000","flow_id":535741018300164,"pcap_cnt":390,"event_type":"dcerpc","src_ip":"1.1.171.176","src_port":7018,"dest_ip":"1.2.34.235","dest_port":6502,"proto":"TCP","dcerpc":{"request":"REQUEST","req":{"opnum":43,"frag_cnt":1,"stub_data_size":20},"response":"RESPONSE","res":{"frag_cnt":1,"stub_data_size":8},"call_id":0,"rpc_version":"5.0"}}
Você pode ver que o script acima analisa o tipo de evento no formato de véspera para alerta, http, dns, tls, smb e outros tipos. O número de alarmes do tipo alerta depende da riqueza da base de regras. Essa área de analistas de segurança precisa ser acumulada por indivíduos e eles precisam ser definidos por eles mesmos quando necessário. Ao mesmo tempo, o script também analisa os campos-chave de HTTP, DNS, TLS, SMB e outros registros de protocolo, conforme mostrado na Figura 2 acima. Quanto a como julgar se há um problema com esses campos e quais informações mais ricas podem ser obtidas com base nesses campos, os artigos subsequentes apresentarão.
Para saber como obter o arquivo de log de véspera, você pode consultar o artigo, aqui . Deve-se observar que muitas informações não são gravadas por padrão no contêiner padrão do Dalton. Se você deseja registrar mais informações, é necessário modificar a configuração padrão em suricata.yaml. A Figura 6 abaixo mostra as informações de configuração do valor md5 do arquivo de registro, veja aqui .
Na Figura 6
, você pode modificar os campos do arquivo yaml de acordo com as necessidades reais.Após gerar o log de véspera, você pode modificar lua de acordo e analisar os campos correspondentes.
Deve-se notar que as regras de detecção de intrusão visam principalmente os pontos de tecnologia de ataque com determinados pontos de detecção, como injeção de SQL, execução de comandos, desserialização, etc. Para recursos de ameaças como IOC, transferência maliciosa de arquivos e certificados maliciosos, embora as regras IDS também possam ser escritas, geralmente é mais conveniente usar a forma de colisão de inteligência de ameaças para detecção. O principal motivo é que o número de recursos IOC é grande e a mudança é relativamente rápida. , que será apresentado no próximo artigo.
Este artigo é um artigo original dos jovens da vila de CSDN, e não pode ser reproduzido sem permissão. O blogger linka aqui .