2

Our server has been hacked, .php file accessible from outside was modified to include execution of shell commands passed in POST parameter. I've been inspecting relevant log file and couldn't find the request which modified the file or find anywhere online how it's generally possible. Here's how the log looks:

First there goes a long probing by Fuzz Faster U Fool tool, it finds that /info.php is accessible.

Then attacker makes these requests:

[29/Jul/2024:16:18:15 +0300] "GET /info.php HTTP/1.1" 200 96189 "-" "curl/8.8.0"
[29/Jul/2024:16:18:36 +0300] "GET /info.php HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:19:42 +0300] "GET /info.php HTTP/1.1" 200 25004 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:19:45 +0300] "GET /favicon.ico HTTP/1.1" 302 61884 "http://_site_url_/info.php" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:19:47 +0300] "GET /favicon.ico HTTP/2.0" 401 188 "http://_site_url_/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:20:47 +0300] "GET /info.php HTTP/1.1" 200 96363 "-" "Wget/1.24.5"
[29/Jul/2024:16:27:47 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:27:51 +0300] "GET / HTTP/1.1" 302 38432 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:27:53 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:36:23 +0300] "GET / HTTP/1.1" 302 37098 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:36:25 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:36:37 +0300] "GET / HTTP/2.0" 401 188 "-" "curl/8.8.0"
[29/Jul/2024:16:36:42 +0300] "GET / HTTP/2.0" 401 188 "-" "curl/8.8.0"
[29/Jul/2024:16:36:56 +0300] "HEAD /info.php HTTP/2.0" 401 0 "-" "curl/8.8.0"
[29/Jul/2024:16:37:05 +0300] "HEAD /info.php HTTP/1.1" 200 0 "-" "curl/8.8.0"
[29/Jul/2024:16:37:12 +0300] "HEAD / HTTP/1.1" 302 0 "-" "curl/8.8.0"
[29/Jul/2024:16:37:17 +0300] "HEAD / HTTP/1.1" 302 0 "-" "curl/8.8.0"
[29/Jul/2024:16:37:48 +0300] "GET /favicon.ico HTTP/2.0" 401 188 "https://_site_url_/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:49:00 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:49:03 +0300] "GET / HTTP/1.1" 302 48050 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:49:05 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[site_user] [29/Jul/2024:16:49:46 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:16:49:50 +0300] "GET / HTTP/1.1" 302 48050 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:17:15:35 +0300] "POST /b369a70a.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:15:42 +0300] "POST /pub/b369a70a.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:16:13 +0300] "POST /b369a70a.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:16:18 +0300] "POST /b369a70a.php HTTP/2.0" 401 188 "-" "curl/8.8.0"
[29/Jul/2024:17:16:42 +0300] "GET /b369a70a.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:16:47 +0300] "GET /b369a70a.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:16:53 +0300] "GET /info.php HTTP/1.1" 200 96189 "-" "curl/8.8.0"
[29/Jul/2024:17:17:10 +0300] "GET /health_check.php HTTP/1.1" 200 5 "-" "curl/8.8.0"
[29/Jul/2024:17:17:19 +0300] "GET /get.php HTTP/1.1" 404 78593 "-" "curl/8.8.0"
[29/Jul/2024:17:18:24 +0300] "POST /b369a70a.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:18:36 +0300] "POST /pub/b369a70a.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:20:18 +0300] "GET /pub/static.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:20:24 +0300] "GET /static.php HTTP/1.1" 500 3836 "-" "curl/8.8.0"
[29/Jul/2024:17:21:24 +0300] "GET /test.html HTTP/1.1" 200 0 "-" "curl/8.8.0"
[29/Jul/2024:17:21:28 +0300] "GET /test.html HTTP/1.1" 200 0 "-" "curl/8.8.0"
[29/Jul/2024:17:22:02 +0300] "GET /944bfb63.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:23:01 +0300] "GET /static/test.php HTTP/1.1" 404 658 "-" "curl/8.8.0"
[29/Jul/2024:17:25:13 +0300] "POST /info.php HTTP/1.1" 200 96564 "-" "curl/8.8.0"
[29/Jul/2024:17:41:08 +0300] "GET /out.txt HTTP/1.1" 200 0 "-" "curl/8.8.0"
[29/Jul/2024:17:45:41 +0300] "GET /out.txt HTTP/1.1" 200 552716 "-" "curl/8.8.0"
[29/Jul/2024:17:59:32 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:17:59:35 +0300] "GET / HTTP/2.0" 401 188 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
[29/Jul/2024:17:59:38 +0300] "GET /favicon.ico HTTP/2.0" 401 188 "https://_site_url_/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"

From what i know, it's generally only possible to modify a file on server using PUT or POST request, and only if server allows it. There is only one successful POST request to /info.php using curl (file's path is /pub/info.php related to server root), and that request most likely contains a command to be executed in server shell, following with "out.txt" which i presume contained keys that were later used to connect to server using SSH. File was modified sometime among these requests, I've deleted malicious code as soon as I've noticed it and didn't write down the last time it was edited.

Nginx config that's relevant to pub directory where info.php is located is:

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}

location /pub/ {
    location ~ ^/pub/media/(downloadable|customer|import|custom_options|theme_customization/.*\.xml) {
        deny all;
    }
    alias $MAGE_ROOT/pub/;
    add_header X-Frame-Options "SAMEORIGIN";
}

...

# PHP entry point for main application
location ~ ^/(info|index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
    try_files $uri =404;
    fastcgi_pass   fastcgi_backend;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;

    fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
    fastcgi_param  PHP_VALUE "memory_limit=6G \n max_execution_time=1800000";
    fastcgi_read_timeout 60000s;
    fastcgi_connect_timeout 60000s;

    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

File permissions for info.php were 755, can't tell exactly what were /pub directory permissions - as soon as change in file was noticed I've updated all permission to recommended ones, but let's assume they were 777. Is it possible that in this case outsider could change the file using http and why isn't it captured in logs? What steps should I take so that it doesn't happen again?

8
  • A file cannot simply be overwritten through an HTTP request. If there’s a vulnerability in your web application, then this might enable such an action (regardless of the request method), but nothing of what you’ve shown so far proves this. It could be an entirely different attack vector that didn’t involve the webserver at all, so don’t jump to conclusions.
    – Ja1024
    Commented Aug 2 at 19:43
  • If you want to investigate the web application first, then check for known vulnerabilities (if it’s a third-party application) and any features that might enable writing a file (like an upload or admin interface). Check the PHP log for possible errors caused during the attack.
    – Ja1024
    Commented Aug 2 at 19:43
  • 1
    simplest way to do this is exploit some backend code that trusts user input... say on a file upload where the backend actually trusts the user's filename. Path traversal, and bam they've uploaded/overwritten a file. (they use your back end code's privileges not their request) Commented Aug 2 at 19:51
  • can you include code for "static.php"? It's interesting that they caused a 500 error when posting to it. What is that used for? Also "info.php" (I think generally that leaks a lot of data about your server... is that your file?) They actually got a 200 response from a POST to that, which seems odd. They seemed to be probing for previous infections before that. Commented Aug 2 at 20:23
  • PUT and POST verbs allowing direct uploads and changing of data was from the old old old days of the internet's REST protocol. (when it was a closed network of trusted clients) Not to be confused with frameworks marketed as a "RESTful" API of some sort. (they brought back the old verbs, but not in the same way... things used to be truly state-less... but again that was in the very old days) Commented Aug 2 at 20:38

1 Answer 1

2

From what i know, it's generally only possible to modify a file on server using PUT or POST request, and only if server allows it.

If your server accepts incoming data in any form, and a security vulnerability exists, modifications can occur. A server that doesn't accept any incoming data is pretty useless, in general.

My guess here would be a vulnerability in your app or webserver; not in the configuration. Furthermore, nginx tends to be quite robust, so the main culprit I'd be poking would be the PHP application.

To protect against it - keep software up to date, and possibly look into an Web Application Firewall that can prevent some attacks. You anyway have to ensure that your web application doesn't have known vulnerabilities; a WAF is only part of a defence in depth-concept.

1
  • Thanks, will try to find possible vulnerabilities in the app.
    – Heinlein
    Commented Aug 4 at 16:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .