..

Identifying Attacks from Log Files

Web server logs provide invaluable insights in identifying attacks against web applications. Common web servers like Apache and nginx generate 2 log files by default, namely access.log and error.log. During an investigation, one should examine the most recent and rotated logs, as log files usually contain only a fraction of the full chain of events. Normally, there are too many logs from all the different sensors, so the primary focus of this post is to identify attacks in the context of an Apache web server.

127.0.0.1 - bob [26/Oct/2023:13:55:36 -0700] "GET /index.html HTTP/1.0" 2000 2326 "http://www.example.com/link.html" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT5.1; .NET CLR 1.1.4322)"

Let us consider the log entry shown above, a typical Apache log is interpreted as follows:

  Field Description
127.0.0.1 The IP address of the client  
- A hyphen indicates that the information is unavailable, in this case, the identity of the client  
bob The user id requesting the document, as determined by HTTP authentication. This field is usually empty.  
[26/Oct/2023:13:55:366 -0700 The timestamp when the server finished processing the request  
"GET /index.html HTTP/1.0" The method and HTTP method used to request the document  
200 The HTTP status code. In this case, 200 returns successful  
2326 This entry includes the size of the object returned to the client, excluding response headers.  
http://www.example.com/links.html The Referer in the HTTP header.  
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR1.1.4322) The user agent/browser of the client. In this entry, it says Internet Explorer 7 was used.  

As far as HTTP security is concerned, HTTP evasion techniques need to be bear in mind. These usually occur in the request URI portion of the request. The idea is to bypass IDS by inserting or obfuscating strings in the URI. A trivial technique to showcase this is to include additional slashes(in the case of path traversal attacks), null byte poisoning, multiple HTTP encodings, etc.

Denial-of-Service

Denial-of-service(DoS) attacks target application and web servers, in which network services are slowed down or rendered unusable(availability) by traffic congestion. For instance, a website is bombarded with bogus traffic, slowing it down or crashing it entirely. A combination of IP spoofing and botnets are usually used to carry out the attack, also known as distributed denial-of-service(DDoS).

If the traffic is originating from a single source IP, then mitigating the attack is trivial. One could simply read the logs to monitor the number of requests being made by the IP address in a given time frame to determine if there is a DoS attempt. This applies to distributed attacks as well, but it is very difficult to differentiate malicious traffic from legitimate traffic.

For amplification attacks, one could monitor the response sizes for abnormally large payloads. A ping of death example is shown below, where a large ICMP payload was crafted. The 172.17.0.3 address belongs to the “attacker” container, and the 172.17.0.2 address belongs to the victim server.

ping of death

It is also worth monitoring the server’s resource usage for abnormal activity. In the example shown below, the web server is being flooded with HTTP requests and there is a sudden spike in CPU usage.

resource usage

Cross Site Scripting(XSS)

XSS attacks inject malicious scripts into trusted websites through HTTP requests and by enticing unsuspecting users to click on them, the code is executed at the client. Similar to SQL injection, it is caused by improper input validation and encoding, so web applications that accept user inputs for displaying outputs are more likely to be vulnerable.

A trivial method to test for XSS vulnerability is by using the <script>document.alert(1)</script> payload. Therefore, when searching through logs, one can consider filtering for HTML tags such as img, iframes, and any expressions that can trigger JavaScript execution.

Consider the log entry below. The client IP 217.160.165.173 attempted to run a script through the URL field /foo.jsp?<script>foo</script>.jsp, and the server responded with 200 status OK. Assuming that there is no input validation and sanitization in place, this may suggest that the website is vulnerable to XSS and the attempt was successful.

212.140.165.153 ­ ­ [12/Mar/2014:22:31:12 ­0500]  "GET /foo.jsp?<SCRIPT>foo</SCRIPT>.jsp HTTP/1.1" 200 578 "­"  "Mozilla/4.75 [en] (X11, U; Nessus)"

The log entry below also shows an attempt to run JavaScript through the URL field, but the server rejected the request by responding with 403 status code.

212.140.165.153 ­ ­ [12/Mar/2014:22:37:17 ­0500] "GET /cgi­ bin/cvslog.cgi?file=<SCRIPT>window.alert</SCRIPT> HTTP/1.1" 403  302 "­" "Mozilla/4.75 [en] (X11, U; Nessus)"

SQL Injection

SQL injection(SQLI) attacks work by injecting malicious SQL queries via input data from the client(user) to the application. Successful SQLI allows attackeres to have control over the underlying database of the application, in which they can perform privilege escalation, modify data, read sensitive data, or even issue commands to the operating system. Again, this attack is made possible by improper input validation, where the original query is manipulated to query for sensitive information.

Common patterns include using the ' character and UNION joins. A simple example is shown below.

http://localhost/crud-php/read.php?id=-1 UNION SELECT password FROM users where id=5

Therefore, one should consider grepping for SQL keywords and operators in log files to find SQL injection attempts.

Consider the log entry below:

84.55.41.57- - [14/Apr/2016:08:22:13 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=1 AND (SELECT 6810 FROM(SELECT COUNT(*),CONCAT(0x7171787671,(SELECT (ELT(6810=6810,1))),0x71707a7871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) HTTP/1.1" 200 166 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"

Obviously, there was an SQLI attempt that was made by 84.55.41.57.

Cross Site Request Forgery(CSRF)

CSRF is an attack that forces an unsuspecting user to execute unwanted actions in a web application in which they are currently authenticated. For most sites, browser requests will include credentials associated with the site such as session cookies, so the site has no way of distinguishing a forged request sent by the victim and a legitimate request sent by the victim. CSRF targets state-changing requests on the server such as changing passwords or transferring funds.

One approach to detect CSRF is to verify the origin of the Referer HTTP header. This header contains the address from which the resource was requested from. If CSRF was attempted, this would point to the attacker’s forged website.

Consider the following scenario:

An attacker has forged a website at http://www.attacker.com/foo. The target user is currently authenticated and logged in to website A(http://www.a.com). The user is tricked into clicking on the attacker’s website, and upon landing, the website makes a request using the target’s authentication cookies to transfer funds.

Then, the following log entry would show up on website A’s web server:

192.168.4.6 ­ ­ [22/09/2023:21:43:36 ­0700] "GET /transfer.php? amt=99999&toAcct=attacker HTTP/1.0" 200 4926  "http://www.attacker.com/foo" "Mozilla/4.0 (compatible;  MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322)"

From the log entry, we can see that the request for fund transfer was redirected from http://www.attacker.com/foo which is from a different source origin than http://www.a.com.

Of course, this is a terrible toy example because state changing HTTP requests should be made through POST methods. Furthermore, all authenticated requests must happen over HTTPS for encryption.

Path Traversal

Path traversal allows an adversary to read arbitrary files or execute commands on the server that is running the application. Applications that use filename parameters to return the contents of a file are vulnerable.

<img src="/loadFile?filename=file.png"

Assuming that file.png was stored in /var/www/files/, the application appends the filename to the directory to read the content. Therefore, the parameter can be manipulated to access different directories on the server.

<img src="/loadFile?filename=../../../etc/passwd"

Consider the log entry below:

192.168.4.6  [22/09/2023:21:43:36 0700] "GET /foo.php?filename=../../../../etc/passwd HTTP/1.1" 200 1234

The log captured a succesful path traversal attack to retrieve information for all user accounts on the server.

References