JS payloads in 2021

and where to find them

2021-11-28 * Wintrmvte

Introduction

Eventhough the golden age of executing raw Javascript assets on the browser side without suspicion is long gone, still over 93% of the web in general uses at least some Javascript on the backend. This short entry will show you how older code snippets can survive a trial of time and how to adapt them to still operate well against input validation techniques.

Modifying the tag separator

The value between the tag declaration and it's first parameter is interpreted in the same way regardless of the separator. Both fixed and randomly selected separators can be inserted, including tabs, spaces, newlines and carriage returns.

Script markers obfuscation

When the code is embedded inside a pair of content-type tags, it is often easy to fingerprint regular patterns that state the start and the end of the payload. Tags of randomized case often evade those patterns, yet they look kinda strange:

Script markers
Script markers

Manual dependencies specification

This is probably the smallest change to the tool so far, but is easily extendable and quite useful if our generated code should support something more than plain Javascript. Using --jquery switch, we can insert a JQuery dependency right before created payload (but inside the <script> tags). Basically, it just prepends:

... src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js">

before the payload's body. This functionality can be modified in a few steps to load arbitrary, remote scripts and frameworks according to our needs.

POC scenarios

PoC
PoC
In case when no actual functionality is required, and we only need to check if the payload execution was successful, two new dynamic code generators were added. Selecting either random or random_confirm with the --payload/-p flag creates a random, compact one-liner code for easy injection. Using --random-max option, we can instruct the framework to use size restrictions when choosing a payload line.

Injection via template engine

When no JS code can be executed on our host of interest, expressing payloads in different logical formats is often desirable. Current release supports placing payload inside a frontend mold of VueJS (V2 and V3) + AngularJS. Corresponding option: --v2 + --v3 + --angular

Polyglot wrappers...

Polyglots
Polyglots
Polyglot templates might come-in handy when we can't be sure about any specifics of the input parsing/validation on the backend. Aformentioned are often valid (in terms of ability to execute) in multiple places, data fields and environments. Any of the payloads provided with the tool can be ebmedded inside such template - the keyword PAYLOAD will me modified accordingly. Polyglots can be specified via --polyglot <polyglot_id>

...and their triggers

Triggers
Triggers
Sometimes we either need to run payloads only when certain environmental criteria are met, or we want them executed right-away, without user's interaction. Script invocation triggers can be specified using the --polyglot-trigger <trigger_name> switch. Running:

--polyglot random --polyglot-trigger random

will instruct the template builder to select any polyglot and insert any event trigger inside it.

[ Resources ]

-> https://netsec.expert/posts/xss-in-2021/