由奇安信集团、清华大学网络研究院、蚂蚁集团、腾讯安全大数据实验室、Coremail论客主办的DataCon2022大数据安全分析竞赛线上赛和决赛已圆满落幕,五大赛道第一名也已各归其主。赛后,DataCon组委会后台收到很多关于“求大佬Writeup”的私信,今天,大家期待的冠军Writeup闪亮登场啦!
首先要分享的是网络流量分析赛道排名第一的见世面战队writeup。见世面战队是由广州大学网络空间安全学院方滨兴院士班的五位小伙伴组建而成,分别为曾东阳、顾家乐、张哲维、孙一航、徐颖慧,指导老师为李树栋老师。
广州大学方滨兴院士班简称“方班”,自2017年成立以来,斩获各类比赛大奖,方班loom战队曾荣获2019首届DataCon大数据安全分析竞赛(恶意代码行为分析方向)冠军,方班IStar战队和loom战队又在2020第二届DataCon(DNS恶意域名分析和恶意代码分析赛道)荣获奖项。
见世面战队成员们研究方向广泛,热爱大数据和网络安全。秉持“多参与,增阅历,见世面”的原则,团队共同学习,积极参与比赛,学习先进思想技术,立志为网络与信息安全贡献力量。
[温馨提示:本文篇幅较长
欢迎收藏转发,随时浏览查看]
第1章 挖矿流量检测
1.1 比赛题目
本题文件中提供的是一段时间的校园网网关部分流量数据,其中目标域名、IP已经过匿名化处理,需要选手审计所给的数据包,实现一个不依赖于IOC的挖矿流量检测分析引擎,并找出数据包中的所有挖矿流量。选手需要上传一个txt文件,文件的每一行代表挖矿流量在pcap文件包中的编号数字。
1.2 概述
通过自行挖矿的方法获取已知挖矿流量包进行审计分析,根据审计分析得到的结论对赛方提供的pcap文件训练分类器进行分类并执行规则过滤,最终根据双方通讯时包大小分布频率、通讯频率、包占比等等信息得到最终结果。
1.3 解题思路
整体思路是先对流量进行基本审计分析,然后根据挖矿协议的明文流量特征对流量进行筛选得到非加密的流量包列表,然后自行租用国外地区的GPU服务器采用stratum+ssl协议进行多种类加密货币的挖矿操作并抓包,对自行取得的挖矿流量进行特征分析,根据发掘的流量特征与单分类器(孤立森林)设计了一套挖矿流量检测规则找出所有的可疑挖矿流量,并通过发起IP请求获取当前证书和发起HTTPS请求获取当前状态码的方式对可疑挖矿流量做进一步的检测,优先人工审计与确认无证书且HTTPS连接失败的IP,最终确定答案。
1.3.1 题目分析与流量简单审计
团队通过调研和抓包得到的挖矿流量分析可知,目前的挖矿流量在Wireshark中均被识别为TCP或TLSv1.x协议,具体如图1.1所示,据此我们可以暂时排除全部Protocol字段识别为HTTP与SSL的流量。
然后通过赛方所给的pcap文件中分析可知192.168.60.78为源IP,发送或接收IP报文中的另一个IP则为外部IP。同时,从第一包与最后一个包的时间可知,本次分析的pcap文件抓取的时间是从Oct24,202212:09:46到Oct24,202212:22:24,时间只间隔13分钟左右。因为本次抓包的时间间隔较短,据此我们假设在这个时间段内同个IP的流量包都是指向相同的服务器,同个IP的同个端口号的流量包都是指向同个服务器的同种服务,所以我们根据(外部IP,外部IP的port)这个二元组唯一确定服务。
因此我们的目标转化为找到所有提供挖矿服务的(外部IP,外部IP的port)二元组,并根据这个过滤出所有与该IP:port通信的挖矿包ID并提交。
接下来对所给pcap的数据包类型分布进行分析,发现有相当一部分的流量是加密流量,并且有些数据流是不完整的,所以加密流量握手包也无法成功识别或被大量剔除。pcap数据包协议分级如图1.2所示。
图1.2pcap数据包协议分级统计
随后在Wireshark中将包括流量包编号、时间、源IP、源端口、目的IP、目的端口、协议、长度、TCP流编号、信息字段在内的全部流量包信息进行导出,并按csv格式存储方便后续处理。
针对开头所提根据Protocol字段进行排除,则在此根据csv进行过滤形成安全流量的(外部IP,外部IP的port)二元组白名单,代码如图1.3所示:
1.3.2 非加密挖矿流量包识别
通过调研[1]与分析现在主流的挖矿协议Stratum及其相关变种[2],发现其传输过程均基于JSON-RPC协议,并且具备显著特征关键词”method”与“params”。同时,如果是采用“stratum+tcp://”方式进行连接,则挖矿机器与矿池之间将采用TCP的形式传输明文数据。我们可以根据以上发现编写规则:tcpcontains”method”在wireshark中进行过滤即可找到全部可疑的TCP流量包并获得其对应的矿池(外部IP,外部IP的port)二元组。查找结果如图1.4所示。
图1.4查找可疑TCP流量包代码
在找到可疑流量包后,在HTTP请求所属的(外部IP,外部IP的port)二元组从中除去HTTP协议的白名单二元组后即可获得全部的非加密挖矿流量包所对应的二元组。
随后对矿池IP的其他端口进行查找,可惜的是并未发现其他有效信息。又尝试了其他字段和挖矿协议,也暂时没有新的发现,可以明确的是当前找到的二元组为所有未加密的挖矿流量所对应的二元组。经过确认,以上发现的矿池IP均只使用443端口提供服务,所以使用IP进行过滤即可得到全部的未加密的挖矿流量包。具体过滤规则如图1.5所示。
图1.5挖矿流量包过滤规则
1.3.3 加密挖矿流量特征分析
根据我们提交的明文挖矿流量包的答案与分数分析可得到方程式:2*1*(189/x)/(1+189/x)=0.629,求解可得一共有412个流量包,还余有223个流量包需要找到,所以需要对加密流量进行分析。
由于团队本身其实并未接触过挖矿流量,所以对于加密的挖矿流量特征与特点一无所知[3]。对此我们决定租用日本东京的GPU服务器进行挖矿测试并捕获其流量,采用NBMiner作为挖矿程序[9],nicehash与f2pool作为矿池服务器,使用stratum+ssl通讯协议测试了ETH、ETC、AE、BEAM、CONFLUX、ERGO等数种加密货币,挖矿时长从3秒钟到20分钟不等,进行了多次测试。对抓包到的数据根据矿池IP进行过滤得到了40个加密挖矿TCP流与2554个加密流量包。
通过对其中每个流进行分析可知,大多数通讯包比较小,除了开头的TLS握手交换密钥的几个包较大之外,其他流量包的大小均比较小且比较有规律。之后我们选择先分析握手后常规通讯的包,因为其比较有规律。
通过对握手后的常规通讯包规律进行分析,得到了一下的结论:
从TCP包角度看,矿池与矿机之间通讯是有来有回,其中非TLS包的包长是100以内,矿池到矿机的非TLS的TCP包长通常固定一个值,矿机到矿池的也是固定一个数值。如图1.6所示,矿机到矿池的纯TCP包长均为54,矿池到矿机的纯TCP包长均为60,其包长相对固定。同时,其通信大多数符合2个矿机到矿池接着2个矿池到矿机的包,或1个矿机到矿池接着1个矿池到矿机的包,不会不停地连续发包。
图1.6抓取TCP通讯包
从TLS包角度来看(即只保留TLS的包来分析),可以发现包大小也是比较固定的,并且大多数情况下矿机到矿池的包后面会跟着数个矿池到矿机的包,极少会出现连续3个矿机到矿池的TLS包。如图1.7所示,矿机到矿池的包基本上固定为240长度,矿池到矿机的包基本只有282、141、112这三种包大小。
图1.7抓取TLS通讯包
以上的包分析均为同一个流包的特点,对于不同的服务器以及加密货币,其包长度具体数值是不一样的,但是他们都具备一样的分布特点,包括流量包的交替发包特征、流量包大小较固定等特点,只是包大小的具体数值不一样。如图1.8所示,矿机到矿池的包大小变为了234,矿池到矿机的包大小变为了283或282。
图1.8常规通讯TLS通讯包
通过对常规通信过程中包的特点进行分析,我们还要分析为何会出现这种特点以及特征。根据以上常规通讯过程中的包特点,我们还需要判断这个特点是从哪里开始具备的,通过对多个流的握手包分析,可以发现从最后一个“ChangeCIPherSpec”开始算最多第5个TLS包就具备上述的“常规通讯过程中的包特点”。如图1.9所示,从第5个包就开始具备重复包长度141。根据此特点我们可以找到每个流的最后一个“ChangeCIPherSpec”的5个TLS包后的流量包再进行分析。
同时,我们通过对wireshark识别包的协议占比进行了分析,通常被识别为TLS协议的包占全部包数量一半,相差不超过3个包。
除此之外,根据上述明文流量以及挖矿场景推断,挖矿过程中需要长时间在线。这点在自行构建的挖矿数据集上也得到了验证:挖矿过程中会持续使用该流,导致流时间持续时间较长。同时,我们也对赛方提供的pcap文件进行了分析,根据流的第一包时间于最后一个包时间来计算流的持续时间,可以发现流的持续时间在2秒以内的占81.4%,3秒内的占90.8%,并发现明文流的持续时间普遍较长,最短的6秒,最长的312秒,如图1.10所示。
综上所述,我们认为加密挖矿流量通常具备以下几个特征:
1.从最后一个“ChangeCIPherSpec”后的第5个TLS包后的流量包来计算,无论是矿池到矿机还是矿机到矿池,都不会连续单边发超过4个包,这里可以把条件放宽到10个包。
2.从最后一个“ChangeCIPherSpec”后的第5个TLS包后的流量包来计算,无论是全部包还是TLS包,至少80%的包大小值分布在5种包大小值。
3.从最后一个“ChangeCIPherSpec”后的第5个TLS包后的流量包来计算,矿机到矿池的TLS包后面会跟着多个矿池到矿机的TLS包,极少会出现连续3个矿机到矿池的TLS包,在这里我们可以将其放宽为最多允许连续6个矿机到矿池的TLS包作为浮动。上述具体规则如图1.11、图1.12所示。
图1.11“ChangeCIPherSpec”流量包限制条件
图1.12“ChangeCIPherSpec”流量包限制条件
4.从最后一个“ChangeCIPherSpec”后的第5个TLS包后的流量包来计算,包大小一般不超过500,这里我们放宽到数量最多的包不超过900。具体规则如图1.13所示。
5.一个TCP流中被识别为TLS协议的包占全部包数量一半,相差不超过3个包,这里我们放宽到6个包。具体规则如图1.14所示。
图1.14“ChangeCIPherSpec”流量包限制条件
6.流的持续时间比较长,这里为了方便找到答案,我们先对3秒以上的包进行处理,如果答案缺失再逐步放宽条件。
图1.15“ChangeCIPherSpec”流量包限制条件
1.3.4 排除加密挖矿流量的干扰项
为了减少干扰,我们对加密流量进行了二次审计,用wireshark过滤了具备H2协议的HTTP请求,并与之前的HTTP协议的请求合并,形成规则:(tcpcontains”http/1.1″&&tcpcontains”h2″)||http,导出匹配的包到full_http2.csv。在后续处理中,如果处理的流编号在该文件中存在则被忽略,代码如图1.16所示。
图1.16二次审计加密流量代码
随后通过对资料的查找,我们借鉴一篇挖矿流量挖掘的论文《基于机器学习的加密数字货币恶意挖掘行为检测系统》[2]里面所使用的工具:CICFlowMeter[5][8],该工具能够提取流量包流的一系列特征,包括特征如表1.1所示:
表1.1流量包特征表
运行界面如图1.17所示。
对cryptomining.pcap处理可以得到cryptomining.pcap_Flow.csv文件,内含上述表格所述内容。
图1.17运行界面
对数据处理完成后,由于没有该论文所述的相关数据集文件,于是我们采用一种单分类模型——孤立森林(isolationForest)进行训练[7] 。为了避免遗漏可疑IP,设置污点率为偏大的0.2,后续检查流时只检查该模型分类为非正常流量包流的(IP,port)二元组,降低工作量,核心代码如图1.18所示。
图1.18孤立森林模型代码
1.3.5 识别加密挖矿流量
通过上述手段排除干扰后,再通过1.3.3所述特征对包的流进行识别过滤,最终得到29个可疑流。因为cryptomining.pcap的抓包时间并不久远,且IP经过尝试疑似真实IP,考虑到如果是真实服务,其使用的IP在这段时间内大概率还是原有业务所使用。所以我们尝试请求流所对应的“外部IP:外部IP端口”的证书,并对其发起https请求,代码如图所示。如果证书无法获得或者是证书是可疑的commonName则有较大嫌疑,或者如果https请求失败也有较大嫌疑。对于存有较大嫌疑的流进行优先审计,具体审计代码如图1.19所示。
图1.19特征包识别过滤代码
根据上述操作执行完成后可以得到相关结果如图1.20所示。
其中,嫌疑最大的几个流如下图1.21所示,获取cert证书与发送https请求均失败。
图1.21嫌疑最大的流结果
对这些流进行人工审计,查找流的流量包内是否具有疑似证书的信息内存有commonName,如52.184.216.226的流量包中可以发现疑似微软域名的证书,暂时排除其嫌疑,如下图1.22所示。
图1.22人工审计流结果
最终经过人工审计排除与提交验证找到全部的加密流量包所对应的(外部IP:外部IP端口)二元组,并经检查发现这些IP均只使用443端口,于是通过规则:IP.addr==2.15.17.3||IP.addr==172.104.153.3||IP.addr==43.135.17.103||IP.addr==185.71.65.31||IP.addr==37.187.148.73||IP.addr==23.223.18.120||IP.addr==39.106.134.208||IP.addr==120.79.12.36||IP.addr==120.79.19.176将相关挖矿流量包全部导出并提交。
1.4 总结与体会
近些年来,随着区块链技术的兴起,虚拟货币的出现给传统货币造成了不小的冲击,虚拟货币与传统货币不同,它是以数字化形式存在于网络世界中的,且不能作为货币在市场上流通使用,投资和交易虚拟货币也不受法律保护。但许多不法分子却干起了挖矿的非法勾当,挖矿就是将一段时间内虚拟货币系统中发生的交易进行确认,并记录在区块链上,形成新的区块,并从中获益,因此对于非法挖矿流量的捕捉就极为重要。
回顾整个寻找挖矿流量的过程,团队一边观察流量一边学习寻找合适的方法和手段,从中也总结了许多经验:仔细阅读题目会让解题事半功倍。题目是对问题的初步了解,也是最重要的一次认识,打好基础,理清思路才能对题目有更深的理解。
比赛的过程也是学习的过程。比赛期间对题目的分析和解决的同时,不可能都是团队会的知识,这时候比赛的压力就可以很好的提高学习效率,面对不了解的技术时要积极地寻找资料,相互讨论。
面对效果不好的答案要加以分析。每一次提交答案都是对当前阶段成果的总结,面对效果好坏的答案,不单单只看分数本身,更要分析出不同的组合是否能缩小范围。
题目给出的挖矿流量中有明文流量和密文流量,通过对明文流量的审计,想先寻找到明文中的挖矿流量然后寻找相关联的IP查看是否与密文流量有所关联。在之后对加密流量进行筛选时,我们还使用了模拟的方法学习加密挖矿流量的特征,对之后进行规则的制定打下了基础。在整个做题的过程中,思维上的活跃是必不可少的一环,要从多个角度去分析和观察,才可能有更多的思路进行实验。在这过程中团队也学习了许多宝贵的知识,收获许多。
1.5 附加文件说明
black_ssl3.pcap:自行获取的加密挖矿流量包
black_ssl3.pcap_Flow.csv:CICFlowMeter对black_ssl3.pcap的处理结果cryptomining.pcap_Flow.csv:CICFlowMeter对赛方提供的cryptomining.pcap处理结果
full.csv:cryptomining.pcap用wireshark导出的全部流量包信息
full_http2.csv:用于排除干扰的http与h2协议http的包信息
mining_check_finish.py:代码文件,其中check_stream函数为主要处理函数
第2章 智能蜜罐环境构建-Level1
2.1 比赛题目
本题赛方提供虚拟环境,选手需要在虚拟环境中构建一个智能靶标环境;并开放指定端口以接收poc,并对接收到的poc进行正确的响应。
2.2 概述
团队利用tcppc工具[13]捕获提交答案时所发起的所有udp与tcp请求,确认为http请求后,根据请求的path信息在github上检索相关的poc文件,并根据多个请求的信息锁定为xray的poc文件。随后编写程序解析poc文件,根据poc文件中请求的path、header、body信息匹配到对应规则与请求,并尝试提取其中变量,随后根据poc中的expression字段构造相应的响应。
2.3 解题思路
团队通过对题目的分析,先根据找到的poc构造出每个规则的请求的匹配正则表达式,外部请求到来时采用前面构造的正则表达式进行匹配,找出这个请求所对应poc与poc中的请求规则并利用正则提取poc中set内的变量。随后根据匹配到poc中的请求规则内的expression字段构造响应,并在默认响应基础上进行修改。其中,expression字段的匹配与生成则是利用文本匹配与正则提取响应内容,并对其中的包含复杂表达式response.body.bcontains(xxx1(xxx2(xxx3)))的部分替换为Python函数后利用eval函数执行后再根据执行结果构造响应。
2.3.1 解析请求
团队通过对流量的评判,决定采用Python自带的ThreadingHTTPServer作为HTTP服务器接收与处理请求[12]。其中,由于部分poc的请求不完全符合HTTP的标准,在请求行内存在超过两个空格(即path内的空格未编码为%20)导致官方Python库无法解析,不经过自行编写的处理函数而直接返回400。所以这里重写请求解析代码对请求进行处理,其逻辑为对第一个空格与最后一个空格之间的path内的空格替换为%20后再调用处理程序,代码如下图2.1所示。
2.3.2 解析poc文件
我们采用的poc文件为scan4all项目[14]中的poc,其文件为yml格式,具体如下图2.2所示。
图2.2yml格式poc文件
在这里我们主要关注里面的set字段、rules内每个规则的request字段与expression字段,其中我们将利用request来匹配规则与对应的poc,利用expression字段构造满足其要求的响应。
我们首先解析set字段的内容,对于randomInt开头的变量匹配任意长度的数字,对于randomLowercase开头的变量匹配任意长度的小写字母,对于变量定义处内编写数字的则匹配任意长度数字,其他情况则匹配任意长度字符,代码如图2.3所示。
图2.3解析set字段内容代码
然后对每个规则(请求)的path、body与headers生成正则表达式,并对其中的空格、括号与星号做处理允许匹配其本身或其对应的url编码,并且根据前面解析的set中的变量将其中全部的“{{变量名}}”都替换为对应的正则匹配项。其中,每个变量的第一次替换会替换为(?P<变量名>匹配表达式)的形式,采用正则表达式命名分组提取变量,后面的替换则简单替换为(匹配表达式)。其中,正则表达式命名分组提取的变量值将会按规则所在的文件名作为命名空间进行存储,即每个poc文件有自己的变量状态,一个poc里面的每个请求规则共用一个变量状态空间,以便处理跨请求的状态传递。
生成完匹配规则后,将这个请求的匹配规则及其文件名、变量、响应表达式等信息按请求方法分类存储,代码如下图2.4所示。
图2.4分类存储匹配规则代码
2.3.3 匹配规则
根据请求中的方法对该方法所对应的匹配规则逐个进行匹配测试,每个规则均需要匹配path、body、header字段成功才视为成功匹配。其中,因为”Host”与”Content-Length”头无匹配价值被忽略,对于”Cookie”头因为Python的HTTPServer在处理头时会将其最后的分号忽略并且会存在意外双引号,所有需要专门处理将其替换处理。对于匹配成功项,同时也通过前面的正则表达式中的命名分组将对应变量存储进这个规则文件的状态空间。此部分代码如图2.5所示。
图2.5测试匹配规则代码
如果有多个匹配成功规则,从所有匹配成功的规则中选取匹配到header字段最多的那个规则,因为其满足了额外的header。如不能通过区分头字段数量的方式进行区分,则根据匹配的path长度进行筛选,如果最长的path匹配规则相比第二长的path匹配规则要长得多(经测试设置为长15个字符以上)的情况下,则采用最长匹配的path。不直接采用最长的原因为带通配符的正则表达式较长,相比无通配符的正确匹配更容易成为最长表达式,此处这世上通过明显的长度优势表明其不是因为带有通配符表达式才会长,从而避免漏匹配规则。
如果请求不能通过前面的手段筛选出唯一的匹配规则,则对所有规则执行构造响应操作,如果能够匹配唯一规则就只执行那个规则的构造响应操作,如果没有匹配则返回默认响应。尽量精准匹配的目的在于降低构造响应的开销以及避免规则之间的冲突。本部分所对应的代码如下图2.6所示。
图2.6执行构造响应操作代码
2.3.4 生成响应
前文所述默认响应内容如下图2.7所示,后续生成响应的操作均为在此基础上进行修改。
图2.7默认响应操作代码
对前面所匹配的每个规则,均按照规则内expression字段类型生成和修改响应。对于expression字段,首先按&&或||拆分为多个不同的响应规则。通过分析,可以发现95%以上的响应规则为下列模式构成,其中response.body.bcontains(*)内的*为动态表达式、reverse.wait(*)为反连请求、”*”.bmatches(response.body)的*为正则表达式以及response.headers[“location”].contains(string(r1*r2))是特例需要专门处理,余下的基本为字符串或数字,可以直接正则提取并解析。对于不等于符号,除了返回状态修改为不会出现的203之外,其他情况不做处理,如下表2.1所示。对于极少数不在列表内的情况,可以通过改写poc文件处理。
表2.1响应规则列表
对于上述匹配的response.headers,如果为content-type头,则在其原有内容上检测并补齐缺失的”application/”前缀或”text/”前缀。
response.body.bcontains(*)内的动态表达式通过Python的eval来实现,通过传递函数dict作为全局变量以及传递规则的变量状态作为局部变量让Python执行,其中会先对数据类型操作进行相关的替换处理,如bytes与string统一替换为Python中的str,数据类型为int的先行转换规则的变量状态的值类型为整型,该部分代码如图2.8所示。
reverse.wait(*)的反连请求则根据提取的reverseURL以及可选的reverseHost构造请求链接,通过requests.get发送连接请求并设置两秒钟超时避免卡住,代码如图2.9所示。
图2.9反连请求代码
“*”.bmatches(response.body)内的正则表达式,经过分析,发现其主要涉及的正则内容为(.*?)、[x*]、*、?、”、^这几种,经过匹配替换以及内容前置即可满足条件,其代码如图2.10所示。
图2.10匹配替换及内容前置代码
对于特例response.headers[“location”].contains(string(r1*r2))则根据其要求手动构造即可,代码如图2.11所示。
图2.11手动构造代码
在构造完响应内容后,对其合法性进行修复,如301或302状态需要Location头,文件内容需要和Content-type匹配等,代码如下图所示,其中的need_start为bmatches规则执行时要求其响应内容为最前面(即”^xxx”表达式),代码如图2.12所示。
图2.12修复合法性代码
完成合法性修复后对二进制特例进行处理,因为poc原始存储的二进制数据字符串在处理expression时没有进行二进制转义,需要统一替换后再写入响应体,代码如图2.13所示。
图2.13处理二进制特例代码
2.3.5 poc改写
对于特殊的复杂poc需要手动进行改写,如youphptube-encoder-cve-2019-5129,其返回表达式的变量无法直接从请求中提取,如下图2.14所示,其返回所依赖的content并未直接通过请求传递,而是特殊编码在了payload里面。
图2.14无法直接提前变量代码
面对这种情况,需要将poc文件的expression表达式改写为对payload的直接引用,如下图2.15所示。其中b64decode与urldecode为自行实现的函数,可以在解析执行expression表达式时被执行。
图2.15改写expression表达式
除此之外,对于下步请求内容依赖上步请求响应构造内容的poc,则直接利用上步的表达式固定死具体内容,以便匹配与准确响应,比如drupal-cve-2018-7600-rce中的search。其原版如图2.16所示。
图2.16search原版代码
其中search将会从drupal70请求的响应中提取build_id的内容,为了能让攻击成功提取,我们将其改写为固定值返回,如下图2.17所示。
图2.17search改写代码
2.3.6 poc测试
我们在本地采用xray进行测试[10][11],其使用的poc为原版的xray自带poc,通过此测试判断我们的是否能够正确响应对应的poc。如下图2.18所示。
通过测试发现可以响应不同的poc,测试结果如图2.19所示。
对于线上环境,我们通过抓包生成了一份攻击请求的转储。并通过socket接口重发请求,以便测试,代码如图2.20所示。
图2.20攻击请求转储代码
2.4 总结与体会
随着近些年来网络攻击的多元化、复杂化、智能化,其特点也开始逐步显现,网络安全问题日益严峻,传统的网络防御技术大都是通过入侵检测、防火墙等方法来保护网络及系统安全,被动防御手段使得防御方在攻防过程中基本处于劣势地位,而蜜罐技术的出现可以改变这一现状,突出主动防御技术的地位。
本题的设计思路挺有意思的,通过漏洞扫描器的poc文件反向使用构造出一系列漏洞,从而让攻击者的漏洞扫描器失效,这成功引起了我们队伍的兴趣。
为解决此题,我们利用工具捕获了一系列请求,并根据请求信息检索到相关poc文件。其中存有一系列仓库有着不同格式但相似的poc,如何确定赛方所使用的具体poc也是一个挑战,我们先后尝试了fscan、scan4all,最终才确定是xray仓库的旧版poc,这个过程也挺有意思的。在根据poc文件去匹配请求并构造响应的实现过程中,也碰到了一系列问题与挑战。从poc表达式的复杂多变到请求HTTP不标准导致Python官方库无法解析,我们都迎难而上,把问题逐一解决。
通过此题,我们体会到在解题中要坚持尝试不气馁,面对碰到的问题,通过队伍中每个成员共同努力,群策群力,最终成功解决问题,收获到成功的喜悦。
2.5 附加文件说明
datacon_l1_sever.py:构建的服务器,用于接收请求报文并返回正确的响应。datacon_l1_poc_sent.py:请求重发器,用于测试构造的代码是否正确。
第3章 智能蜜罐环境构建-Level2
3.1 比赛题目
本题赛方提供虚拟环境,选手需要在虚拟环境中构建一个智能靶标环境;并开放指定端口以接收poc,一个poc可能会有多次请求,对接收到的请求进行正确的响应。
3.2 概述
通过Level1的程序进行测试,发现其请求为修改后的poc请求以及少数几个是完全找不到匹配乃至相似的请求。我们在Level1程序的基础添加了基于Python自带的difflib库的模糊匹配规则实现,并通过原有变量前后数个字符以及变量出现前后关系来提取变量值。其中,部分情况下会因为url编码以及空格问题导致无法依赖变量前后数个字符成功提取变量,这种会对请求与poc规则内容进行url解码等处理后再次尝试匹配提取,对于仍然无法提取的变量或额外添加的变量则通过修改poc文件实现对变量的提取与处理。除此之外,对于极易混淆的/{{xxx}}.php路径,人为构造特殊规则进行二次匹配处理。
3.3 解题思路
通过对题目的解读,我们考虑到题目比较重视智能化,并且存在智能系数这样的参考标准,于是团队对智能程度的判断方法做出推测及其应对思路:
1.返回响应的合法性,包括各种头是否合法并且与真实服务器相似,返回内容是否符合对应响应类型,此点已经在Level1的代码中实现。其中,在后续测试中排除了“返回内容是否符合对应响应类型”的要求。
2.可能对反连做干扰,提供无效反连地址等干扰,看能否正确返回响应,此点也在Level1代码中实现。经过请求审计,发现并无反连类型poc,排除此项要求。
3.对请求的path、body与header进行修改,导致无法精准匹配原有poc。经过请求审计确定有大量此类型的请求。采用精准匹配失败后模糊匹配最相似的请求的方法进行匹配。
4.对变量前后字符进行修改,导致无法提取变量。通过url解码+空格处理+逐步后退匹配策略+人工修改poc的方式进行处理。
5.对变量进行修改,如原poc为4位小写字母修改为4位小写字母加数字。针对此项,将变量提取的原有匹配规则进一步放宽即可成功匹配与提取。
6.原有请求为固定值,请求中修改为随机值导致响应规则无法生成满足要求的响应,如原请求内为md5(1234)并且硬编码了response.body.bcontains(b”1234的MD5值”),这种需要手工修改poc为md5({{rand}}),并添加响应表达式response.body.bcontains(md5(rand))。
7.出现无法匹配任何poc的请求。这种请求仍然会匹配最相似的规则并在默认响应基础上进行修改。
8.修改请求细节,造成攻击失败,判断是否正确响应攻击失败。如部分poc中的默认密码漏洞内的包括默认密码信息的认证头被删除,这种仍然会被模糊匹配到原有规则,导致返回攻击成功响应。针对这种请求,我们通过人为修改poc的方式,添加失败响应,让其优先匹配攻击失败响应,如前面所述的默认密码漏洞从成功的200修改为403禁止访问。
9.对于极易错误匹配的相似通配符项目能否准确区分不同的攻击。此项通过设计精准唯一匹配失败的后备特殊匹配规则实现。
10.对于完全相同路径(如/)能否触发多个不同规则并同时满足要求,此项已经在Level1代码中实现。
整体思路与Level1的相一致,在Level1基础上添加了对规则的模糊匹配与模糊匹配情况下的变量提取实现。其中,需要对攻击请求进行审计与处理,这里对无精准匹配与多精准匹配的攻击请求进行了人工审计,并根据需要修改代码与poc的yml文件。
3.3.1 模糊匹配规则
这部分功能将会在规则解析与规则匹配这两部分中分别进行实现。首先在解析规则时会将规则信息的字典转化为字符串dk用作后续的模糊匹配。其中,头部分将会按头名称排序后再进行字符串的转换。代码如下图3.1所示。
在规则匹配中,精准匹配失败后,将会进入模糊匹配流程,在模糊匹配中先利用一样的规则生成此请求的dk,再利用difflib的get_close_matches方法返回最相似的规则dk,并通过此规则dk能定位到对应规则完成模糊匹配,代码如下图3.2所示。
图3.2模糊测试请求dk代码
其中,通过请求审计可以发现攻击请求中的Accept、Accept-Encoding、Connection、Host、和User-Agent头字段为攻击方自动附加的头,为了避免干扰模糊匹配将其从请求头中删除。除此之外,发现许多请求会残留之前某次攻击响应的Set-Cookie字段的内容:Cookie为“ac_userid=”admin,ac_passwd=””,为了避免其干扰模糊匹配,仍然将其从请求头中去除。此工作的代码如下图3.3所示。
图3.3去除请求头干扰代码
3.3.2 模糊匹配规则的变量提取
这一块仍然分为规则解析与规则匹配这两部分中分别进行实现。
在规则解析阶段,将会生成6种匹配规则,包括前后5个字符匹配中间变量、前后5个url解码后的字符匹配中间变量、前后2个字符匹配中间变量、前后2个url解码后的字符匹配中间变量、前后2个字符匹配中间变量并替换花括号为通配符、前后2个url解码后的字符匹配中间变量并替换花括号为通配符,在最终执行匹配时会每种从前往后匹配直到匹配成功,其中越前面的匹配约束越多越不容易出现匹配失误。其代码如下图3.4所示,其中dk_uq为url解码后的dk。
图3.4规则解析阶段代码
为了避免变量匹配失误,我们也将变量出现前后顺序作为匹配需要遵循的内容,通过将多个变量的正则匹配规则用.*连接,并在最终匹配提取变量时采用连接后的正则表达式,可以保证变量出现的前后顺序与原始poc相一致。其代码如下图3.5所示。
在规则匹配的模糊匹配阶段,变量提取跟精准匹配的变量提取与使用思路相似。采用前面构造的正则表达式对请求的dk进行提取变量提取,直到提取成功后更新规则对应的变量状态。其中,每次匹配均跟原始请求dk与经过url解码处理的请求dk_uq进行尝试匹配,从而解决url编码问题。
图3.6规则匹配模糊匹配阶段代码
3.3.3 变量匹配规则放宽
原来的数字型与小写字母型内容规则放宽到对应类型开头后面允许任意数字字母,并配置默认值。其对应代码如下图3.7所示。
图3.7匹配内容代码
3.3.4 特殊匹配规则
针对极易混淆的“/动态内容.php”与“/动态内容”这种请求路径,我们根据请求内容专门制定,了一套特殊匹配规则,根据请求的动态内容的长度以及内容去精准匹配做出正确响应。特别是对于thinkphp-v6-file-write而言,他有两步攻击是完全一致的,但是结果不同。为了识别当前攻击步为哪个,专门引入了thinkphp-v6-file-write_step变量标识步骤。所定义的特殊匹配规则如下图3.8所示。
图3.8特殊匹配规则代码
在执行匹配时,如果无法精准唯一匹配,则尝试能否进行特殊匹配,在此会根据上述正则表达式逐一对请求的path记进行测试,如果匹配则直接使用匹配的特殊匹配规则,代码如下图3.9所示。
图3.9特殊匹配规则代码
3.3.5 请求转储与测试
因为此题审计工作量更大,请求情况更复杂,我们改进了Level1中的请求转储与重发机制,在接收到请求后将请求内容保存,并在接收到特殊path时再用json格式转存到本地以供重放与审计,其代码如图3.10所示。
图3.10Level1机制改进代码
其中的reqs0则是无精准匹配的规则,单独存储以便审计,代码如图3.11所示。
图3.11reqs0匹配规则代码
在保存攻击请求后,我们通过requests重放攻击请求来完成对代码的测试工作。重放请求代码如下图3.12所示。
图3.12requests重放攻击请求代码
3.4 总结与体会
随着近些年来网络攻击的多元化、复杂化、智能化,其特点也开始逐步显现,网络安全问题日益严峻,传统的网络防御技术大都是通过入侵检测、防火墙等方法来保护网络及系统安全,被动防御手段使得防御方在攻防过程中基本处于劣势地位,而蜜罐技术的出现可以改变这一现状,突出主动防御技术的地位。
我们团队蜜罐Level2的解题过程是一个根据自己对于题目本身的理解、Level1的经验以及提交答案后的结果对Level1程序目前存在的不足的持续改进过程。比如,题目在原有的基础上修改请求,导致无法精准匹配与提取变量,我们通过模糊匹配与前后字符提取变量等方式解决,成功提高了程序的对不同攻击成功响应的鲁棒性。对于请求变量化的一些攻击,我们通过修改yml文件实现其变量化响应,而不是只能响应某个特定值的结果,特别是带MD5值响应的请求。但是,修改yml文件是一件费时费力分事情,需要对比变量,path、body、header等字段与之前请求的相关字段的差异,构造大家认为的能够符合正确响应规则的文件。大家在这个过程中相互支持,一起探讨,收获了很多。
3.5 附加文件说明
datacon_l2_server_clean.py:构建的Level2服务器,用于接收请求并返回响应。datacon_l2_poc_sent.py:Level2的请求重发器,用于测试服务器是否能够正确响应。
参考文献
[1]Xti9er、七夜、pav1.(2021,November18).虚拟货币挖矿检测与防御.腾讯安全应急响应心.https://security.tencent.com/index.php/blog/msg/208
[2]Charm1y.(2019,February7).Suricata下的挖矿行为检测.FREEBUF.https://www.freebuf.com/articles/network/195171.html
[3]Mubie,haoyuma.(2021).MaliciousMiningBehaviorDetectionSystemofEncryptedDigitalCurrencyBasedonMachineLearning.SafetyTechnologiesandFaultTolerantMethodsforEngineering2021.https://doi.org/10.1155/2021/2983605
[4]Madneai.(2020,May8).流量分析的瑞士军刀:Zeek.FREEBUF.https://www.freebuf.com/sectool/235587.html
[5]Jayus.(2020,June19).网络安全数据集流量特征提取工具Cicflowmeter.安全客.https://www.anquanke.com/post/id/207835
[6]Lebron-jian.(2019,May11).Python机器学习笔记:异常点检测算法——OneClassSVM.博客园.https://www.cnblogs.com/wj-1314/p/10701708.html
[7]Lebron-jian.(2019,April13).Python机器学习笔记:异常点检测算法——IsolationForest.博客园.https://www.cnblogs.com/wj-1314/p/10461816.html
[8]Ahlashkari.(2020,June18).CICFlowMeter.Github.
https://github.com/ahlashkari/CICFlowMeter
[9]Nebutech.(2022,September2).NBMiner.Github.
https://github.com/NebuTech/NBMiner
[10]Chaitin.(2022,October31).Xray.Github.https://github.com/chaitin/xray
[11]Chaitin.(2022,October31).Xray.Xray安全评估工具文档.
https://docs.xray.cool/#/guide/poc
[12]Python官方.(2019,October14).Http.Server—HTTP服务器.Python.Org.https://docs.Python.org/zh-cn/3.8/library/http.server.html#http.server.HTTPServer
[13]Md-irohas.(2019,November13).Tcppc.GitHub.https://github.com/md-irohas/tcppc-go
[14]hktalent.(2022,July27).Scan4all.GitHub.
https://github.com/hktalent/scan4all/tree/main/pocs_yml/ymlFiles
微信号:DataConofficial
获取更多大数据安全知识
进群还有超多活动、福利
DataCon定制服饰、背包等精彩好礼
等你来拿!
原文始发于微信公众号(DataCon大数据安全分析竞赛):冠军Writeup大放送 | DataCon2022网络流量分析赛道之“见世面”战队