# Verskillende JS-truuks & relevante inligting
Leer AWS-hacking van nul tot held methtARTE (HackTricks AWS Red Team Expert)!
* Werk jy in 'n **cybersecurity-maatskappy**? Wil jy jou **maatskappy adverteer in HackTricks**? Of wil jy toegang hê tot die **nuutste weergawe van die PEASS of HackTricks aflaai in PDF-formaat**? Kyk na die [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Ontdek [**The PEASS Family**](https://opensea.io/collection/the-peass-family), ons versameling eksklusiewe [**NFTs**](https://opensea.io/collection/the-peass-family)
* Kry die [**amptelike PEASS & HackTricks swag**](https://peass.creator-spring.com)
* **Sluit aan by die** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord-groep**](https://discord.gg/hRep4RUj7f) of die [**telegram-groep**](https://t.me/peass) of **volg** my op **Twitter** 🐦[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Deel jou hacking-truuks deur PR's in te dien by die** [**hacktricks-repo**](https://github.com/carlospolop/hacktricks) **en** [**hacktricks-cloud-repo**](https://github.com/carlospolop/hacktricks-cloud).
## Javascript Fuzzing
### Geldige JS Kommentaar Karakters
```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]
```
### Geldige JS Nuwe Lyn Karakters
In JavaScript kan jy verskillende karakters gebruik om 'n nuwe lyn te skep binne 'n string. Hier is 'n lys van geldige karakters wat jy kan gebruik:
- `\n`: Skep 'n nuwe lyn.
- `\r`: Skep 'n karretjie-terugkeer.
- `\u2028`: Skep 'n lynafbreking.
- `\u2029`: Skep 'n paragraafafbreking.
Hier is 'n voorbeeld van hoe jy hierdie karakters kan gebruik:
```javascript
var string = "Hierdie is 'n voorbeeld\nvan 'n nuwe lyn";
```
Dit sal 'n nuwe lyn skep na die woord "voorbeeld".
```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
```
### Geldige JS-spasies in funksie-oproep
In sommige situasies kan die gebruik van geldige JS-spasies in 'n funksie-oproep nuttig wees om XSS-aanvalle te omseil. Hier is 'n paar voorbeelde van hoe dit gedoen kan word:
1. **Gebruik van new line karakter**: Jy kan die new line karakter (`\n`) gebruik om 'n funksie-oproep oor meerdere lyne te verdeel. Byvoorbeeld:
```javascript
aler\nt('XSS');
```
2. **Gebruik van tab karakter**: Die tab karakter (`\t`) kan ook gebruik word om 'n funksie-oproep oor meerdere spasies te verdeel. Byvoorbeeld:
```javascript
aler\t('XSS');
```
3. **Gebruik van backslash karakter**: Die backslash karakter (`\`) kan gebruik word om 'n funksie-oproep oor meerdere spasies te verdeel. Byvoorbeeld:
```javascript
aler\ t('XSS');
```
Dit is belangrik om te onthou dat hierdie tegnieke slegs werk in spesifieke omstandighede en nie altyd betroubaar is nie. Dit is dus belangrik om ander XSS-verdedigingsmaatreëls te implementeer om jou webtoepassing te beskerm.
```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
```
### **Geldige karakters om Strings te genereer**
```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**
Hierdie tegniek sal nie baie nuttig wees vir XSS nie, maar dit kan nuttig wees om WAF-beskerming te omseil. Hierdie Python-kode ontvang as inset 2 byte en soek 'n surrogate-paar wat die eerste byte as die laaste bytes van die Hoë surrogate-paar het en die laaste byte as die laaste byte van die lae surrogate-paar.
```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"))
```
Meer inligting:
* [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
URL Fuzzing is 'n tegniek wat gebruik word om potensiële kwesbaarhede in 'n webtoepassing te identifiseer deur verskillende variante van 'n URL te probeer. Dit behels die invoeging van verskillende waardes en parameters in die URL om te sien of dit lei tot enige onverwagte gedrag of fouttoestande. Hierdie tegniek kan gebruik word om potensiële XSS-kwesbaarhede te ontdek deur te kyk of die webtoepassing korrek omgaan met ongeldige of skadelike invoer in die URL.
```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.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 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
HTML Fuzzing is a technique used to discover vulnerabilities in web applications by injecting malicious or unexpected input into HTML elements. This technique involves sending a large number of test cases to the target application, with the goal of triggering unexpected behavior or uncovering security flaws.
During HTML Fuzzing, various types of input can be injected into HTML elements, such as:
- **Script tags**: Injecting script tags can help identify Cross-Site Scripting (XSS) vulnerabilities. By injecting malicious scripts, an attacker can execute arbitrary code in the victim's browser.
- **HTML tags**: Injecting HTML tags can help identify HTML injection vulnerabilities. This can lead to the manipulation of the website's structure and content.
- **Event attributes**: Injecting event attributes can help identify DOM-based XSS vulnerabilities. By injecting malicious event handlers, an attacker can execute code within the context of the victim's browser.
- **URL parameters**: Injecting malicious input into URL parameters can help identify vulnerabilities such as Server-Side Request Forgery (SSRF) or Remote File Inclusion (RFI).
To perform HTML Fuzzing, you can use automated tools or write custom scripts to generate and send a large number of test cases to the target application. The goal is to observe how the application handles different types of input and identify any unexpected behavior or vulnerabilities.
It is important to note that HTML Fuzzing should only be performed on applications that you have permission to test. Unauthorized testing can lead to legal consequences. Always ensure you have proper authorization before conducting any security testing.
```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
```
## **Ontleding van eienskappe**
Die instrument **Hackability-inspekteur** van Portswigger help om die **eienskappe** van 'n JavaScript-objek te **ontleed**. Kyk: [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-lêers**
* Truuk om .map js-lêers af te laai: [https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7](https://medium.com/@bitthebyte/javascript-for-bug-bounty-hunters-part-2-f82164917e7)
* Jy kan hierdie instrument gebruik om hierdie lêers te ontleed [https://github.com/paazmaya/shuji](https://github.com/paazmaya/shuji)
## "--" Toekenning
Die dekrement-operator `--` is ook 'n toekenning. Hierdie operator neem 'n waarde en verminder dit dan met een. As daardie waarde nie 'n nommer is nie, sal dit op `NaN` gestel word. Dit kan gebruik word om die inhoud van veranderlikes uit die omgewing te **verwyder**.
![](<../../.gitbook/assets/image (553).png>)
![](<../../.gitbook/assets/image (554).png>)
## Funksie Truuks
### .call en .apply
Die **`.call`**-metode van 'n funksie word gebruik om die funksie uit te voer.\
Die **eerste argument** wat dit standaard verwag, is die **waarde van `this`** en as **niks** voorsien word nie, sal **`window`** daardie waarde wees (tensy **`strict mode`** gebruik word).
```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"])
```
### Pylpuntfunksies
Pylpuntfunksies maak dit makliker om funksies in 'n enkele lyn te genereer (as jy hulle verstaan)
```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;
```
So, die meeste van die vorige funksies is eintlik nutteloos omdat ons hulle nie enige plek stoor om hulle te bewaar en aan te roep nie. Byvoorbeeld, die skep van die `plusone` funksie:
```javascript
// Traductional
function plusone (a){ return a + 1; }
//Arrow
plusone = a => a + 100;
```
### Bind-funksie
Die bind-funksie maak dit moontlik om 'n **kopie** van 'n **funksie te skep wat** die **`this`** objek en die **parameters** wat gegee word, wysig.
```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')
```
{% hint style="info" %}
Let daarop dat jy met behulp van **`bind`** die **`this`** objek kan manipuleer wat gebruik sal word wanneer die funksie geroep word.
{% endhint %}
### Funksie kode lek
As jy toegang het tot die objek van 'n funksie, kan jy die kode van daardie funksie kry.
```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
```
In gevalle waar die **funksie geen naam het nie**, kan jy steeds die **funksie kode** binne die funksie druk:
```javascript
(function (){ return arguments.callee.toString(); })()
(function (){ return arguments[0]; })("arg0")
```
Sommige **willekeurige** maniere om die kode van 'n funksie (selfs kommentaar) uit 'n ander funksie te **onttrek**:
```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 */ })()
```
## Sandbakkie-ontsnapping - Herstel van vensterobjek
Die vensterobjek maak dit moontlik om globaal gedefinieerde funksies soos alert of eval te bereik.
{% code overflow="wrap" %}
```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"