本文仅用于安全研究与技术学习,请勿用于任何违法用途。
一、背景介绍
企业内网的网络准入系统一般会在终端安装agent,利用agent检测终端符合企业内部安全要求才能接入内网。某些企业可能要求接入内网的计算机不能同时连接其他网络。
某网络准入系统的安全检测项中,有一项多网卡检测,如果检测到存在2个或以上的处于已连接状态的网卡,则禁止连接内网。

同时还有设置了例外情况,如果网卡的名称中包含“VMware”或者“virtual”,则不算是多网卡,因为企业内有些虚拟桌面的瘦客户端或者虚拟机,如果都禁止了,会影响人员办公。
二、破解需求
某些特殊情况下,需要同时连接内网和互联网,如远程运维等。而企业内网又无法直接连接互联网,就需要用一台计算机同时连接双网,才能进行远程桌面的运维。
三、解决方案
总共有三种方案,推荐第一种,剩余两种仅供学习研究。
1、向企业网络管理部门申请,在准入系统中开启策略,以允许该计算机同时连接双网。
2、想办法将该计算机的网卡名称中添加“VMware”字段,以跳过多网卡检测。
3、通过逆向破解agent,让agent即便检测到了多网卡,也返回正常。
这里介绍一下后2种方法,重点是第3种方法。
四、使用方法2:修改网卡名称
首先,使用“重命名”的方法修改网络连接名称是不可行的,说明agent检测的不是这个字段

尝试修改注册表,在注册表中搜索网卡的硬件名称,将搜索出来的含有硬件名称的字段后面都加上“VMware”字段。重启计算机,发现绕过成功!
但这种方法有2个问题:
1、内网经常掉线,用一会就掉线了,需要手动重新进行准入安全检测,等检测成功才能入网,但过一会又自动掉线了。原因不明,也未深究。
2、必须对除了连接内网的网卡外的其他所有网卡都进行注册表的修改,如果其他网卡中有USB网卡,每次网卡插拔后,会重新识别网卡内嵌的硬件名称,这样与已修改的名称对不起来,系统就会认为这是个新网卡,就会在注册表里添加新网卡,这样就还需要再次修改注册表的网卡名称。改来改去好麻烦。
采用破解的方式可一次性解决所有问题。
五、使用方法3:破解agent
(一)网络准入系统的检测机制及破解思路
1、计算机启动后,agent自动打开。
2、进行注册用户的认证登录。这里需要提前取得企业网络管理部门的注册认可,才能自动登录。如未注册或未登录成功,则不予放行,待注册登录后进行后续的动作。
3、agent进行安全检查,检查的内容根据企业给分配的角色不同而有所差别。
4、通过检查后,予以放行,可访问内网。未通过检查,不许放行,启动自动修复机制,对能自动修复的检查项进行自动修复,如开启屏保密码、添加本地防火墙策略等等。有些不能自动修复的,如安装指定的杀毒软件、多网卡时禁用网卡等操作,则进行提示,由用户自行修复。
5、修复完成后,再次进行安检,安检通过后,予以放行。
破解思路:逆向找到agent检测多网卡的那段代码,将返回值进行修改。
(二)逆向过程
第一,观察agent的进程,存在3个进程:

通过观察cpu的使用情况,确认第一个是准入检测的进程,剩下两个有一个是守护进程,另一个可能是控制网络通断的进程,这两个不是重点关注对象,主要关注第一个。
第二,进入agent的安装目录,逐个文件的观察,重点观察:
1、dll文件的文件名,通过文件名能发现一些大致的线索,比如AsmAuthClient.dll可能跟客户端认证相关,AsmFunctionMgr.dll可能是管理函数的,这些信息不一定准,但能提供一个大致的方向。
2、每个exe文件都点点看,有些有反应,有些没反应,有些是调试软件用的工具。这里,我发现了AsmFuncView.exe程序,是供运维人员使用的一个工具箱,可以查看软件运行过程中的各种日志。

3、每个xml文件和txt文件都打开看看,里面的内容即便一开始看不明白,先记住文件名和大概的内容,说不定后面就有用。这里发现存在几个xml文件,应该对安检策略有关联,包括:
—— SecurityCheckPolicy.xml,里面存储这安检策略的信息
—— SecurityCheckResult.xml,里面存储这安检结果的信息
推测,agent应该是从服务器获取安检策略,进行检查后将结果上传给服务器。策略文件是从服务器获取的,结果文件是在程序生成时直接上传给服务器的,直接修改这两个文件没有任何意义。
进一步观察文件内容,发现SecurityCheckResult.xml中一些值得警觉的内容:
<Result>
<ItemID>613</ItemID>
<Key>Yes</Key>
<DllVersion>5, 2, 0, 226</DllVersion>
<CheckType>
<InsideName>CheckUnlawfulConnectOut</InsideName>
<OutsideName>网络连接检查</OutsideName>
<Desc>检查当前计算机是否存在网络连接行为,或者双网卡,拨号上网,无线上网等情况,如果存在以上情况,给予相应处理.</Desc>
<Result>No</Result>
<Message>发现违规网络连接</Message>
</CheckType>
<Info>
<AdapterInfo>
<Description>Realtek Gaming 2.5GbE Family Controller</Description>
<Mac>a0:36:bc:d1:ff:af</Mac>
<Ip>10.114.241.176</Ip>
</AdapterInfo>
<AdapterInfo>
<Description>ASIX USB to Gigabit Ethernet Family Adapter</Description>
<Mac>f8:e4:3b:ef:af:04</Mac>
<Ip>192.168.83.4</Ip>
</AdapterInfo>
<AdapterInfo>
<Description>Intel(R) Wi-Fi 6E AX211 160MHz</Description>
<Mac>c8:cb:9e:b1:8d:66</Mac>
<Ip>172.17.26.101</Ip>
</AdapterInfo>
</Info>
</Result>
这部分内容就是检查是否存在多网卡连接的检测结果,其中<Result>字段是no,应该是检查不合格,我需要让程序最终将这个字段填写为yes,另外,还发现<InsideName>字段的内容是CheckUnlawfulConnectOut,这个字段叫内部名称,可能是该检查项在程序内的名称,也有可能是该检查项的内部函数名称。
还有一个文件Internal_Config.xml:(看名字有点意思,“内部配置”)
<ASM>
<LoadBeforeNetwork>
<Module>LcfGatwayMacBind.dll</Module>
<Module>LcfVRVIntegrate.dll</Module>
<Module>LcfRunTimeCheck.dll</Module>
<Module>AsmAuthClient.dll</Module>
</LoadBeforeNetwork>
<LoadAfterNetwork>
<Module>LcfProbeAgent.dll</Module>
<Module>LcfProcessWarden.dll</Module>
<Module>LcfUpdateDot1xModule.dll</Module>
<Module>LcfGrayUpdate.dll</Module>
<Module>ThirdLinkageModule.dll</Module>
</LoadAfterNetwork>
</ASM>
这里面有两个字段,<LoadBeforeNetwork>和<LoadAfterNetwork>,网络连接前加载的dll文件,和网络连接后加载的dll文件。这里的Network虽然意义不是特别明确,但先记住。
其他的xml大多意义不明,不过看文件名,都与本次逆向的方向无关。而txt文件多为flag型的,即某个功能运行到某个阶段了,放一个txt文件,证明已经做过了,内容多为“start”这类意义不明的内容。
好了,观察完了,可以做个大致的推测,程序使用了CheckUnlawfulConnectOut这个内部函数进行多网卡连接的检测,而这个函数,可能在某个dll文件中,现在需要定位到这个dll文件。
可疑的dll文件包括:
1、AsmFunctionMgr.dll,可能涉及函数管理
2、LcfRunTimeCheck.dll和MsacAssRuntimeCheck.dll,这两个文件都是运行时检查,可能涉及网卡的检测。
第三,使用x32dbg加载程序,看看程序具体载入了哪些dll文件。查到上面列举的这3个dll文件都被加载了,那就逐个逆向一下看看。
第四,使用IDA逐个逆向看看,发现MsacAssRuntimeCheck.dll中存在CheckUnlawfulConnectOut这个函数,分析其内容,发现这个函数就是用来写SecurityCheckResult.xml中的检测结果用的,而具体检测的步骤不在里面,这里面的检测内容不只是多网卡,还有是否存在拨号上网、无线上网等等,总共十几个跟网络连接的小检测项,将各检测项的函数入口做了一个队列,按照队列去逐个执行检测项,具体的队列顺序不好去查,也就是说想直接干预检测步骤本身有点困难(当然费点劲肯定也能找出来)。这个函数中大量的篇幅是在写xml文件,那么就干预一下xml文件的编写吧。

这一段是将网卡的具体信息写入xml文件,使用了for循环,那么这个循环内的次数应该就是实际网卡的数量,在循环中,可以看到一个break,即循环数n10_1>=p_n10时,就结束循环,推测p_n10为检测到的网卡数量,与p_n10相关的是前面的if判断条件中的函数调用sub_10008B50(v41,&p_n10),这个调用中传递了p_n10的地址,进入这个函数看

发现函数里面有个判断,当p_n10的数值为0时,直接return 0,那么调用它的那个if语句就会判断为false,不会执行if里面的内容,于是我将p_n10=10这条语句改为了p_n10=0,那么就永远不会进入if中的那个循环体。事后分析,其实if中的那个v44=0这句话才是重点,一旦v44为0,那么这个检查项就判断为不合格。虽然没有第一时间找出关键点,但也算歪打正着。
修改完后,生成了新的dll文件对原文件进行了替换,重新运行检测程序,发现检测还是不通过,进一步观察,dll文件被自动替换为原文件了。这是怎么回事?
(三)解决dll文件自动替换的问题
通过问文心一言,我这才知道windows系统普遍有dll文件放篡改的功能,就是在某个文件夹中存着dll文件的MD5校验值,每次加载dll文件前,计算该文件的MD5校验值,与存着的校验值进行对比,若不一样,则将备份的dll文件对其进行覆盖还原。但是准入软件不是windows系统自带的软件,其备份的dll文件没有保存在本地,肯定是从准入服务器中下载的,那么下载前的MD5校验值的对比,是在本地对比的,还是将本地dll文件的MD5校验值上传到服务器,由服务器进行对比呢?我的感觉是都有可能,如果是后者,那就阻止MD5值上传,如果是前者,那就简单了,直接把本地存着的MD5值改成我已经修改好的dll文件的值就行了。
通过查找,让我找到了在安装目录中有个update文件夹,里面保存着所有dll文件和其他关键文件的MD5校验值。找到文件“MsacAssRuntimeCheck.dll.xml”将里面的MD5值改成新的值
<MSAC>
<Md5>9F4D348158687C804E208F8513A13383</Md5>
<DependFile>MsacCheckSecuritySet.dll</DependFile>
<DependFile>MsacHttpClient.dll</DependFile>
<DependFile>MsacAssConfigMgr.dll</DependFile>
<DependFile>MsacActivex.dll</DependFile>
<DependFile>UsbKeyId.db</DependFile>
<DependFile>AsmFunctionMgr.dll</DependFile>
</MSAC>
然后重启检测,就在我以为大功告成的时候,竟然还是检测失败了。这背后的原因和处理办法才是本次逆向破解的最重头的内容,我将在后续进行分享。
再次声明:本文仅用于安全研究与技术学习,请勿用于任何违法用途。