Avoiding Phishing Detections Through HTML Obfuscation

Avoiding Phishing Detections Through HTML Obfuscation

A twist to a tried and true method


3 min read

Cover Illustration by ireneparamithaa

Despite what many red teamers and cybersecurity companies will let you believe, the biggest threats aren't zero days or APT groups, the real biggest threat is still from phishing sites.

These days, phishing is easy. Most people aren't trained to differentiate phishing emails and very convincing email templates are easily found on GitHub.

Many of these templates look very realistic too, unlike the usual phishing pages with broken english and missing HTML objects.

But Gmail, Outlook, and other email vendors have been proactively fingerprinting and blocking perceived spam threats. Technologies such as SPIF/DKIM, signature-based phishing protections, and domain ownership declaration have decreased the number of phishing emails that get into our inboxes.

But if you embed these templates from your mail server, something running nginx and mailhog will do (I tend to avoid frameworks like GoPhish or KingPhiser due to them having declarative email headers and its default RID key that makes them very notable) and the send email, the recipient most likely will get something like this.

The website linked in the email will also be scanned and will be blocked by Google Safe Browsing API, which is the same technology used by Windows SmartScreen and Apple's Phishing Protection.

There also exist more advanced solutions made by vendors such as FortiGuard or Proofpoint Aegis.

Google Safe Browsing's documentation says that it checks the content of a website against Google's constantly updated lists of unsafe web resources. This can be likened to Antiviruses that use signature-based detection methods to detect malicious software.

In the ever-evolving landscape of web technologies, JavaScript has emerged as a ubiquitous tool, offering a plethora of functionalities. One intriguing application is the ability to dynamically obfuscate web content using data URIs. This technique, while not entirely new, has seen a resurgence in its potential applications.

By converting the webpage content into a base64 encoded string and then using a data URI to instruct the browser, the content is rendered directly from the encoded string. This means that when the page is loaded, the initial HTML content isn't directly visible when Google crawls the website.

While these protections might be able to pass through Google Safe Browsing, they might be too trivial to detect with more advanced solutions like Proofpoint's Aegis and Fortinet's FortiGate NGFW.

To increase the chances of our obfuscation passing we can use multibyte XOR encoding through Javascript. We can start by creating the formula.

function encrypt(s) {
    var r = "";
    var tmp = s.split("<random number>");
    s = unescape(tmp[0]);
    var k = unescape(tmp[1] + "817390");
    for (var i = 0; i < s.length; i++) {
        r += String.fromCharCode((parseInt(k.charAt(i % k.length)) ^ s.charCodeAt(i)) + -7);
    return r;

The function modifies the input string s by XORing its characters from another set of derived values k and then adjusting the ASCII value by subtracting 7. The tmp variable becomes an array by splitting the data into two parts, where a random (but selectable) number occurs in the variable. tmp[0] holds the encoded data, while tmp[1] holds what will be used as a key for decoding.

<script type="text/javascript">
//... continue the sequences ...

And when the users don't use Javascript in their browser (rare but can still happen), we can use <noscript> to describe what the browser should see which should be an error message prompting the user to enable Javascript which is a reasonable request for most websites.

        <meta http-equiv="Refresh" content="0; URL=https://login.live.com/jsDisabled.srf?mkt=EN-US&lc=1033&uaid=0efb867f68d940fa8cc318b0ae6e246a" />Microsoft account requires JavaScript to sign in. This web browser either does not support JavaScript, or scripts are being blocked.<br /><br />To find out whether your browser supports JavaScript, or to allow scripts, see the browser's online help.</noscript>
    <title>Sign in to your Microsoft account</title>
    <meta name="robots" content="none">
    <meta name="PageID" content="i5030">
    <meta name="SiteID" content="292841">
    <meta name="ReqLC" content="1033">
    <meta name="LocLC" content="1033">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, minimum-scale=1.0, user-scalable=yes">