# Razne JS Trikovi i Relevantne Informacije
{{#include ../../banners/hacktricks-training.md}}
## Javascript Fuzzing
### Validni JS Komentari Karakteri
```javascript
//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 line
for (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")
continue
err = 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]
```
### Valid JS New Lines Chars
```javascript
//Javascript interpret as new line these chars:
String.fromCharCode(10) //0x0a
String.fromCharCode(13) //0x0d
String.fromCharCode(8232) //0xe2 0x80 0xa8
String.fromCharCode(8233) //0xe2 0x80 0xa8
for (let j = 0; j < 65536; j++) {
try {
var cmd = '"aaaaa";' + String.fromCharCode(j) + '-->a.orange.ctf"'
eval(cmd)
} catch (e) {
var err = e.toString().split("\n")[0].split(":")[0]
if (err === "SyntaxError" || err === "ReferenceError") continue
err = e.toString().split("\n")[0]
}
console.log(`[${err}]`, j, cmd)
}
//From: https://balsn.tw/ctf_writeup/20191012-hitconctfquals/#bounty-pl33z
```
### Valid JS Spaces in function call
```javascript
// 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 ()
function x(){}
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
```
### **Validni karakteri za generisanje stringova**
```javascript
// 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 string
log = []
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)
```
### **Surrogate Pairs BF**
Ova tehnika neće biti veoma korisna za XSS, ali bi mogla biti korisna za zaobilaženje WAF zaštita. Ovaj python kod prima kao ulaz 2 bajta i traži surrogate parove koji imaju prvi bajt kao poslednji bajt visokog surrogate para i poslednji bajt kao poslednji bajt niskog surrogate para.
```python
def unicode(findHex):
for i in range(0,0xFFFFF):
H = hex(int(((i - 0x10000) / 0x400) + 0xD800))
h = chr(int(H[-2:],16))
L = hex(int(((i - 0x10000) % 0x400 + 0xDC00)))
l = chr(int(L[-2:],16))
if(h == findHex[0]) and (l == findHex[1]):
print(H.replace("0x","\\u")+L.replace("0x","\\u"))
```
Više informacija:
- [https://github.com/dreadlocked/ctf-writeups/blob/master/nn8ed/README.md](https://github.com/dreadlocked/ctf-writeups/blob/master/nn8ed/README.md)
- [https://mathiasbynens.be/notes/javascript-unicode](https://mathiasbynens.be/notes/javascript-unicode) [https://mathiasbynens.be/notes/javascript-encoding](https://mathiasbynens.be/notes/javascript-encoding)
### `javascript{}:` Protokol Fuzzing
```javascript
// 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 option
let anchor = document.createElement('a');
anchor.href = `javascript${String.fromCodePoint(58)}:alert(1337)`;
anchor.append('Click me')
document.body.append(anchor)
// Another way to test
Test
```
### URL Fuzzing
```javascript
// Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (pp. 36-37). Kindle Edition.
// Before the protocol
a = document.createElement("a")
log = []
for (let i = 0; i <= 0x10ffff; i++) {
a.href = `${String.fromCodePoint(i)}https://hacktricks.wiki`
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 slashes
a = 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 Fuzzing
```javascript
// Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 38). Kindle Edition.
// Fuzzing chars that can close an HTML comment
let log = []
let div = document.createElement("div")
for (let i = 0; i <= 0x10ffff; i++) {
div.innerHTML = ``
if (div.querySelector("span")) {
log.push(i)
}
}
console.log(log) //33,45,62
```
## **Analiza atributa**
Alat **Hackability inspector** iz Portswigger-a pomaže da se **analiziraju** **atributi** javascript objekta. Proverite: [https://portswigger-labs.net/hackability/inspector/?input=x.contentWindow\&html=%3Ciframe%20src=//subdomain1.portswigger-labs.net%20id=x%3E](https://portswigger-labs.net/hackability/inspector/?input=x.contentWindow&html=%3Ciframe%20src=//subdomain1.portswigger-labs.net%20id=x%3E)
## **.map js datoteke**
- Trik za preuzimanje .map js datoteka: [https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7](https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7)
- Možete koristiti ovaj alat za analizu ovih datoteka [https://github.com/paazmaya/shuji](https://github.com/paazmaya/shuji)
## "--" Dodeljivanje
Operator dekrementa `--` je takođe dodeljivanje. Ovaj operator uzima vrednost i zatim je smanjuje za jedan. Ako ta vrednost nije broj, biće postavljena na `NaN`. Ovo se može koristiti za **uklanjanje sadržaja promenljivih iz okruženja**.
.png>)
.png>)
## Trikovi sa funkcijama
### .call i .apply
Metoda **`.call`** funkcije se koristi za **pokretanje funkcije**.\
**Prvi argument** koji očekuje po defaultu je **vrednost `this`** i ako **ništa** nije pruženo, **`window`** će biti ta vrednost (osim ako se koristi **`strict mode`**).
```javascript
function test_call() {
console.log(this.value) //baz
}
new_this = { value: "hey!" }
test_call.call(new_this)
// To pass more arguments, just pass then inside .call()
function test_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:
function test_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:
function test_apply() {
console.log(arguments[0]) //"arg1"
console.log(arguments[1]) //"arg2"
console.log(this) //[object Window]
}
test_apply.apply(null, ["arg1", "arg2"])
```
### Arrow functions
Arrow functions omogućavaju lakše generisanje funkcija u jednoj liniji (ako ih razumete)
```javascript
// Traditional
function (a){ return a + 1; }
// Arrow forms
a => a + 100;
a => {a + 100};
// Traditional
function (a, b){ return a + b + 1; }
// Arrow
(a, b) => a + b + 100;
// Tradictional no args
let a = 4;
let b = 2;
function (){ return a + b + 1; }
// Arrow
let a = 4;
let b = 2;
() => a + b + 1;
```
Dakle, većina prethodnih funkcija je zapravo beskorisna jer ih nigde ne čuvamo da bismo ih sačuvali i pozvali. Na primer, kreiranje `plusone` funkcije:
```javascript
// Traductional
function plusone(a) {
return a + 1
}
//Arrow
plusone = (a) => a + 100
```
### Bind funkcija
Funkcija bind omogućava kreiranje **kopije** **funkcije koja menja** **`this`** objekat i **parametre** koji su dati.
```javascript
//This will use the this object and print "Hello World"
var fn = 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")
```
> [!NOTE]
> Imajte na umu da korišćenjem **`bind`** možete manipulisati **`this`** objektom koji će biti korišćen prilikom pozivanja funkcije.
### Curjenje koda funkcije
Ako možete **pristupiti objektu** funkcije, možete **dobiti kod** te funkcije.
```javascript
function afunc() {
return 1 + 1
}
console.log(afunc.toString()) //This will print the code of the function
console.log(String(afunc)) //This will print the code of the function
console.log(this.afunc.toString()) //This will print the code of the function
console.log(global.afunc.toString()) //This will print the code of the function
```
U slučajevima kada **funkcija nema ime**, i dalje možete ispisati **kod funkcije** iznutra:
```javascript
;(function () {
return arguments.callee.toString()
})()(function () {
return arguments[0]
})("arg0")
```
Neki **slučajni** načini za **izvlačenje koda** funkcije (čak i komentara) iz druge funkcije:
```javascript
;(function () {
return (retFunc) => String(arguments[0])
})((a) => {
/* Hidden commment */
})()(function () {
return (retFunc) => Array(arguments[0].toString())
})((a) => {
/* Hidden commment */
})()(function () {
return String(this)
}).bind(() => {
/* Hidden commment */
})()((u) => String(u))((_) => {
/* Hidden commment */
})((u) => (_) => String(u))((_) => {
/* Hidden commment */
})()
```
## Sandbox Escape - Oporavak window objekta
Window objekat omogućava pristup globalno definisanim funkcijama kao što su alert ili eval.
```javascript
// Some ways to access window
window.eval("alert(1)")
frames
globalThis
parent
self
top //If inside a frame, this is top most window
// Access window from document
document.defaultView.alert(1)
// Access document from a node object
node = document.createElement('div')
node.ownerDocument.defaultView.alert(1)
// There is a path property on each error event whose last element is the window
// In other browsers the method is
// In case of svg, the "event" object is called "evt"