Content stylesheets (CSS) are the primary way that websites tell a browser how to shape, color, and indent the content of a website and what fonts to use for the text. But did you know that malicious actors can also use CSS stylesheets to add malware to your site?
In this article, we look at a simple and obvious stylesheet injection attack and discuss how this could have been a lot worse.
The first thing of note in this injection is a huge array of numbers, each of which is followed by /t, without any quotes around them. This means the array is not a set of strings but rather a set of mathematical operations.
The next important part is at the beginning of the script block, a function named createCSS. With the lack of carriage returns in the original code, it might be a little difficult to read, but after prettying it up, we have a much better idea of what it is doing.
Above we see that the createCSS function receives two arguments: a variable named “selector”, and another named “declaration.” The function begins by taking the browser UserAgent and converting it to all lowercase characters before checking for the presence of three strings. In this case, it is looking for “msie” in the UserAgent string as well as “win” and it is making sure that the string “opera” is not present in the UserAgent. This is essentially a check to see if the browser is an older version of Windows Internet Explorer, setting the “isIE” variable to true if it is an older Internet Explorer and setting it too “false” if it is anything else. It then creates a new style element and, if isIE is false, it creates an HTML stylesheet entry, using the selector and declaration passed in, that gets inserted into the page immediately after the <head> element. If isIE is true, however, the code checks to see how many stylesheets there are. It then finds the last stylesheet and tries to add a new rule to that sheet using the selector and declaration.
So far, this is just odd, but nothing terrible. However, after this point, the code shows its true colors and we can say, with 100% certainty, that this is a malicious injection even before we decode the payload.
Uh oh. This is NOT looking good.
If we continue, the code initializes a new variable (ucyq) and then sets another variable to the array of stylesheets present in the page, before entering a loop that will iterate over those stylesheets. As it iterates over the stylesheets, the code sets the “vpm” variables to all the rules for the stylesheet and iterates over those rules. For each of the rules in a sheet, the code checks to see if the selector contains “#va”. It skips all selectors that do not contain the string. If the rule selector contains “#va”, it sets the zio variable to the name of the selector without the “#” and the “ucyq” variable to the part of the declaration that starts with a capital S and continues to the end of the declaration. In the code sample above, that means zio is set to “va” and ucyq is set to “String.fromCharCode”.
This is followed by a curious two lines of code that get the seconds from a Date object and then the huge array mentioned in the beginning.
The action of assigning the seconds from this Date object to the variable t is illuminating, however. The seconds are represented by the last argument to the “new Date()” call, in this case, 4, which means that the array is dividing all the values by 4 and brings them well within the range of values for ASCII characters (0-128).
Here, the code is initializing a new variable, fme, to an empty string and creates a function reference, g, that simply returns the arguments passed. Then, the code sets the tevq variable to the concatenation of “e,” the value of the zio variable, and “l”. Since we know that zio is the string “va”, we now know that tevq is the string “eval”. Next, another variable, cet, is initialized to an empty string and the variable hj is set to the eval of the ucyq variable. This means that hj is now the same as “String.fromCharCode”. Lastly, the code iterates over the large array, evals each element to perform the math, and appends the character to the cet variable, before eval’ing the resulting string.
This is 100% malicious even before we look at the payload.
It is worthwhile to mention that even though the code itself is malicious and needs to be removed, it can be helpful to understand what it was attempting to inject.
This code checks to see if there is a pre-existing body tag in the page. If there is one, the code simply creates an iframe element, sets the source to the URL specified, makes it hidden, and appends the iframe to the body tag. If there are no body tags, the code creates a new body and, if successful, executes that same code. If it was not able to create a body tag, the code simply writes out an iframe tag with identical properties.
In the sample that we encountered above; the IP address (belonging to Vodafone Portugal) was no longer responding to requests.
The Good News
The good news is that this is much easier to detect because of the large array of values that are included as the payload. Additionally, the fact that the supposed CSS is clearly not a stylesheet means that you, as a website owner, can feel confident that you can safely remove the script block that this was in. Overall, this injection was dangerous but easy to spot. However, in combination with the techniques we found in last month’s article, this could have been significantly harder to detect.
The Bad News
The Better News
SiteLock is here to help. Whether it is our informative blog articles or our knowledgeable support staff, SiteLock is here for you if you have questions or need assistance. If you think your website has been infected by malware, give us a call and talk to an agent today.
Maarten Broekman has worked as a system administrator and systems engineer for over 25 years, primarily in the shared web-hosting space. One of the main concerns for web-hosting providers is being able to serve their customers’ websites as quickly and efficiently as possible. As a result, anything that detracts from performance needed to be examined closely and this is where his interest in malware and code analysis sprang from. For over a decade, finding, decoding, and removing malware (and automating that process) has been his primary focus.