NODLINK:一个细粒度APT攻击在线检测与调查系统_nodlink an online system for fine-grained apt att

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

process_behavior.py(路径:src/Sysdig/process_behavior.py)

一、原始数据

1.benign.json(数据示例)

keyvalue
evt.args"res=0 "
evt.num5414
evt.time1648196412403647385
evt.type“fstat”
fd.name“”/root/data""
proc.cmdline“node /root/.vscode-server/bin/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/out/bootstrap-fork --type=watcherServiceChokidar”
proc.name“node”
proc.pcmdline“node /root/.vscode-server/bin/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/out/vs/server/main.js --start-server --host=127.0.0.1 --enable-remote-auto-shutdown --port=0 --connection-secret /root/.vscode-server/.ccbaa2d27e38e5afa3e5c21c1c7bef4657064247.token”
proc.pname“node”

2.anomaly.json(数据示例)

keyvalue
evt.args"res=0 "
evt.num195
evt.time1648192288041289626
evt.type“fstat”
fd.name“/root/data”
proc.cmdline“node /root/.vscode-server/bin/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/out/bootstrap-fork --type=watcherServiceChokidar”
proc.name“node”
proc.pcmdline“node /root/.vscode-server/bin/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/out/vs/server/main.js --start-server --host=127.0.0.1 --enable-remote-auto-shutdown --port=0 --connection-secret /root/.vscode-server/.ccbaa2d27e38e5afa3e5c21c1c7bef4657064247.token”
proc.pname“node”
is_warnfalse
二、代码解读
1.process_behavior
if __name__ == "\_\_main\_\_":
	# 接收控制台参数
    parser = ArgumentParser()
    # 指定要解析的json文件名
    parser.add_argument("--file",type = str, default='benign-labeled.json')
    # 指定json文件所在的目录
    parser.add_argument("--d",type = str, default = 'hw17')
    args = parser.parse_args()
    file_path = args.file
    dataset = args.d
    # 初始化一个有向图
    G = nx.DiGraph()
    # 逐行读取日志文件,返回一个DataFrame对象
    org_log = read_org_log_from_json(dataset + '/' + file_path)
	
	# 判断文件操作FILE\_OP是否在org\_log的evt.type列中,记录与文件操作相关的行
    file_op_logs = org_log[org_log['evt.type'].isin(APTLOG_TYPE.FILE_OP)]
    print('file logs count:', len(file_op_logs))
    # 记录与进程操作相关的日志行
    process_op_logs = org_log[org_log['evt.type'].isin(APTLOG_TYPE.PROCESS_OP)]
    print('process logs count:', len(process_op_logs))
    # 记录与网络操作相关的行
    net_op_logs = org_log[org_log['evt.type'].isin(APTLOG_TYPE.NET_OP)]
    print('net logs count:', len(net_op_logs))
    # execve\_op\_logs = org\_log[org\_log['evt.type'].isin(APTLOG\_TYPE.EXECVE\_OP)]
    # print('execve logs count:', len(execve\_op\_logs))

    if len(file_op_logs) > 0:
        file_op_logs = file_op_logs[APTLOG_ARTRIBUTE.FILE_ARTRIBUTE]
    if len(process_op_logs) > 0:
        process_op_logs = process_op_logs[APTLOG_ARTRIBUTE.PROCESS_ARTRIBUTE]
    if len(net_op_logs) > 0:
        net_op_logs = net_op_logs[APTLOG_ARTRIBUTE.NET_ARTRIBUTE]
    # if len(execve\_op\_logs) > 0:
    # execve\_op\_logs = execve\_op\_logs[APTLOG\_ARTRIBUTE.EXECVE\_ARTRIBUTE]
	
	# 初始化一个空的有向图
    G = graph_init()

    md5_to_node = {}
    node_to_type = {}
    anomalyset = set()
    # 将FILE节点添加到图G中
    G, x = graph_add_node_realapt(G, file_op_logs, APTLOG_KEY.FILE, md5_to_node, node_to_type)
    anomalyset |= x
    # 将PROCESS节点添加到图G中
    G, x = graph_add_node_realapt(G, process_op_logs, APTLOG_KEY.PROCESS, md5_to_node, node_to_type)
    anomalyset |= x
    # 将NET节点添加到图G中
    G, x = graph_add_node_realapt(G, net_op_logs, APTLOG_KEY.NET, md5_to_node, node_to_type)
    anomalyset |= x
    # 经过上边3步,得到了包含全部节点和边的有向图G和异常节点集合anomalyset(节点都以md5值标识)
    print(len(anomalyset))
    # G = graph\_add\_node\_realapt(G, execve\_op\_logs, APTLOG\_KEY.EXECVE, md5\_to\_node, node\_to\_type)

    # nx.drawing.nx\_pydot.write\_dot(G, 'test.dot')
    # DAG = directed\_acyclic\_graph(graph=G)

    # print(len(G.nodes))
    # for i,g in enumerate(nx.weakly\_connected\_components(G)):
    # subgraph = G.subgraph(g)
    # nx.drawing.nx\_pydot.write\_dot(subgraph, str(i) + '.dot')

    attack_process = set()
    # DAG = directed\_acyclic\_graph(graph=G)
    is_anomaly = True
    # 依据处理的json文件是良性活动还是包含攻击活动的,决定is\_anomaly和event\_file的取值
    if 'benign' in file_path:
        is_anomaly = False
        # event\_file指定了最终输出的结果txt文件路径
        event_file = dataset + '/process-event-benign.txt'
    else:
        event_file = dataset + '/process-event-anomaly.txt'
    # 以写的方式打开结果文件
    data = open(event_file,'w')
    for node in G:
    	# 处理图中PROCESS类型的顶点
        if G.nodes[node]['type'] == APTLOG_NODE_TYPE.PROCESS:
        	# 顶点取值有意义
            if G.nodes[node]['label'] != '':
            	# 当前处理的是包含攻击活动的json文件时
                if is_anomaly:
                	# 将异常节点以 label(即取值)$$$is\_warn 的形式记录到结果文件中
                    data.write(G.nodes[node]['label'] + '$$$' + str(G.nodes[node]['is\_warn']) +'\n')
                    if G.nodes[node]['is\_warn']:
                    	# 将is\_warn值为真的顶点添加到attack\_process集合中
                        attack_process.add(node)
				
				# 当前处理的是良性活动的json文件时
                else:
                	# 以label(即取值)的形式写入结果文档
                    data.write(G.nodes[node]['label'] + '\n')
                # data.write(G.nodes[node]['label'] + '\n')
                
                 # 遍历当前节点node的全部后续节点
                for i in G.successors(node):
                	# 若后续节点的值有意义、不是'unknown'且节点不是PROCESS类型,则将其写入结果文档中
                    if G.nodes[i]['label'] != 'unknown' and G.nodes[i]['type'] != APTLOG_NODE_TYPE.PROCESS and G.nodes[i]['label'] != '':
                        data.write(G.nodes[i]['label'] + '\n')
                # 遍历当前节点node的全部前驱节点
                for i in G.predecessors(node):
                	# 若前驱节点的值有意义、不是'unknown'且节点不是PROCESS类型,则将其写入结果文档中
                    if G.nodes[i]['label'] != 'unknown' and G.nodes[i]['type'] != APTLOG_NODE_TYPE.PROCESS and G.nodes[i]['label'] != '':
                        data.write(G.nodes[i]['label'] + '\n')
                data.write('\n')

    data.close()
    # 打印is\_warn值为真的顶点集合(存放的是md5值)
    print(attack_process)
    # 若处理的是良性活动文件,则要将event\_file中的命令行和文件部分分别记录到两个文件中
    if 'benign' in event_file:
        split_cmd_and_filename(event_file,dataset)

2.辅助函数
(1)split_cmd_and_filename
# 将file\_path的每行内容划分为命令行和文件名两部分,分别写入到两个txt文件中
def split\_cmd\_and\_filename(file_path,dataset):
	# 以读的方式打开结果txt文本
    f = open(file_path,'r')
    # 以写的方式在数据目录下打开两个文本文件
    o1 = open(dataset+'/cmdline.txt','w')
    o2 = open(dataset+'/filename.txt','w')
    print('start graph')
    isprocess_file = True
    while True:
    	# 按行读取txt文件中的数据
        line = f.readline()
        if line == '\n':
            isprocess_file = True
            continue
        if not line:
            break
        # 去除首位空格并转换为小写
        filepath = line.strip().lower()
        # 判断是否以 $$$true 结尾
        if filepath.endswith('$$$true'):
        	# 将 '$$$true' 替换为 ' '
            filepath = filepath.replace('$$$true','')
        elif filepath.endswith('$$$false'):
        	# 将 '$$$false' 替换为 ' '
            filepath = filepath.replace('$$$false','')

        split_path = sanitize_string(filepath)
        if len(split_path) == 0:
            continue

        if isprocess_file:
            o1.write(filepath + '\n')
            isprocess_file = False
        else:
            o2.write(filepath + '\n')
    o1.close()
    o2.close()

(2)graph_add_node_realapt
# 向图中添加顶点和边
def graph\_add\_node\_realapt(g: nx.Graph, logs, key, md5_to_node:dict, node_to_type:dict):
    node_set = set()
    edge_set = set()
    anomaly_set = set()
    # 将FILE类型节点添加到图中
    if key == APTLOG_KEY.FILE:
    	# 按行遍历FILE类型的logs,index是行名,row是此行的数据(Series类型)
        for index, row in logs.iterrows():
        	# 获取每条FILE日志的proc.cmdline属性值的md5值
            s_node = get_md5(row['proc.cmdline'])
            # 获取每条FILE日志的fd.name属性值的md5值
            t_node = get_md5(row['fd.name'])
            # 将新的(s\_node,row['proc.cmdline'])添加到字典md5\_to\_node中
            if s_node not in md5_to_node:
            	# 记录各个md5值和命令行值的映射
                md5_to_node[s_node] = row['proc.cmdline']
                # 记录各个md5值和对应类型、is\_warn的映射
                node_to_type[s_node] = {'type':APTLOG_NODE_TYPE.PROCESS, 'is\_warn':row['is\_warn']}
            # 将新的(t\_node,row['fd.name'])添加到字典md5\_to\_node中
            if t_node not in md5_to_node:
            	# 记录各个md5值和fd.name的映射
                md5_to_node[t_node] = row['fd.name']
                # 记录各个md5值和对应类型、is\_warn的映射
                node_to_type[t_node] = {'type':APTLOG_NODE_TYPE.FILE, 'is\_warn':False}
            # e\_id = row['log\_id']
            is_warn = row['is\_warn']
            # 将被标记为警报的日志对应的md5值加入到异常集合中
            if is_warn:
                anomaly_set.add(s_node)
            # 将文件命令行proc.cmdline和文件名字fd.name属性值对应的md5值添加到node\_set集合中
            node_set.add(s_node)
            node_set.add(t_node)
            # 将(文件命令行md5值,文件名字md5值,是否警报)添加到edge\_set集合中
            edge_set.add((s_node, t_node, is_warn))
    # 将PROCESS类型节点添加到图中
    elif key == APTLOG_KEY.PROCESS:
        for index, row in logs.iterrows():
            s_node = get_md5(row['proc.pcmdline'])
            t_node = get_md5(row['proc.cmdline'])
            if s_node not in md5_to_node:
                md5_to_node[s_node] = row['proc.pcmdline']



本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。


最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。


最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。


![](https://img-blog.csdnimg.cn/img_convert/311903982dea1d8a5d2c98fc271b5b41.jpeg)

**需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)**

### 学习路线图


 其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。


相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。


![](https://img-blog.csdnimg.cn/img_convert/1ddfaf7dc5879b1120e31fafa1ad4dc7.jpeg)


#### 网络安全工具箱


当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份**我自己整理的网络安全入门工具以及使用教程和实战。**


![](https://img-blog.csdnimg.cn/img_convert/bcd1787ce996787388468bb227d8f959.jpeg)


#### 项目实战


最后就是项目实战,这里带来的是**SRC资料&HW资料**,毕竟实战是检验真理的唯一标准嘛~


![](https://img-blog.csdnimg.cn/img_convert/35fc46df24091ce3c9a5032a9919b755.jpeg)


#### 面试题


归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值