Current situation: PHP2Shell. Two critical PHP vulnerabilities (CVSS 9.2) allow malicious code without login. Patches since 21 October 2026.What to do now →

Analysing web server logs after an attack: reading the access log properly

After an attack, log files are often the most important trace. How to secure access, error and PHP logs properly, find conspicuous requests and avoid typical mistakes in the analysis.

Last updated 6 min readGuides

In short: Anyone who wants to analyse the access log after an attack first secures the logs unchanged and then works only with copies. The search is for requests with status 200 to unknown PHP files, conspicuous POST requests, access to upload directories and time patterns. For PHP2Shell there are no published, confirmed indicators of compromise, so the overall picture from several log sources counts.

Secure first, then analyse

On most servers, log files are rotated automatically and deleted after a fixed time. After an attack, the first step is therefore to secure the existing logs before they disappear. This applies even if you are not yet sure whether anything happened at all. On PHP2Shell, the trade press advises keeping logs from 20 October 2026 onward.

# Copy logs with timestamps and record checksums
ZIEL=/root/sicherung-logs-$(date +%F)
mkdir -p "$ZIEL"
cp -a /var/log/nginx /var/log/apache2 /var/log/php* "$ZIEL"/ 2>/dev/null
cp -a /var/log/auth.log* /var/log/syslog* "$ZIEL"/ 2>/dev/null
find "$ZIEL" -type f -exec sha256sum {} + > "$ZIEL.sha256"

Also store the backup on a different system. An attacker with access to the server could otherwise alter logs afterwards. The checksums show later that the copy is unchanged. If a court-proof backup is needed, for example for a complaint or the insurer, IT forensics should take over the backup.

Important

Check log rotation (/etc/logrotate.d/) and extend retention temporarily so that no further files are deleted during the analysis.

Where the logs are and how a line is built

The storage locations depend on the distribution and the management interface. Typical paths:

System Access and error log
Debian, Ubuntu with Apache /var/log/apache2/
RHEL, AlmaLinux, Rocky with Apache /var/log/httpd/
Nginx /var/log/nginx/
Plesk /var/www/vhosts/system/<domain>/logs/
PHP-FPM /var/log/php*-fpm.log or in the journal

In the widespread Combined format, each line contains the client address, date and time, method and path of the request, the status code, the response size in bytes, the referrer and the user agent. Watch the time zone in the timestamp, especially when you compare logs with reports in UTC. The PHP2Shell patches, for example, were released on 21 October 2026 at 14:00 UTC, which is 16:00 German time.

If your website sits behind a proxy, CDN or load balancer, the log may show only its address. The visitor's real address is then found in a separate field or in the logs of the upstream service.

Without a command line: logs in the panel or at the hosting provider

Not every operator has shell access. With shared hosting or managed servers, management interfaces usually offer a log view and a download of the access and error logs. Download the files for the entire available period and keep them safe. Ask your hosting provider in writing how long logs are retained and whether older states can be secured before they expire.

Mind data protection here: logs contain IP addresses and often further personal details. Store the copies with access protection, pass them only to people who need them for clarification, and define when they are deleted after the incident is closed.

Analysing the access log: the most important queries

The following commands only read and are suitable for Nginx and Apache in the Combined format. Search rotated and compressed files with zgrep or zcat.

LOG=/root/sicherung-logs-2026-10-25/nginx/access.log

# Successful requests to PHP files, by frequency
awk '$9 == 200 && $7 ~ /\.php/ {split($7,p,"?"); print p[1]}' "$LOG" | sort | uniq -c | sort -rn | head -40

# PHP calls in upload, cache or image directories
grep -E '"(GET|POST) /[^ ]*(uploads|cache|images|tmp)/[^ ]*\.php' "$LOG"

# POST requests by target and address
awk '$6 == "\"POST" {print $1, $7}' "$LOG" | sort | uniq -c | sort -rn | head -40

# 5xx errors per hour: clusters can point to crashing PHP processes
awk '$9 ~ /^5/ {print substr($4, 2, 14)}' "$LOG" | sort | uniq -c

# Include rotated logs
zgrep -h ' 200 ' /var/log/nginx/access.log.*.gz | grep -c '\.php'

In the first query, file names you do not know or that do not belong to the application are of particular interest. Compare suspicious files with the file system: when were they created, who owns them, what do they contain? Pointers are given in the guide Detecting and removing webshells.

Specifics of PHP2Shell

With PHP2Shell, the vulnerabilities lie in PHP's own request processing. With mod_php, an exploit was demonstrated before any application code even runs. That means: a request for a completely normal page can be enough. In the access log, such a request may look inconspicuous, because the content of the request body is not recorded there.

There are no published, confirmed indicators of compromise. Therefore watch behaviour and connections, for example from 17 October 2026, the first observed attack attempt according to media reports:

  • Clusters of 500 errors or aborted responses on ordinary pages.
  • Messages about exhausted memory or terminated workers in the error and PHP-FPM logs.
  • New PHP files or modified files shortly after such clusters.
  • New cron jobs, processes or outgoing connections under the web server user.

None of these signals is proof on its own. Together with other traces, however, they form a picture that answers the question of a compromise or justifies a deeper investigation. An overview of the signs is at Am I already compromised?.

Further sources: error log, PHP-FPM and system logs

The access log shows only part of the picture. For a complete picture, add further sources:

# PHP-FPM and web server in the journal since a date
journalctl -u 'php*-fpm*' --since "2026-10-17" --no-pager | tail -200

# Logins to the server
last -Fa | head -40
grep -E 'Accepted|Failed' /var/log/auth.log | tail -100

# Check scheduled tasks of all users
for u in $(cut -d: -f1 /etc/passwd); do crontab -l -u "$u" 2>/dev/null | sed "s/^/$u: /"; done

Typical mistakes in the analysis are searching only the current rather than also the rotated logs, overlooking the time zone, and taking individual hits from automated scanners for a successful attack. Just as risky is the opposite: treating an inconspicuous access log as the all-clear although the error log and file system have not yet been checked.

Note every finding with time, source and observation in a timeline. This timeline later forms the basis for decisions, for notifications to authorities or insurers and for the final report.

How does PHP SOS help?

  • We secure logs and relevant files in such a way that they remain traceable for later checks.
  • We analyse access, error, PHP and system logs together and create a timeline of the incident.
  • If there are signs of a compromise, we take over incident response with containment and cleanup.
  • We set up log rotation and retention so that the necessary data is available for the next incident.

Frequently asked questions

How long should I keep web server logs?

As long as your data protection concept allows and an analysis makes sense. On PHP2Shell, the trade press advises keeping logs from 20 October 2026 onward. Check log rotation so that older files are not deleted automatically.

Does the access log show whether an attack was successful?

Not on its own. It shows requests, status codes and response sizes, but not which code was executed on the server. Only together with the error log, PHP-FPM log, file changes and system logs does a reliable picture emerge.

May I pass IP addresses from logs on to third parties?

IP addresses are generally regarded as personal data. There are bases for clarifying an incident and for criminal complaints, but passing them on should be agreed with the data protection officer.

Why do I see many attacks in the log although nothing happened?

Public servers are scanned automatically all the time. Most of these requests lead nowhere and end with 404 or 403. Of interest are above all requests with status 200 for unknown files and patterns that coincide in time with other traces.

Sources

Immediate contact

Every hour counts. Write to us now.

Briefly describe your system, PHP version and observation. We will get back to you, clarify the situation and work remotely until the incident is closed and documented.

Immediate help