增加白名单、进程链增加详细信息

增加白名单、进程链增加详细信息
This commit is contained in:
huoji
2022-08-31 17:52:26 +08:00
parent 5c15aa975d
commit e3ae734150
29 changed files with 666 additions and 335 deletions

BIN
Image/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

@@ -21,16 +21,23 @@ https://key08.com/index.php/2022/08/09/1505.html
5. 对RPC、COM、ALPC基本无能为力 5. 对RPC、COM、ALPC基本无能为力
6. 不支持更高级的扩展检测,如检测脚本、下发规则,主机链 6. 不支持更高级的扩展检测,如检测脚本、下发规则,主机链
7. 受限于Sysmon,很多att&ck的T没有覆盖,也无法覆盖. 7. 受限于Sysmon,很多att&ck的T没有覆盖,也无法覆盖.
8. 没有响应能力,只能被动记录.
请牢记,RmEye自身定位是轻量级威胁检出工具 请牢记,RmEye自身定位是轻量级威胁检出工具
### 最新新闻 ### 最新新闻
2022/8/31:
增加进程白名单系统,现在能给进程加白名单了.在打开进程链后,点击某个进程加入白名单即可
2022/8/29: 2022/8/29:
增加uac提权检测插件`uac_bypass_detect`,但是受限于sysmon,没有办法获取RPC信息,因此只能检测一部分的UAC提权行为.并且有误报,请酌情考虑 增加uac提权检测插件`uac_bypass_detect`,但是受限于sysmon,没有办法获取RPC信息,因此只能检测一部分的UAC提权行为.并且有误报,请酌情考虑
### 检出截图 ### 检出截图
威胁列表: 威胁列表:
![image](Image/1.png) ![image](Image/1.png)
powershell: 进程链行为回溯
![image](Image/8.png)
powershell恶意执行:
![image](Image/2.png) ![image](Image/2.png)
apt样本: apt样本:
![image](Image/3.png) ![image](Image/3.png)
@@ -148,8 +155,7 @@ https://github.com/SwiftOnSecurity/sysmon-config
### 交流 ### 交流
开源的目的不是为了免费填鸭式教学,或者被免费拿去发公众号引流、去拿去集成产品方案去赚钱,而是要一起完善这个工具,从而实现共赢. 开源的目的不是为了免费填鸭式教学,或者被免费拿去发公众号引流、去拿去集成产品方案去赚钱,而是要一起完善这个工具,从而实现共赢.
扫一扫加入这个工具内部测试群,这样就能获取实时动态 扫一扫加入这个工具的交流群,这样就能获取实时动态.参与开发、参与交流规则编写等等.欢迎加入
![image](Image/group2.png) ![image](Image/group2.png)
### 特别感谢 ### 特别感谢

17
Server/hash_white_list.py Normal file
View File

@@ -0,0 +1,17 @@
import sql
g_white_list = []
def add_white_list(path, hash, reason):
global g_white_list
if hash in g_white_list:
return False
g_white_list.append(hash)
sql.push_white_list(path, hash, reason)
def synchronization_white_list():
sql_data = sql.query_all_white_list()
for data in sql_data:
g_white_list.append(data[1])
print("sync white list success, size: {}".format(len(sql_data)))

View File

@@ -8,6 +8,7 @@ import sql
import global_vars import global_vars
import config import config
import plugin import plugin
import hash_white_list
def process_log(host, json_log, raw_log): def process_log(host, json_log, raw_log):
@@ -53,8 +54,9 @@ def process_log(host, json_log, raw_log):
parent_user, parent_user,
host, host,
) )
is_white_list = hash in hash_white_list.g_white_list
child = process.Process( child = process.Process(
pid, ppid, path, params, create_time, hash, parent_user, host pid, ppid, path, params, create_time, hash, parent_user, host, is_white_list
) )
chain = process.create_chain(parent_process) chain = process.create_chain(parent_process)
chain.add_process(child, parent_pid) chain.add_process(child, parent_pid)
@@ -63,8 +65,9 @@ def process_log(host, json_log, raw_log):
child.set_score(score, rule_hit_name) child.set_score(score, rule_hit_name)
had_threat = global_vars.THREAT_TYPE_PROCESS had_threat = global_vars.THREAT_TYPE_PROCESS
else: else:
is_white_list = hash in hash_white_list.g_white_list
child = process.Process( child = process.Process(
pid, ppid, path, params, create_time, hash, user, host pid, ppid, path, params, create_time, hash, user, host, is_white_list
) )
parent_process.chain.add_process(child, ppid) parent_process.chain.add_process(child, ppid)
current_process = child current_process = child
@@ -81,7 +84,8 @@ def process_log(host, json_log, raw_log):
pid = log["processid"] pid = log["processid"]
current_process = process.get_process_by_pid(pid) current_process = process.get_process_by_pid(pid)
if current_process is not None: if current_process is not None:
plugin.dispath_process_terminal(host, current_process, raw_log, json_log) plugin.dispath_process_terminal(
host, current_process, raw_log, json_log)
current_process.active = False current_process.active = False
current_process.chain.terminate_count += 1 current_process.chain.terminate_count += 1
if current_process.chain.terminate_count >= ( if current_process.chain.terminate_count >= (

View File

@@ -85,7 +85,7 @@ g_ProcessChainList = []
class Process: class Process:
def __init__(self, pid, ppid, path, params, time, md5, user, host): def __init__(self, pid, ppid, path, params, time, md5, user, host, is_white=False):
self.pid = pid self.pid = pid
self.ppid = ppid self.ppid = ppid
self.path = path self.path = path
@@ -105,6 +105,7 @@ class Process:
self.user = user self.user = user
self.chain: ProcessChain = None self.chain: ProcessChain = None
self.host = host self.host = host
self.is_white = is_white
def set_chain_data(self, chain): def set_chain_data(self, chain):
self.chain = chain self.chain = chain
@@ -119,6 +120,8 @@ class Process:
self.rmppid = rmppid self.rmppid = rmppid
def set_score(self, new_score, opertion): def set_score(self, new_score, opertion):
if self.is_white:
return
if opertion not in self.operationlist: if opertion not in self.operationlist:
self.risk_score += new_score self.risk_score += new_score
self.operationlist[opertion] = 1 self.operationlist[opertion] = 1

View File

@@ -17,7 +17,7 @@ rule = [
'rules': [ '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"', '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': 40, 'score': 20,
'name': '异常进程访问' 'name': '异常进程访问'
}, },
{ {

View File

@@ -20,6 +20,8 @@ g_rawdata_table = None
g_rawdata_table_ins = None g_rawdata_table_ins = None
g_threat_table = None g_threat_table = None
g_threat_table_ins = None g_threat_table_ins = None
g_hash_white_list_table = None
g_hash_white_list_table_ins = None
class raw_process_log(g_base): class raw_process_log(g_base):
@@ -62,6 +64,15 @@ class raw_process_log(g_base):
return self.id return self.id
class hash_white_list(g_base):
__tablename__ = "hash_white_list"
id = Column(Integer, primary_key=True)
hash = Column(String)
path = Column(String)
timestamp = Column(Integer)
reason = Column(String)
class threat_log(g_base): class threat_log(g_base):
__tablename__ = "threat_log" __tablename__ = "threat_log"
# 定义各字段 # 定义各字段
@@ -99,8 +110,11 @@ def init():
global g_rawdata_table_ins global g_rawdata_table_ins
global g_threat_table global g_threat_table
global g_threat_table_ins global g_threat_table_ins
global g_hash_white_list_table
global g_hash_white_list_table_ins
g_engine = create_engine("sqlite:///syseye.db?check_same_thread=False", echo=False) g_engine = create_engine(
"sqlite:///syseye.db?check_same_thread=False", echo=False)
g_base.metadata.create_all(g_engine) g_base.metadata.create_all(g_engine)
g_metadata = MetaData(g_engine) g_metadata = MetaData(g_engine)
g_rawdata_table = Table("raw_process_log", g_metadata, autoload=True) g_rawdata_table = Table("raw_process_log", g_metadata, autoload=True)
@@ -109,6 +123,54 @@ def init():
g_threat_table = Table("threat_log", g_metadata, autoload=True) g_threat_table = Table("threat_log", g_metadata, autoload=True)
g_threat_table_ins = g_threat_table.insert() g_threat_table_ins = g_threat_table.insert()
g_hash_white_list_table = Table(
"hash_white_list", g_metadata, autoload=True)
g_hash_white_list_table_ins = g_hash_white_list_table.insert()
def query_white_list_by_hash(pHash):
global g_hash_white_list_table
sql_session = sessionmaker(bind=g_engine)
white_list = sql_session().query(
g_hash_white_list_table).filter_by(hash=pHash).first()
sql_session().close()
return white_list
def delete_white_list(pHash):
global g_hash_white_list_table
global g_engine
conn = g_engine.connect()
result = conn.execute(
delete(g_hash_white_list_table).where(
g_hash_white_list_table.columns.hash == pHash)
)
return result
def push_white_list(pPath, pHash, pReason):
global g_hash_white_list_table_ins
current_time = int(round(time.time() * 1000))
ins = g_hash_white_list_table_ins.values(
path=pPath, hash=pHash, reason=pReason, timestamp=current_time)
# 连接引擎
conn = g_engine.connect()
# 执行语句
result = conn.execute(ins)
return result
def query_all_white_list():
global g_hash_white_list_table
sql_session = sessionmaker(bind=g_engine)
white_list = (
sql_session()
.query(g_hash_white_list_table)
.all()
)
sql_session().close()
return white_list
def push_process_raw( def push_process_raw(
host, host,
@@ -241,7 +303,8 @@ def delete_threat(threat_id):
global g_engine global g_engine
conn = g_engine.connect() conn = g_engine.connect()
result = conn.execute( result = conn.execute(
delete(g_threat_table).where(g_threat_table.columns.id == int(threat_id)) delete(g_threat_table).where(
g_threat_table.columns.id == int(threat_id))
) )
return result return result

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.070221f5.js></script><script defer src=js/app.3ea8aeff.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.3ff22fb9.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>

View File

@@ -1 +1 @@
"use strict";(globalThis["webpackChunksyseye"]=globalThis["webpackChunksyseye"]||[]).push([[193],{2193:(e,t,s)=>{s.r(t),s.d(t,{default:()=>p});var l=s(3673);const n={class:"fullscreen bg-blue text-white text-center q-pa-md flex flex-center"},o=(0,l._)("div",{style:{"font-size":"30vh"}}," 404 ",-1),c=(0,l._)("div",{class:"text-h2",style:{opacity:".4"}}," Oops. Nothing here... ",-1);function a(e,t,s,a,r,i){const u=(0,l.up)("q-btn");return(0,l.wg)(),(0,l.iD)("div",n,[(0,l._)("div",null,[o,c,(0,l.Wm)(u,{class:"q-mt-xl",color:"white","text-color":"blue",unelevated:"",to:"/",label:"Go Home","no-caps":""})])])}const r=(0,l.aZ)({name:"Error404"});var i=s(4260),u=s(9400),h=s(7518),b=s.n(h);const d=(0,i.Z)(r,[["render",a]]),p=d;b()(r,"components",{QBtn:u.Z})}}]); "use strict";(globalThis["webpackChunksyseye"]=globalThis["webpackChunksyseye"]||[]).push([[193],{2193:(e,t,s)=>{s.r(t),s.d(t,{default:()=>p});var l=s(3673);const n={class:"fullscreen bg-blue text-white text-center q-pa-md flex flex-center"},o=(0,l._)("div",{style:{"font-size":"30vh"}}," 404 ",-1),c=(0,l._)("div",{class:"text-h2",style:{opacity:".4"}}," Oops. Nothing here... ",-1);function a(e,t,s,a,r,i){const u=(0,l.up)("q-btn");return(0,l.wg)(),(0,l.iD)("div",n,[(0,l._)("div",null,[o,c,(0,l.Wm)(u,{class:"q-mt-xl",color:"white","text-color":"blue",unelevated:"",to:"/",label:"Go Home","no-caps":""})])])}const r=(0,l.aZ)({name:"Error404"});var i=s(4260),u=s(8240),h=s(7518),b=s.n(h);const d=(0,i.Z)(r,[["render",a]]),p=d;b()(r,"components",{QBtn:u.Z})}}]);

View File

@@ -0,0 +1 @@
"use strict";(globalThis["webpackChunksyseye"]=globalThis["webpackChunksyseye"]||[]).push([[315],{7315:(e,a,t)=>{t.r(a),t.d(a,{default:()=>_});var n=t(3673),s=t(2323);function o(e,a,t,o,i,l){const r=(0,n.up)("q-td"),p=(0,n.up)("q-btn"),d=(0,n.up)("q-tr"),h=(0,n.up)("q-table");return(0,n.wg)(),(0,n.j4)(h,{class:"q-pa-lg",dense:e.$q.screen.lt.md,title:"白名单列表",columns:e.data_columns,rows:e.data_columns_data,loading:e.loading,pagination:e.pagination,"onUpdate:pagination":a[0]||(a[0]=a=>e.pagination=a),onRequest:e.onRequest},{body:(0,n.w5)((a=>[(0,n.Wm)(d,{props:a},{default:(0,n.w5)((()=>[(0,n.Wm)(r,{key:"path",props:a},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(a.row.path),1)])),_:2},1032,["props"]),(0,n.Wm)(r,{key:"hash",props:a},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(a.row.hash),1)])),_:2},1032,["props"]),(0,n.Wm)(r,{key:"reason",props:a},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(a.row.reason),1)])),_:2},1032,["props"]),(0,n.Wm)(r,{key:"timestamp",props:a},{default:(0,n.w5)((()=>[(0,n.Uk)((0,s.zw)(e.time_parase(a.row.timestamp)),1)])),_:2},1032,["props"]),(0,n.Wm)(r,{key:"action",props:a},{default:(0,n.w5)((()=>[(0,n.Wm)(p,{color:"red",label:"移除白名单",onClick:t=>e.delete_white_hash(a.row.hash)},null,8,["onClick"])])),_:2},1032,["props"])])),_:2},1032,["props"])])),_:1},8,["dense","columns","rows","loading","pagination","onRequest"])}var i=t(52),l=t.n(i);const r=(0,n.aZ)({name:"WhiteList",data:function(){return{data_columns:[{name:"path",align:"center",label:"路径",field:"path"},{name:"hash",align:"center",label:"hash",field:"hash"},{name:"reason",align:"center",label:"原因",field:"reason"},{name:"timestamp",align:"center",label:"时间",field:"timestamp"},{name:"action",align:"center",label:"操作",field:"steamid"}],data_columns_data:[],loading:!1,pagination:{sortBy:"desc",descending:!1,page:1,rowsPerPage:10,rowsNumber:10}}},mounted(){this.onRequest({pagination:this.pagination,filter:void 0})},methods:{delete_white_hash(e){l().get("/api/v1/del/white_list?hash="+e).then((e=>{console.log("duck was gone")}))},time_parase(e){const a=e=>e<10?"0"+e:e,t=new Date(Number(e));console.log("time",e);const n=t.getFullYear(),s=t.getMonth()+1,o=t.getDate(),i=t.getHours(),l=t.getMinutes(),r=t.getSeconds();return n+"-"+a(s)+"-"+a(o)+" "+a(i)+":"+a(l)+":"+a(r)},onRequest(e){this.data_columns_data=[],this.loading=!0;const{page:a}=e.pagination;l().get("/api/v1/query/white_list_all").then((e=>{const t=e.data.result;console.log(t);for(let a=0;a<t.length;a++){const e=t[a];this.data_columns_data.push(e)}this.pagination.page=a,this.pagination.rowsNumber=this.data_columns_data.length,this.pagination.rowsPerPage=this.data_columns_data.length,this.loading=!1}))}}});var p=t(4260),d=t(1779),h=t(8186),g=t(3884),u=t(8240),c=t(7518),m=t.n(c);const w=(0,p.Z)(r,[["render",o]]),_=w;m()(r,"components",{QTable:d.Z,QTr:h.Z,QTd:g.Z,QBtn:u.Z})}}]);

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

Binary file not shown.

View File

@@ -1 +0,0 @@
"use strict";(globalThis["webpackChunksyseye"]=globalThis["webpackChunksyseye"]||[]).push([[950],{950:(e,a,t)=>{t.r(a),t.d(a,{default:()=>T});var l=t(3673);const r=(0,l.Uk)(" DuckSysEye内部测试版本v0.0.0.1 "),i=(0,l.Uk)(" 仪表盘 "),n=(0,l.Uk)(" 未处理威胁列表 "),o=(0,l.Uk)(" 已处理威胁列表 "),u=(0,l.Uk)(" 已忽略威胁列表 ");function c(e,a,t,c,s,d){const m=(0,l.up)("q-toolbar-title"),w=(0,l.up)("q-btn"),p=(0,l.up)("q-toolbar"),b=(0,l.up)("q-header"),_=(0,l.up)("q-icon"),h=(0,l.up)("q-item-section"),v=(0,l.up)("q-item"),f=(0,l.up)("q-list"),W=(0,l.up)("q-scroll-area"),k=(0,l.up)("q-drawer"),g=(0,l.up)("router-view"),y=(0,l.up)("q-page-container"),L=(0,l.up)("q-layout"),Z=(0,l.Q2)("ripple");return(0,l.wg)(),(0,l.j4)(L,{view:"lHh Lpr lFf",style:{"background-color":"rgb(239, 243, 246)"}},{default:(0,l.w5)((()=>[(0,l.Wm)(b,{elevated:"","height-hint":"98"},{default:(0,l.w5)((()=>[(0,l.Wm)(p,{class:"text-primary bg-white"},{default:(0,l.w5)((()=>[(0,l.Wm)(m,null,{default:(0,l.w5)((()=>[r])),_:1}),(0,l.Wm)(w,{flat:"",round:"",dense:"",icon:"more_vert"})])),_:1})])),_:1}),(0,l.Wm)(k,{"show-if-above":"",mini:e.miniState,onMouseover:a[4]||(a[4]=a=>e.miniState=!1),onMouseout:a[5]||(a[5]=a=>e.miniState=!0),width:200,breakpoint:500,bordered:"",class:"bg-white text-primary"},{default:(0,l.w5)((()=>[(0,l.Wm)(W,{class:"fit"},{default:(0,l.w5)((()=>[(0,l.Wm)(f,{padding:""},{default:(0,l.w5)((()=>[(0,l.wy)(((0,l.wg)(),(0,l.j4)(v,{active:"dashboard"==e.selectLabel,clickable:"","active-class":"menu-active",onClick:a[0]||(a[0]=a=>e.selectLabel="dashboard"),to:"/page/dashboard"},{default:(0,l.w5)((()=>[(0,l.Wm)(h,{avatar:""},{default:(0,l.w5)((()=>[(0,l.Wm)(_,{name:"dashboard"})])),_:1}),(0,l.Wm)(h,null,{default:(0,l.w5)((()=>[i])),_:1})])),_:1},8,["active"])),[[Z]]),(0,l.wy)(((0,l.wg)(),(0,l.j4)(v,{active:"non_hanlde_report"==e.selectLabel,clickable:"","active-class":"menu-active",onClick:a[1]||(a[1]=a=>{e.selectLabel="non_hanlde_report",e.routerToThreatList(0)})},{default:(0,l.w5)((()=>[(0,l.Wm)(h,{avatar:""},{default:(0,l.w5)((()=>[(0,l.Wm)(_,{name:"report"})])),_:1}),(0,l.Wm)(h,null,{default:(0,l.w5)((()=>[n])),_:1})])),_:1},8,["active"])),[[Z]]),(0,l.wy)(((0,l.wg)(),(0,l.j4)(v,{active:"handle_report"==e.selectLabel,clickable:"","active-class":"menu-active",onClick:a[2]||(a[2]=a=>{e.selectLabel="handle_report",e.routerToThreatList(1)})},{default:(0,l.w5)((()=>[(0,l.Wm)(h,{avatar:""},{default:(0,l.w5)((()=>[(0,l.Wm)(_,{name:"done"})])),_:1}),(0,l.Wm)(h,null,{default:(0,l.w5)((()=>[o])),_:1})])),_:1},8,["active"])),[[Z]]),(0,l.wy)(((0,l.wg)(),(0,l.j4)(v,{active:"ingore_report"==e.selectLabel,clickable:"","active-class":"menu-active",onClick:a[3]||(a[3]=a=>{e.selectLabel="ingore_report",e.routerToThreatList(2)})},{default:(0,l.w5)((()=>[(0,l.Wm)(h,{avatar:""},{default:(0,l.w5)((()=>[(0,l.Wm)(_,{name:"texture"})])),_:1}),(0,l.Wm)(h,null,{default:(0,l.w5)((()=>[u])),_:1})])),_:1},8,["active"])),[[Z]])])),_:1})])),_:1})])),_:1},8,["mini"]),(0,l.Wm)(y,null,{default:(0,l.w5)((()=>[(0,l.Wm)(g)])),_:1})])),_:1})}const s=(0,l.aZ)({name:"MainLayout",setup(){return{}},data:function(){return{selectLabel:"non_hanlde_report",drawer:!1,miniState:!0}},methods:{routerToThreatList(e){this.$router.push({name:"index",params:{queryIndex:e}})}}});var d=t(4260),m=t(9214),w=t(3812),p=t(9570),b=t(3747),_=t(9400),h=t(2901),v=t(7704),f=t(7011),W=t(3414),k=t(2035),g=t(4554),y=t(2652),L=t(6489),Z=t(7518),q=t.n(Z);const Q=(0,d.Z)(s,[["render",c]]),T=Q;q()(s,"components",{QLayout:m.Z,QHeader:w.Z,QToolbar:p.Z,QToolbarTitle:b.Z,QBtn:_.Z,QDrawer:h.Z,QScrollArea:v.Z,QList:f.Z,QItem:W.Z,QItemSection:k.Z,QIcon:g.Z,QPageContainer:y.Z}),q()(s,"directives",{Ripple:L.Z})}}]);

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

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -1,3 +1,4 @@
import hash_white_list
import json import json
from flask import Flask from flask import Flask
from flask import request from flask import request
@@ -8,6 +9,7 @@ import config
from flask import Flask, render_template, request from flask import Flask, render_template, request
import plugin import plugin
import logging import logging
import html
app = Flask( app = Flask(
__name__, __name__,
@@ -65,6 +67,59 @@ def threat_statistics():
return {"data": return_data} return {"data": return_data}
@app.route("/api/v1/query/white_list_all", methods=["GET"])
def white_list_query_all():
if request.remote_addr not in config.ALLOW_ACCESS_IP:
return "Access Denied"
all_list = sql.query_all_white_list()
result = []
for iter in all_list:
result.append({
"hash": iter[1],
"path": iter[2],
"timestamp": iter[3],
"reason": iter[4]
})
return {"status": "success", "result": result}
@app.route("/api/v1/query/white_list", methods=["GET"])
def white_list_query():
hash = request.args.get("hash")
if request.remote_addr not in config.ALLOW_ACCESS_IP or hash is None or len(hash) == 0:
return "Access Denied"
hash = hash.lower()
result = 0
if hash in hash_white_list.g_white_list:
result = 1
return {"status": "success", "result": result}
@app.route("/api/v1/del/white_list", methods=["GET"])
def white_list_del():
hash = request.args.get("hash")
if request.remote_addr not in config.ALLOW_ACCESS_IP or hash is None or len(hash) == 0:
return "Access Denied"
hash = hash.lower()
if hash in hash_white_list.g_white_list:
sql.delete_white_list(hash)
hash_white_list.g_white_list.remove(hash)
return {"status": "success"}
@app.route("/api/v1/set/white_list", methods=["POST"])
def white_list_set():
body_data = request.data.decode()
if request.remote_addr not in config.ALLOW_ACCESS_IP:
return "Access Denied"
json_data = json.loads(body_data)
hash = html.escape(json_data["hash"]).lower()
path = html.escape(json_data["path"]).lower()
reason = html.escape(json_data["reason"])
hash_white_list.add_white_list(path, hash, reason)
return {"status": "success"}
@app.route("/api/v1/get/process_chain/handle", methods=["GET"]) @app.route("/api/v1/get/process_chain/handle", methods=["GET"])
def handle_chain_data(): def handle_chain_data():
id = request.args.get("id") id = request.args.get("id")
@@ -159,6 +214,7 @@ if __name__ == "__main__":
plugin.reload_plugs() plugin.reload_plugs()
sql.init() sql.init()
rule.init_rule() rule.init_rule()
hash_white_list.synchronization_white_list()
# 如果你觉得日志太多了,去掉这个注释... # 如果你觉得日志太多了,去掉这个注释...
flask_log = logging.getLogger("werkzeug") flask_log = logging.getLogger("werkzeug")

View File

@@ -2,7 +2,7 @@
<q-layout view="lHh Lpr lFf" style="background-color: rgb(239, 243, 246)"> <q-layout view="lHh Lpr lFf" style="background-color: rgb(239, 243, 246)">
<q-header elevated height-hint="98"> <q-header elevated height-hint="98">
<q-toolbar class="text-primary bg-white"> <q-toolbar class="text-primary bg-white">
<q-toolbar-title> DuckSysEye内部测试版本v0.0.0.1 </q-toolbar-title> <q-toolbar-title> RmEye内部测试版本v0.0.0.1 </q-toolbar-title>
<q-btn flat round dense icon="more_vert"></q-btn> <q-btn flat round dense icon="more_vert"></q-btn>
</q-toolbar> </q-toolbar>
</q-header> </q-header>
@@ -77,23 +77,21 @@
</q-item-section> </q-item-section>
<q-item-section> 已忽略威胁列表 </q-item-section> <q-item-section> 已忽略威胁列表 </q-item-section>
</q-item> </q-item>
<template v-for="(item, index) in plugin" v-bind:key="index">
<q-item <q-item
:active="selectLabel == item['name']" :active="selectLabel == 'white_list'"
clickable clickable
v-ripple v-ripple
active-class="menu-active" active-class="menu-active"
@click=" @click="
selectLabel = item['name']; selectLabel = 'white_list';
routerToPlugin(item['html']); routerToWhiteList();
" "
> >
<q-item-section avatar> <q-item-section avatar>
<q-icon :name="item['icon']" /> <q-icon name="list" />
</q-item-section> </q-item-section>
<q-item-section> {{ item["name"] }} </q-item-section> <q-item-section> 白名单列表 </q-item-section>
</q-item> </q-item>
</template>
</q-list> </q-list>
</q-scroll-area> </q-scroll-area>
</q-drawer> </q-drawer>
@@ -116,7 +114,9 @@ import { defineComponent } from 'vue'
import HtmlPanel from '../components/Html.vue' // 根据实际路径导入 import HtmlPanel from '../components/Html.vue' // 根据实际路径导入
import axios from 'axios' import axios from 'axios'
export default defineComponent({ export default defineComponent({
components: { HtmlPanel }, components: {
HtmlPanel
},
name: 'MainLayout', name: 'MainLayout',
setup () { setup () {
return {} return {}
@@ -132,9 +132,20 @@ export default defineComponent({
} }
}, },
methods: { methods: {
routerToWhiteList () {
this.isInPlugin = false
this.$router.push({
name: 'whitelist'
})
},
routerToThreatList (index) { routerToThreatList (index) {
this.isInPlugin = false this.isInPlugin = false
this.$router.push({ name: 'index', params: { queryIndex: index } }) this.$router.push({
name: 'index',
params: {
queryIndex: index
}
})
}, },
routerToPlugin (url) { routerToPlugin (url) {
this.isInPlugin = true this.isInPlugin = true

View File

@@ -4,20 +4,9 @@
<q-card class="bg-transparent no-shadow no-border"> <q-card class="bg-transparent no-shadow no-border">
<q-card-section class="q-pa-none"> <q-card-section class="q-pa-none">
<div class="row q-col-gutter-sm"> <div class="row q-col-gutter-sm">
<div <div v-for="(item, index) in Threatitems" :key="index" class="col-md-3 col-sm-12 col-xs-12">
v-for="(item, index) in Threatitems" <q-item :style="`background-color: ${item.color1}`" class="q-pa-none">
:key="index" <q-item-section side :style="`background-color: ${item.color2}`" class="q-pa-lg q-mr-none text-white">
class="col-md-3 col-sm-12 col-xs-12"
>
<q-item
:style="`background-color: ${item.color1}`"
class="q-pa-none"
>
<q-item-section
side
:style="`background-color: ${item.color2}`"
class="q-pa-lg q-mr-none text-white"
>
<q-icon :name="item.icon" color="white" size="24px"></q-icon> <q-icon :name="item.icon" color="white" size="24px"></q-icon>
</q-item-section> </q-item-section>
<q-item-section class="q-pa-md q-ml-none text-white"> <q-item-section class="q-pa-md q-ml-none text-white">
@@ -37,24 +26,13 @@
<div class="col"> <div class="col">
<div class="row q-gutter-md q-mb-sm q-pa-lg"> <div class="row q-gutter-md q-mb-sm q-pa-lg">
<q-timeline layout="dense" side="right" color="red"> <q-timeline layout="dense" side="right" color="red">
<template <template v-if="!server_threat.data || server_threat.data.length == 0">
v-if="!server_threat.data || server_threat.data.length == 0"
>
<h4>暂无可用数据,下次刷新时间 {{last_refresh}}...</h4> <h4>暂无可用数据,下次刷新时间 {{last_refresh}}...</h4>
</template> </template>
<template <template v-for="(threat, index) in server_threat.data" :key="index">
v-for="(threat, index) in server_threat.data"
:key="index"
>
<q-timeline-entry :subtitle="'主机:' + threat.host" side="left"> <q-timeline-entry :subtitle="'主机:' + threat.host" side="left">
<div> <div>
<q-card <q-card flat bordered style="overflow: auto" :thumb-style="thumbStyle" :bar-style="barStyle">
flat
bordered
style="overflow: auto"
:thumb-style="thumbStyle"
:bar-style="barStyle"
>
<q-card-section horizontal> <q-card-section horizontal>
<div class="bg-red-5">&nbsp;</div> <div class="bg-red-5">&nbsp;</div>
<q-card-actions vertical class="justify-around q-px-md"> <q-card-actions vertical class="justify-around q-px-md">
@@ -63,75 +41,38 @@
<div>用户: {{ threat.start_process.user }}</div> <div>用户: {{ threat.start_process.user }}</div>
<div> <div>
分数: 分数:
<q-chip <q-chip square color="orange" text-color="white" icon-right="visibility">
square
color="orange"
text-color="white"
icon-right="visibility"
>
{{ threat.risk_score }} {{ threat.risk_score }}
</q-chip> </q-chip>
</div> </div>
<div> <div>
活动状态: 活动状态:
<q-chip <q-chip square :color="threat.is_end == 1 ? 'negative' : 'red'" text-color="white">
square
:color="threat.is_end == 1 ? 'negative' : 'red'"
text-color="white"
>
{{ threat.is_end == 1 ? "已结束" : "进行中" }} {{ threat.is_end == 1 ? "已结束" : "进行中" }}
</q-chip> </q-chip>
</div> </div>
<div> <div>
产生的威胁: 产生的威胁:
<template <template v-for="(index, operation) in threat.hit_rule" :key="index">
v-for="(index, operation) in threat.hit_rule"
:key="index"
>
<q-chip square color="rgb(239,243,246)"> <q-chip square color="rgb(239,243,246)">
{{ operation }}&nbsp;({{ index }}) {{ operation }}&nbsp;({{ index }})
</q-chip> </q-chip>
</template> </template>
</div> </div>
<div> <div>
<q-btn <q-btn flat color="accent" @click="show_details(threat.id)" icon="open_in_new">
flat
color="accent"
@click="show_details(threat.id)"
icon="open_in_new"
>
查看详情 查看详情
</q-btn> </q-btn>
<q-btn <q-btn flat color="accent" @click="search_vt(threat.start_process.hash)" icon="search">
flat
color="accent"
@click="search_vt(threat.start_process.hash)"
icon="search"
>
在VT上搜索 在VT上搜索
</q-btn> </q-btn>
<q-btn <q-btn flat color="accent" @click="handle_threat(threat.id, 1)" icon="done">
flat
color="accent"
@click="handle_threat(threat.id, 1)"
icon="done"
>
确认威胁 确认威胁
</q-btn> </q-btn>
<q-btn <q-btn flat color="accent" @click="handle_threat(threat.id, 2)" icon="texture">
flat
color="accent"
@click="handle_threat(threat.id, 2)"
icon="texture"
>
忽略威胁 忽略威胁
</q-btn> </q-btn>
<q-btn <q-btn flat color="accent" icon="close" @click="delete_threat(threat.id)">
flat
color="accent"
icon="close"
@click="delete_threat(threat.id)"
>
删除报警 删除报警
</q-btn> </q-btn>
</div> </div>
@@ -147,42 +88,26 @@
<div class="col"></div> <div class="col"></div>
</div> </div>
</div> </div>
<q-dialog <q-dialog v-model="addwhiteListHash" persistent transition-show="scale" transition-hide="scale">
v-model="dialog" <q-card style="min-width: 350px">
persistent <q-card-section>
:maximized="maximizedToggle" <div class="text-h6">填写缘由</div>
transition-show="slide-up" </q-card-section>
transition-hide="slide-down"
> <q-card-section class="q-pt-none">
<q-input dense v-model="this.whiteListPostData.reason" autofocus />
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="取消" @click="addwhiteListHash = false" v-close-popup />
<q-btn flat label="加入白名单" v-close-popup @click="add_to_white_hash_post()" />
</q-card-actions>
</q-card>
</q-dialog>
<q-dialog v-model="dialog" persistent :maximized="maximizedToggle" transition-show="slide-up" transition-hide="slide-down">
<q-card class="text-white"> <q-card class="text-white">
<q-bar> <q-bar>
<q-space></q-space> <q-space></q-space>
<q-btn
dense
flat
icon="minimize"
@click="maximizedToggle = false"
:disable="!maximizedToggle"
>
<q-tooltip
v-if="maximizedToggle"
content-class="bg-white text-primary"
>Minimize</q-tooltip
>
</q-btn>
<q-btn
dense
flat
icon="crop_square"
@click="maximizedToggle = true"
:disable="maximizedToggle"
>
<q-tooltip
v-if="!maximizedToggle"
content-class="bg-white text-primary"
>Maximize</q-tooltip
>
</q-btn>
<q-btn dense flat icon="close" v-close-popup> <q-btn dense flat icon="close" v-close-popup>
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip> <q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
</q-btn> </q-btn>
@@ -192,12 +117,68 @@
1 1
</div> </div>
</div> </div>
<q-drawer show-if-above v-if="processChainShowDetails" v-model="processChainShowDetails" side="right" bordered width="350" class="text-dark">
<q-list style="width: 100%;word-break: break-all;">
<q-item>
<q-item-section>活跃状态: {{processChainDetails.active ? "运行中" : "已结束"}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>进程名字: {{processChainDetails.name}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>进程路径: {{processChainDetails.path}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>进程参数: {{processChainDetails.params}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>进程id: {{processChainDetails.pid}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>父进程id: {{processChainDetails.ppid}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>进程hash: {{processChainDetails.md5}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<q-item-section>是否在白名单中: {{processChainDetails.isWhite ? "是" : "否"}}</q-item-section>
</q-item>
<q-separator />
<q-item>
<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>
</q-item>
<q-item>
<q-btn icon="search" outline style="color: grey;width: 100%;" label="搜索hash" @click="search_vt(processChainDetails.md5)" />
</q-item>
<q-item>
<template v-if="processChainDetails.isWhite == false">
<q-btn icon="texture" outline style="color: grey;width: 100%;" label="加入白名单" @click="add_to_white_hash_pre(processChainDetails.path,processChainDetails.md5)" />
</template>
<template v-else>
<q-btn icon="clear" outline style="color: grey;width: 100%;" label="从白名单中删除" @click="delete_white_hash(processChainDetails.md5)" />
</template>
</q-item>
</q-list>
</q-drawer>
</q-card> </q-card>
</q-dialog> </q-dialog>
</template> </template>
<script> <script>
import { defineComponent } from 'vue' import {
defineComponent
} from 'vue'
import axios from 'axios' import axios from 'axios'
import * as echarts from 'echarts' import * as echarts from 'echarts'
@@ -205,7 +186,21 @@ export default defineComponent({
name: 'PageIndex', name: 'PageIndex',
data: function () { data: function () {
return { return {
addwhiteListHash: false,
whiteListPostData: {
path: '',
hash: '',
reason: ''
},
processChainShowDetails: false,
last_refresh: 360, last_refresh: 360,
processChainDetails: {
hash: '',
prams: '',
hitRule: [],
isWhite: false,
whiteListReason: ''
},
thumbStyle: { thumbStyle: {
right: '4px', right: '4px',
borderRadius: '5px', borderRadius: '5px',
@@ -226,9 +221,7 @@ export default defineComponent({
ingore: 1, ingore: 1,
working: 0 working: 0
}, },
Threatitems: Threatitems: [{
[
{
title: '发现的威胁', title: '发现的威胁',
icon: 'remove_red_eye', icon: 'remove_red_eye',
value: '200', value: '200',
@@ -264,6 +257,32 @@ export default defineComponent({
} }
}, },
methods: { methods: {
delete_white_hash (hash) {
axios.get('/api/v1/del/white_list?hash=' + hash).then(res => {
this.processChainDetails.isWhite = false
})
},
query_white_hash (hash) {
axios.get('/api/v1/query/white_list?hash=' + hash).then(res => {
this.processChainDetails.isWhite = res.data.result === 1
})
},
add_to_white_hash_pre (path, hash) {
this.whiteListPostData = {
path: path,
hash: hash,
reason: ''
}
this.addwhiteListHash = true
console.log('addwhiteListHash', this.addwhiteListHash)
},
add_to_white_hash_post () {
axios
.post('/api/v1/set/white_list', this.whiteListPostData)
.then((response) => {
this.processChainDetails.isWhite = true
})
},
set_chain_data (data) { set_chain_data (data) {
if (data.path) { if (data.path) {
const str = data.path.split('\\') const str = data.path.split('\\')
@@ -302,8 +321,7 @@ export default defineComponent({
return result return result
} }
}, },
series: [ series: [{
{
roam: true, roam: true,
type: 'tree', type: 'tree',
id: 0, id: 0,
@@ -335,16 +353,30 @@ export default defineComponent({
emphasis: { emphasis: {
focus: 'descendant' focus: 'descendant'
}, },
symbolSize: [40, 50], // 宽40 高50 symbolSize: [30, 30], // 宽40 高50
symbol: symbol: 'image://data:image/png;base64,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',
'image://data:image/png;base64,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', expandAndCollapse: false,
expandAndCollapse: true, animationDuration: 350,
animationDuration: 550, animationDurationUpdate: 450
animationDurationUpdate: 750 }]
}
]
} }
myChart.setOption(option) myChart.setOption(option)
myChart.on('click', params => {
const data = params.data
this.processChainDetails = {
path: data.path,
active: data.active,
md5: data.md5,
name: data.name,
params: data.params,
pid: data.pid,
ppid: data.ppid,
hitRules: data.operationlist,
isWhite: false
}
this.query_white_hash(data.md5)
this.processChainShowDetails = true
})
}, },
search_vt (hash) { search_vt (hash) {
window.open('https://www.virustotal.com/gui/search/' + hash, '_blank') window.open('https://www.virustotal.com/gui/search/' + hash, '_blank')

View File

@@ -0,0 +1,137 @@
<template>
<q-table
class="q-pa-lg"
:dense="$q.screen.lt.md"
title="白名单列表"
:columns="data_columns"
:rows="data_columns_data"
:loading="loading"
v-model:pagination="pagination"
@request="onRequest"
>
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="path" :props="props">{{ props.row.path }}</q-td>
<q-td key="hash" :props="props">{{ props.row.hash }}</q-td>
<q-td key="reason" :props="props">{{ props.row.reason }}</q-td>
<q-td key="timestamp" :props="props">{{ time_parase(props.row.timestamp) }}</q-td>
<q-td key="action" :props="props">
<q-btn color="red" label="移除白名单" @click="delete_white_hash(props.row.hash)"/>
</q-td>
</q-tr>
</template>
</q-table>
</template>
<script>
import {
defineComponent
} from 'vue'
import axios from 'axios'
export default defineComponent({
name: 'WhiteList',
data: function () {
return {
data_columns: [
{
name: 'path',
align: 'center',
label: '路径',
field: 'path'
},
{
name: 'hash',
align: 'center',
label: 'hash',
field: 'hash'
},
{
name: 'reason',
align: 'center',
label: '原因',
field: 'reason'
},
{
name: 'timestamp',
align: 'center',
label: '时间',
field: 'timestamp'
},
{
name: 'action',
align: 'center',
label: '操作',
field: 'steamid'
}
],
data_columns_data: [],
loading: false,
pagination: {
sortBy: 'desc',
descending: false,
page: 1,
rowsPerPage: 10,
rowsNumber: 10
}
}
},
mounted () {
this.onRequest({
pagination: this.pagination,
filter: undefined
})
},
methods: {
delete_white_hash (hash) {
axios.get('/api/v1/del/white_list?hash=' + hash).then(res => {
console.log('duck was gone')
})
},
time_parase (pTime) {
// shijianchuo是整数否则要parseInt转换
const add0 = m => {
return m < 10 ? '0' + m : m
}
const time = new Date(Number(pTime))
console.log('time', pTime)
const y = time.getFullYear()
const m = time.getMonth() + 1
const d = time.getDate()
const h = time.getHours()
const mm = time.getMinutes()
const s = time.getSeconds()
return (
y +
'-' +
add0(m) +
'-' +
add0(d) +
' ' +
add0(h) +
':' +
add0(mm) +
':' +
add0(s)
)
},
onRequest (props) {
this.data_columns_data = []
this.loading = true
const { page } = props.pagination
axios.get('/api/v1/query/white_list_all').then(response => {
const data = response.data.result
console.log(data)
for (let index = 0; index < data.length; index++) {
const element = data[index]
this.data_columns_data.push(element)
}
this.pagination.page = page
this.pagination.rowsNumber = this.data_columns_data.length
this.pagination.rowsPerPage = this.data_columns_data.length
this.loading = false
})
}
}
})
</script>

View File

@@ -12,7 +12,8 @@ const routes = [
component: () => import('layouts/MainLayout.vue'), component: () => import('layouts/MainLayout.vue'),
children: [ children: [
{ path: 'dashboard', component: () => import('pages/Dashboard.vue') }, { path: 'dashboard', component: () => import('pages/Dashboard.vue') },
{ path: 'index', name: 'index', component: () => import('pages/Index.vue') } { path: 'index', name: 'index', component: () => import('pages/Index.vue') },
{ path: 'index', name: 'whitelist', component: () => import('pages/Whitelist.vue') }
] ]
}, },
// Always leave this as last one, // Always leave this as last one,