Can't execute powershell script function using PHPs shell_exec - php

I'm trying to pass arguments from a PHP page's POST request into a powershell script.
This is the relevant PHP snippet:
$selectedPartner = $_POST['partner'];
$selectedGroup = $_POST['group'];
$script = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe AddRemPartners";
if (isset($_POST['partner']) && isset($_POST['group'])){
if (isset($_POST['AddButton']) && $selectedPartner !== "Select Partner" && $selectedGroup !== "Select Group") {
echo "<br>";
echo "Adding " . $selectedPartner . " to " . $selectedGroup . "...<br>";
$cmd = $script . " -Add $selectedPartner $selectedGroup";
echo "command is:<br>" . $cmd;
shell_exec($cmd);
//shell_exec('C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe C:\\xampp\\htdocs\\admin\\AddRemPartners.ps1 -Add $selectedPartner //$selectedGroup');
//$command = shell_exec('C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe telnet 10.11.14.32 4444');
//echo "User added successfully!";
}
if (isset($_POST['RemoveButton']) && $selectedPartner !== "Select Partner" && $selectedGroup !== "Select Group") {
echo "<br>";
//echo "selection was REMOVE";
}
}
And this is my powershell script:
Param([switch]$Add, [switch]$Remove, [string]$User, [string]$Group)
$secpasswd = ConvertTo-SecureString "P#sSw0rd" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("userPortal", $secpasswd)
$server = "host.fqdn"
function AddRemPartners
{
if ($Add){
Write-Host "Add var = $Add"
Write-Host "Add was selected"
Add-ADGroupMember -Server $server -Credential $creds -Identity $Group -Member $User
}
if ($Remove) {
Write-Host "Remove var = $Remove"
Write-Host "Remove was selected"
Remove-ADGroupMember -Server $server -Credential $creds -Identity "$Group" -Member "$User" -Confirm:$false
}
}
AddRemPartners -Add $Add -Remove $Remove -User $User -Group $Group
Things I know:
The php post parameters are good. I captured the request in burpsuit and know that all the correct args are getting sent
The resultant ps query that is built is also good. I output it to the screen and it looks like this:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe AddRemPartners -Add Dude1 Dude1Group
No network issues. If I run the above command directly from within PowerShell is executes correctly.
I've sourced my script using . .\AddRemPartners.ps1 so I can call my function directly as such:
PS > AddRemPartners -Add User Group
PS > AddRemPartners -Remove User Group
I've narrowed it down to this: I can't execute my ps script from cmd like this:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe AddRemPartners -Add User Group
As that errors out with this:
AddRemPartners : The term 'AddRemPartners' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
I believe this to be suspect/culpable since I need run that in PHP. So PHP is probably running into the same issue. So why won't cmd recognize my script if I call powershell at the same time as execution?
Any tips and guidance greatly appreciated. I'm at wits end unfortunately. :/

First parameter for PS should be full path of script. Then you should respect parameter definition of PS, on command line as in the script.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\whereis\AddRemPartners.ps1 -Add -user User -group Group
First line of the script should be parameter definition and defaults.
param([string]$user, [string]$group, [switch]$Add, ...);

Related

How to answer to command response? (shell_exec, exec)

I should enter confirmation code after my function execute. My command wait an answer but I can't reply.
$cmd = 'cd/ && cd .... && ....';
echo shell_exec($cmd);
I tried:
shell_exec($confirmation_code);
I must enter confirmation code after get permission for some access.
Try this
$cmd = 'echo "Yes"| cd/ && cd .... && ....';
echo shell_exec($cmd);
Replace "Yes" by what you want
Symphony Process command can do this for you:
https://symfony.com/doc/current/components/process.html#streaming-to-the-standard-input-of-a-process

Login to Docker Hub from PHP script

I am trying to login and push Docker images from a PHP script as part of our CICD process. Here is the code:
<?php
include '../php/database.php';
$duser = 'username';
$dpass = 'password';
$dmail = 'email';
$tag = 'from system';
function tagImage($tag) {
$getImageID = "SELECT `imageID` FROM `docker_images` WHERE `tag` = :tag ";
$params = array(':tag' => $tag);
$results = dataQuery($getImageID, $params);
if(!empty($results)) {
$image = $results[0]['imageID'];
global $repo = $results[0]['repo']; // I know this is a bad idea, will change it when all else is working
$last = system("sudo docker tag -f $image $repo 2>&1", $retval);
}
return $retval;
}
$tagStatus = tagImage($tag);
if(0 == $tagStatus) {
echo '<pre>';
$login = system("sudo docker login --username=$duser", $retval);
var_dump($login);
var_dump($retval);
// push it real good
$last = system("sudo docker push $repo 2>&1", $retval1);
var_dump($last);
var_dump($retval1);
}
?>
This returns the following:
string(0) ""
int(1)
The push refers to a repository [app/ap-name] (len: 1)
21d623eb89a9: Image push failed
Please login prior to push:
Username: EOF
string(13) "Username: EOF"
int(1)
The push is failing because the login is not working from the PHP script, however, when I login from the command line the login is successful.
What am I doing wrong? Can I login to Docker Hub with PHP like this? Or should the technique be different?
EDIT: The PHP script will be called via AJAX, effectively making it run as if it were being run from the browser. I am running it from the browser for testing purposes.
The login requires all of the credentials including password and email address associated with the Docker hub repo:
$login = system("sudo docker login --username $duser --password $dpass --email $dmail 2>&1", $retval);
var_dump($login);
var_dump($retval);
Using this syntax returns the following (expected):
WARNING: login credentials saved in /root/.dockercfg.
Login Succeeded
string(15) "Login Succeeded"
int(0)
Past that point the push works properly and returns no errors.

Powershell command in PHP

I'm trying to be clever and create a form to create a VM in ESX.
I have found the PowerCLI add-in for Poweshell and i have manually managed to create one.
This is my code but I'm struggling to make it work.
{
// Get the variables submitted by POST in order to pass them to the PowerShell script:
$name = $_POST["name"];
$diskmb = $_POST["diskmb"];
$MemoryMB = $_POST["MemoryMB"];
$NumCPU = $_POST["NumCPU"];
$connectesx = "Connect-VIServer -Server IPADDRESS -Protocol https -User 'USERNAME' -password 'PASSWORD'";
$createvm = "New-VM -Name $name -DiskMB $diskmb -MemoryMB $MemoryMB -NumCPU $NumCPU";
$psScriptPath = "C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\esxdhb.psc1";
// Execute the PowerShell script, passing the parameters:
shell_exec("powershell -psc $psScriptPath -command $connectesx && $createvm");
echo ("$name Created Successfully.");

Run Scripts from PHP

I have a question about interaction PHP and Linux system.
I want to launch Steam from WebPage, and address of this page is
http://site.eu/cp/user/services/21/steaminstall
And internal path to WebPage from where im running command is
/var/www/wwwuser/data/www/site.eu/panel.php?(here goes $_POST[''] data)
and the Steam Client is
/var/www/wwwuser/data/Steam/SteamInstall
The thing is, i know how to access this script, also i can execute simple
echo "Script is Runing"
But when my actions comes to this code
#!/bin/bash
wget -P /var/www/aftersoft/data/Servers/Steam/ http://media.steampowered.com/client/steamcmd_linux.tar.gz &&
tar xvfz /var/www/aftersoft/data/Servers/Steam/steamcmd_linux.tar.gz -C /var/www/aftersoft/data/Servers/Steam/ &&
sh /var/www/aftersoft/data/Servers/Steam/steamcmd.sh +login anonymous +quit &&
rm /var/www/aftersoft/data/Servers/Steam/steamcmd_linux.tar.gz &&
echo "Steam Installation and Update Completed"
It's not doing anything if im running it from WebPage, but it works when im trying to run it under the SSH user (same as apache user with permissions to write to this folder)
So my question, what am i doing wrong?
UPDATE:
My php code to run script is
if($path[2] === 'steaminstall')
{
$InstallSteam = exec('/var/www/aftersoft/data/Servers/Steam/SteamInstall', $Output, $Error);
if($Error === 0)
{
$Status = $DB->SteamStatus($_SESSION['username']);
if($Status)
{
header('Location: /cp/'.$_SESSION['username'].'/services/');
}
else
{
$Smarty->assign('InstallStatus', 'Database Error Occured');
$Smarty->display('steaminstall.tpl');
}
}
if($Error === 2)
{
$Smarty->assign('InstallStatus', $Output);
$Smarty->display('steaminstall.tpl');
}
}
And this is my database query function
public function SteamStatus($Username)
{
$Status = '1';
$Statement = $this->DBConnection->prepare("UPDATE account set steaminstalled = ? where username = ?");
$Statement->bindParam(1, $Status);
$Statement->bindParam(2, $Username);
$IStatus = $Statement->execute();
if($IStatus)
{
return true;
}
else
{
return false;
}
}
Problem solved, you just need to specify direct path to your script (as if you dont, the script itself dont know where to download and where to extract)
So the final bash script (PHP part is perfectly fine):
#!/bin/bash
wget -P /var/www/aftersoft/data/Servers/Steam/ http://media.steampowered.com/client/steamcmd_linux.tar.gz &&
tar xvfz /var/www/aftersoft/data/Servers/Steam/steamcmd_linux.tar.gz -C /var/www/aftersoft/data/Servers/Steam/ &&
sh /var/www/aftersoft/data/Servers/Steam/steamcmd.sh +login anonymous +quit &&
rm /var/www/aftersoft/data/Servers/Steam/steamcmd_linux.tar.gz &&
echo "Steam Installation and Update Completed"

Call a PERL script which connect to a host with SSH

I've created a Perl script which connects to a host and executes some commands, and it works fine! I'm kinf of proud 'cause I'm a real newb with Perl ^^...
A overview of the perl script:
use Expect;
$|=0;
$Expect::Debug=0;
$Expect::Exp_Internal=0;
$Expect::Log_Stdout=1;
my $ip = $ARGV[0];
my $file = $ARGV[1];
my $username = $ARGV[2];
my $password = $ARGV[3];
open(CONF,$file) || die "File not found";
while(<CONF>){
$con .= $_;
}
my #conf = split("#",$con);
my $ssh = Expect->spawn("ssh -q -l $username $ip") || die "Spawn ssh failed, $!";
if($ssh->expect(5,"yes")) {
print $ssh "yes\r";
if($ssh->expect(10,"assword")) {
print $ssh "$password\r";
}
else {
warn $ssh->exp_error()."\n";
next;
}
}
elsif($ssh->expect(10,"assword")) {
print $ssh "$password\r";
}
else {
warn $ssh->exp_error()."\n";
next;
}
#Variables Globales
my $rcmd;
my #lcmd;
my $lrcmd;
$regExpCmd = "\#";
$regExpCmd2 = "^(A|B).*(\$|\#)";
$regExp = "\n";
$ssh->expect(10,$regExpCmd);
my $cmd0 = "environment no more\r";
my $cmdExit = "logout\r";
$ssh->send($cmd0);
$ssh->expect(5,$regExpCmd);
foreach my $step (#conf) {
my #lines = split("\n",$step);
foreach my $val (#lines){
$val =~ s/^\s+//;
$val =~ s/\r//;
$ssh->send("$val\r");
$i *= 1;
if(!$ssh->expect(2,$regExpCmd2)){
$i *= 0;
# if($ssh->expect(1,"MINOR")){
# die "Erreur mineur: $val";}
if($ssh->expect(2,"Error")){
die "Erreur majeur: $val";
}
}
}
$ssh->expect(1,$regExpCmd2);
}
$ssh->send($cmdExit);
print $i;
Now, I'd like to call it from PHP...
I have tried different way:
Like calling my perl script with the exec() function :
<?php
$arg1 = "MY.ADD.IP";
$arg2 = "MY/FILE";
$arg3 = "USERNAME";
$arg4 = "PASSWORD";
$result = exec("perl /path/of/perl/script.pl $arg1 $arg2 $arg3 $arg4");
if($result == 1) {
return true: }
else {
return false;
} ?>
but it is not doing anything (Checked on the remote host and so SSH connexion at all)...
I also tried using the PECL Perl interpreter for PHP, calling my script like that:
<?php
$perl = new Perl();
$perl->require('myperl.pl'); ?>
but I didn't figure how to send some arg to my script..
The fact is that I need to call it with an jQuery $.ajax request and I need to wait for the end of the script before sending back any "answer" to jQuery.
Everything I tried did not work, as the PHP script ends "before" the Perl Script...
PS: I also tried to create a Package in PERL called with PHP, like below:
package Connect;
sub new{
#Init some var... }
sub connect {
#Something like the script above.....
}
<?php
$perl = new Perl();
$perl->require('myscript.pl');
$perl->call('connect',$args);
?>
Have you ever succeeded in something like that? I really don't know what to do :(
Why don't you use ssh from php? It looks like the ssh part would be easier than what you've done in perl, and you can still get the perl regexes using preg_ functions.
PHP.net ssh2 manual page
PHP.net preg_match manual page
phpseclib, a pure PHP SSH implementation, has something very similar to expect.
An example follows:
<?php
include('Net/SSH2.php');
$sftp = new Net_SSH2('www.domain.tld');
$sftp->login('username', 'password');
echo $sftp->read('username#username:~$');
$sftp->write("sudo ls -la\n");
$output = $sftp->read('#Password:|username#username:~\$#', NET_SSH2_READ_REGEX);
echo $output;
if (preg_match('#Password:#', $lines)) {
$ssh->write("password\n");
echo $sftp->read('username#username:~$');
}
?>
It does "sudo ls -la" and waits for either "Password:" or "username#username:~".

Categories