How to capture x screen using PHP, shell_exe and scrot - php

I'm building a web page screen capture application for an internal R&D project.
Environment: Ubuntu 9.04 (default desktop install), Apache, PHP.
So far I've got a bash script that takes one parameter (URL), fires up firefox, grabs the screen and saves it as a PNG. I've tried running this from terminal and it works fine.
Here's the Bash script:
#!/bin/bash
firefox $1 # Start firefox and go to the passed in URL
scrot -d 5 test.png # Take screen grab with 5 second delay
Next I created a simple PHP page that uses shell_exec to run the script:
<?
// Sample URL
$url = 'http://www.google.com';
// Run the script
shell_exec('sh script.sh ' . $url);
// Out put HTML to display image
echo '<img src="test.png" />';
?>
However, when the PHP page is called the screen is not captured.
A quick look in the apache error logs show the following message:
Error: no display specified
giblib error: Can't open X display. It *is* running, yeah
I'm guessing this is because apache is running as a different user and hasn't got access to my X display.
So, can anyone shed any light on what I'm doing wrong or how I can capture the current user display.
Thanks.

Launching firefox from PHP running under Apache seems to me like a bad idea (it definitly feels wrong).
The way I would do that :
a PHP webpage (which runs under Apache) that receives the URL ; something like a form, for instance
that page inserts the URL in a database-like system, that will be used as a queue
this URL is marked as "to process"
a PHP (or another language) script, totally independant from Apache ; for instance, launched by the crontab
this scripts selects an URL from the queue in the database (least recent one, for instance), and marks it as "processing"
it then lauches your shell-script, which launches firefox and does the screenshot
one the screenshot is done, the URL in the queue is marked as "done", and the screenshot's path is associated to the URL
this will work, as it is independant from Apache
another web page displays the queue, and the status of each URL ("to process", "processing", "done + path to the screenshot"
you can even imagine having an association betwen a user and an URL, to not display every URL+screenshot to everyone.
With this system, several advantages :
php+apache for the webpages
php outside of apache for the "system" parts
you can have the webpages on one server
and you can have several machines (linux, windows, mac -- maybe using virtual machines) to make the screenshots
allow you to get screenshots from different OSes
scales way better ^^
It's not really an answer to the question, but I think it's a better way... Hope this helps !

Here is a guide to do screen-capturing using firefox and xvfb. The advantage with this approach is that there will be no firefox windows opening and closing on your main X server. It will also solve your problem with permissions.

Can't you run your bash and firefox as the same user as apache?

Related

Run Cron Job on PHP Script, on localhost in Windows

I have a php script and want to run it on an schedule. I am using local web server on windows (WAMP server) and need a way to run my_script.php every 10 min.
How to run a cron job on a PHP script, on localhost in windows?
recently I had sort of problems to run a cron job on a php script on localhost (WAMP server) in windows 7, when I was on a test to chronically fetch some links from www out there.
By the way I am sharing this for anyone that is on the same thing.
You will need a shellscript to run chronically, using Windows Task Scheduler. Also you will need a batch script (script.bat) to call the php.exe and run your php script (here called as my_process.php)
shellscript.vbs
Set WinScriptHost = CreateObject("WScript.Shell")
WinScriptHost.Run Chr(34) & "C:\path\to\script\script.bat" & Chr(34), 0
Set WinScriptHost = Nothing
script.bat
"C:\wamp\bin\php\php5.4.12\php.exe" -f "C:\wamp\www\website\my_process.php"
Now, we are ready to set the Windows Task Scheduler to run shellscript.vbs at the required time interval:
Open Task Scheduler from windows Start menu
Go to Action menu and hit Create Task...
in General tab, fill the Name and Description fields as you want
in Triggers tab, hit New button.
from Begin the Task dropdown, select On a schedule and choose Daily
from Advanced settings section, select Repeat task every as you want and set for a duration on Indefinitely.
on Actions tab, from Action dropdown, select Start a program.
on the Program\script box, enter path to shellscript.vbs like C:\path\to\shellscript.vbs.
leave Add argumentts (optional) section empty.
in Start in (optional) box, enter parent directory of shellscript.vbs like C:\path\to\.
Hit upvote on this tutorial :) Have fun.
To setup a Windows machine to run cron.php at a specific time follow the specific instructions below. This can be useful if you are not familiar with Linux/Unix, or if your web host does not offer the ability to run cron jobs; you can run them remotely from your own computer.
Note: These instructions were written for Windows XP but should be similar in other versions of Windows.
https://www.drupal.org/node/31506
If you use answer from Trix and get same problem as Metafaniel:
I have a problem, with this procedure, the task is beinge executed,
however my php script it's not running, I got the "Open with"
dialogue. If I see the properties of my task, it states: ActionName
C:\Windows\system32\OpenWith.exe even if I set it to the vbs file as
you suggested. What am I doing wrong?
you should use this:
Instead "enter path to shellscript.vbs like C:\path\to\shellscript.vbs." use "C:\Windows\System32\wscript.exe"
Instead "leave Add argumentts (optional) section empty" use (with quotes):
"C:\path\to\shellscript.vbs"
After many failed attempts at using Windows Task Scheduler this is the method that worked for me on my Windows 10 Professional machine. I just skipped adding a .vbs and .bat file and posted the PATH to the script file directly.
Under "Actions > Settings" Where it gives the option to browse for a "Program/Script" that's where I put the full PATH AND Filename to the script I wanted to run WITHOUT quotes.
C:\Server\Scripts\script.py
Then in the same area under "Actions > Settings" right below the text box where you just entered your "Program/Script", it has the area that says "Start in (optional)". That's where I put the PATH to the program that runs the script (ie: python.exe in this instance). But I did not specify "python.exe" directly I used the PATH ONLY without quotes like shown below.
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64
If you installed Python directly without Visual Studio it will be under a different path probably something like "C:\Program Files\Python\Python37" or something similar if I remember correctly...
Little bit late but just for someone who don't want it to be lengthy and don't want to waste time in testing (as the aim is to host it to server), can do one thing by adding http content refresh in the html meta tag of that php file and add the required timer to it and run it in the browser.
NOTE: You have to make the system remain open untill you don't get the required output.
Again I am saying this is not the perfect and proper way but ya can save someone's configuration setting time.

Server side script for launching application

I have been trying unsuccessfully so far to write a php script that will run when a page is opened and that will launch metasploit!
I ve tried shell_exec and exec and all the other alternatives but although I can get it to do simple things (i.e. ls, cds etc) if I try msfconsole it doesnt do anything!
I have also tried a different script that launches firefox and again nothing happens!
Now i know that php runs on the server and I m not expecting to see a console or firefox opening in the clients machine! Instead in order to check if it works I am trying to echo out the output of the shell_exec!But anyway since im hosting the files on my machine (i.e. this is the server and a VM is the client) if it could actually launch firefox i should be able to see the app opening here in the same way as by just doing this from the command line!
What am I missing?
Is there any other way to do this?(i.e. Launch metasploit everytime a user opens up my page)
NOTE: I've tried specifying the full path for msfconsole but that didnt work either!
Heres what I have so far:
$output = shell_exec('/opt/local/libexec/metasploit3/msfconsole;show');
echo "<pre>$output</pre>";
The ";show" bit was used in order to actually make it run something and print some stuff but didnt make any difference!
When you run a gui application from the command prompt in a X window system, it will use the default display. When you run it using php which is embedded in apache webserver, the program may not know where to display the gui application.
there are 2 things to make this work.
The program that executes the gui application must have permission to use display
you need to tell the program which display to use.
I used the following in my php script
<?php
$cmd = `export DISPLAY=:0; gedit`;
shell_exec($cmd);
?>
and ran the script from terminal using php -f test.php
I got the gedit up and running.
You can test the same with the script in apache too.
Please add apache user with privileges to access display server
update: I just added the following in /etc/apache2/apache2.conf (I am using ubuntu)
User poomalai
Group poomalai
and restarted the web server
sudo service apache2 restart
now I accessed localhost/test.php
and Presto!! I got the gedit :)
Hope this helps

Run a script on a computer from php

I'm unsuccessfully trying to execute a shell command from php. The goal is to switch on/off my music player of my computer/server via internet (with my phone for example). Here is what I would be able to do :
I have a very simple file "play.sh" :
Code:
xdotool key XF86AudioPlay;
echo "switched";
if I run it ./play.sh, that works (music player switches on/off)
then I have an other very simple php file "play.php" :
Code:
<?php echo shell_exec("./play.sh"); ?>
These two files are in the main folder of my server which is a partition of my computer. (I'm using lampp) But music is playing from my computer.
But when I'm going on localhost/play.php, I can see "switched" that showed me the sh file as been executed, but the sound doesn't turn off .
I just tried exec(), shell_exec(), passthru(), system(), .. with ./play.sh and /opt/lampp/.../play.php the result is exactly the same, and there is no error message.. :/
But that's weird, I'm not sure, but I think that what I run on my computer side is not the same than what I run on my server side. I mean that it's like the sound was turning on/off on the virtual server but had no link with the sound of my computer. That could be an explanation.. but then, how to execute a script on my computer from internet/my server..?
Does someone have an idea to do that ? Is it a configuration of apache..?
Thanks !
EDIT :
Here is how I solved my problem :
xhost + local:www-data
Thanks for all your replies
It may be a permissions issue - keep in mind that when PHP runs a command, it's run as the user the webserver is running as, e.g. www-data or apache or whatever. If your music player is running as your own personal user, your script may not have the ability to change it when run as a different user.
Shell_exec works. Try to put in your .sh script absolute path to the executables
/usr/bin/xdotool key XF86AudioPlay;

PHP's shell_exec won't allow "Watir::Browser.new :firefox" to execute

I'm brand new to ruby and Watir, here's my issue...
I have a MySQL DB with test data that I need. I've done a lot in the past with this data and so I have a whole library of PHP tools for accessing this data, marking data as in use/used/bad/etc, and in general I have a lot of time invested in the PHP framework. So I'd really like to use the PHP framework as a wrapper around the Watir script - for example, use PHP to grab test user login data from the DB and pass it to the ruby script for processing.
I now have sites with javascript that need work/testing and PHP & cURL can't deal with this. So I'm working with Watir-WebDriver on Ubuntu 10.10 (Maverick, Desktop not Server) for these sites. The problem I'm having is with the use of PHP's shell_exec of the ruby script with all the Watir code.
The PHP shell_exec is executing the file - I can see it because I have some puts lines in the file which are being displayed. However, the code appears to be failing on the line
ff = Watir::Browser.new :firefox
I'm not getting an error from PHP.
The PHP line is:
echo shell_exec('ruby /var/www/watir_test.rb');
The ruby script works fine when I call it from a terminal window with the line:
ruby /var/www/watir_test.rb
I originally expected this was a permissions issue since it worked from the command line but not from a browser. However, since it can call the file well enough to return the hardcoded data I've provided for the test then ruby file permissions don't seem to be the issue. Could there be a permissions issue with opening a Firefox window from the www-data user?
When I run
ruby -d -v /var/www/watir_test.rb
I get:
{:extension=>:webdriver} {"app.update.enabled"=>"false"} {"browser.link.open_newwindow"=>"2"} {"browser.shell.checkDefaultBrowser"=>"false"} {"extensions.update.enabled"=>"false"} {"security.warn_entering_secure.show_once"=>"false"} {"webdriver_assume_untrusted_issuer"=>true} {"startup.homepage_welcome_url"=>"\"about:blank\""} {"browser.tabs.warnOnClose"=>"false"} {"extensions.update.notifyUser"=>"false"} {"toolkit.networkmanager.disable"=>"true"} {"security.warn_entering_weak.show_once"=>"false"} {"webdriver_firefox_port"=>"7055"} {"browser.download.manager.showWhenStarting"=>"false"} {"extensions.logging.enabled"=>"true"} {"network.manage-offline-status"=>"false"} {"network.http.max-connections-per-server"=>"10"} {"security.warn_submit_insecure"=>"false"} {"security.warn_entering_weak"=>"false"} {"security.warn_leaving_secure"=>"false"} {"prompts.tab_modal.enabled"=>"false"} {"security.warn_viewing_mixed.show_once"=>"false"} {"dom.max_script_run_time"=>"30"} {"webdriver_accept_untrusted_certs"=>true} {"browser.safebrowsing.enabled"=>"false"} {"security.warn_leaving_secure.show_once"=>"false"} {"signon.rememberSignons"=>"false"} {"javascript.options.showInConsole"=>"true"} {"app.update.auto"=>"false"} {"browser.EULA.3.accepted"=>"true"} {"browser.tabs.warnOnOpen"=>"false"} {"dom.disable_open_during_load"=>"false"} {"network.http.phishy-userpass-length"=>"255"} {"security.warn_entering_secure"=>"false"} {"browser.startup.homepage"=>"\"about:blank\""} {"browser.EULA.override"=>"true"} {"browser.dom.window.dump.enabled"=>"true"} {"browser.startup.page"=>"0"} {"browser.link.open_external"=>"2"} {"browser.search.update"=>"false"} {"browser.sessionstore.resume_from_crash"=>"false"} {"security.warn_viewing_mixed"=>"false"} {"dom.report_all_js_exceptions"=>"true"} {"webdriver_enable_native_events"=>false} {"devtools.errorconsole.enabled"=>"true"}
How do I get PHP to execute the shell_exec properly? The script works and my initial tests were run using firewatir (which shell_exec ran fine) but I am really wanting to use Watir-WebDriver instead of FireWatir - WatirWebDriver should be capable of running a Chrome browser (and IE on a Windows machine) while FireWatir can only run Firefox.
Thanks
Gabe
Here's my "Create Browser" code:
# Include the RubyGems file
require 'rubygems'
# Include the Watir-WebDriver file.
require 'watir-webdriver'
# Create the necessary objects
def create_browser(proxy)
# Setup the proper Firefox Profile
profile = Selenium::WebDriver::Firefox::Profile.new
profile.proxy = Selenium::WebDriver::Proxy.new :http => proxy
puts "<br>Using proxy " + proxy + "..."
#ff=FireWatir::Firefox.new :profile => profile
ff = Watir::Browser.new :firefox #, :profile => profile
puts "<br>Firefox ready..."
return ff
end
If the server is headless, you should install the headless gem so that Firefox can work.
require 'watir-webdriver'
require 'headless'
headless = Headless.new
headless.start
b = Watir::Browser.start 'www.google.com'
puts b.title
b.close
headless.destroy
See: http://watirwebdriver.com/headless/
It't a permission problem, the PHP script runs with the permissions of the server, normally apache.
You can do a sudo www and try to run the script then with rb to see if there is a problem when running ruby with the server user.
Put the two lines of code that is below at the very top of your PHP script. The result of this is that when you browse to your PHP page with your browser it will display exactly what the errors are, including any permission errors.
ini_set("display_errors",1);
error_reporting(E_ALL);
So a recent update to Firefox killed it's support for Watir (no JSSH update if I remember). As a result I rewrote what little code I had for Selenium::WebDriver. But I'm thinking that isn't particularly relevant (its included in case it is relevant I don't know it).
My ultimate solution was to use phpseclib. This allows me to SSH into the machine via their SSH2 PHP class. Once logged in as my typical username (with typical password) I was able to fire off a headless version of my script no problem. The only real issues this creates is that I now have to view everything that's going on through log files and screenshots but that was likely to be true no matter what solution I came up with.
phpseclib needs your username and password for the server (at least until you set some form of public private key pair). So I wouldn't want to do this on a publicly available machine without a couple of layers of security - like setting .htaccess to deny read access to the file with the login data, encrypting the password stored in the file, etc. However, for my purposes I'm logging into one machine on my LAN from another machine on my LAN. The password is only good on my LAN (not my web servers) and while my LAN can see out it should not be (easily) available to the rest of the world (to the best of my knowledge). So the security concerns are minimal.
I never did figure this out. Headless isn't the answer to getting PHP to exec the script. I'm pretty sure it is a permissions issue with Firefox's executable but I can't be positive until I find an actual fix.
Ultimately I've had to break up the tool where PHP manages the DB and task scheduling. Then PHP creates text files with all the data necessary for ruby to run the browser to right site, login, etc, etc... Then ruby moves the data file to one of a few different folders (success, failure, bad login, etc) and adds some text to the data file. Finally PHP parses all this info in the moved text files and updates the DB with that info.
It's less than ideal but it is getting the job done. Now I just need to figure out how to run all of this with mutliple threads...
Thanks for the help

Why has my PHP system() command stopped returning output to my scripts ... i used to work!

I have a PHP script that calls a .bat file using system(). The output is written to the screen and I derive some values from parsing this output. This is running on windows 2003 IIS server. PHP v5.2.0
Specifically I am using this script to launch an Amazon EC2 instance and assign an IP address to it. It has worked great for me so far but recently the problem started.
Here is the code
$resultBatTemp = system("cmd /C C:\Inetpub\ec2\my_batch_file_to_launch_instance.bat");
$resultBat = (string)$resultBatTemp;
$instanceId = substr($resultBat, 9, 10);
...
Once I have this instace Id I can run another batch file that calls associates an ip address with this instance. It would appear that the instance does get launched but I never get the output on the screen.
For some reason this has all stopped working, the page freezes and never refreshes. I also need to completely exit safari or mozilla otherwise all pages from the website fail to load. Only when I relaunch the browser can i view the website again. I've connected to the webserver that hosts these scripts and checked PHP error log but nothing shows there. I've opened a DOS prompt and entered the code from the bat file that way and it connects to amazon and launches the instance fine. Ive isolated this bit of code and removed the system command and the rest of the script runs fine, so it appears that the hold up is with outputting the results of the bat file.
Recently I have purchased a new domain name for the site so this script is running from this domain. Might this cause the problem?
thanks
------------------------------------------------UPDATE-----------------------------------------------
Well hope this helps someone, I didnt find out what was wrong but created a new PHP file with a simple system command that called a .bat file, and a non-existent .bat file expecting to get an error back but nothing - just the usual hang for ages. So I restarted IIS and this fixed the problem. Dont know what was wrong but that did the trick.
Maybe first check what the system() call returns. According to documentation it will return FALSE in case of failure. Also, including your my_batch_file_to_launch_instance.bat in the question might help in solving it.
Try using the passthru function
Also make sure that all your commands are safe use escapeshellarg() or escapeshellcmd() to ensure that users cannot trick the system into executing arbitrary commands.

Categories