OTRF / detection-hackathon-apt29

Place for resources used during the Mordor Detection hackathon event featuring APT29 ATT&CK evals datasets
GNU General Public License v3.0
130 stars 41 forks source link

4.C) File and Directory Discovery, System Owner/User Discovery, System Information Discovery, System Network Configuration Discovery, Process Discovery, Security Software Discovery, Permission Groups Discovery, Execution through API #10

Open Cyb3rWard0g opened 4 years ago

Cyb3rWard0g commented 4 years ago

Description

Finally, the attacker launches a PowerShell script that performs a wide variety of reconnaissance commands (T1083, T1033, T1082, T1016, T1057, T1063, T1069), some of which are done by accessing the Windows API (T1106).

Invoke-Discovery

Cyb3rWard0g commented 4 years ago

Maybe?: https://github.com/mitre-attack/attack-arsenal/blob/master/adversary_emulation/APT29/Emulation_Plan/Day%201/payloads/SysinternalsSuite/readme.txt#L591

Basic Query to find for handles requested to AD objects over the network

SELECT o.`@timestamp`, o.TargetUserName, o.TargetLogonId,
    a.EventID, a.ObjectName, a.ObjectType, a.ObjectServer, a.Hostname
FROM apt29Table o
INNER JOIN (
    SELECT EventID, SubjectLogonId, ObjectName, ObjectType, ObjectServer, Hostname
    FROM apt29Table
    WHERE lower(Channel) = "security"
        AND EventID = 4661
        AND ObjectType = "SAM_DOMAIN"
        AND ObjectServer = "Security Account Manager"
    ) a
ON o.TargetLogonId = a.SubjectLogonId
WHERE lower(Channel) = "security" 
        AND o.EventID = 4624
        AND o.LogonType = 3
        AND NOT o.TargetUserName LIKE "%$"

Results:

-RECORD 0----------------------------------
 @timestamp     | 2020-05-02T03:04:05.749Z 
 TargetUserName | pbeesly                  
 TargetLogonId  | 0x5dd594                 
 EventID        | 4661                     
 ObjectName     | DC=dmevals,DC=local      
 ObjectType     | SAM_DOMAIN               
 ObjectServer   | Security Account Manager 
 Hostname       | NEWYORK.dmevals.local 
Cyb3rWard0g commented 4 years ago

4.C.12 Execution through API

Detection Gategory - Telemetry

Procedure: Executed API call by reflectively loading Netapi32.dll Criteria: The NetUserGetLocalGroups API function loaded into powershelle.exe from Netapi32.dll

Query needs some validation and filtering

netapi = spark.sql(
    '''
SELECT Image, count(*) as count
FROM apt29Table
WHERE Channel = "Microsoft-Windows-Sysmon/Operational"
AND EventID = 7 AND LOWER(ImageLoaded) LIKE "%netapi32.dll%"
GROUP BY Image
ORDER BY count DESC
                          ''')
netapi.show(100,truncate = False, vertical = False)

results

+------------------------------------------------------------------------+-----+
|Image                                                                   |count|
+------------------------------------------------------------------------+-----+
|C:\Windows\System32\wbem\WmiPrvSE.exe                                   |6    |
|C:\Windows\System32\sppsvc.exe                                          |5    |
|C:\Windows\System32\svchost.exe                                         |5    |
|C:\Windows\PSEXESVC.exe                                                 |4    |
|C:\Program Files\SysinternalsSuite\PsExec64.exe                         |4    |
|C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe               |3    |
|C:\Windows\System32\WerFault.exe                                        |2    |
|C:\Program Files (x86)\Google\Update\1.3.35.452\GoogleCrashHandler.exe  |2    |
|C:\Program Files (x86)\Google\Update\1.3.35.452\GoogleCrashHandler64.exe|2    |
|C:\ProgramData\victim\‮cod.3aka3.scr                                  |1    |
|C:\Windows\System32\rundll32.exe                                        |1    |
|C:\Windows\System32\wermgr.exe                                          |1    |
|C:\Windows\Temp\python.exe                                              |1    |
+------------------------------------------------------------------------+-----+
Cyb3rWard0g commented 4 years ago

4.C.1 File and Directory Discovery

Procedure: Enumerated user's temporary directory path using PowerShell Criteria: powershell.exe executing $env:TEMP

Cyb3rWard0g commented 4 years ago

Sysmon + PowerShell Logs

SELECT Message
FROM apt29Host f
INNER JOIN (
  SELECT d.ProcessId
  FROM apt29Host d
  INNER JOIN (
    SELECT a.ProcessGuid, a.ParentProcessGuid
    FROM apt29Host a
    INNER JOIN (
      SELECT ProcessGuid
      FROM apt29Host
      WHERE Channel = "Microsoft-Windows-Sysmon/Operational"
          AND EventID = 1
          AND LOWER(Image) LIKE "%control.exe"
          AND LOWER(ParentImage) LIKE "%sdclt.exe"
    ) b
    ON a.ParentProcessGuid = b.ProcessGuid
    WHERE a.Channel = "Microsoft-Windows-Sysmon/Operational"
      AND a.EventID = 1
      AND a.IntegrityLevel = "High"
  ) c
  ON d.ParentProcessGuid= c.ProcessGuid
  WHERE d.Channel = "Microsoft-Windows-Sysmon/Operational"
    AND d.EventID = 1
    AND d.Image LIKE '%powershell.exe'
) e
ON f.ExecutionProcessID = e.ProcessId
WHERE f.Channel = "Microsoft-Windows-PowerShell/Operational"
  AND f.EventID = 4104
  AND LOWER(f.ScriptBlockText) LIKE "%$env:temp%"

Results

Creating Scriptblock text (1 of 1):
function Invoke-Discovery {
    $DiscoveryInfo =@()
    $CurrentDir = Get-Location

    $DiscoveryInfo += [PSCustomObject]@{
                CurrentDirectory = $CurrentDir
                TempDirectory = $env:TEMP
                UserName = $env:USERNAME
                ComputerName = $env:COMPUTERNAME
                UserDomain = $env:USERDOMAIN
                CurrentPID = $PID
            }

    $DiscoveryInfo | Format-List

    $NameSpace = Get-WmiObject -Namespace "root" -Class "__Namespace" | Select Name | Out-String -Stream | Select-String "SecurityCenter"
    foreach ($SecurityCenter in $NameSpace) { 
        Get-WmiObject -Namespace "root\$SecurityCenter" -Class AntiVirusProduct -ErrorAction SilentlyContinue | Select DisplayName, InstanceGuid, PathToSignedProductExe, PathToSignedReportingExe, ProductState, Timestamp | Format-List
        WmiObject -Namespace "root\$SecurityCenter" -Class FireWallProduct -ErrorAction SilentlyContinue | Select DisplayName, InstanceGuid, PathToSignedProductExe, PathToSignedReportingExe, ProductState, Timestamp | Format-List 
    } 

    Gwmi Win32_OperatingSystem | Select Name, OSArchitecture, CSName, BuildNumber, Version | Format-List
    Invoke-NetUserGetGroups
    Invoke-NetUserGetLocalGroups
}

ScriptBlock ID: 70878299-2ee1-4a5d-869f-124b349aee1d
Path: C:\Program Files\SysinternalsSuite\readme.ps1 
Cyb3rWard0g commented 4 years ago

Security Logs + PowerShell Logs

SELECT Message
FROM apt29Host f
INNER JOIN (
  SELECT split(d.NewProcessId, '0x')[1] as NewProcessId
  FROM apt29Host d
  INNER JOIN(
    SELECT a.ProcessId, a.NewProcessId
    FROM apt29Host a
    INNER JOIN (
      SELECT NewProcessId
      FROM apt29Host
      WHERE LOWER(Channel) = "security"
          AND EventID = 4688
          AND LOWER(NewProcessName) LIKE "%control.exe"
          AND LOWER(ParentProcessName) LIKE "%sdclt.exe"
    ) b
    ON a.ProcessId = b.NewProcessId
    WHERE LOWER(a.Channel) = "security"
      AND a.EventID = 4688
      AND a.MandatoryLabel = "S-1-16-12288"
      AND a.TokenElevationType = "%%1937"
  ) c
  ON d.ProcessId = c.NewProcessId
  WHERE LOWER(d.Channel) = "security"
    AND d.EventID = 4688
    AND d.NewProcessName LIKE '%powershell.exe'
) e
ON LOWER(hex(f.ExecutionProcessID)) = e.NewProcessId
WHERE f.Channel = "Microsoft-Windows-PowerShell/Operational"
  AND f.EventID = 4104
  AND LOWER(f.ScriptBlockText) LIKE "%$env:temp%"

Results

Creating Scriptblock text (1 of 1):
function Invoke-Discovery {
    $DiscoveryInfo =@()
    $CurrentDir = Get-Location

    $DiscoveryInfo += [PSCustomObject]@{
                CurrentDirectory = $CurrentDir
                TempDirectory = $env:TEMP
                UserName = $env:USERNAME
                ComputerName = $env:COMPUTERNAME
                UserDomain = $env:USERDOMAIN
                CurrentPID = $PID
            }

    $DiscoveryInfo | Format-List

    $NameSpace = Get-WmiObject -Namespace "root" -Class "__Namespace" | Select Name | Out-String -Stream | Select-String "SecurityCenter"
    foreach ($SecurityCenter in $NameSpace) { 
        Get-WmiObject -Namespace "root\$SecurityCenter" -Class AntiVirusProduct -ErrorAction SilentlyContinue | Select DisplayName, InstanceGuid, PathToSignedProductExe, PathToSignedReportingExe, ProductState, Timestamp | Format-List
        WmiObject -Namespace "root\$SecurityCenter" -Class FireWallProduct -ErrorAction SilentlyContinue | Select DisplayName, InstanceGuid, PathToSignedProductExe, PathToSignedReportingExe, ProductState, Timestamp | Format-List 
    } 

    Gwmi Win32_OperatingSystem | Select Name, OSArchitecture, CSName, BuildNumber, Version | Format-List
    Invoke-NetUserGetGroups
    Invoke-NetUserGetLocalGroups
}

ScriptBlock ID: 70878299-2ee1-4a5d-869f-124b349aee1d
Path: C:\Program Files\SysinternalsSuite\readme.ps1
Cyb3rWard0g commented 4 years ago

4.C.2 System Owner/User Discovery

Procedure: Enumerated the current username using PowerShell Criteria: powershell.exe executing $env:USERNAME

Same as before but looking for LIKE "%$env:username%"

Cyb3rWard0g commented 4 years ago

4.C.3 System Information Discovery

Procedure: Enumerated the computer hostname using PowerShell Criteria: powershell.exe executing $env:COMPUTERNAME Same as before but looking for LIKE "%$env:computername%"

Cyb3rWard0g commented 4 years ago

4.C.4 System Network Configuration Discovery

Procedure: Enumerated the current domain name using PowerShell Criteria: powershell.exe executing $env:USERDOMAIN

Same as before but looking for LIKE "%$env:userdomain%"

Cyb3rWard0g commented 4 years ago

4.C.5 Process Discovery

Procedure: Enumerated the current process ID using PowerShell Criteria: powershell.exe executing $PID

Same as before but looking for LIKE "%$pid%"

Cyb3rWard0g commented 4 years ago

4.C.6 System Information Discovery

Procedure: Enumerated the OS version using PowerShell Criteria: powershell.exe executing​ Gwmi Win32_OperatingSystem

Same as before but looking for "%gwmi win32_operatingsystem%"

Cyb3rWard0g commented 4 years ago

4.C.7 Security Software Discovery

Procedure: Enumerated anti-virus software using PowerShell Criteria: powershell.exe executing​ Get-WmiObject ...​ -Class AntiVirusProduct

Same as before but looking for "%-class antivirusproduct%"

Cyb3rWard0g commented 4 years ago

4.C.8 Security Software Discovery

Procedure: Enumerated firewall software using PowerShell Criteria: powershell.exe executing Get-WmiObject ...​​ -Class FireWallProduct

Same as before but looking for "%-class firewallproduct%"

Cyb3rWard0g commented 4 years ago

4.C.9 Permission Groups Discovery

Procedure: Enumerated user's domain group membership via the NetUserGetGroups API Criteria: powershell.exe executing the NetUserGetGroups API

One could look for the Invoke-NetUserGetGroups script name in PowerShell Logs but that can be bypassed by simply renaming the function/script :/

Another option (I like the most) is to look for Domain users requesting handles to SAM_DOMAIN objects with access rights 'getlocalgroupmembership'

Security Event Logs

SELECT a.EventTime, o.TargetUserName, o.IpAddress, a.Message
FROM apt29Table o
INNER JOIN (
    SELECT Message, EventTime, SubjectLogonId
    FROM apt29Table
    WHERE lower(Channel) = "security"
        AND EventID = 4661
        AND ObjectType = "SAM_DOMAIN"
        AND SubjectUserName NOT LIKE '%$'
        AND AccessMask = '0x20094'
        AND LOWER(Message) LIKE '%getlocalgroupmembership%'
    ) a
ON o.TargetLogonId = a.SubjectLogonId
WHERE lower(Channel) = "security" 
        AND o.EventID = 4624
        AND o.LogonType = 3

Results

EventTime      | 2020-05-01 23:04:04                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
 TargetUserName | pbeesly                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
 IpAddress      | 10.0.1.4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
 Message        | A handle to an object was requested.

Subject :
    Security ID:        S-1-5-21-1830255721-3727074217-2423397540-1107
    Account Name:       pbeesly
    Account Domain:     DMEVALS
    Logon ID:       0x5DD594

Object:
    Object Server:  Security Account Manager
    Object Type:    SAM_DOMAIN
    Object Name:    DC=dmevals,DC=local
    Handle ID:  0x1fccecf7240

Process Information:
    Process ID: 0x2c0
    Process Name:   C:\Windows\System32\lsass.exe

Access Request Information:
    Transaction ID: {00000000-0000-0000-0000-000000000000}
    Accesses:   READ_CONTROL
                ReadOtherParameters
                CreateUser
                GetLocalGroupMembership

    Access Reasons:     -
    Access Mask:    0x20094
    Privileges Used for Access Check:   -
    Properties: ---
    {19195a5a-6da0-11d0-afd3-00c04fd930c9}
READ_CONTROL
ReadOtherParameters
CreateUser
GetLocalGroupMembership
        {c7407360-20bf-11d0-a768-00aa006e0529}
            {bf9679a4-0de6-11d0-a285-00aa003049e2}
            {bf9679a5-0de6-11d0-a285-00aa003049e2}
            {bf9679a6-0de6-11d0-a285-00aa003049e2}
            {bf9679bb-0de6-11d0-a285-00aa003049e2}
            {bf9679c2-0de6-11d0-a285-00aa003049e2}
            {bf9679c3-0de6-11d0-a285-00aa003049e2}
            {bf967a09-0de6-11d0-a285-00aa003049e2}
            {bf967a0b-0de6-11d0-a285-00aa003049e2}
        {b8119fd0-04f6-4762-ab7a-4986c76b3f9a}
            {bf967a34-0de6-11d0-a285-00aa003049e2}
            {bf967a33-0de6-11d0-a285-00aa003049e2}
            {bf9679c5-0de6-11d0-a285-00aa003049e2}
            {bf967a61-0de6-11d0-a285-00aa003049e2}
            {bf967977-0de6-11d0-a285-00aa003049e2}
            {bf96795e-0de6-11d0-a285-00aa003049e2}
            {bf9679ea-0de6-11d0-a285-00aa003049e2}
        {ab721a52-1e2f-11d0-9819-00aa0040529b}

    Restricted SID Count:   0 
Cyb3rWard0g commented 4 years ago

4.C.10 Execution through API

Procedure: Executed API call by reflectively loading Netapi32.dll Criteria: The NetUserGetGroups API function loaded into powershell.exe from Netapi32.dll

Correlating the netapi32.dll load with the previous Bypassuac deff helps to add contexts since that DLL is loaded by several other process.

Sysmon

SELECT Message
FROM apt29Host f
INNER JOIN (
    SELECT d.ProcessGuid
    FROM apt29Host d
    INNER JOIN (
      SELECT a.ProcessGuid, a.ParentProcessGuid
      FROM apt29Host a
      INNER JOIN (
        SELECT ProcessGuid
        FROM apt29Host
        WHERE Channel = "Microsoft-Windows-Sysmon/Operational"
            AND EventID = 1
            AND LOWER(Image) LIKE "%control.exe"
            AND LOWER(ParentImage) LIKE "%sdclt.exe"
      ) b
      ON a.ParentProcessGuid = b.ProcessGuid
      WHERE a.Channel = "Microsoft-Windows-Sysmon/Operational"
        AND a.EventID = 1
        AND a.IntegrityLevel = "High"
    ) c
    ON d.ParentProcessGuid= c.ProcessGuid
    WHERE d.Channel = "Microsoft-Windows-Sysmon/Operational"
      AND d.EventID = 1
      AND d.Image LIKE '%powershell.exe'
) e
ON f.ProcessGuid = e.ProcessGuid
WHERE f.Channel = "Microsoft-Windows-Sysmon/Operational"
AND f.EventID = 7
AND LOWER(f.ImageLoaded) LIKE "%netapi32.dll"

Results

Image loaded:
RuleName: -
UtcTime: 2020-05-02 03:04:04.361
ProcessGuid: {47ab858c-e23d-5eac-c603-000000000400}
ProcessId: 3876
Image: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
ImageLoaded: C:\Windows\System32\netapi32.dll
FileVersion: 10.0.18362.1 (WinBuild.160101.0800)
Description: Net Win32 API DLL
Product: Microsoft® Windows® Operating System
Company: Microsoft Corporation
OriginalFileName: NetApi32.DLL
Hashes: SHA1=7DFDD188B30162DAA87FDD3E5B7A55C80CD839F1,MD5=86A9DF3FA9D5FCAC8EF57601FCCD78F9,SHA256=F8CDA38FD3FF371E772875EA657A37662321EBB7AD8D6978DBCCCA7FC6DB64F1,IMPHASH=7D4E1695394CF47BD397AFD45A40E55D
Signed: true
Signature: Microsoft Windows
SignatureStatus: Valid
Cyb3rWard0g commented 4 years ago

4.C.11 Permission Groups Discovery

Procedure: Enumerated user's local group membership via the NetUserGetLocalGroups API Criteria: powershell.exe executing the NetUserGetLocalGroups API

One could look for the Invoke-NetUserGetLocalGroups script name in PowerShell Logs but that can be bypassed by simply renaming the function/script :/

Cyb3rWard0g commented 4 years ago

4.C.12 Execution through API

Procedure: Executed API call by reflectively loading Netapi32.dll Criteria: The NetUserGetLocalGroups API function loaded into powershelle.exe from Netapi32.dll

Correlating the netapi32.dll load with the previous Bypassuac deff helps to add contexts since that DLL is loaded by several other process. Same as query above 4.C.10