【技术分享】如何检测使用USB设备创建的隐藏网络

https://p5.ssl.qhimg.com/t01cd9b3ca857ee8197.jpg

译者:興趣使然的小胃

预估稿费:300RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


时至今日,许多企业和政府机构都建有通信隔离网络或者在不同网络之间使用受限数据流。这些计算机网络都是针对特定环境创建的,因为这些环境中可能包含非常特别或者非常重要的信息,比如工业控制系统、处理特定数据的高度安全环境或者符合安全标准的生产网络等。在当代网络安全历史上,发生过诸如震网(Stuxnet)的恶意软件渗透进核电厂隔离网络中的真实事件。鉴于这个案例,我们可以看出,如果只是单纯地将计算机网络与其他网络断开是远远不够的(不管是通过断开网线还是断开WiFi连接方式)。任何类型的外部连接都有可能给计算机带来安全风险。本文分析了此类隐藏网络(Hidden Network)的可能性,介绍了如何检测此类网络的方法,并且介绍了如何在企业网络中对此类网络进行防护。

一、网络连接的安全风险

就数据网络安全方面而言,人们趋向于使用基于链路层的网络连接(如以太网、WiFi连接等等)来分析网络安全性。企业网络的复杂度远远超过这类网络,因此我们需要从多个角度分析企业网络的安全性。

对企业数据网络的流量分析是理解企业网安全性的主要方法。此外,我们也可以对使用常见协议的网络节点进行搜索分析,以了解企业网的安全性,这些节点往往是提供重要服务或者承担关键作用的节点。基于这些背景知识,我们可以得出结论,那就是基于风险的网络分析可以根据不同的准则在企业网安全方面为我们提供丰富的数据及信息。

以直观的方式映射网络结构是理解网络节点和网络设置的最佳选择,因此,这种情况下,使用远程测量方式来分析网络安全风险是非常必要的一种选择。通过分析网络上交换的数据,我们能够更好地理解网络整体结构以及网络内部的安全威胁。

http://p3.qhimg.com/t011629b896db4f5b96.png

图1. 反映不同节点以及节点连接情况的网络拓扑图

节点的表示方法以及节点的连接结构对网络内部不同边界的勾画来说特别重要,合适的表示方法可以在抵御入侵行为、检测攻击活动或者预先实施安防措施方面起到非常大的作用。

问题在于对网络的理解上。在许多情况下,人们将网络定义为一组连接在一起的计算机,各个节点之间可能通过不同的技术或者协议相互通信。在大多数情况下,普通用户或者系统、网络管理员乐于通过以太网或WiFi方式连接到不同机构的计算机上,本文针对的并不是这种场景。当某个组织没有对USB设备的使用做出限制时,它就容易受到隐藏网络的威胁。攻击者可以使用USB设备创建隐藏网络,在物理或逻辑隔离的计算机之间进行通信。

1.1 网络隔离及USB连接

我们通过一个简单的案例,使大家更好理解基于USB设备的隐藏网络的危害。假设某个组织的网络由3种类型的VLAN(虚拟局域网)组成,第一个VLAN包含:

1、计算机A。该计算机与同一VLAN的其他计算机相连。

2、计算机B。该计算机与同一VLAN的其他计算机相连。

第二个VLAN包含:

1、计算机C。该计算机与同一VLAN的其他计算机相连。

2、计算机D。该计算机与同一VLAN的其他计算机相连。

3、计算机E。该计算机与同一VLAN的其他计算机相连。

第三个VLAN包含:

1、计算机F。该计算机与同一VLAN的其他计算机相连。

网络拓扑大致如下图所示,从中我们可以看到VLAN对计算机的隔离效果。假设该机构的员工使用USB设备来传输数据,那么这些数据很有可能会从一个VLAN中的计算机传输到另一个VLAN中的计算机。USB设备本身就是一个安全威胁源,可以在组织内部创建一个隐藏网络。

http://p7.qhimg.com/t01a80e091276efabf6.png

图2. 计算机在不同VLAN中的连接情况

假设计算机F以及计算机E正在使用USB设备来交换信息,此时这两台计算机之间正在创建一个隐藏网络。这一情况可以使用两个节点(E和F)以及从USB设备来源主机到第二台主机之间的一条有向弧边来表示。

http://p8.qhimg.com/t01f6680aac0d6b345a.png

图3. 在已有网络拓扑上形成的一个覆盖型(overlapping)隐藏网络


二、操作系统中的USB设备连接情况

当某个USB设备在两台主机之间交叉连接时,这种情况就类似于植物的“授粉”现象。这原本是生物学领域的一个概念,这里指的是不同主机间通过USB设备交叉传递安全威胁或风险(即使这些主机不处于同一网络中)。

当用户连接USB设备时,Windows注册表中会创建一系列键值。这类信息价值很高,比如,在安全取证中,分析人员可借此了解信息泄露的源头或者在安全事件发生后进行溯源。

Windows系统注册表中的USBStor键值用于保存插入当前计算机的所有不同设备的信息。当某个USB设备插入到某台主机中时,我们可以在USBStor键值中找到这个设备的信息,这些信息足以用来识别这个USB设备。

http://p9.qhimg.com/t0107aa2b8d6b71f98d.png

图4. 已插入的USB设备在注册表中留下的信息

当USB设备插入到某台主机中时,我们可以收集到以下信息:

1、设备名

2、设备类型(Class)

3、设备类型的唯一标识符(ClassGUID)

4、设备所提供的服务,如硬盘服务

5、驱动

6、其他信息

2.1 隐藏链接:如何探测此类网络

了解了微软操作系统保存USB设备相关信息的位置及具体方式,我们就能知道是那些主体在共享这个USB设备。这样一来,我们可以使用两个节点来表示两台主机,使用一条弧边来表示这两台主机之间的连接。正是由于隐藏链接(Hidden Link)的存在,我们才能发现隐藏网络。此外,由于我们可以从操作系统中获取许多相关事件,从中识别源头计算机,进而准确绘制弧边的方向。

为了能够自动化检测隐藏链接,我们建议使用如下方案:

http://p2.qhimg.com/t01a18fa3e297ce0c3c.png

图5. 检测隐藏链接的脚本在活动目录(AD)中的投放路径

存在中央节点的网络中应用程序的执行路径如上图所示,在这个网络拓扑中,有多种方法可以在每台主机上执行命令,比如以下方法:

1、WinRM

2、SMB(服务器消息块,Server Message Block)

3、WMI

Powershell是微软出品的面向对象的命令行工具,提供与微软操作系统中任何结构交互的功能强大的接口。

http://p2.qhimg.com/t01106fde24d08ecc43.png

图6. 使用Powershell收集已连接的USB设备信息

2.2 使用WinRM检测USB隐藏网络

在PowerShell中使用WinRM版探测脚本的前提是在每台主机上启用Windows远程管理(WinRM,Windows Remote Management)服务:

http://p5.qhimg.com/t0107ff420fed8cdc95.png

图7. WinRM服务

此外,我们已经在启用活动目录的单个域网络中,使用这个脚本自动化地收集尽可能多的信息。在本地网络中使用这个脚本时,会有窗口弹出提示输入域管凭证。

http://p7.qhimg.com/t013fcdbf1b2d027f10.png

图8. 运行脚本时需要输入凭证信息

脚本的主要功能由“LaunchUSBHiddenNetworks.ps1”来实现,这个程序使用“RecollectUSB.ps1”这个脚本连接到远程主机,“RecollectUSB.ps1”用来收集USB设备的相关信息。因此,我们需要对每台主机单独执行这一脚本。

2.2.1 LaunchUSBHiddenNetworks脚本

这个脚本主要是通过“Invoke-Command”这个PowerShell命令来执行的。该命令可以使用FQDN、主机名以及IP地址作为参数,连接网络中的某台主机,也可以在参数中指定需要执行的PowerShell脚本:

$salida=invoke-command -ComputerName (Get-Content servers.txt) -FilePath 'PathToScriptRecollectUSBData.ps1'-Credential testdomainadministrador

我们可以在通过“-ComputerName”参数指定AD域中待审计的目标主机。我们当然可以在这个参数后面,使用逗号隔开的主机名来指定多台目标主机,但在本文中,我们使用一个包含主机列表的文本文件(servers.txt)作为参数完成这一任务。

“-FilePath”指定了用来收集信息的脚本的具体路径。最后,我们可以通过“-Credential”参数指定需要使用的域管账户,在本例中,域为“testdomain”,用户为“administrator”。

程序的运行结果保存在$salida对象中。我们可以将搜集到的信息存放在CSV文件中,如“USBDATA.csv”:

$salida | Out-File USBDATA.csv

CSV结果文件格式如下所示,每一行包含4列,分别代表计算机名、IP地址(IPv4格式)、USB设备名、ID(唯一标识符):

http://p0.qhimg.com/t01cb08e011e7265c74.png

图9. 结果保存为CSV文件

收集到这些信息后,我们就能使用Gephi这个应用,创建如下一张图:

http://p6.qhimg.com/t015745239b148d2bf8.png

图10. 图形化显示网络中USB设备形成的隐藏连接

2.2.2 RecollectUSBData脚本

这个脚本用来收集连接到计算机上的USB设备的所有信息,需要在待审计的目标计算机本地中运行。所收集的信息来源于Windows注册表中的某个特定路径。

$USBDevices = @()
$USBContainerID = @()
$USBComputerName = @()
$USBComputerIP = @()
$SubKeys2 = @()
$USBSTORSubKeys1 = @()

我们需要将与目标主机相关的信息保存到这些变量中,并且检查注册表中存储的USB设备的相关信息。

$Hive = "LocalMachine"
$Key = "SYSTEMCurrentControlSetEnumUSBSTOR"

$Hive以及$Key这两个变量共同组成了注册表中存储USB设备信息的完全路径。$Hive变量的值为“LocalMachine”,这个值与HKLM或者HKEY_LOCAL_MACHINE效果相同。

$ComputerName = $Env:COMPUTERNAME
$ComputerIP = $localIpAddress=((ipconfig | findstr [0-9]..)[0]).Split()[-1]

计算机名以及IP地址分别存放到$ComputerName以及$ComputerIP变量中。

$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($Hive,$Computer)
$USBSTORKey = $Reg.OpenSubKey($Key)
$nop=$false

与注册表查询有关的对象为$Reg对象,我们以$Hive以及$Computer变量为参数,组成待查询的注册表路径,通过OpenRemoteBaseKey命令查询注册表,随后在代码中通过$nop变量控制程序的执行流程。

Try {
$USBSTORSubKeys1 = $USBSTORKey.GetSubKeyNames()
}
Catch
{
Write-Host "Computer: ",$ComputerName -foregroundcolor "white" -
backgroundcolor "red"
Write-Host "No USB data found"
$nop=$true
}

程序使用Try-Catch代码来管理可能遇到的错误。如果没有挖掘到与USB设备相关的任何信息,$nop变量就会被赋值为$true,中断整个处理流程。

if(-Not $nop)

如果程序检测到与USB设备连接有关的任何信息,以上条件语句为真,程序会执行如下代码:

代码段1:

ForEach($SubKey1 in $USBSTORSubKeys1)
{
$Key2 = "SYSTEMCurrentControlSetEnumUSBSTOR$SubKey1"
$RegSubKey2 = $Reg.OpenSubKey($Key2)
$SubkeyName2 = $RegSubKey2.GetSubKeyNames()
$Subkeys2 += "$Key2$SubKeyName2"
$RegSubKey2.Close()
}

注册表中存储的每一条信息都代表着一个不同的USB设备。这些设备会被保存到@Subkeys2数组中。

代码段2:

ForEach($Subkey2 in $Subkeys2)
{
$USBKey = $Reg.OpenSubKey($Subkey2)
$USBDevice = $USBKey.GetValue('FriendlyName')
$USBContainerID = $USBKey.GetValue('ContainerID')
If($USBDevice)
{
$USBDevices += New-Object -TypeName PSObject -Property @{
USBDevice = $USBDevice
USBContainerID = $USBContainerID
USBComputerName= $ComputerName
ComputerIP = $ComputerIP
}
}
$USBKey.Close()
}

这段代码用来处理上一段代码中识别出的保存在@Subkeys2数组中的每个USB设备。如果某个设备包含$USBDevice字段,那么程序就会获取USB设备的ID信息(USBContainerID)。程序会顺便获取计算机的主机名以及IP地址,以便导出到CSV输出文件中。

http://p9.qhimg.com/t01ec8e7cf3247db65d.png

图11. 存放USB设备信息的注册表路径

代码段3:

for ($i=0; $i -lt $USBDevices.length; $i++) {
$IDUnico=$USBDevices[$i] | Select -ExpandProperty "USBContainerID"
$USBNombre=$USBDevices[$i] | Select -ExpandProperty "USBDevice"
Write-Host "Computer: ",$ComputerName -foregroundcolor "black" -
backgroundcolor "green"
Write-Host "IP: ",$ComputerIP
Write-Host "USB found: ",$USBNombre
Write-Host "USB ID: ",$IDUnico
Echo "$ComputerName,$ComputerIP,$USBNombre,$IDUnico"
}

最后,这段代码用来格式化显示从远程主机获取的信息。Write-Host这条命令用来在当前屏幕中打印出相关信息。Echo命令作为数据输出方式,以便在CSV文件中写入数据。

http://p8.qhimg.com/t016fa98f2387b23622.png

图12. 程序运行后的输出结果

2.3 使用SMB及PSExec检测USB隐藏网络

为了使用SMB协议来运行检测脚本,我们需要事先安装PSTools,具体说来,我们需要在待检测主机中运行PSExec命令。这个脚本的原理与WinRM版的脚本几乎完全一致。服务器需要连接到远程主机,并且使用域管账户运行检测脚本,然后通过脚本收集USB设备相关数据。

我们稍微修改了LaunchUSBHiddenNetworks.ps1脚本,以适应这种连接环境。主要的改动是没有使用Invoke-Command这条命令来远程运行脚本。我们会通过Powershell运行一个shell接口,然后利用该接口运行脚本。脚本需要从某个网络位置中下载,最好能通过使用HTTP协议的Web服务器来下载这个脚本。通过这种方式,我们可以规避在访问本地共享资源时可能碰到的一些问题,如执行策略问题以及权限问题。

与WinRM版的脚本类似,我们会将执行结果存储在CSV文件中。为了避免出现同步问题,也为了给远程主机上的脚本预留充足的运行时间,我们在代码中使用了一些延迟量。

2.3.1 LaunchUSBHiddenNetworks脚本

$computers = gc "C:scriptsHiddenNetworksPSExecUSBHiddenNetworks_for_SMBservers.txt"
$url = "http://192.168.1.14/test/RecollectUSBData.ps1"
$sincro = 40

这段代码中分配了几个变量。servers.txt文件中保存的服务器名或IP地址信息会被赋值到$computers变量中,$url变量用来存储RecollectUSBData.ps1脚本的网络地址,$sincro变量表示同步操作所需等待的时长。我们需要根据具体运行的环境来调整这个数字。某个执行样例如下所示:

http://p2.qhimg.com/t016f9e44626161d5bf.png

图13. 使用PSEXEC工具运行Powershell以及脚本程序

servers.txt文件保存了计算机名或者IP地址,如下所示:

http://p8.qhimg.com/t01427ed7b4457f9a0a.png

图14. 待分析的计算机列表

foreach ($computer in $computers) {
$Process = [Diagnostics.Process]::Start("cmd.exe","/c psexec.exe
\$computer powershell.exe -C IEX (New-Object Net.Webclient).Downloadstring('$url') >>
C:scriptsHiddenNetworksPSExecUSBHiddenNetworks_for_SMBusbdata.csv")
$id = $Process.Id
sleep $sincro
Write-Host "Process created. Process id is $id"
taskkill.exe /PID $id
}

以上这个循环会对servers.txt文本中的所有计算机(存储在$computers变量中)进行检查。对于这段代码,我们可以重点关注一下$Process这个对象。在这个对象中,程序会打开一台远程电脑的控制台,利用该控制台启动其他Powershell控制台,通过$url变量传入RecollectUSBData.ps1文件。在运行脚本前,我们必须正确配置每个文件的正确路径。

在处理列表中的下一台主机之前,程序必须保证当前的信息收集过程已经结束。有多种方法可以做到这一点,这里我们选择在两次动作之间添加一个sleep命令,延迟X秒运行来实现。一旦收集过程被终止,在审计下一台主机前,我们会通过taskkill命令结束当前的执行进程。程序会将当前操作的ID以及结果输出到屏幕上,如下图所示:

http://p0.qhimg.com/t018182f172cff35957.png

图15. 在Powershell中运行的脚本

2.3.2 RecollectUSBData脚本

我们只对这个脚本的最后一个代码段(第3个代码段)进行了修改,使输出格式与新的执行环境相匹配。如下代码中,“Echo”已经被替换为带有变量的“Write-Host”:

for ($i=0; $i -lt $USBDevices.length; $i++) {
$IDUnico=$USBDevices[$i] | Select -ExpandProperty "USBContainerID"
$USBNombre=$USBDevices[$i] | Select -ExpandProperty "USBDevice"
Write-Host "$ComputerName,$ComputerIP,$USBNombre,$IDUnico"
}

程序生成的USBData.CSV文件与前一个版本的程序完全一致。

2.4 历史信息收集

如果我们需要了解隐藏网络中的USB设备路由的更多信息,我们可以收集USB设备首次连接到计算机上的注册日期。Windows的所有版本中默认会在事件日志中禁用这个功能,这一功能的具体路径为:

Windows Logs -> Applications and Services Logs ->Microsoft-> Windows -> DriverFrameworks->UserMode -> Operational

因此,无需访问计算机,我们可以分析系统中的如下文件,获取该计算机中USB设备的首次连接日期:

C:Windowsinfsetuoapi.dev.log

这个文件除了记录其他数据,也会记录首次连接的时间。为了准确定位已插入的USB设备,我们需要在运行“RecollectUSBData.ps1”脚本时,保存一个新的字段,这个字段即为DiskID:

http://p1.qhimg.com/t0158a9104e228549a4.png

图16. DiskID键值

对于某个USB设备来说,这个字段的值在当前Windows系统中具有唯一性,但当它连接到其他计算机中时,这个值就会发生改变,这种情况与ContainerId这个字段不同,它在每台Windows主机上的值都一致。我们可以在setupoapi.dev.log文件中使用这个值识别USB设备。如下图所示,我们可以通过DiskID识别USB设备的位置,也能识别出首次插入目标系统中的日期:

http://p7.qhimg.com/t019f90b7c67a068b56.png

图17. 获取USB设备的连接日期

2.5 OS X中的隐藏链接

对于运行Mac OS X或者macOS的计算机,有一个PLIST文件用来保存连接到计算机的USB设备的相关信息,这个文件名为com.apple.finder.plist。OS X或者macOS环境中该文件的典型内容如下图所示:

http://p9.qhimg.com/t01a0b996b7aa0f7fde.png

图18. 连接到OS X系统中的USB设备的相关信息

2.6 防御措施

防止企业网络中计算机之间交叉感染的一种方法是限制USB设备的使用。我们可以通过活动目录策略强制部署防御措施或预防措施,在这种情况下,只有当用户同意或授权后,USB设备才能连接到主机中。这种安全策略可以与经过授权设备的白名单策略配合使用,这样一来,每个用户都能避免受到此类隐藏链接的影响,但这种解决方法在日常维护上代价较为昂贵。

http://p1.qhimg.com/t010e113372c70027d2.png

图19. 受主机策略影响USB设备无法连接到当前主机


三、总结

除了有可能会泄露企业信息,隐藏网络也会对企业的完整性造成影响。这类USB设备可以在基础架构内的不同设施之间传播恶意软件,而这些设施的安全级别各有不同,理论上讲,恶意软件可能借助这类网络从低级别设施传播到高级别设施中。将内部网络与互联网断开后,人们误认为这种情况下自己会得到更高级别的保护,直到安全事件发生才意识到这是一种错觉,实际上这会带来更多的系统漏洞。

通过USB设备传播恶意软件是一个现实问题,更是一个潜在问题,不仅有震网病毒的前车之鉴,CIA出品的野蛮袋鼠(Brutal Kangaroo)系列工具也能给我们足够的警示。

为了避免此类网络对我们的基础设施造成严重的影响,我们发表了这篇文章,介绍了此类隐藏网络的识别方法,同时也提供了相关工具来控制这类网络。因此,对于这类网络的安全取证而言,预防及控制工作也会变得更为简单。


四、参考资料

[1] https://blogs.technet.microsoft.com/heyscriptingguy/2012/05/18/use-powershell-to-find-thehistory-of-usb-flash-drive-usage/ 

[2] http://www.elladodelmal.com/2017/06/brutal-kangaroo-y-la-infeccion-por-usb.html 

[3] https://github.com/ElevenPaths/USBHiddenNetworks 

(完)