上期和大家一块探讨了边缘资产的安全问题。边缘资产安全问题是当前数字化时代面临的重要挑战,这些资产在网络边缘,往往缺乏足够的安全性保障,容易成为黑客攻击的目标。而黑客通过边缘资产入侵后,往往会使用恶意软件,比如病毒、木马、间谍软件等,来实施攻击和持久的侵入行为。肯定有小明会问:“什么是恶意软件,我看流量设备上时不时会产生恶意软件的告警,到底是什么,对我来说有什么风险,该如何处置,又该如何防范?”"恶意软件"用作一个集合名词,来指代故意在计算机系统上执行恶意任务的病毒、蠕虫和特洛伊木马等。- 二进制恶意软件:包括常见的病毒、蠕虫、木马、后门等,通常是用汇编语言、C/C++等编写,直接在底层操作系统和硬件上运行
- 脚本恶意软件:通常是用一些脚本语言编写的,比如 Python、JavaScript、VBScript 等,需要依赖解释器或虚拟机环境才能运行
- 宏恶意软件:通常是利用 Microsoft Office 等应用程序中的宏语言编写的,可以在打开 Office 文件时自动执行恶意代码
- 嵌入式恶意软件:通常是嵌入在硬件设备或嵌入式系统中,比如智能手机、路由器、工控设备等,可以利用设备的漏洞或弱点进行攻击和入侵
- Web 恶意软件:通常是通过 Web 网站或服务进行传播和攻击的恶意代码,比如恶意 JavaScript、恶意 Flash 等,可以利用浏览器和插件的漏洞进行攻击和入侵
从恶意软件的功能、行为、传播和代码等方面分析,有一些明显的特征:- 通过电子邮件、网页下载、网络钓鱼、漏洞利用等方式感染计算机系统
看到这里,肯定会有小明问:“我现在知道了恶意软件是啥,也知道那些分类和特征,但是我还是感觉很朦胧,真的遇见了可能也是不知道如何分析处置。”既然如此,那今天我就再带大家一起看看一个恶意软件可能含有的一些功能模块和实现原理。正巧前些天看到一个脚本类的恶意软件,我们从代码层面看看这个恶意软件到底是个啥?!获取到的样本刚开始没运行起来,python写的,大概改了下代码的一些逻辑和功能提示,将每个功能部分进行函数封装,运行起来发现这个恶意的脚本代码,确实存在一些比较敏感的行为特征。我这里就不放完整的代码了,按照功能模块简单介绍下该恶意脚本的行为和实现原理。权限维持是指攻击者通过各种手段保持其控制的系统权限,以便长期维持恶意活动。Windows权限维持有很多种方式,这里简单罗列常见的几种:我们今天分析的恶意脚本维持权限的方式比较简单,通过“开始菜单启动项”来维持权限,具体的位置是“开始”菜单中的“所有程序”-“启动”选项:C:Users用户AppDataRoamingMicrosoftWindowsStart MenuProgramsStartup,如下图所示:从代码看,实现方式比较粗暴,就是直接将恶意文件复制到启动文件夹下。这种方式一般的终端杀毒软件或者EDR都会产生异常行为告警,因为本身需要管理员权限才能将脚本复制到启动文件夹中,另外启动目录本身就比较敏感。
这部分主要是在用户不知情的情况下静默收集一些系统敏感信息。上述代码使用MongoDB进行收集到的信息存储,通过wmi.WMI()对象访问并收集系统硬件信息。收集的信息包括计算机名称、CPU、GPU、Disk、RAM和目标系统出口地址的位置信息等。(实际上这部分大可自己DIY来实现其他信息的收集,如操作系统版本、安全补丁情况等)看到这部分比较感兴趣,以前也使用过一些工具进行密码提取,如BrowserGhost、hack-browser-data、LaZagne等,但是一直没有具体的探究过实现原理,这次就以Chrome为例一并看下。通过样本代码和一些其他资料了解到,提取浏览器密码与浏览器类型和版本均存在一定关联性,会存在加密方式和存储方式的差异性。以Chrome为例,80.x版本前后的Chrome的加密方式就存在一些变化。在这里补充一个前置知识, 当我们在Chrome中查看密码时,需要输入Windows登录凭证,这里实际是Windows的DPAPI机制。DPAPI是一种使用对称密钥进行加密和解密数据的机制,它可以帮助应用程序和系统组件保护敏感数据,例如用户密码、证书和私钥等。DPAPI 可以帮助开发人员快速地保护敏感数据,而无需自行实现加密算法。- Windows 中每个用户帐户都有一个称为“主密钥”的密钥,这个密钥是由用户的登录密码派生出来的。当用户选择“记住密码”或“自动登录”时,应用程序可以使用 DPAPI 来加密用户密码,并将加密后的密码保存在注册表或文件系统中,以便下次自动登录。
- DPAPI 可以使用“用户模式”和“系统模式”来加密和解密数据。在用户模式下,DPAPI 使用用户的主密钥来加密和解密数据。在系统模式下,DPAPI 使用一个称为“系统主密钥”的密钥来加密和解密数据,这个密钥是由操作系统生成并保存在本地计算机上,它与用户无关,通常用于加密操作系统的敏感数据。
- DPAPI 可以使用“保护密钥”来提高安全性。保护密钥是由应用程序生成的一个随机密钥,它被用来加密用户数据,同时还使用用户的主密钥来加密保护密钥。这样,即使攻击者能够获取保护密钥,他们也无法解密用户数据,因为他们不知道用户的主密钥。
- DPAPI 还提供了两个用户态接口:CryptProtectData 和 CryptUnprotectData,用于加密和解密数据。加密后的数据由应用程序负责安全存储,应用无需解析加密后的数据格式。
- DPAPI 还提供了两个接口用来加密和解密内存数据,即 CryptProtectMemory 和 CryptUnprotectMemory。
看完了上面DPAPI的描述,大家是不是觉得微软提供的这个机制还挺方便的,不但能够帮助应用程序和系统组件保护敏感数据的安全性,还无需过多纠结起内部的加解密过程?那么我们换个角度考虑,该机制并不能保证绝对的安全性!如果攻击者能够获取用户的主密钥或保护密钥,那么他们就可以轻松地解密保存在 DPAPI 中的所有数据。 Chrome功能和一些基本使用,想必大家一定用的比我熟。那么就一定对“保存密码”的功能不陌生,是不是超方便呢!方便我们的同时,也给攻击者带来了方便。真叫是:与己方便与人方便...🙃在Google Chrome 80.x版本之前,Chrome 浏览器会将用户的登录信息加密保存在一个 SQLite 数据库文件中,其中包括网站地址、用户名和密码等信息。Chrome密码加密存储位置为:%LocalAppData%GoogleChromeUser DataDefaultLogin Data,将该文件复制出来加个sqlite后缀,即可通过数据库可视化工具即可看到所有表项字段。而 80.x版本之前,仅使用DPAPI提供的用户态接口CryptProtectData 和 CryptUnprotectData进行加密和解密。Chrome存储的加密密码,在用户登录网站时,Chrome调用CryptUnprotectData来进行数据解密,以便用户无需手动填入密码即可登录。既然可如此进行解密,可直接python利用win32crypt 模块的 CryptUnprotectData 函数可对加密后的密码进行解密。80.x版本之前的密码提取没什么难度,紧接着我们再看看80.x版本之后的Chrome~在 Google Chrome 80.x 及更高版本中,加密密码文件路径不变,还是%LOCALAPPDATA%GoogleChromeUser DataDefaultLogin Data。至于与老版本的区别,我们结合官方文档看看是如何写的(Chromium code官方文档):在命名空间中,提到了encrypted_key加密密钥(使用 DPAPI 加密的 Base64 随机密钥)、AEAD加密模式(加密秘钥长度、随机nonce长度)、密钥加密数据时的加密版本前缀“v10”、DPAPI加密秘钥前缀、测试秘钥开关、DPAPI模式开关等。 其中,密钥加密数据时的加密版本前缀如果是v10或者v11,那就表示是Chrome新版,如下所示:这部分中,函数EncryptStringWithDPAPI()和DecryptStringWithDPAPI()用于使用DPAPI加密和解密字符串。这两个函数接受一个字符串参数,并使用DPAPI中的CryptProtectData()和CryptUnprotectData()函数接口对字符串进行加密和解密操作。加密操作将字符串转换为字节序列,并使用DPAPI对其进行加密,然后将加密结果存储在输出参数ciphertext中。解密操作将加密结果转换为字节序列,并使用DPAPI对其进行解密,然后将解密结果存储在输出参数plaintext中。 在第一部分namespace中,多处提到了DPAPI加密秘钥、测试秘钥和用户配置文件秘钥,根据全局变量g_use_legacy和g_use_mock_key的不同取值,决定了秘钥的使用,使用绑定到用户配置文件的密钥可以提供更高的安全性,而使用DPAPI加密密钥则可以在不同计算机之间共享加密数据。该部分用AES_256_GCM算法对输入的字符串进行加密,并返回加密后的字符串。如果g_use_legacy为真,则使用DPAPI进行加密。否则,使用GetEncryptionKeyInternal获得的密钥初始化加密器,生成一个随机的nonce,使用aead.Seal对输入的字符串进行加密,然后将nonce和加密版本前缀插入到加密后的字符串的开头处,最后返回加密后的字符串,这里的字符串即最终存储的密码。即:明文密码---AES_256_GCM加密(作为加密密钥:原始key)---版本前缀+nonce---Login Data该部分对输入的字符串进行解密操作。如果输入的字符串不是加密版本前缀开头的,则使用DPAPI进行解密。否则,使用GetEncryptionKeyInternal获得的密钥初始化解密器,通过ciphertext字符串的开头获取nonce,然后使用aead.Open对输入的字符串进行解密,并将结果存储在plaintext中。在该部分中引入了local_state配置文件,在初始化‘OSCrypt’类时,从local_state中检索加密密钥。如果已经存在一个加密密钥,则函数会丢出错误。如果本地local_state中存在一个加密密钥,则函数会解码该密钥。如果密钥以‘kDPAPIKeyPrefix’开头(这里kDPAPIKeyPrefix为变量名),则使用DPAPI解密该密钥,并将其设置为加密密钥。否则,函数会生成一个新的加密密钥,并将其加密存储在本地local_state配置文件中。后半段中,当在本地local_state检索加密密钥成功,则解码该密钥,并检查它是否以kDPAPIKeyPrefix开头。若不是,则函数返回假。否则,函数会将密钥的前缀截去,并使用DPAPI解密密钥。若解密成功,则将该密钥设置为加密密钥,返回真。若解密失败,则函数会记录DPAPI解密密钥时出错。如果本地local_state中没有加密密钥或DPAPI解密失败,则函数会生成一个新的加密密钥。函数会使用长度为kKeyLength的随机字节数组生成一个新的密钥,然后使用DPAPI对其进行加密。加密后的密钥字符串会添加一个前缀kDPAPIKeyPrefix,并将其转换为base64格式后存储在本地local_state配置中。最后,函数将密钥设置为加密密钥,并返回真。- 原始key---DPAPI加密---插入'DPAPI'前缀---base64编码---Local State
- 长度32字节的随机数---DPAPI加密---插入'DPAPI'前缀---base64编码---Local State
- Chrome使用AES_256_GCM对称加密算法对输入的明文密码进行加密
- 使用DPAPI加密密钥时的密钥前缀,其值为"DPAPI",即代码中kDPAPIKeyPrefix的取值
- 存储在本地local_state配置前会做base64编码
即加密密钥存储在本地local_state配置文件,路径为:%LOCALAPPDATA%GoogleChromeUser DataLocal State 中。该文件为JSON格式,提取加密密钥encrypted_key后对其base64解密,然后去除密钥前的5个字符,最后利用win32crypt中的CryptUnprotectData()函数解密加密密钥。和我们分析的过程一致。这里面提到了IV,在上面也提到过,实际上就是之前提到的随机nonce长度,会和加密版本前缀一起插入到加密后的字符串开头。在命名空间中,AEAD加密的随机nonce长度占12字节。这里的目的就是为了保护密码,使明文相同得到的密文不同,或者即使密文相同明文也不相同,这里就不展开了。从Local Data中获取加密密码,如果执行是Chrome正在运行,则会被占用,可将该文件复制一份进行提取。效果如下:所以,同学们!还要把密码存储在浏览器中吗?!?!😈☠️除了保存在Login Data中的地址和账号密码,用户最近的浏览记录也是一项敏感信息。浏览器历史记录包含用户的浏览活动,如访问过的网站、搜索历史和输入的表单数据等。攻击者可以利用这些信息来进行各种形式的攻击,如:利用登录凭证、手机号、卡号等针对个人隐私进行收集,再利用用户浏览记录了解用户兴趣爱好和活动情况,定向进行钓鱼和社工活动的攻击。此处是直接提取%LOCALAPPDATA%GoogleChromeUser DataDefault路径下的History文件,该文件也是sqlite数据库文件,直接提取urls表中的url和title列即可提取所有的历史记录。实际上,在Default目录下还有很多其他的文件存在上述敏感信息,如Top Sites 会保存最用户经常访问的网站列表,Web Data会保存浏览历史记录、表单数据、登录信息等。键盘记录,顾名思义可以记录用户在键盘上输入的所有信息,配合历史记录提取,会对用户的隐私和安全造成严重的危害和风险。keyboard库用于监听键盘事件并执行相应的操作,其中Listener类,用于创建一个键盘事件监听器。通过创建一个Listener对象,并将on_press和on_release函数作为参数传递给它来实现键盘记录。在日常生活中,用户应该保持警惕,避免在不安全的环境,如网吧、他人PC中输入敏感信息,并使用安全的密码管理器来保护自己的密码。同时,企业和组织也应该采取适当的措施来保护用户的隐私和安全,例如使用加密技术来保护敏感数据,并对可能存在的恶意软件进行监测和防御。该部分的代码就不贴了,简单来说可以利用请求类似api.ipify.org、4.ipw.cn等接口获取当前出出口地址,再通过ipapi.co这样的IP地址定位接口获取大致位置。而攻击者做这一步的主要目的是为进一步攻击做准备,如攻击目标识别、用户所在地理位置、网络服务提供商(ISP)以及其他网络信息的详细信息,进而进行目标身份、群体确认,通过隐私泄露(追踪目标位置行踪)、钓鱼和诈骗活动进行牟利。1.7 连接远控地址(Command & Control,C2)我们本次分析的样本也涉及这块,不过不多,仅通过固有功能的计划执行,将获取的信息传递到远端DB。而在一些真实场景中,会涉及到恶意软件频繁连接远控地址的情况,即攻击者会多次进行命令的下发和任务结果的接收,更个性化的选择需要获取哪些信息。受害者设备 <--> 恶意软件 <--> C2服务器如上面简图所示,箭头表示数据流和命令的传输方向。恶意软件在受害者设备上运行,与C2服务器建立连接。C2服务器发送命令给恶意软件,恶意软件在受害者设备上执行命令并将结果发送回C2服务器。在这个过程中,恶意软件和C2服务器之间的通信可能会使用加密和混淆技术以逃避检测。恶意软件的种类繁多,目的性也多种多样,除了上述的基本能力外,还有病毒、蠕虫、勒索软件、僵尸网络等等一系列破坏性严重的恶意软件,都需要小心,避免中招!- 安装最新的终端杀毒软件,并及时更新病毒库。主流量防病毒软件可以有效防止大多数病毒、木马等恶意软件的攻击;
- 定期更新系统和软件补丁。许多攻击都是利用系统和软件的漏洞实现的,更新补丁可以针对这些漏洞进行修复。
- 谨慎打开邮件附件和下载内容。大量恶意软件都通过邮件附件或下载内容进行传播。
- 使用复杂密码和双因素认证。复杂密码和双因素认证可以提高账号被入侵的难度。
- 远离盗版软件。从官方渠道下载软件,其他渠道下载软件无法得到官方的安全更新,容易被植入恶意代码。
- 定期全面扫描电脑。除了防病毒软件的实时防护外,还需要定期全面扫描,查杀任何遗漏的恶意软件。
- Backup 重要数据。当系统被入侵后,重要数据的备份可以最大限度减少损失。
肯定有人会问到,那我按照上👆面的办法做了,还是中招了,该怎么办?- 断开网络连接。立即断开电脑的网络连接,封禁恶意C2,避免恶意软件继续传播或遭受更多攻击。
- 进入安全模式并扫描。重新启动电脑,进入安全模式,然后使用防病毒软件进行全面扫描,消除所有的恶意软件。
- 还原系统备份。如果防病毒软件无法彻底清除恶意软件,可以还原到最近的系统备份。
- 重装操作系统。在严重情况下,唯一彻底的解决方案就是重装操作系统。注意先备份重要数据。
- 修改密码。扫描并清除恶意软件后,应立即修改各个在线账号的密码,以防止后续被入侵。
- 联系微步应急响应团队,24小时在线,为您排忧解难!嘿嘿🤪
- 手动排查,这里就不展开了,大佬们已经处理完在旁边喝茶了~🍵
讲到这里,有人可能又问了,查杀不掉,难道我只能重装系统了吗,还得重新配置系统环境......对于大多数没有安全基础的人来说,真遇到这样的安全事件就是杀毒,至于能不能杀得掉全凭运气。要是杀不掉“开摆”、“重装”二选一。微步OneSEC不仅具备反病毒、资产盘点、软件管控等常规终端安全能力,还具备标准意义上的EDR模块,从技术到场景全面对标国际头部厂商,有效应对僵木蠕常见网络威胁和钓鱼、勒索、挖矿与APT等新型威胁攻击,并提供了SaaS和本地化两种部署模式,实现政企办公网络从风险发现、事前预防、事中检测响应、事后溯源处置的一体化安全闭环。- END -
微步应急响应团队为企业客户提供应急响应服务。当企业遭遇突发重大安全事件(APT攻击、勒索加密、数据窃取、漏洞攻击、主机被控、钓鱼事件等),微步可提供快速事件定位取证、隔离清除、溯源分析、安全加固等专业安全服务,帮助企业信息系统在最短时间内恢复正常工作,将事件影响降到最低。
如果发生安全事件,可联系微步应急响应团队,联系方式:400-030-10512. 内容引用,请注明出处:以上内容引自公众号“微步在线应急响应团队”
还没有评论,来说两句吧...