Windows.Forensics.SolarwindsSunburst

“SolarWinds.Orion.Core.BusinessLayer.dll is a SolarWinds digitally-signed component of the Orion software framework that contains a backdoor that communicates via HTTP to third party servers.”

We can look for evidence of this dll by first performing a YARA search on the MFT across all drives, then applying an additional FireEye-supplied rule against the file found via MFT.


name: Windows.Forensics.SolarwindsSunburst

description: |
    "SolarWinds.Orion.Core.BusinessLayer.dll is a SolarWinds digitally-signed component of the Orion software framework that contains a backdoor that communicates via HTTP to third party servers."

    We can look for evidence of this dll by first performing a YARA search on the MFT across all drives, then applying an additional FireEye-supplied rule against the file found via MFT.

reference:
  - https://www.fireeye.com/blog/threat-research/2020/12/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor.html

author: Wes Lambert - @therealwlambert

tools:
  - name: SunburstYARARules
    url: https://raw.githubusercontent.com/fireeye/sunburst_countermeasures/main/all-yara.yar

parameters:
    - name: yaraMFT
      type: yara
      description: "The term we will use to search the MFT"
      default: |
        rule Hit {
           strings:
             $a = "SolarWinds.Orion.Core.BusinessLayer.dll" wide nocase
           condition:
             any of them
        }
    - name: SizeMax
      type: int64
      description: "Entries in the MFT under this size in bytes."
      default: 1200000
    - name: SizeMin
      type: int64
      description: "Entries in the MFT over this size in bytes."
      default: 1000000

sources:
  - query: |
      LET yara_rules <= SELECT read_file(filename=OSPath) AS Rule,
           basename(path=OSPath) AS ToolName
        FROM Artifact.Generic.Utils.FetchBinary(
             ToolName="SunburstYARARules", IsExecutable=FALSE)

      LET ntfs_drives = SELECT OSPath + '/$MFT'as Path, OSPath AS Device
          FROM glob(globs="/*", accessor="ntfs")

      LET MFTEntries = SELECT * from foreach(
            row=ntfs_drives,
            query={ SELECT Device, String.Offset AS Offset,
               String.HexData AS HexData,
               Device + "\\" + parse_ntfs(device=Device,
                          mft=String.Offset / 1024).OSPath AS FilePath,
               parse_ntfs(device=Device,
                          mft=String.Offset / 1024) AS MFT
            FROM yara(
             rules=yaraMFT, files=Device + "/$MFT",
             end=10000000000,
             number=1000,
             accessor="ntfs")}) WHERE MFT.Size > SizeMin AND MFT.Size < SizeMax

      LET yarasearch = SELECT Rule, String.Offset AS HitOffset,
             str(str=String.Data) AS HitContext,
             FileName,
             File.Size AS Size,
             File.ModTime AS ModTime
        FROM yara(
            rules=yara_rules[0].Rule, key="A",
            files=FilePath)
        LIMIT 1

      LET yarahits = SELECT * FROM if(condition=yara_rules,
        then={
          SELECT *
          FROM foreach(row=MFTEntries,query=yarasearch)
        })

      SELECT *,
        hash(path=FileName) AS Hash
      FROM yarahits