SIEM On ELK
安装
参考链接里有详细的安装步骤,测试客户端是Windows,安装了如下软件:
- sysmon.exe(配置文件)
.\sysmon64.exe -accepteula -i c:\windows\config.xml
- winlogbeat.exe
.\install-service-winlogbeat.ps1
.\winlogbeat.exe setup -e
- ElasticAgent.exe
.\elastic-agent.exe install --insecure -f --fleet-server-es=<ES> --fleet-server-service-token=<token>
规则监测和绕过
规则有5种查询,一般使用EQL(Event Query Language)查询类型:
SIEM有内置很多规则,默认是关闭状态,这些规则都是ATT&CK框架攻击行为转化而来的,例如windows下的whoami
查询规则(正经人谁查whoami啊):
process where event.type in ("start", "process_started") and process.name : "whoami.exe"
我们拿这条规则做分析,这条规则匹配了当进程开始的时候,进程名为whoami.exe
的时候触发,所以我们把whoami.exe
复制一下,就可以绕过去了:
copy C:\Windows\System32\whoami.exe C:\Windows\temp\x.exe
C:\Windows\temp\x.exe
是不是把siem想的简单了,这跟通过复制net.exe
绕过添加用户一模一样,仔细观察下elk里面的字段,可以发现process.pe.original_file_name
仍然保留了whoami.exe
,这是PE文件里面固定的,所以我们手动把预警规则修改一下:
process where event.type in ("start", "process_started") and process.pe.original_file_name: "whoami.exe"
此时通过复制绕过就失效了,那么process.pe.original_file_name
能不能改呢?可以的,rcedit:
cedit-x64.exe x.exe --set-version-string OriginalFilename "hello.exe"
此时再次执行x.exe
,SIEM里面不会有告警信息,所以可以通过这种形式绕过和process.pe.original_file_name
相关的规则,所以在实际过程中,要从多个维度思考,比如network、注册表、事件ID
告警通知
ELK的基础版没有用户通知的功能,需要开通白金版,可以申请试用30天或者破解,如果想通知钉钉,可以选择webhook的方式,在webhook的时候注意添加一个请求头字段:Content-Type: application/x-wwww-form-data
,Action里面增加body格式:
{{#context.alerts}}
timestamp={{@timestamp}}&rule_name={{context.rule.name}}&risk_score={{context.rule.risk_score}}&host_name={{host.name}}&process_parent_name={{process.parent.name}}&process_command_line={{process.command_line}}&process_name={{process.name}}&user_name={{user.name}}&result_link={{{context.results_link}}}
{{/context.alerts}}
服务端解析body然后通知钉钉:
import requests
import json
from flask import Flask, request, jsonify
from datetime import datetime, timedelta
app = Flask(__name__)
@app.route('/', methods=['POST'])
def handler():
form = request.form
print(form)
timestamp = date2local(form["timestamp"])
rule_name = form["rule_name"]
# risk_score = form["risk_score"]
host_name = form["host_name"]
process_parent_name = form["process_parent_name"]
process_name = form["process_name"]
process_command_line = form["process_command_line"]
user_name = form["user_name"]
result_link = form["result_link"].replace("\n", "%0a")
dingTalk_notify(timestamp, rule_name, host_name, process_parent_name, process_name, process_command_line, user_name, result_link)
return jsonify({"status": "OK"})
def date2local(date):
date = datetime.strptime(date, "%Y-%m-%dT%H:%M:%S.%fZ")
return (date + timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")
def dingTalk_notify(timestamp, rule_name, host_name, process_parent_name, process_name, process_command_line, user_name, result_link):
token = ""
ddrobot = f"https://oapi.dingtalk.com/robot/send?access_token={token}"
headers = {
'Content-Type': 'application/json;charset=utf-8'
}
json_text = {
"msgtype": "markdown",
"markdown": {
"title": f"SIEM告警",
"text": f"### SIEM告警通知\n##### 触发时间: {timestamp}\n##### 触发规则: {rule_name}\n##### 触发主机: {host_name}\n##### 关联父进程: {process_parent_name}\n##### 当前进程: "
f"{process_name}\n#### 进程参数:{process_command_line}\n##### 当前用户: {user_name}\n##### [告警详情]({result_link})"
},
"at": {
"atMobiles": [],
"isAtAll": "false"
}
}
requests.post(ddrobot, data=json.dumps(json_text), headers=headers).json()
if __name__ == "__main__":
app.run('0.0.0.0', 9999, threaded=True)
规则示例
SIEM内置的规则有很多,常用的规则打开的有如下几个:
规则名称:Conhost Spawned By Suspicious Parent Process
规则介绍:Console Window Host (conhost.exe)作为子进程被启动,通常是在代码注入进程的时候出现
process where event.type in ("start", "process_started") and
process.name : "conhost.exe" and
process.parent.name : ("svchost.exe", "lsass.exe", "services.exe", "smss.exe", "winlogon.exe", "explorer.exe",
"dllhost.exe", "rundll32.exe", "regsvr32.exe", "userinit.exe", "wininit.exe", "spoolsv.exe",
"wermgr.exe", "csrss.exe", "ctfmon.exe")
规则名称:Encoding or Decoding Files via CertUtil
规则介绍:通过CertUtil编码解码文件
process where event.type == "start" and
(process.name : "certutil.exe" or process.pe.original_file_name == "CertUtil.exe") and
process.args : ("?decode", "?encode")
规则名称:Unusual Child Processes of RunDLL32
规则介绍:不正常的rundll32.exe活动(通常用在启动木马过程中,比如CS的Spawn)
sequence with maxspan=1h
[process where event.type in ("start", "process_started") and
(process.name : "rundll32.exe" or process.pe.original_file_name == "RUNDLL32.EXE") and
process.args_count == 1
] by process.entity_id
[process where event.type in ("start", "process_started") and process.parent.name : "rundll32.exe"
] by process.parent.entity_id
规则名称:Creation of a Hidden Local User Account
规则介绍:添加隐藏账户(用于权限维持)
registry where registry.path : "HKLM\\SAM\\SAM\\Domains\\Account\\Users\\Names\\*$\\"
规则名称:Windows Script Executing PowerShell
规则介绍:使用wscript或者cscript执行Powershell
process where event.type in ("start", "process_started") and
process.parent.name : ("cscript.exe", "wscript.exe") and process.name : "powershell.exe"
规则名称:Windows Suspicious Command
规则介绍:Windows可疑命令
process where event.type in ("start", "process_started") and
process.pe.original_file_name in ("whoami.exe", "tasklist.exe", "ipconfig.exe", "powershell.exe", "sctasks.exe", "bitsadmin.exe", "netstat.exe", "systeminfo.exe")
规则名称:Security Software Discovery using WMIC
规则介绍:使用wmic查询安全软件
process where event.type in ("start", "process_started") and
(process.name:"wmic.exe" or process.pe.original_file_name:"wmic.exe") and
process.args:"/namespace:\\\\root\\SecurityCenter2" and process.args:"Get"
规则名称:Net command via SYSTEM account
规则介绍:以SYSTEM权限执行net.exe
process where event.type in ("start", "process_started") and
user.id in ("S-1-5-18", "S-1-5-19", "S-1-5-20") and
process.name : "whoami.exe" or
(process.name : "net1.exe" and not process.parent.name : "net.exe")
sigma(Generic Signature Format for SIEM Systems),这种描述方式特别像病毒软件的特征码。
思考
- 绕过的方式应该还有很多,未测试
- 安骑士的原理类似,比如碰到过阿里云上执行
whoami、systeminfo
就告警 - 看完通过SYSMON日志检测Cobalt Strike木马我觉得这个才是SIEM的解决方式