keepcalculator

06 Numbers and Powers

How to Investigate Strange PHP Access Attempts in Nginx Logs

Card No. 06·69175 · Updated · Standard formula, shown below

If your nginx access log shows frequent requests for PHP files you don’t recognize, your server is likely being probed by bots or attackers scanning for vulnerable scripts. This guide shows you how to identify those attempts, trace their source, and decide whether to block them or dig deeper.

What You’ll Need

  • SSH access to your server (or a way to read the nginx logs)
  • Basic familiarity with the command line and grep
  • Permission to read log files (usually root or a user in the adm group)
  • Optional: a tool like goaccess or jq for analysis

Step-by-Step

  1. Locate your nginx access log. The default path is /var/log/nginx/access.log, but it may be customized in your nginx config. Check with nginx -T 2>/dev/null | grep access_log or look in your site’s server block.
  2. Filter for PHP requests. Run grep '\.php' /var/log/nginx/access.log | tail -n 50 to see the most recent attempts. This narrows the noise to requests that target PHP scripts.
  3. Identify the suspicious patterns. Look for requests to files like shell.php, cmd.php, wp-login.php, or paths like /uploads/, /images/, or /tmp/ that shouldn’t contain PHP. Also watch for query strings with cmd=, exec=, or base64-encoded data.
  4. Extract the source IPs. Use grep '\.php' /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -n 20 to list the top IPs hitting PHP files. High counts from a single IP often indicate a scanner.
  5. Check the user-agent strings. Run grep '\.php' /var/log/nginx/access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn | head to see common user-agents. Bots often use generic ones like python-requests, curl, or random strings.
  6. Look at the response codes. A 404 means the file doesn’t exist; a 200 or 403 means it may have executed or been blocked. Filter for PHP requests with status 200: grep '\.php' /var/log/nginx/access.log | grep ' 200 ' — these are the most concerning.
  7. Correlate with error logs. Check /var/log/nginx/error.log for related PHP errors or warnings. For example, grep 'PHP' /var/log/nginx/error.log | tail may show attempts to include remote files.
  8. Trace the IP origin. Use whois or an online lookup to see if the IP belongs to a cloud provider, a known scanner, or a random residential range. This helps you decide whether to block it.
  9. Test if any file actually exists. If a request like /wp-content/uploads/evil.php returns 200, check if that file exists on your server. Run find /var/www -name 'evil.php' (adjust the path) to see if it was uploaded.
  10. Decide on action. If the attempts are harmless (404s from scanners), you can ignore them or block the IPs. If a file exists or you see 200 responses, treat it as a potential compromise and investigate further.

Common Mistakes

  • Ignoring 404s. A 404 doesn’t mean the attempt is harmless; attackers often probe for files that may exist later. Log them and monitor for repeats.
  • Blocking IPs too aggressively. Some scanners come from shared hosting IPs or cloud providers that may also host legitimate visitors. Block only the specific IP if it’s clearly malicious.
  • Forgetting about IPv6. Logs may contain IPv6 addresses; include them in your analysis and blocking rules.
  • Not checking the actual file path. A request to /shell.php might be rewritten by nginx to a different location. Always check the request_uri and the actual file system.
  • Overlooking POST requests. Attackers often use POST to send payloads. Filter for both GET and POST: grep -E 'POST|GET' log | grep '\.php'.

Tips

  • Use tail -f /var/log/nginx/access.log to watch attempts in real time while you work.
  • Set up logrotate to keep logs manageable; old logs can be compressed and archived for later analysis.
  • Create a simple script that greps for common malicious patterns and emails you a daily summary.
  • Use fail2ban to automatically block IPs that trigger certain rules, but test the rules first to avoid false positives.
  • If you use a CDN or proxy, remember that the IP in your logs may be the proxy’s IP, not the attacker’s. Check for the X-Forwarded-For header.

Troubleshooting

No PHP requests appear in the log. Your access log may be in a different format or location. Check the nginx config for log_format and access_log directives. Also, if you use a reverse proxy, the log might be on the backend server.

Log file is huge. Use grep with a time filter, e.g., grep '30/Nov/2024' log or use zcat for rotated logs. Alternatively, use tail -n 1000 to limit the output.

Requests are encoded. Attackers often URL-encode paths. Decode with python3 -c "import urllib.parse; print(urllib.parse.unquote('...'))" or use jq -r '.request_uri' | python3 -c 'import sys,urllib.parse; print(urllib.parse.unquote(sys.stdin.read()))' if logs are in JSON.

You see a 200 for a PHP file that doesn’t exist. This could be due to a rewrite rule or a custom error page. Check the nginx config for try_files and location blocks that may route requests to a PHP handler.

Attempts come from many different IPs. This is typical of a distributed scan. Focus on the patterns rather than individual IPs, and consider blocking at the firewall level with a list of known scanner subnets.

Frequently Asked Questions

Q: What does a typical malicious PHP request look like?
A: Often something like GET /shell.php?cmd=whoami or POST /wp-content/plugins/revslider/revslider.php. The path is usually for a known vulnerable script or a generic name like c99.php.

Q: Should I block every IP that hits a PHP file?
A: No. Many legitimate requests, like to index.php, are normal. Only block IPs that repeatedly target suspicious files or show a clear scanning pattern.

Q: How can I tell if an attempt succeeded?
A: Look for a status code of 200 and a response size that isn’t zero. Also check if the requested file exists on your server. If it does, that’s a red flag.

Q: What if I find a suspicious PHP file on my server?
A: Do not open it in a browser. Move it to a quarantine directory, check its contents for malicious code, and review your server for other signs of compromise. Change all passwords and update your software.

Q: Can I use nginx to block these attempts?
A: Yes, you can add a location block to deny access to common malicious files, or use a module like ngx_http_access_module to deny specific IPs. However, this is reactive; a Web Application Firewall is more proactive.

Q: Why do I see so many attempts from the same IP range?
A: Attackers often use cloud services or compromised servers to scan. The IP range may belong to a hosting provider that is being abused. Blocking the entire range may be too broad; block the specific IPs.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →