秋季更新

秋季更新
This commit is contained in:
huoji
2022-09-20 18:31:15 +08:00
parent 5fcfd6ec02
commit 05aea0a27b
25 changed files with 781 additions and 849 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 224 KiB

179
README.md
View File

@@ -1,179 +0,0 @@
![image](Image/logo.png)
# RmEye
RmEye是一个window上的基于att&ck现代EDR设计思想的威胁响应工具.
不同于EDR,它轻量、高效.自身定位是轻量级威胁检出工具.
而不是繁重的、需要付费的、效果不明的所谓的EDR
RmEye基于att&ck模型,如果您对att&ck模型不熟悉,请先阅读相关文章后再使用:
https://key08.com/index.php/2022/08/09/1505.html
### 功能特点
1. 基于att&ck设计.所有设计只是为了符合att&ck的攻击路径、攻击链(虽然规则里面没有标注T因为懒惰)
2. 轻量、高效.为了不适用繁重超占内存的ELK设计思路,而且要保证检出的同时保证不会太重,agent端使用了大量规则过滤,这样才使得后端使用sqlite作为数据库成为可能.单机日志平均一天4M.此外轻量级别的客户端一天只占40-400KB的内存.
3. 行为检出,让免杀成为过去式.基于att&ck设计,只看行为不看文件.文件类免杀已经成为过去式.
4. 高扩展性.可随需求定制功能
### RmEye 之所以不是 Edr/Xdr/Mdr/Ndr/XXXXXdr
1. RmEye没有流量监控
2. RmEye仅覆盖20%左右的datasource
3. RmEye没有联动WAF、IPS/IDS
4. RmEye没有实时拦截功能
5. 对RPC、COM、ALPC基本无能为力
6. 不支持更高级的扩展检测,如检测脚本、下发规则,主机链
7. 受限于Sysmon,很多att&ck的T没有覆盖,也无法覆盖.
8. 没有响应能力,只能被动记录.
请牢记,RmEye自身定位是轻量级威胁检出工具
### 最新新闻
2022/9/8:
增加服务端规则指南: \
[doc_server_rule_manual.md](./doc_server_rule_manual.md)
2022/9/5:
增加规则编写教程:
https://github.com/RoomaSec/RmEye/blob/main/doc_day0_rule.md
增加`mimikatz`检测
2022/8/31:
增加进程白名单系统,现在能给进程加白名单了.在打开进程链后,点击某个进程加入白名单即可
2022/8/29:
增加uac提权检测插件`uac_bypass_detect`,但是受限于sysmon,没有办法获取RPC信息,因此只能检测一部分的UAC提权行为.并且有误报,请酌情考虑
### 检出截图
威胁列表:
![image](Image/1.png)
进程链行为回溯
![image](Image/8.png)
powershell恶意执行:
![image](Image/2.png)
apt样本:
![image](Image/3.png)
勒索软件:
![image](Image/4.png)
网站入侵提权到执行cobalt strike:
![image](Image/5.png)
offic宏钓鱼:
![image](Image/6.png)
uac提权检测:
![image](Image/7.png)
mimikatz检测:
![image](Image/14.png)
### 待做列表
1. 更好的前端(目前是VUE-CDN模式,不太好,想换成VUE-CLI) 已经完成
2. 日志回放【目前重点】
3. 威胁狩猎【目前重点】
4. att&ck热力图
5. 在线规则编辑器
6. 内网横向检测
7. iis、apache、nginx日志搜集分析(aka: XDR的实现)
8. 集成反病毒引擎
9. 完善目前的插件系统【目前重点】
10. 云日志检测能力【目前重点】
### 安装
下载release( https://github.com/RoomaSec/RmEye/releases ),里面有客户端,服务端自行clone本项目
服务端是python3编写,安装完依赖库后输入
```
python webserver.py
```
即可部署
服务端部署后,修改config.py里面的
```
# 检出阈值,越高越难检出但是也会越准确
MAX_THREAT_SCORE = 170
# 授权访问主站的IP列表.如果不在后台里面则不能访问后台
ALLOW_ACCESS_IP = ['127.0.0.1']
```
MAX_THREAT_SCORE代表报警分数,意思为进程链总分超过此分数则报警,越高越准但是也会漏报
ALLOW_ACCESS_IP代表允许的IP,只有在此名单里面的IP才能访问后台.请增加自己的IP地址
客户端则编辑config.ini
```
[communication]
server = http://192.168.111.189:5000
```
其中server改成你的服务端的地址
然后分发三个文件给客户端并且放在同一目录:
config.ini、install.cmd、RmEye.exe、sysmon.xml、Sysmon64.exe
之后管理员身份运行install.cmd安装sysmon与RmEye
访问 http://服务器ip:5000(flask默认端口) 查看后台
当然一开始啥数据也没有,为了确认是否安装成功可以将webserver.py中的
```
flask_log = logging.getLogger('werkzeug')
flask_log.setLevel(logging.ERROR)
```
注释掉,检查有没有客户端的请求即可
手动安装(cmd脚本其实执行了这些命令):
```
//安装sysmon:
sysmon -i
//sysmon加载配置项
sysmon -c sysmon.xml
//安装RmEye
RmEye /install
```
### 卸载
卸载RmEye:
在RmEye目录下执行
```
SysEye /uninstall
```
如果您需要卸载sysmon
执行
```
sysmon /uninstall
```
即可干净卫生的卸载掉RmEye
### 规则相关的问题
1. 规则目前仅120条,很多攻击面没有覆盖,其他规则请访问《社区》
2. 规则目前只支持rule_engine与yara的规则,其中yara的规则支持是以插件的形式支持
3. 目前的规则字段完全依赖sysmon的字段,sysmon的字段请检查根目录下的provider.json(但是请记住纯小写,自行做大小写转换)
规则目前在`Server/rules`目录规则目前有两种规则:
rule_engine:
如检测由CMD启动的ipconfig:
```
{
'rules': [
'originalfilename =~ ".*cmd.exe" and commandline =~ ".*ipconfig.*"',
],
'score': 80,
'name': 'cmd启动ipconfig'
},
```
分数代表的是本次规则给进程链所增加的分数,报警是根据前面的MAX_THREAT_SCORE设置的
规则编写教程请移步:
https://github.com/RoomaSec/RmEye/blob/main/doc_day0_rule.md
规则引擎的语法请移步:
https://github.com/zeroSteiner/rule-engine
yara,需要安装插件,具体请看交流部分
### 第三方引用库
1. sysmon
https://docs.microsoft.com/zh-cn/sysinternals/downloads/sysmon
2. rule_engine
https://github.com/zeroSteiner/rule-engine
3. yara
https://github.com/VirusTotal/yara
4. sysmon-config(客户端使用的默认的规则,但是我做了一些修改)
https://github.com/SwiftOnSecurity/sysmon-config
请遵守相关库的开源协议.相关法律风险本项目不负任何责任
### 交流
开源的目的不是为了免费填鸭式教学,或者被免费拿去发公众号引流、去拿去集成产品方案去赚钱,而是要一起完善这个工具,从而实现共赢.
扫一扫加入这个工具的交流群,这样就能获取实时动态.参与开发、参与交流规则编写等等.欢迎加入
最近进群的人有点多,所以不活跃的哥们暂时清理掉,但是微信太不好使了.要是t错了或者还想在群待着不发言的重新加群吧
![image](Image/group2.png)
### 特别感谢
@Pwn0x01 yara插件
@zeroSteiner 规则引擎插件
@SwiftOnSecurity 客户端规则
@Fplyth0ner-Combie 规则相关文档

View File

@@ -1,4 +1,4 @@
# 检出阈值,越高越难检出但是也会越准确
MAX_THREAT_SCORE = 170
MAX_THREAT_SCORE = 45
# 授权访问主站的IP列表.如果不在后台里面则不能访问后台
ALLOW_ACCESS_IP = ['127.0.0.1', '192.168.111.189', '192.168.111.187']

View File

@@ -1,6 +1,5 @@
import json
import time
import operator
import process
import rule
@@ -10,6 +9,66 @@ import config
import plugin
import hash_white_list
LOG_TYPE_PROCESS_CREATE = 1
LOG_TYPE_PROCESS_ACTION = 2
def update_att_ck(process: process.Process, score, hit_name, attck_t_list):
if process.is_white or process.chain.root_process.is_white or process.parent_process.is_white:
score = 0
for t in attck_t_list:
process.set_attck(score, t, hit_name)
# 更新命中的规则
return global_vars.THREAT_TYPE_PROCESS
def update_threat(process: process.Process, score, rule_hit_name):
had_threat = global_vars.THREAT_TYPE_NONE
if process.is_white or process.chain.root_process.is_white or process.parent_process.is_white:
return had_threat
if score > 0:
# 更新命中的规则
process.set_score(score, rule_hit_name)
had_threat = global_vars.THREAT_TYPE_PROCESS
return had_threat
def match_threat(process: process.Process, log, log_type):
had_threat = global_vars.THREAT_TYPE_NONE
success_match = False
hit_name = ''
hit_score = 0
is_ioa = False
if log_type == LOG_TYPE_PROCESS_CREATE:
success_match, is_ioa, attck_t_list, hit_score, rule_hit_name = rule.calc_score_in_create_process(
log)
elif log_type == LOG_TYPE_PROCESS_ACTION:
success_match, is_ioa, attck_t_list, hit_score, rule_hit_name = rule.calc_score_in_action(
log)
if success_match == False:
return had_threat, is_ioa, hit_name, hit_score
# 匹配到了首先更新att&ck的t
had_threat = update_att_ck(
process, hit_score, rule_hit_name, attck_t_list)
hit_name = rule_hit_name
if is_ioa:
had_threat = update_threat(
process, hit_score, rule_hit_name)
else:
is_match_software, software_name, software_score = rule.match_att_ck_software(
process.chain.attck_hit_list)
if is_match_software:
# 匹配到software了,设置为ioa
had_threat = update_threat(
process, software_score, software_name)
hit_name = software_name
hit_score = software_score
#print('match_threat', had_threat, is_ioa, hit_name, hit_score)
# if had_threat != global_vars.THREAT_TYPE_NONE:
# print('path: {} hit_name: {} socre: {}'.format(
# process.path, hit_name, hit_score))
return had_threat, is_ioa, hit_name, hit_score
def process_log(host, json_log, raw_log):
log = json_log["data"]
@@ -20,6 +79,7 @@ def process_log(host, json_log, raw_log):
chain_hash = ""
params = ""
user = ""
is_ioa = False
if json_log["action"] == "processcreate":
pid = log["processid"]
@@ -39,7 +99,7 @@ def process_log(host, json_log, raw_log):
if path in process.skip_process_path or path in process.skip_process_path:
return
parent_process: process.Process = process.get_process_by_pid(ppid)
score, rule_hit_name = rule.calc_score_in_create_process(log)
if hash in process.skip_md5:
return
if parent_process is None or parent_path in process.root_process_path:
@@ -63,9 +123,9 @@ def process_log(host, json_log, raw_log):
chain = process.create_chain(parent_process)
chain.add_process(child, parent_pid)
current_process = child
if score > 0:
child.set_score(score, rule_hit_name)
had_threat = global_vars.THREAT_TYPE_PROCESS
had_threat, is_ioa, rule_hit_name, score = match_threat(
current_process, log, LOG_TYPE_PROCESS_CREATE)
else:
is_white_list = hash in hash_white_list.g_white_list
child = process.Process(
@@ -74,9 +134,9 @@ def process_log(host, json_log, raw_log):
child.parent_process = parent_process
parent_process.chain.add_process(child, ppid)
current_process = child
if score > 0:
child.set_score(score, rule_hit_name)
had_threat = global_vars.THREAT_TYPE_PROCESS
had_threat, is_ioa, rule_hit_name, score = match_threat(
current_process, log, LOG_TYPE_PROCESS_CREATE)
had_threat_plugin = plugin.dispath_rule_new_process_create(
host, current_process, raw_log, json_log
@@ -100,6 +160,7 @@ def process_log(host, json_log, raw_log):
host,
current_process.chain.risk_score,
json.dumps(current_process.chain.operationlist),
json.dumps(current_process.chain.attck_hit_list),
current_process.chain.hash,
current_process.chain.get_json(),
global_vars.THREAT_TYPE_PROCESS,
@@ -110,10 +171,8 @@ def process_log(host, json_log, raw_log):
current_process = process.get_process_by_pid(log["processid"])
if current_process is not None:
log["action"] = json_log["action"]
score, rule_hit_name = rule.calc_score_in_action(log)
if score > 0:
current_process.set_score(score, rule_hit_name)
had_threat = global_vars.THREAT_TYPE_PROCESS
had_threat, is_ioa, rule_hit_name, score = match_threat(
current_process, log, LOG_TYPE_PROCESS_ACTION)
had_threat_plugin = plugin.dispath_rule_new_process_action(
host, current_process, raw_log, json_log
)
@@ -145,6 +204,7 @@ def process_log(host, json_log, raw_log):
host,
current_process.chain.risk_score,
json.dumps(current_process.chain.operationlist),
json.dumps(current_process.chain.attck_hit_list),
current_process.chain.hash,
current_process.chain.get_json(),
global_vars.THREAT_TYPE_PROCESS,
@@ -155,6 +215,7 @@ def process_log(host, json_log, raw_log):
host,
current_process.chain.risk_score,
json.dumps(current_process.chain.operationlist),
json.dumps(current_process.chain.attck_hit_list),
current_process.chain.hash,
current_process.chain.get_json(),
global_vars.THREAT_TYPE_PROCESS,
@@ -179,29 +240,34 @@ def process_log(host, json_log, raw_log):
target_hash = target_process.md5
self_hash = current_process.md5
# 以后有其他排除需求再优化
if json_log['action'] == 'imageload' and json_log['data']['imageloaded'] not in hash_white_list.g_white_dll_load_list:
sql.push_process_raw(
host,
raw_json_log,
rule_hit_name,
score,
chain_hash,
had_threat,
parent_pid,
target_pid,
self_hash,
target_image_path,
target_hash,
params,
user,
)
if json_log['action'] == 'imageload' and (json_log['data']['imageloaded'][len(json_log['data']['imageloaded']) - 4:] == '.exe' or json_log['data']['imageloaded'] in hash_white_list.g_white_dll_load_list):
return
"""
if json_log['action'] == 'imageload':
print(json_log['data']['imageloaded'])
return
sql.push_process_raw(
host,
raw_json_log,
rule_hit_name,
score,
chain_hash,
had_threat,
parent_pid,
target_pid,
self_hash,
target_image_path,
target_hash,
params,
user,
)
'''
for iter in process.g_ProcessChainList:
item: process.Process = iter
if item.risk_score >= config.MAX_THREAT_SCORE:
item.print_process()
"""
'''
def process_raw_log(raw_logs: list) -> list:

View File

@@ -34,7 +34,7 @@ mimikatz_dll_list = [
def rule_new_process_create(current_process: process.Process, host, raw_log_data, json_log_data):
# 服务端提供了一个 plugin_var 变量用于存放当前进程插件的上下文
if current_process.path != 'c:\\windows\\system32\\wbem\\wmic.exe' and current_process.parent_process.path != 'c:\\windows\\system32\\svchost.exe':
if current_process.path != 'c:\\windows\\system32\\wbem\\wmic.exe' and current_process.parent_process.path != 'c:\\windows\\system32\\svchost.exe' and current_process.path != 'c:\\windows\\system32\\svchost.exe':
current_process.plugin_var['mimikatz_matched_num'] = 0
current_process.plugin_var['mimikatz_detected'] = False
return global_vars.THREAT_TYPE_NONE

View File

@@ -94,6 +94,8 @@ class Process:
self.chain_hash = ''
self.active = True
self.operationlist = {}
self.attck_hit_list = {}
self.risk_score = 0
self.terminate = False
self.rmpid = tools.get_md5(
@@ -120,9 +122,16 @@ class Process:
def set_rmppid(self, rmppid):
self.rmppid = rmppid
def set_attck(self, new_score, t, name):
if t not in self.attck_hit_list:
self.risk_score += new_score
self.attck_hit_list[t] = name
if t not in self.chain.attck_hit_list:
self.chain.risk_score += new_score
self.chain.attck_hit_list[t] = name
def set_score(self, new_score, opertion):
if self.is_white or self.chain.root_process.is_white or self.parent_process.is_white:
return
if opertion not in self.operationlist:
self.risk_score += new_score
self.operationlist[opertion] = 1
@@ -146,6 +155,7 @@ class ProcessChain:
self.terminate_count = 0
self.risk_score = 0
self.operationlist = {}
self.attck_hit_list = {}
self.process_list = []
self.json_arrays = []
self.active = True
@@ -234,6 +244,7 @@ class ProcessChain:
"rmppid": proc_info.rmppid,
"params": proc_info.params,
"operationlist": proc_info.operationlist,
"attck_hit_list": proc_info.attck_hit_list,
"md5": proc_info.md5,
"active": proc_info.active,
"children": []

View File

@@ -1,82 +1,132 @@
import rule_engine
import rules.py.process as rule_process
import rules.py.action as rule_action
import rules.py.attck.process as attck_process
import rules.py.attck.attck as attack_software
import rules.py.attck.action as attack_action
import rules.py.ioa.action as ioa_action
import rules.py.ioa.process as ioa_process
import plugin
g_sample_rule = {}
g_sample_rule['process'] = rule_process.rule
g_sample_rule['action'] = rule_action.rule
g_sample_rule['attack_process'] = attck_process.rule
g_sample_rule['attack_action'] = attack_action.rule
g_sample_rule['attack_software'] = attack_software.rule
g_sample_rule['ioa_action'] = ioa_action.rule
g_sample_rule['ioa_process'] = ioa_process.rule
attck_process_rules = []
attck_action_rules = []
ioa_process_rules = []
ioa_action_rules = []
base_process_rules = []
base_action_rules = []
base_host_rules = []
def calc_score_in_action(log):
global base_action_rules
for iter in base_action_rules:
for rule in iter['rules']:
# 这是or
try:
if rule.matches(log):
return iter['score'], iter['name']
except:
print("error: {} ".format(log))
def match_att_ck_software(t_list):
# 返回是否命中,命中命中,分数
return 0, ''
global g_sample_rule
is_match = False
match_name = ''
match_score = 0
for iter in g_sample_rule['attack_software']:
rule_list = iter['rules']
min_match_num = iter['hit_num']
match_num = 0
for t in t_list.keys():
if t in rule_list:
match_num += 1
if match_num >= min_match_num:
is_match = True
match_name = iter['name']
match_score = iter['score']
break
if is_match:
break
return is_match, match_name, match_score
def calc_score_in_action(log):
# 返回 是否匹配到,是否ioa,attck,分数,名字
global attck_action_rules
global ioa_action_rules
for iter in ioa_action_rules:
for rule in iter['rules']:
if rule.matches(log):
return True, True, iter['attck_hit'], iter['score'], iter['name']
for iter in attck_action_rules:
for rule in iter['rules']:
if rule.matches(log):
return True, False, iter['attck_hit'], iter['score'], iter['name']
return False, False, [], 0, ''
def calc_score_in_create_process(log):
global base_process_rules
for iter in base_process_rules:
# 返回 是否匹配到,是否ioa,attck,分数,名字
global ioa_process_rules
global attck_process_rules
for iter in ioa_process_rules:
for rule in iter['rules']:
# 这是or
if rule.matches(log):
return iter['score'], iter['name']
return 0, ''
def calc_score_in_host(log):
global base_host_rules
for iter in base_host_rules:
return True, True, iter['attck_hit'], iter['score'], iter['name']
for iter in attck_process_rules:
for rule in iter['rules']:
# 这是or
if rule.matches(log):
return iter['score'], iter['name']
return 0, ''
return True, False, iter['attck_hit'], iter['score'], iter['name']
return False, False, [], 0, ''
def init_rule():
global base_process_rules
global base_action_rules
global base_host_rules
for iter in g_sample_rule['process']:
global attck_process_rules
global attck_action_rules
global ioa_process_rules
global ioa_action_rules
for iter in g_sample_rule['attack_process']:
temp_process_rules = []
score = 0
if 'score' not in iter:
score = 5
else:
score = iter['score']
for iter_i in iter['rules']:
print(iter_i)
print('rule: {} score: {}'.format(iter_i, score))
temp_process_rules.append(rule_engine.Rule(
iter_i
))
base_process_rules.append(
{'name': iter['name'], 'score': iter['score'], 'rules': temp_process_rules})
for iter in g_sample_rule['action']:
attck_process_rules.append(
{'name': iter['name'], 'attck_hit': iter['attck_hit'], 'score': score, 'rules': temp_process_rules})
for iter in g_sample_rule['attack_action']:
temp_process_rules = []
score = 0
if 'score' not in iter:
score = 5
else:
score = iter['score']
for iter_i in iter['rules']:
print(iter_i)
print('rule: {} score: {}'.format(iter_i, score))
temp_process_rules.append(rule_engine.Rule(
iter_i
))
base_action_rules.append(
{'name': iter['name'], 'score': iter['score'], 'rules': temp_process_rules})
'''
for iter in g_sample_rule['host']:
attck_action_rules.append(
{'name': iter['name'], 'attck_hit': iter['attck_hit'], 'score': score, 'rules': temp_process_rules})
for iter in g_sample_rule['ioa_action']:
temp_process_rules = []
for iter_i in iter['rules']:
print(iter_i)
print('rule: {} score: {}'.format(iter_i, score))
temp_process_rules.append(rule_engine.Rule(
iter_i
))
base_host_rules.append(
{'name': iter['name'], 'score': iter['score'], 'rules': temp_process_rules})
'''
ioa_action_rules.append(
{'name': iter['name'], 'attck_hit': iter['attck_hit'], 'score': iter['score'], 'rules': temp_process_rules})
for iter in g_sample_rule['ioa_process']:
temp_process_rules = []
for iter_i in iter['rules']:
print('rule: {} score: {}'.format(iter_i, score))
temp_process_rules.append(rule_engine.Rule(
iter_i
))
ioa_process_rules.append(
{'name': iter['name'], 'attck_hit': iter['attck_hit'], 'score': iter['score'], 'rules': temp_process_rules})
plugin.dispath_rule_init()
print('init rule done')

View File

@@ -1,172 +0,0 @@
rule = [
{
'rules': [
'action == "processaccess" and targetimage =~ ".*lsass.exe" and grantedaccess & 0x0010 and sourceimage =~ ".*rundll32.exe"',
],
'score': 300,
'name': '已知内存加载mimikazt行为'
},
{
'rules': [
'action == "processaccess" and targetimage =~ ".*lsass.exe"',
],
'score': 60,
'name': 'LSASS高权限访问'
},
{
'rules': [
'action == "processaccess" and calltrace =~ ".*unknown.*" and not calltrace =~ ".*conpty\.node.*" and not calltrace =~ ".*java\.dll.*" and not calltrace =~ ".*appvisvsubsystems64\.dll.*" and not calltrace =~ ".*twinui\.dll.*" and not calltrace =~ ".*nativeimages.*" and not targetimage == "c:\\windows\\system32\\cmd.exe"',
],
'score': 20,
'name': '异常进程访问'
},
{
'rules': [
'action == "processaccess" and sourceimage =~ ".*office16.*" and calltrace =~ ".*kernelbase\.dll.*"',
],
'score': 100,
'name': 'office异常进程内存'
},
{
'rules': [
'action == "processaccess" and calltrace =~ ".*wshom\.ocx.*"',
'action == "processaccess" and calltrace =~ ".*shell32\.dll.*"',
'action == "processaccess" and calltrace =~ ".*dbgcore\.dll.*"',
'action == "processaccess" and calltrace =~ ".*kernelbase\.dll\+de67e.*"',
'action == "processaccess" and calltrace =~ ".*framedynos\.dll.*"',
],
'score': 40,
'name': '不正常的进程访问'
},
{
'rules': [
'action == "pipecreate" and pipename =~ ".*msagent.*"',
'action == "pipecreate" and pipename =~ ".*msse.*"',
'action == "pipecreate" and pipename =~ ".*postex_.*"',
'action == "pipecreate" and pipename =~ ".*postex_ssh.*"',
'action == "pipecreate" and pipename =~ ".*status_.*"',
],
'score': 300,
'name': '已知CobalStrike'
},
{
'rules': [
'action == "pipecreate" and pipename =~ ".*paexec.*"',
'action == "pipecreate" and pipename =~ ".*remcom.*"',
'action == "pipecreate" and pipename =~ ".*csexec.*"'
],
'score': 300,
'name': '已知内网横向工具'
},
{
'rules': [
'action == "pipecreate" and pipename =~ ".*lsadump.*"',
'action == "pipecreate" and pipename =~ ".*cachedump.*"',
'action == "pipecreate" and pipename =~ ".*wceservicepipe.*"'
],
'score': 300,
'name': '已知mimikazt内存dump'
},
# todo 懒得做详细的规则了.加油完善规则吧
{
'rules': [
'action == "createremotethread"',
],
'score': 60,
'name': '疑似远程线程注入'
},
{
'rules': [
'action == "filecreatestreamhash"',
],
'score': 100,
'name': '文件流创建'
},
{
'rules': [
'action == "registryadd"',
'action == "registryvalueSet"',
'action == "registryobjectSet"',
],
'score': 100,
'name': '可疑注册表访问'
},
{
'rules': [
'action == "dnsquery"',
],
'score': 30,
'name': 'DNS解析'
},
{
'rules': [
'action == "networkconnect"',
],
'score': 30,
'name': '可疑网络链接'
},
{
'rules': [
'action == "clipboardchange"',
],
'score': 30,
'name': '可疑剪切板访问'
},
{
'rules': [
'action == "processtampering"',
],
'score': 200,
'name': '进程执行流劫持'
},
{
'rules': [
'action == "filedeletedetected"',
],
'score': 50,
'name': '删除可执行文件'
},
{
'rules': [
'action == "filecreate" and targetfilename =~ "c:\\\\\\\\windows\\\\\\\\.*"',
'action == "filecreate" and targetfilename =~ ".*\.exe"',
'action == "filecreate" and targetfilename =~ ".*\.cmd"',
'action == "filecreate" and targetfilename =~ ".*\.bat"',
'action == "filecreate" and targetfilename =~ ".*\.dll"',
],
'score': 80,
'name': '在windows目录创建可执行文件'
},
{
'rules': [
'action == "filecreate" and targetfilename =~ "c:\\\\\\\\windows\\\\\\\\.*"',
],
'score': 50,
'name': '在C盘目录创建文件'
},
{
'rules': [
'action == "filecreate" and targetfilename =~ "c:\\\\\\\\users\\\\\\\\.*"',
'action == "filecreate" and targetfilename =~ ".*\.exe"',
'action == "filecreate" and targetfilename =~ ".*\.cmd"',
'action == "filecreate" and targetfilename =~ ".*\.bat"',
'action == "filecreate" and targetfilename =~ ".*\.dll"',
],
'score': 30,
'name': '在appdata目录创建可执行文件'
},
{
'rules': [
'action == "filecreate"',
],
'score': 50,
'name': '创建可疑文件'
},
{
'rules': [
'action == "imageload" and imageloaded == "c:\\windows\\system32\\samlib.dll"',
],
'score': 10,
'name': 'samlib的dll被加载'
}
]

View File

@@ -0,0 +1,106 @@
rule = [
{
'rules': [
'action == "processaccess" and targetimage =~ ".*lsass.exe"',
],
'attck_hit':['T1003'],
'name': 'OS Credential Dumping: LSASS Memory'
},
{
'rules': [
'action == "processaccess" and calltrace =~ ".*unknown.*" and not calltrace =~ ".*conpty\.node.*" and not calltrace =~ ".*java\.dll.*" and not calltrace =~ ".*appvisvsubsystems64\.dll.*" and not calltrace =~ ".*twinui\.dll.*" and not calltrace =~ ".*nativeimages.*" and not targetimage == "c:\\windows\\system32\\cmd.exe"',
],
'attck_hit':['T1620'],
'name': 'Reflective Code Loading'
},
{
'rules': [
'action == "processaccess" and calltrace =~ ".*wshom\.ocx.*"',
'action == "processaccess" and calltrace =~ ".*shell32\.dll.*"',
'action == "processaccess" and calltrace =~ ".*dbgcore\.dll.*"',
'action == "processaccess" and calltrace =~ ".*kernelbase\.dll\+de67e.*"',
'action == "processaccess" and calltrace =~ ".*framedynos\.dll.*"',
],
'attck_hit':['T1559.001'],
'name': 'Inter-Process Communication: Component Object Model'
},
# todo 懒得做详细的规则了.加油完善规则吧
{
'rules': [
'action == "createremotethread"',
],
'attck_hit':['T1055'],
'name': 'Process Injection'
},
{
'rules': [
'action == "filecreatestreamhash"',
],
'attck_hit':['T1564.004'],
'name': 'Hide Artifacts: NTFS File Attributes'
},
{
'rules': [
'action == "dnsquery"',
],
'attck_hit':['T1071.004'],
'name': 'Application Layer Protocol: DNS'
},
{
'rules': [
'action == "networkconnect"',
],
'attck_hit':['T1071'],
'name': 'Application Layer Protocol'
},
{
'rules': [
'action == "clipboardchange"',
],
'attck_hit':['T1115'],
'name': 'Clipboard Data Monitor API'
},
{
'rules': [
'action == "processtampering"',
],
'attck_hit':['T1574'],
'name': 'Hijack Execution Flow'
},
{
'rules': [
'action == "filecreate" and targetfilename =~ "c:\\\\\\\\windows\\\\\\\\.*"',
'action == "filecreate" and targetfilename =~ ".*\.exe"',
'action == "filecreate" and targetfilename =~ ".*\.cmd"',
'action == "filecreate" and targetfilename =~ ".*\.bat"',
'action == "filecreate" and targetfilename =~ ".*\.dll"',
],
'attck_hit':['T1036.005'],
'name': 'Masquerading: Match Legitimate Name or Location'
},
{
'rules': [
'action == "filecreate" and targetfilename =~ "c:\\\\\\\\windows\\\\\\\\.*"',
],
'attck_hit':['T1036.005'],
'name': 'Masquerading: Match Legitimate Name or Location'
},
{
'rules': [
'action == "filecreate" and targetfilename =~ "c:\\\\\\\\users\\\\\\\\.*"',
'action == "filecreate" and targetfilename =~ ".*\.exe"',
'action == "filecreate" and targetfilename =~ ".*\.cmd"',
'action == "filecreate" and targetfilename =~ ".*\.bat"',
'action == "filecreate" and targetfilename =~ ".*\.dll"',
],
'attck_hit':['T1036.005'],
'name': 'Masquerading: Match Legitimate Name or Location'
},
{
'rules': [
'action == "imageload" and imageloaded == "c:\\windows\\system32\\samlib.dll"',
],
'attck_hit':['T1003.002'],
'name': 'OS Credential Dumping: Security Account Manager'
}
]

View File

@@ -0,0 +1,8 @@
rule = [
{'name': "Ransomware", 'rules': ['T1071',
'T1036.005', 'T1620', 'T1564.001', 'T1222.001', 'T1059.005', 'T1543.003', 'T1490'], 'hit_num': 7, 'score':100},
{'name': "APT-System discovery", 'rules': ['T1018',
'T1087.001', 'T1087.001', 'T1082', 'T1016'], 'hit_num': 3, 'score':65},
{'name': "APT-Hydra", 'rules': ['T1027.004',
'T1018', 'T1559.001', 'T1218.011', 'T1059.001', 'T1059.005', 'T1570', 'T1087.002', 'T1564', 'T1106', 'T1082', 'T1087.001', 'T1003', 'T1071'], 'hit_num': 10, 'score':100}
]

View File

@@ -0,0 +1,314 @@
rule = [
{
'rules': [
'originalfilename =~ ".*taskill.exe.*"',
'originalfilename =~ ".*net.exe.*" and commandline =~ ".*stop.*"',
'originalfilename =~ ".*sc.exe.*" and commandline =~ ".*config.*" and commandline =~ ".*disabled.*"',
],
'attck_hit':['T1489'],
'score': 30,
'name': 'Service Stop'
},
{
'rules': [
'originalfilename =~ ".*curl.exe" or originalfilename =~ ".*wget.exe" or originalfilename =~ ".*dget.exe"',
'originalfilename =~ ".*certutil.exe"',
'originalfilename =~ ".*powershell.exe" and commandline =~ ".*invoke-webrequest.*"'
],
'attck_hit':['T1105'],
'score': 30,
'name':'Ingress Tool Transfer'
},
{
'rules': [
'image =~ ".*\.doc\.exe"',
'image =~ ".*\.docx\.exe"',
'image =~ ".*\.ppt\.exe"',
'image =~ ".*\.pdf\.exe"',
'image =~ ".*\.html\.exe"',
'image =~ ".*\.htm\.exe"',
'image =~ ".*\.zip\.exe"',
'image =~ ".*\.rar\.exe"'
],
'attck_hit':['T1036.007'],
'score': 60,
'name':'Masquerading: Double File Extension'
},
{
'rules': [
'commandline =~ ".*-k dcomlaunch.*"'
],
'attck_hit':['T1559.001'],
'score': 30,
'name':'Inter-Process Communication: Component Object Model'
},
{
'rules': [
'originalfilename =~ ".*vssadmin.exe.*" and commandline =~ ".*create.*"',
],
'attck_hit':['T1003.003'],
'score': 30,
'name':'OS Credential Dumping: NTDS'
},
{
'rules': [
'originalfilename =~ ".*wbadmin.exe.*" and commandline =~ ".*delete.*"',
'originalfilename =~ ".*bcdedit.exe" and commandline =~ ".*recoveryenabled.*no.*"',
'originalfilename =~ ".*bcdedit.exe" and commandline =~ ".*bootstatuspolicy.*ignoreallfailures.*"',
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*shadowcopy.*" and commandline =~ ".*delete.*"',
'originalfilename =~ ".*vssadmin.exe" and commandline =~ ".*shadows.*" and commandline =~ ".*delete.*"',
],
'attck_hit':['T1490'],
'score': 30,
'name': 'Inhibit System Recovery'
},
{
'rules': [
'originalfilename =~ ".*net.exe.*" and commandline =~ ".*view.*"',
'originalfilename =~ ".*net.exe.*" and commandline =~ ".*group.*"',
'originalfilename =~ ".*ping.exe"',
],
'attck_hit':['T1018'],
'score': 10,
'name': 'Remote System Discovery'
},
{
'rules': [
'originalfilename =~ ".*fsutil.exe.*" and commandline =~ ".*deletejournal.*"',
],
'attck_hit':['T1070.004'],
'score': 10,
'name': 'Indicator Removal on Host'
},
{
'rules': [
'originalfilename =~ ".*net.exe.*" and commandline =~ ".*user.*"',
'originalfilename =~ ".*whoami.*"',
'originalfilename =~ ".*query.exe"',
'originalfilename =~ ".*setspn.exe"',
'originalfilename =~ ".*cmdkey.exe.*"'
],
'attck_hit':['T1087.001'],
'score': 30,
'name': 'Account Discovery: Local Account'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*useraccount.*"',
],
'attck_hit':['T1087.001', 'T1047'],
'score': 30,
'name': 'Account Discovery: Local Account by wmic'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*startup.*"',
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*share.*"',
],
'attck_hit':['T1082', 'T1047'],
'score': 30,
'name': 'System Information Discovery by wmic'
},
{
'rules': [
'originalfilename =~ ".*systeminfo.exe"',
'originalfilename =~ ".*chcp.com"'
],
'attck_hit':['T1082'],
'score': 10,
'name': 'System Information Discovery'
},
{
'rules': [
'originalfilename =~ ".*tasklist.exe"',
],
'attck_hit':['T1057'],
'score': 10,
'name': 'Process Discovery'
},
{
'rules': [
'originalfilename =~ ".*at.exe.*"',
],
'attck_hit':['T1053.002'],
'score': 10,
'name': 'Scheduled Task/Job: at'
},
{
'rules': [
'originalfilename =~ ".*schtasks.exe.*"',
],
'attck_hit':['T1053.005'],
'score': 10,
'name': 'Scheduled Task/Job: Scheduled Task'
},
{
'rules': [
'image =~ ".*\\\\\\\\appdata\\\\\\\\local\\\\\\\\temp\\\\\\\\.*" or image =~ ".*\\\\\\\\windows\\\\\\\\temp\\\\\\\\.*"',
],
'attck_hit':['T1106'],
'score': 10,
'name': 'Execution: Native API'
},
{
'rules': [
'originalfilename =~ ".*rubeus.*" and commandline =~ ".*domain.*"',
],
'attck_hit':['T1558.003'],
'score': 10,
'name': 'Steal or Forge Kerberos Tickets: Kerberoasting'
},
{
'rules': [
'originalfilename =~ ".*\u202e.*"',
],
'attck_hit':['T1564'],
'score': 10,
'name': 'Hide Artifacts'
},
{
'rules': [
'parentimage =~ ".*mmc.exe" and commandline =~ ".*eventvwr\.msc.*"',
],
'attck_hit':['T1218.014'],
'score': 10,
'name': 'System Binary Proxy Execution: MMC'
},
{
'rules': [
'originalfilename =~ ".*net.exe" and commandline =~ ".*domain.*"',
'originalfilename =~ ".*net.exe" and commandline =~ ".*view.*"',
'originalfilename =~ ".*net.exe" and commandline =~ ".*workstation.*"'
],
'attck_hit':['T1087.002'],
'score': 10,
'name': 'Account Discovery: Domain Account'
},
{
'rules': [
'originalfilename =~ ".*netsh.exe" and commandline =~ ".*firewall.*"',
],
'attck_hit':['T1562.004'],
'score': 10,
'name': 'Impair Defenses: Disable or Modify System Firewall'
},
{
'rules': [
'originalfilename =~ ".*ipconfig.exe"',
'originalfilename =~ ".*netstat.exe"'
],
'attck_hit':['T1016'],
'score': 10,
'name': 'System Network Configuration Discovery'
},
{
'rules': [
'originalfilename =~ ".*attrib.exe"',
],
'attck_hit':['T1564.001'],
'score': 10,
'name': 'Hide Artifacts: Hidden Files and Directories'
},
{
'rules': [
'originalfilename =~ ".*psexesvc.exe"',
],
'attck_hit':['T1570'],
'score': 10,
'name': 'Lateral Tool Transfer'
},
{
'rules': [
'originalfilename =~ "\\\\\\\\.*\\\\\\C\$.*"',
],
'attck_hit':['T1080'],
'score': 10,
'name': 'Taint Shared Content'
},
{
'rules': [
'originalfilename =~ ".*icacls.exe"',
],
'attck_hit':['T1222.001'],
'score': 10,
'name': 'Windows File and Directory Permissions Modification'
},
{
'rules': [
'parentimage =~ ".*services.exe"',
],
'attck_hit':['T1543.003'],
'score': 10,
'name': 'Create or Modify System Process: Windows Service'
},
{
'rules': [
'originalfilename =~ ".*werfault.exe" and parentimage =~ ".*svchost.exe"',
],
'attck_hit':['T1218'],
'score': 10,
'name': 'System Binary Proxy Execution'
},
{
'rules': [
'originalfilename =~ ".*wscript.exe"',
'originalfilename =~ ".*cscript.exe"',
],
'attck_hit':['T1059.005'],
'score': 10,
'name': 'Command and Scripting Interpreter: Visual Basic'
},
{
'rules': [
'originalfilename =~ ".*mofcomp.exe.*"'
],
'attck_hit':['T1546.015'],
'score': 10,
'name':'Event Triggered Execution: Component Object Model Hijacking'
},
{
'rules': [
'originalfilename =~ ".*csc.exe.*"'
],
'attck_hit':['T1027.004'],
'score': 10,
'name':'Compile After Delivery'
},
# https://attack.mitre.org/software/S0552/
{
'rules': [
'originalfilename =~ ".*adfind.exe.*"'
],
'attck_hit':['T1018'],
'score': 10,
'name':'Remote System Discovery'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe.*"'
],
'attck_hit':['T1559.001'],
'score': 30,
'name':'Windows Management Instrumentation'
},
{
'rules': [
'originalfilename =~ ".*rundll32.exe.*"'
],
'attck_hit':['T1218.011'],
'score': 10,
'name':'System Binary Proxy Execution: Rundll32'
},
{
'rules': [
'originalfilename =~ ".*powershell.exe"'
],
'attck_hit':['T1059.001'],
'score': 10,
'name':'Command and Scripting Interpreter: PowerShell'
},
]

View File

@@ -0,0 +1,50 @@
rule = [
{
'rules': [
'action == "processaccess" and targetimage =~ ".*lsass.exe" and grantedaccess & 0x0010 and sourceimage =~ ".*rundll32.exe"',
],
'attck_hit':['T1003.002'],
'score': 100,
'name': '已知内存加载mimikazt行为'
},
{
'rules': [
'action == "processaccess" and sourceimage =~ ".*office16.*" and calltrace =~ ".*kernelbase\.dll.*"',
],
'attck_hit':['T1003.002'],
'score': 60,
'name': 'office异常进程内存'
},
{
'rules': [
'action == "pipecreate" and pipename =~ ".*msagent.*"',
'action == "pipecreate" and pipename =~ ".*msse.*"',
'action == "pipecreate" and pipename =~ ".*postex_.*"',
'action == "pipecreate" and pipename =~ ".*postex_ssh.*"',
'action == "pipecreate" and pipename =~ ".*status_.*"',
],
'attck_hit':['T1003.002'],
'score': 100,
'name': '已知CobalStrike'
},
{
'rules': [
'action == "pipecreate" and pipename =~ ".*paexec.*"',
'action == "pipecreate" and pipename =~ ".*remcom.*"',
'action == "pipecreate" and pipename =~ ".*csexec.*"'
],
'attck_hit':['T1003.002'],
'score': 100,
'name': '已知内网横向工具'
},
{
'rules': [
'action == "pipecreate" and pipename =~ ".*lsadump.*"',
'action == "pipecreate" and pipename =~ ".*cachedump.*"',
'action == "pipecreate" and pipename =~ ".*wceservicepipe.*"'
],
'attck_hit':['T1003.002'],
'score': 100,
'name': '已知mimikazt内存dump'
},
]

View File

@@ -0,0 +1,35 @@
rule = [
{
'rules': [
'originalfilename =~ ".*todesk_service.*" or originalfilename =~ ".*sunloginclient.*" or originalfilename =~ ".*teamviewer_service.exe.*" or originalfilename =~ ".*logmein.*" or originalfilename =~ ".*dwrcs.*" or originalfilename =~ ".*aa_v3.*" or originalfilename =~ ".*screenconnect.*" or originalfilename =~ ".*tvnserver.*" or originalfilename =~ ".*vncserver.*"',
],
'attck_hit':['T1133'],
'score': 30,
'name': '已知远程协助程序'
},
{
'rules': [
'originalfilename =~ ".*phoenixminer.*" or originalfilename =~ ".*ccminer.*" or originalfilename =~ ".*csminer.exe.*" or originalfilename =~ ".*xmrig.*" or originalfilename =~ ".*xmr-stak.*"',
],
'attck_hit':['T1496'],
'score': 100,
'name': '已知挖矿程序'
},
{
'rules': [
'originalfilename =~ "\\\\\\.*" and parentimage =~ ".*services.exe"',
],
'attck_hit':['T1021.006'],
'score': 100,
'name': '远程服务被创建'
},
{
'rules': [
'commandline =~ ".*__\d{10}\."',
'originalfilename =~ ".*wmi_share.exe"',
],
'attck_hit':['T00000'],
'score': 100,
'name': 'wmic内网横向移动被触发'
},
]

View File

@@ -1,405 +0,0 @@
rule = [
{
'rules': [
'originalfilename =~ ".*taskill.exe.*"',
'originalfilename =~ ".*net.exe.*" and commandline =~ ".*stop.*"',
'originalfilename =~ ".*sc.exe.*" and commandline =~ ".*config.*" and commandline =~ ".*disabled.*"',
],
'score': 40,
'name': '通过系统程序关闭进程'
},
{
'rules': [
'originalfilename =~ ".*curl.exe" or originalfilename =~ ".*wget.exe" or originalfilename =~ ".*dget.exe"'
],
'score': 40,
'name':'通过应用下载文件'
},
{
'rules': [
'image =~ ".*\.doc\.exe"',
'image =~ ".*\.docx\.exe"',
'image =~ ".*\.ppt\.exe"',
'image =~ ".*\.pdf\.exe"',
'image =~ ".*\.html\.exe"',
'image =~ ".*\.htm\.exe"',
'image =~ ".*\.zip\.exe"',
'image =~ ".*\.rar\.exe"'
],
'score': 30,
'name':'启动双扩展名文件'
},
{
'rules': [
'commandline =~ ".*-k dcomlaunch.*"'
],
'score': 30,
'name':'通过DCOM启动了进程'
},
{
'rules': [
'originalfilename =~ ".*wbadmin.exe.*" and commandline =~ ".*delete.*"',
],
'score': 70,
'name': '通过wbadmin删除备份'
},
{
'rules': [
'originalfilename =~ ".*net.exe.*" and commandline =~ ".*view.*"',
],
'score': 70,
'name': '通过net进行远程系统发现'
},
{
'rules': [
'originalfilename =~ ".*fsutil.exe.*" and commandline =~ ".*deletejournal.*"',
],
'score': 70,
'name': '通过系统工具删除USN'
},
{
'rules': [
'originalfilename =~ ".*net.exe.*" and commandline =~ ".*user.*"',
],
'score': 70,
'name': '通过net进行系统用户发现'
},
{
'rules': [
'originalfilename =~ ".*schtasks.exe.*" and commandline =~ ".*create.*"',
],
'score': 70,
'name': '通过系统应用创建计划任务'
},
{
'rules': [
'originalfilename =~ ".*schtasks.exe.*" and commandline =~ ".*delete.*"',
],
'score': 40,
'name': '通过系统应用删除计划任务'
},
{
'rules': [
'originalfilename =~ ".*vssadmin.exe.*" and commandline =~ ".*create.*"',
],
'score': 40,
'name': '通过系统程序创建卷影备份'
},
{
'rules': [
'originalfilename =~ ".*todesk_service.*" or originalfilename =~ ".*sunloginclient.*" or originalfilename =~ ".*teamviewer_service.exe.*" or originalfilename =~ ".*logmein.*" or originalfilename =~ ".*dwrcs.*" or originalfilename =~ ".*aa_v3.*" or originalfilename =~ ".*screenconnect.*" or originalfilename =~ ".*tvnserver.*" or originalfilename =~ ".*vncserver.*"',
],
'score': 20,
'name': '已知远程协助程序'
},
{
'rules': [
'originalfilename =~ ".*phoenixminer.*" or originalfilename =~ ".*ccminer.*" or originalfilename =~ ".*csminer.exe.*" or originalfilename =~ ".*xmrig.*" or originalfilename =~ ".*xmr-stak.*"',
],
'score': 300,
'name': '已知挖矿程序'
},
{
'rules': [
'image =~ ".*\\\\\\\\appdata\\\\\\\\local\\\\\\\\temp\\\\\\\\.*" or image =~ ".*\\\\\\\\windows\\\\\\\\temp\\\\\\\\.*"',
],
'score': 40,
'name': '从临时文件创建进程'
},
{
'rules': [
'originalfilename =~ ".*rubeus.*" and commandline =~ ".*domain.*"',
],
'score': 100,
'name': '通过系统工具获取域登陆令牌'
},
{
'rules': [
'originalfilename =~ ".*whoami.*"',
],
'score': 70,
'name': 'whoami被执行'
},
{
'rules': [
'originalfilename =~ ".*\u202e.*"',
],
'score': 100,
'name': '伪装名字程序被执行'
},
{
'rules': [
'parentimage =~ ".*mmc.exe" and commandline =~ ".*eventvwr\.msc.*"',
],
'score': 40,
'name': '高权限进程被创建'
},
{
'rules': [
'originalfilename =~ ".*bcdedit.exe" and commandline =~ ".*recoveryenabled.*no.*"',
'originalfilename =~ ".*bcdedit.exe" and commandline =~ ".*bootstatuspolicy.*ignoreallfailures.*"',
],
'score': 80,
'name': '通过系统工具关闭系统恢复'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*useraccount.*"',
],
'score': 70,
'name': '通过wmic进行系统用户发现'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*startup.*"',
],
'score': 70,
'name': '通过wmic查看系统启动项'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*share.*"',
],
'score': 70,
'name': '通过wmic查看系统共享'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe" and commandline =~ ".*shadowcopy.*" and commandline =~ ".*delete.*"',
],
'score': 70,
'name': 'wmic删除卷影备份'
},
{
'rules': [
'originalfilename =~ ".*vssadmin.exe" and commandline =~ ".*shadows.*" and commandline =~ ".*delete.*"',
],
'score': 70,
'name': 'vssadmin删除卷影备份'
},
{
'rules': [
'originalfilename =~ ".*tasklist.exe"',
],
'score': 50,
'name': '通过tasklist查看系统信息'
},
{
'rules': [
'originalfilename =~ ".*systeminfo.exe"',
],
'score': 70,
'name': '通过systeminfo查看系统信息'
},
{
'rules': [
'originalfilename =~ ".*query.exe"',
],
'score': 70,
'name': '通过query进行系统用户发现'
},
{
'rules': [
'originalfilename =~ ".*net.exe" and commandline =~ ".*domain.*"',
'originalfilename =~ ".*net.exe" and commandline =~ ".*view.*"',
'originalfilename =~ ".*net.exe" and commandline =~ ".*workstation.*"'
],
'score': 70,
'name': '通过net进行本地系统用户发现'
},
{
'rules': [
'originalfilename =~ ".*setspn.exe"',
],
'score': 70,
'name': '通过setspn进行本地系统用户发现'
},
{
'rules': [
'originalfilename =~ ".*netsh.exe" and commandline =~ ".*firewall.*"',
],
'score': 70,
'name': '通过netsh关闭防火墙'
},
{
'rules': [
'originalfilename =~ ".*cmd.exe" and commandline =~ ".*ipconfig.*"',
],
'score': 80,
'name': 'cmd启动ipconfig'
},
{
'rules': [
'originalfilename =~ ".*cmd.exe" and commandline =~ ".*net.*"',
],
'score': 60,
'name': 'cmd启动net'
},
{
'rules': [
'originalfilename =~ ".*netstat.exe"',
],
'score': 40,
'name': 'netstat被运行'
},
{
'rules': [
'originalfilename =~ ".*ping.exe"',
],
'score': 40,
'name': 'ping被运行'
},
{
'rules': [
'originalfilename =~ ".*ipconfig.exe"',
],
'score': 40,
'name': 'ipconfig被运行'
},
{
'rules': [
'originalfilename =~ ".*attrib.exe"',
],
'score': 40,
'name': 'attrib被运行'
},
{
'rules': [
'originalfilename =~ ".*PSEXESVC.exe"',
],
'score': 100,
'name': 'PSEXESVC内网横向移动'
},
{
'rules': [
'originalfilename =~ "\\\\\\\\.*\\\\\\C\$.*"',
],
'score': 100,
'name': 'SMB共享启动进程'
},
{
'rules': [
'commandline =~ ".*__\d{10}\."',
'originalfilename =~ ".*wmi_share.exe"',
],
'score': 100,
'name': 'wmic内网横向移动被触发'
},
{
'rules': [
'originalfilename =~ ".*icacls.exe"',
],
'score': 40,
'name': 'icacls被运行'
},
{
'rules': [
'originalfilename =~ "\\\\\\.*" and parentimage =~ ".*services.exe"',
],
'score': 100,
'name': '远程服务被创建'
},
{
'rules': [
'parentimage =~ ".*services.exe"',
],
'score': 30,
'name': '从服务创建的进程'
},
{
'rules': [
'parentimage =~ ".*svchost.exe"',
'originalfilename =~ ".*werfault.exe"'
],
'score': 60,
'name': 'svchost.exe启动了werfault'
},
{
'rules': [
'parentimage =~ ".*werfault.exe"',
],
'score': 30,
'name': '从werfault创建的进程'
},
{
'rules': [
'originalfilename =~ ".*wscript.exe"',
'originalfilename =~ ".*cscript.exe"',
],
'score': 40,
'name': '脚本程序被运行'
},
{
'rules': [
'originalfilename =~ ".*mofcomp.exe.*"'
],
'score': 80,
'name':'注册WMI订阅'
},
{
'rules': [
'originalfilename =~ ".*csc.exe.*"'
],
'score': 80,
'name':'.NET编译器被启动'
},
{
'rules': [
'originalfilename =~ ".*cmdkey.exe.*"'
],
'score': 100,
'name':'通过系统应用查询本机账户'
},
{
'rules': [
'originalfilename =~ ".*adfind.exe.*"'
],
'score': 80,
'name':'通过系统程序发现域信息'
},
# 这些是保底规则 必须放到最底下才匹配
{
'rules': [
'originalfilename =~ ".*cmd.exe"'
],
'score': 30,
'name':'执行CMD命令'
},
{
'rules': [
'originalfilename =~ ".*chcp.com"'
],
'score': 30,
'name':'执行chcp.com'
},
{
'rules': [
'originalfilename =~ ".*wmic.exe.*"'
],
'score': 80,
'name':'执行wmic'
},
{
'rules': [
'originalfilename =~ ".*rundll32.exe.*"'
],
'score': 20,
'name':'通过rundll32启动进程'
},
{
'rules': [
'originalfilename =~ ".*certutil.exe"',
'originalfilename =~ ".*curl.exe"',
'originalfilename =~ ".*powershell.exe" and commandline =~ ".*invoke-webrequest.*"'
],
'score': 80,
'name':'通过系统命令下载文件'
},
{
'rules': [
'originalfilename =~ ".*powershell.exe"'
],
'score': 80,
'name':'Powershell被执行'
},
]

View File

@@ -87,6 +87,8 @@ class threat_log(g_base):
risk_score = Column(Integer)
# 命中的规则
hit_rule = Column(String)
# attck命中
attck_hit_list = Column(String)
# json字段
data = Column(String)
# 时间戳
@@ -262,7 +264,7 @@ def select_threat_by_chain_id(host, process_chain_hash, type):
def update_threat_log(
host, risk_score, hit_rule_json, process_chain_hash, raw_json, type, is_end
host, risk_score, hit_rule_json, attck_hit_list_json, process_chain_hash, raw_json, type, is_end
):
global g_threat_table
global g_engine
@@ -272,6 +274,7 @@ def update_threat_log(
.values(
risk_score=risk_score,
hit_rule=hit_rule_json,
attck_hit_list=attck_hit_list_json,
data=raw_json,
is_end=int(is_end),
)
@@ -335,6 +338,7 @@ def query_all_threat_log(query_type):
threat_log.is_end,
threat_log.start_process_info,
threat_log.handle_type,
threat_log.attck_hit_list,
)
.all()
)
@@ -353,6 +357,7 @@ def query_all_threat_log(query_type):
threat_log.is_end,
threat_log.start_process_info,
threat_log.handle_type,
threat_log.attck_hit_list
)
.filter_by(handle_type=query_type)
.all()
@@ -365,6 +370,7 @@ def push_threat_log(
host,
risk_score,
hit_rule_json,
attck_hit_list_json,
process_chain_hash,
raw_json,
type,
@@ -378,6 +384,7 @@ def push_threat_log(
risk_score=risk_score,
process_chain_hash=process_chain_hash,
hit_rule=hit_rule_json,
attck_hit_list=attck_hit_list_json,
type=type,
data=raw_json,
timestamp=int(round(time.time() * 1000)),

View File

@@ -1 +1 @@
<!DOCTYPE html><html><head><title>Duck Sys Eye</title><meta charset=utf-8><meta name=description content=syseye><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width"><link rel=icon type=image/png sizes=128x128 href=icons/favicon-128x128.png><link rel=icon type=image/png sizes=96x96 href=icons/favicon-96x96.png><link rel=icon type=image/png sizes=32x32 href=icons/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=icons/favicon-16x16.png><link rel=icon type=image/ico href=favicon.ico><script defer src=js/vendor.8b656787.js></script><script defer src=js/app.8fbb593d.js></script><link href=css/vendor.5b8581f0.css rel=stylesheet><link href=css/app.31d6cfe0.css rel=stylesheet></head><body><div id=q-app></div></body></html>
<!DOCTYPE html><html><head><title>Duck Sys Eye</title><meta charset=utf-8><meta name=description content=syseye><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width"><link rel=icon type=image/png sizes=128x128 href=icons/favicon-128x128.png><link rel=icon type=image/png sizes=96x96 href=icons/favicon-96x96.png><link rel=icon type=image/png sizes=32x32 href=icons/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=icons/favicon-16x16.png><link rel=icon type=image/ico href=favicon.ico><script defer src=js/vendor.8b656787.js></script><script defer src=js/app.b7308b45.js></script><link href=css/vendor.5b8581f0.css rel=stylesheet><link href=css/app.31d6cfe0.css rel=stylesheet></head><body><div id=q-app></div></body></html>

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -155,8 +155,9 @@ def pull_chain_data():
"type": threat_data[3],
"risk_score": threat_data[4],
"hit_rule": json.loads(threat_data[5]),
"chain": json.loads(threat_data[6]),
"is_end": threat_data[7],
"hit_attck": json.loads(threat_data[6]),
"chain": json.loads(threat_data[7]),
"is_end": threat_data[8],
}
return {"data": return_data}
@@ -181,6 +182,7 @@ def process_chain():
"id": iter[6],
"is_end": iter[7],
"start_process": json.loads(iter[8]),
"attck_hit_list": json.loads(iter[10]),
}
)
return {"data": return_data}

View File

@@ -52,13 +52,27 @@
</q-chip>
</div>
<div>
产生的威胁:
<template v-for="(index, operation) in threat.hit_rule" :key="index">
ATTCK命中:
<template v-for="(index, operation) in threat.attck_hit_list" :key="index">
<q-chip square color="rgb(239,243,246)">
{{ operation }}&nbsp;({{ index }})
</q-chip>
</template>
</div>
<div>
产生的威胁:
<template v-for="(index, operation) in threat.hit_rule" :key="index">
<q-chip square color="red" text-color="white">
{{ operation }}&nbsp;({{ index }})
</q-chip>
</template>
<template v-if="JSON.stringify(threat.hit_rule) == '{}'">
<q-chip square color="negative" text-color="white">
<!--crowdstrike: 这活我熟-->
机器学习引擎
</q-chip>
</template>
</div>
<div>
<q-btn flat color="accent" @click="show_details(threat.id)" icon="open_in_new">
查看详情
@@ -152,11 +166,32 @@
</q-item>
<q-separator />
<q-item>
<q-item-section>进程命中的规则: <template v-for="(index, operation) in processChainDetails.hitRules" :key="index">
<q-item-section>进程命中的规则:
<template v-for="(index, operation) in processChainDetails.hitRules" :key="index">
<q-chip square color="rgb(239,243,246)">
{{ operation }}&nbsp;({{ index }})
</q-chip>
</template></q-item-section>
</template>
<template v-if="JSON.stringify(processChainDetails.hitRules) == '{}'">
<q-chip square color="rgb(239,243,246)">
</q-chip>
</template>
</q-item-section>
</q-item>
<q-item>
<q-item-section>attck矩阵:
<template v-for="(index, operation) in processChainDetails.hitAttck" :key="index">
<q-chip square color="rgb(239,243,246)">
{{ operation }}&nbsp;({{ index }})
</q-chip>
</template>
<template v-if="JSON.stringify(processChainDetails.hitAttck) == '{}'">
<q-chip square color="rgb(239,243,246)">
</q-chip>
</template>
</q-item-section>
</q-item>
<q-item>
<q-btn icon="search" outline style="color: grey;width: 100%;" label="搜索hash" @click="search_vt(processChainDetails.md5)" />
@@ -197,7 +232,8 @@ export default defineComponent({
processChainDetails: {
hash: '',
prams: '',
hitRule: [],
hitRules: [],
hitAttck: [],
isWhite: false,
whiteListReason: ''
},
@@ -371,7 +407,8 @@ export default defineComponent({
params: data.params,
pid: data.pid,
ppid: data.ppid,
hitRules: data.operationlist,
hitRules: data.operationlist === undefined ? {} : data.operationlist,
hitAttck: data.attck_hit_list === undefined ? {} : data.attck_hit_list,
isWhite: false
}
this.query_white_hash(data.md5)

View File

@@ -353,6 +353,8 @@
<Image condition="image">nmap.exe</Image>
<Image condition="image">psinfo.exe</Image>
<!--Ports: Suspicious-->
<DestinationPort name="HTTP" condition="is">80</DestinationPort> <!--SSH protocol, monitor admin connections-->
<DestinationPort name="HTTPS" condition="is">443</DestinationPort> <!--SSH protocol, monitor admin connections-->
<DestinationPort name="SSH" condition="is">22</DestinationPort> <!--SSH protocol, monitor admin connections-->
<DestinationPort name="Telnet" condition="is">23</DestinationPort> <!--Telnet protocol, monitor admin connections, insecure-->
<DestinationPort name="SMTP" condition="is">25</DestinationPort> <!--SMTP mail protocol port, insecure, used by threats-->