Skip to main content
Create your own
Lesson illustration

Web Shell Upload for Persistent RCE

Hello! Welcome back.

In our last lesson, we focused on the crucial first step of exploiting file upload vulnerabilities: bypassing filters to get your malicious file onto the server. You learned to defeat client-side validation, server-side extension blacklists, and even content-based checks using techniques like magic byte manipulation.

Today, we'll answer the question, "Now what?" Simply uploading a file isn't the end goal. We want to achieve persistent Remote Code Execution (RCE). This lesson will teach you how to turn your initial file upload into a stable, persistent foothold on the target system by using and upgrading web shells.

Our goal is to upload a web shell to a vulnerable application to achieve persistent RCE. We'll explore how to leverage a basic web shell to gain a more interactive reverse shell and discover an advanced technique to ensure our shell executes even in restricted environments, providing a form of persistence.

1. From Basic Web Shell to Interactive Reverse Shell

In the previous lesson, you saw a simple one-liner web shell:

<?php echo system($_GET['cmd']); ?>

While effective for running single commands, this type of shell is limited:

  • It's not interactive: You can't run programs that require user interaction, like ssh or a text editor.
  • It's stateless: Each command is a new HTTP request, and the shell has no memory of the previous one.
  • It's dependent on system() or similar functions: If these are disabled in the PHP configuration, the shell is useless.

A professional pentester or bug bounty hunter will almost always use this initial access to "upgrade" to a more stable and interactive shell, typically a reverse shell. A reverse shell makes the compromised server connect back to you, bypassing firewalls that might block incoming connections to the server.

There are two common ways to achieve this:

  1. Use the simple web shell to execute a command that initiates a reverse shell connection (e.g., using bash, python, or netcat).
  2. Upload a more complex, dedicated reverse shell script.

The following video demonstrates both of these methods clearly.

File Upload Vulnerabilities & Filter Bypass

Watch this segment from 'File Upload Vulnerabilities & Filter Bypass' by Ryan John. It shows how to use a simple web shell to spawn a reverse shell and, alternatively, how to upload a dedicated PHP reverse shell script.

Watch from 03:49 to 08:57. Pay close attention to the two distinct RCE methods: First Method (03:49 - 07:29): The presenter first uploads a simple web.php shell. They use it to execute a URL-encoded bash one-liner, which establishes a reverse shell connection back to their netcat listener. Second Method (07:29 - 08:57): The presenter uploads a complete PHP reverse shell script (from Pentest Monkey). Simply accessing this uploaded file via the browser is enough to trigger the reverse shell connection.

As you saw, a simple web shell is a powerful launchpad. Your ability to read and modify payloads from resources like Pentest Monkey's cheatsheet or the payloadsallthethings repository is a core skill. Given your computer science background, you should find it straightforward to understand and adapt these scripts by changing the IP address and port to match your attacker machine.

2. Achieving Persistent Execution with Server Configuration Files

You've successfully uploaded a shell and gotten RCE. But what happens if the server administrator discovers and deletes it? Or what if the uploads directory is configured to prevent the execution of .php files altogether? This is a common security measure.

This is where we move from simple execution to more persistent and robust execution. If you can't upload a .php file, or can't execute it, you need a way to force the server to execute your code anyway. A powerful way to do this on Apache web servers is by uploading a custom .htaccess file.

An .htaccess file is a configuration file that allows for directory-level changes to how the Apache web server behaves. If you can upload your own .htaccess file to a directory, you can tell Apache to, for example, treat files with a .jpg extension as executable PHP scripts.

This gives you two huge advantages:

  1. Bypass Blacklists: You can name your shell image.jpg or document.txt, which will likely bypass any extension-based filters.
  2. Ensure Execution: You are forcing the server to execute your file, overriding a potentially non-executable configuration for that directory.

The following video is an excellent deep-dive into this technique.

How To Bypass Website File Upload Restrictions

John Hammond provides a masterclass on this technique in his video 'How To Bypass Website File Upload Restrictions'. He discovers a file upload vulnerability with a PHP extension blacklist and uses an .htaccess upload to bypass it completely.

Watch from 08:12 to 18:19. Source Code Analysis (08:12 - 12:02): John reviews the application's PHP source code and discovers a blacklist that blocks various PHP extensions (.php, .phtml, etc.). He also finds a logic flaw where files are uploaded to the webroot instead of the intended uploads directory. This analysis is key. The .htaccess Trick (12:02 - 18:19): He crafts an .htaccess file with a single directive: AddType application/x-httpd-php .subscribe. This tells Apache to treat any file ending in .subscribe as a PHP file. He uploads this file, then uploads his web shell named webshell.subscribe. The server happily executes it, leading to RCE.

This .htaccess technique is a perfect example of the creative thinking required in professional penetration testing. It's not just about finding a vulnerability but understanding the underlying system (in this case, Apache's configuration) to chain weaknesses together for maximum impact.

For a textual reference on this technique, you can review the PortSwigger Web Security Academy article we used previously.

File uploads | Web Security Academy

The Web Security Academy guide on File Uploads also covers this powerful technique. Reading this will reinforce your understanding of how server configuration files can be abused.

In the article, find the section titled 'Exploiting flawed validation of file uploads', and within it, locate the sub-section 'Overriding the server configuration'. This short section explicitly discusses using .htaccess (for Apache) and web.config (for IIS) to make the server execute arbitrary file types.

Test your understanding!

You are testing a web application running on an Apache server. You've identified a file upload function that allows you to upload .txt files but strictly forbids .php files. The uploads directory is web-accessible. You try uploading a .txt file containing PHP code, but when you access it, the browser just displays the raw code instead of executing it.

How would you use the .htaccess technique to achieve RCE? Describe the content of the two files you would need to upload and the order in which you should upload them.

Show answer

I would need to upload two files: first the .htaccess configuration file, and second the web shell disguised as a text file.

  1. File 1: .htaccess

    • Content: AddType application/x-httpd-php .txt
    • Purpose: This directive tells the Apache server that any file in this directory (or its subdirectories) ending with the .txt extension should be processed by the PHP interpreter.
  2. File 2: shell.txt

    • Content: <?php system($_GET['cmd']); ?>
    • Purpose: This is the actual web shell. It's named with a .txt extension to pass the application's filter.

Upload Order:

I would first upload the .htaccess file. This puts the new server configuration rule in place. Then, I would upload shell.txt. When I later access https://target.com/uploads/shell.txt?cmd=whoami, the server will now execute the PHP code within it because of the rule I established with the .htaccess file.

3. A Broader View: The Principle is Universal

While our examples have focused on PHP and Apache, the underlying principle of finding a writable, web-accessible directory and placing an executable script there is universal. Whether it's a JSP shell on a Java Tomcat server or an ASPX shell on a Microsoft IIS server, the goal remains the same.

The following case study from Cobalt demonstrates this principle in a Java environment. The pentester found a way to change the file upload path to a web-accessible temporary directory and then uploaded a JSP web shell.

From CSRF and File Upload to RCE - JAVA

To see how these concepts apply beyond PHP, let's briefly look at a case study from Cobalt involving a Java application.

Skim through the sections that detail the reconnaissance and exploitation. Notice how the pentester first identifies web-accessible directories (/app/xxx/webapp/temp) and then exploits an administrative function to change the upload path to that directory. Finally, they upload a JSP webshell to achieve RCE. You don't need to dive deep into the CSRF aspect, just focus on the file upload to RCE pathway.

Conclusion

You have now moved beyond simply uploading a file to understanding how to make that file a powerful and persistent entry point. This is a critical step in turning a simple vulnerability into a full-blown compromise.

Key Takeaways:

  • A simple web shell is often just a first stage. The primary goal is to upgrade it to a more stable, interactive reverse shell.
  • You can upgrade your shell by either executing a command-line payload (like a bash one-liner) or by uploading a dedicated reverse shell script.
  • Server configuration files like .htaccess are extremely powerful. Uploading one can allow you to bypass extension blacklists and force the server to execute your code, providing a persistent execution method even if the original shell is discovered.
  • The principles of finding a writable, web-accessible directory and uploading an executable script apply across different technologies (PHP, JSP, ASPX, etc.).

Next Lesson Preview:

We've covered a lot of ground on server-side attacks, from LFI to command injection to file upload RCE. In the next module, we will explore even more advanced server-side vulnerabilities. Our first lesson will be "Explain how data serialization works and the RCE risks associated with insecure deserialization." This is a complex but increasingly common vulnerability class that can lead to devastating attacks.

Can't find a good explanation? Sign up and we'll make it for you

Sign up