Cover image "Free Smileys" by Abraham Pena is licensed under CC BY 4.0

Top 4 security vulnerabilities we see in phishing kits

Bradley's author profile picture
Bradley Kemp on

Just like any other website, phishing sites can have security vulnerabilities. But, for once, these security vulnerabilities are actually helpful for defenders: they can let us identify who has fallen victim to the phish, and sometimes even disrupt the site and prevent anyone else being phished.

Vulnerabilities are easiest to find when you've got the source code of a phishing site (the phishing "kit"), but we've analysed numerous kits and identified some trends.

Top vulnerabilities we see in phishing kits

1️⃣ CWE-219: Storage of File with Sensitive Data Under Web Root

One of the most common ways phishing sites collect victim's credentials is by writing them to a log file using code like this:

$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
$ip = getenv("REMOTE_ADDR");
$message = "\n";
$message .= "----------- | IP : $ip  | -----------\n";
$message .= "EM       :  ".$_POST['EM']." \n";
$message .= "PS       :  ".$_POST['PS']."\n";
$message .= "PN       :  ".$_POST['PN']."\n";
$message .= "full       :  ".$_POST['full']." \n";
$message .= "dob       :  ".$_POST['dob']."\n";
$message .= "phone       :  ".$_POST['phone']."\n";
$message .= "ccno       :  ".$_POST['ccno']." \n";
$message .= "exp       :  ".$_POST['exp']."\n";
$message .= "cvv       :  ".$_POST['cvv']."\n";
$message .= "----------- | By JoCker | -----------\n";
$message .= "\n";
$file = fopen("./greyhat.txt", 'a');
fwrite($file, $message);

This takes all victim's information (email, password, credit card number, etc.) out of the request and writes it to a file named greyhat.txt. Later on, the phisher can access this file and get all the data that has been collected while they've been away.

But, the vast majority of phishing sites that write logs this way, fail to protect the log file from being viewed. If you know the log file name (or can guess it), as a defender you can load it in your browser and instantly see which of your users have been compromised.

2️⃣ CWE-548: Exposure of Information Through Directory Listing

Directory listing is a feature of many web servers where if you request a directory (like /css) rather than a specific file (like /css/style.css), a list of all the files in the folder is returned.

A web server with directory listing enabled, via Wikimedia Commons
A web server with directory listing enabled, via Wikimedia Commons

Normally this wouldn't be a problem: you'd expect files on a website to be public. But in phishing sites this actually leaks a lot of useful information:

  • Filenames help us discover log files that are output by the phishing kit.
  • We can more easily discover the features of a site: is there a folder named "admin" that might contain an admin UI that controls the site?
  • Phishing kit source code can be obtained. For a phishing site login-myaccount.com/bankname, we often find you can load login-myaccount.com and see a folder bankname and a bankname.zip containing the phishing kit source code.

3️⃣ CWE-807: Reliance on Untrusted Inputs in a Security Decision

IP addresses are commonly checked by phishing sites in an attempt to evade detection by security tools. They'll get the IP address of whoever's access the phishing site and refuse to load unless the IP address is:

  • From the correct country
  • From a residential/mobile network (not a data center where many security scanners will be hosted)
  • Not on a block list (for example of people who have already submitted details to the site)

However, we almost always see this code implemented incorrectly.

// Function to get the client IP address
function get_client_ip() {
    $ipaddress = '';
    if (getenv('HTTP_CLIENT_IP'))
        $ipaddress = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $ipaddress = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
       $ipaddress = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $ipaddress = getenv('REMOTE_ADDR');
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}

This is a typical function used by a phishing kit to get the user's IP address. If tries a sequence of HTTP headers and if none of them are set finally falls back to PHP's REMOTE_ADDR variable.

The trouble is that these HTTP headers are all untrusted! We can set any IP we like in the X-Forwarded-For header and the phishing kit will blindly trust it.

Why are these functions always so broken? Phishing kit authors need their kits to work in a wide variety of setups. Some phishers will just host their sites publicly, whereas others will put them behind services like Cloudflare in an attempt to make them harder to take down. The phishing kit itself doesn't know whether it's behind a reverse proxy or not, and so has to trust the X-Forwarded-For header.

4️⃣ CWE-425: Direct Request ('Forced Browsing')

Some more advanced phishing kits have admin panels that the phisher can use to monitor the status of their site (and even interact with victims currently on the site). These admins panels are usually password protected to prevent security teams snooping on them. But, the password protection is often implemented poorly.

In many cases, we've seen an admin panel structured like this:

# gateway.php

# Bounce the admin to login page if they're not authed
if(!isset($_SESSION["ok"]))
{
	echo '<meta http-equiv="refresh" content="0;URL=login.php" />';
	die();
}

# Switch functionality based on the request's GET parameters
if(isset($_GET["logs"]))
{
	$res=file_get_contents($panel_url."/functions/logs.php");
}

# ...

The phisher thinks that their admin panel is secure because this gateway handles all the authentication and calls out to separate "functions" files for each feature. But, the reality is we can directly request the /admin/functions/logs.php file and completely bypass the authentication logic.

Exploiting this vulnerability does of course rely on knowing the filenames you need to directly request but, as usual, directory listing is your friend here.

How to find and make use of phishing kit vulnerabilities

Phishing sites vary in how well they're configured, so it sometimes takes some patience before you can really find all the vulnerabilities in a certain kit. This is why it's important you can distinguish between the different phishing kits you see (using our Indicator Of Kit tool can help).

Once you've identified a specific phishing kit and discovered vulnerabilities in it, you're ready to make use of them:

  • Use what you know to bypass security scanner evasion tactics to improve the accuracy of your automated phishing site triage.
  • Scrape the log files to get metrics and how many of your users are affected by the site (and if the logs contain identifying details, remediate compromised accounts)

Want more insight into phishing kits?
Start a trial today.

More posts from the Phish Report team

Cover image

Flake IDs and insensitive ticketing systems

This week the IDs we use for identifying Phish Report cases got 20% longer, but twice as reliable....
Cover image

Using IOK rules to hunt for phishing sites across multiple threat intelligence sources

IOK ("Indicator of Kit") is a small, [open source](https://github.com/phish-report/IOK) language d...
Cover image

Writing an IOK rule for a WhatsApp phishing kit

Let's write an IOK signature for a WhatsApp phishing kit which targeted Chinese-speaking users for...