//This is a 1 line comment/* This is a multiline comment*/#!This is a 1 line comment, but "#!" must to be at the beggining of the line-->This is a 1 line comment, but "-->" must to be at the beggining of the linefor (let j =0; j <128; j++) {for (let k =0; k <128; k++) {for (let l =0; l <128; l++) {if (j ==34|| k ==34|| l ==34)continue;if (j ==0x0a|| k ==0x0a|| l ==0x0a)continue;if (j ==0x0d|| k ==0x0d|| l ==0x0d)continue;if (j ==0x3c|| k ==0x3c|| l ==0x3c)continue;if ((j ==47&& k ==47)||(k ==47&& l ==47))continue;try {var cmd =String.fromCharCode(j) +String.fromCharCode(k) +String.fromCharCode(l) +'a.orange.ctf"';eval(cmd);} catch(e) {var err =e.toString().split('\n')[0].split(':')[0];if (err ==='SyntaxError'|| err ==="ReferenceError")continueerr =e.toString().split('\n')[0]}console.log(err,cmd);}}}//From: https://balsn.tw/ctf_writeup/20191012-hitconctfquals/#bounty-pl33z// From: Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 43). Kindle Edition.log=[];for(let i=0;i<=0xff;i++){for(let j=0;j<=0xfff;j++){try {eval(`${String.fromCodePoint(i,j)}%$┬г234$`)log.push([i,j])}catch(e){}}}console.log(log)//[35,33],[47,47]
// Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (pp. 40-41). Kindle Edition.// Check chars that can be put in between in func name and the ()functionx(){}log=[];for(let i=0;i<=0x10ffff;i++){try {eval(`x${String.fromCodePoint(i)}()`)log.push(i)}catch(e){}}console.log(log)v//9,10,11,12,13,32,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,813 232,8233,8239,8287,12288,65279
// Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (pp. 41-42). Kindle Edition.// Check which pairs of chars can make something be a valid stringlog=[];for(let i=0;i<=0x10ffff;i++){try {eval(`${String.fromCodePoint(i)}%$┬г234${String.fromCodePoint(i)}`)log.push(i)}catch(e){}}console.log(log) //34,39,47,96//single quote, quotes, backticks & // (regex)
// Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 34). Kindle Edition.log=[];let anchor =document.createElement('a');for(let i=0;i<=0x10ffff;i++){anchor.href =`javascript${String.fromCodePoint(i)}:`;if(anchor.protocol ==='javascript:') {log.push(i);}}console.log(log)//9,10,13,58// Note that you could BF also other possitions of the use of multiple chars// Test one optionlet anchor =document.createElement('a');anchor.href =`javascript${String.fromCodePoint(58)}:alert(1337)`;anchor.append('Click me')document.body.append(anchor)// Another way to test<ahref="javascript:alert(1337)">Test</a>
URL Fuzzing
// Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (pp. 36-37). Kindle Edition.// Before the protocola=document.createElement('a');log=[];for(let i=0;i<=0x10ffff;i++){a.href =`${String.fromCodePoint(i)}https://hacktricks.xyz`;if(a.hostname ==='hacktricks.xyz'){log.push(i);}}console.log(log) //0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32// Between the slashesa=document.createElement('a');log=[];for(let i=0;i<=0x10ffff;i++){a.href =`/${String.fromCodePoint(i)}/hacktricks.xyz`;if(a.hostname ==='hacktricks.xyz'){log.push(i);}}console.log(log) //9,10,13,47,92
HTML рдлрдЬрд╝рд┐рдВрдЧ
// Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 38). Kindle Edition.// Fuzzing chars that can close an HTML commentlet log=[];let div =document.createElement('div');for(let i=0;i<=0x10ffff;i++){div.innerHTML=`<!----${String.fromCodePoint(i)}><span></span>-->`;if(div.querySelector('span')){log.push(i);}}console.log(log)//33,45,62
The decrement operator -- is also an рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ. This operator takes a value and then decrements it by one. If that value is not a number, it will be set to NaN. This can be used to рд╣рдЯрд╛рдирд╛ the content of variables from the environment.
Functions Tricks
.call and .apply
The .call method of a function is used to рдЪрд▓рд╛рдирд╛ the function.
The first argument it expects by default is the value of this and if рдХреБрдЫ рднреА is provided, window will be that value (unless strict mode is used).
functiontest_call(){console.log(this.value); //baz}new_this={value:"hey!"}test_call.call(new_this);// To pass more arguments, just pass then inside .call()functiontest_call() {console.log(arguments[0]); //"arg1"console.log(arguments[1]); //"arg2"console.log(this); //[object Window]}test_call.call(null,"arg1","arg2")// If you use the "use strict" directive "this" will be null instead of window:functiontest_call() {"use strict";console.log(this); //null}test_call.call(null)//The apply function is pretty much exactly the same as the call function with one important difference, you can supply an array of arguments in the second argument:
functiontest_apply() {console.log(arguments[0]); //"arg1"console.log(arguments[1]); //"arg2"console.log(this); //[object Window]}test_apply.apply(null, ["arg1","arg2"])
// Traditionalfunction (a){ return a +1; }// Arrow formsa => a +100;a => {a +100};// Traditionalfunction (a, b){ return a + b +1; }// Arrow(a, b) => a + b +100;// Tradictional no argslet a =4;let b =2;function (){ return a + b +1; }// Arrowlet a =4;let b =2;() => a + b +1;
//This will use the this object and print "Hello World"varfn=function ( param1, param2 ) {console.info( this, param1, param2 );}fn('Hello','World')//This will still use the this object and print "Hello World"var copyFn =fn.bind();copyFn('Hello','World')//This will use the "console" object as "this" object inside the function and print "fixingparam1 Hello"var bindFn_change =fn.bind(console,"fixingparam1");bindFn_change('Hello','World')//This will still use the this object and print "fixingparam1 Hello"var bindFn_thisnull =fn.bind(null,"fixingparam1");bindFn_change('Hello','World')//This will still use the this object and print "fixingparam1 Hello"var bindFn_this =fn.bind(this,"fixingparam1");bindFn_change('Hello','World')
functionafunc(){return1+1;}console.log(afunc.toString()); //This will print the code of the functionconsole.log(String(afunc)); //This will print the code of the functionconsole.log(this.afunc.toString()); //This will print the code of the functionconsole.log(global.afunc.toString()); //This will print the code of the function
// Some ways to access windowwindow.eval("alert(1)")framesglobalThisparentselftop //If inside a frame, this is top most window// Access window from documentdocument.defaultView.alert(1)// Access document from a node objectnode =document.createElement('div')node.ownerDocument.defaultView.alert(1)// There is a path property on each error event whose last element is the window<imgsrconerror=event.path.pop().alert(1337)>// In other browsers the method is<img srconerror=event.composedPath().pop().alert(1337)>// In case of svg, the "event" object is called "evt"<svg><image href=1 onerror=evt.composedPath().pop().alert(1337)>// Abusing Error.prepareStackTrace to get Window backError.prepareStackTrace=function(error, callSites){2 callSites.shift().getThis().alert(1337);3 };4 new Error().stack// From an HTML event// Events from HTML are executed in this contextwith(document) {with(element) {//executed event}}// Because of that with(document) it's possible to access properties of document like:<img srconerror=defaultView.alert(1337)><img srconerror=s=createElement('script');s.append('alert(1337)');appendChild(s)>
// Stop when a property in sessionStorage or localStorage is set/get// via getItem or setItem functionssessionStorage.getItem =localStorage.getItem=function(prop) {