NotionCommotion Posted April 26, 2017 Share Posted April 26, 2017 The first nc command goes to the server (but is invalid without the prefix), however, the second does not. What should I change? Thanks <?php $dest="12.34.56.789 1337"; $cmd="echo 'testing' | nc $dest"; $response=shell_exec($cmd); echo('$response: '.$response.'<br>'); $original_message='{"method": "test", "id": 5}'; echo('$original_message: '.$original_message.'<br>'); $new_message=pack("V", strlen($original_message)).$original_message; echo('$new_message: '.$new_message.'<br>'); $cmd="echo '$new_message' | nc $dest"; echo('$cmd: '.$cmd.'<br>'); $response=shell_exec($cmd); echo('$response: '.$response.'<br>'); $new_response=substr($response, 4); echo('$original_message: '.$new_response.'<br>'); Quote Link to comment Share on other sites More sharing options...
requinix Posted April 26, 2017 Share Posted April 26, 2017 Binary data as an argument to a shell command is just crazy. exec and siblings are just for simple situations. Use the proc_* functions to get the kind of support you need: an actual stdin you can write to. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 26, 2017 Author Share Posted April 26, 2017 (edited) Yeah, I suppose it was crazy! Would proc_open be the one to use? The server is now receiving the data, but my attempt to concatenate the binary length with the message evidently is not the way to do it. <?php $dest="12.34.56.789 1337"; $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to ); $process = proc_open("nc $dest", $descriptorspec, $pipes); if (is_resource($process)) { // $pipes now looks like this: // 0 => writeable handle connected to child stdin // 1 => readable handle connected to child stdout // Any error output will be appended to /tmp/error-output.txt $msg='{"method": "test", "id": 5}'; $lng=pack("V", strlen($msg)); $in=$lng.$msg; fwrite($pipes[0], $in); fclose($pipes[0]); $out=stream_get_contents($pipes[1]); fclose($pipes[1]); // It is important that you close any pipes before calling // proc_close in order to avoid a deadlock $return_value = proc_close($process); echo "command returned ".substr($return_value, 4, strlen($return_value)); } Edited April 26, 2017 by NotionCommotion Quote Link to comment Share on other sites More sharing options...
requinix Posted April 26, 2017 Share Posted April 26, 2017 Looks right. But does it work? And any reason you're using nc? PHP can do raw TCP too.. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 26, 2017 Author Share Posted April 26, 2017 (edited) Looks right. But does it work? And any reason you're using nc? PHP can do raw TCP too.. No, syslog shows receiving #033. If I change the message to$msg='{"method": "test", "id": 5, "bla":" hello"}';, I now receive * at the server. $this->socket->on('data', function($data){ syslog(LOG_INFO,$data); }); Also, no reason I am using nc other than grasping for straws. Maybe I am way off base. My intent is to test my reactphp server. If I send just text, I see it come over, but without the length prefix. When I add the prefix, I just get the #033. Edited April 26, 2017 by NotionCommotion Quote Link to comment Share on other sites More sharing options...
requinix Posted April 26, 2017 Share Posted April 26, 2017 Binary data might not work so well with nc either... Try PHP. $msg='{"method": "test", "id": 5}'; $lng=pack("V", strlen($msg)); $in=$lng.$msg; $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); for ($buf = $in, $off = 0, $len = strlen($in); $off < $len; ) { $sent = socket_sendto($sock, substr($buf, $off), $len - $off, MSG_EOF, "12.34.56.789", 1337); if (!$sent) { echo "error sending\n"; break; } $off += $sent; } socket_close($sock); Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 26, 2017 Author Share Posted April 26, 2017 With the opening php tag, line 7 is one from the last. Warning: socket_sendto(): unable to write to socket [32]: Broken pipe in /var/www/html/test2.php on line 7 Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 26, 2017 Author Share Posted April 26, 2017 I didn't notice you script changed. Same results, but now line 8. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 26, 2017 Author Share Posted April 26, 2017 Tried the following, and didn't get the broken pipe warning, but still same as nc results. Got out wireshark, and saw that the data was right. Then saw that I made a stupid mistake. Sorry for wasting your time. <?php $fp = fsockopen("12.34.56.789", 1337, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $msg='some text'; $lng=pack("V", strlen($msg)); $out=$lng.$msg; fwrite($fp, $out); while (!feof($fp)) { echo fgets($fp, 128); } fclose($fp); } echo('done'); 1 Quote Link to comment Share on other sites More sharing options...
requinix Posted April 27, 2017 Share Posted April 27, 2017 ...derp. fsockopen is totally the way to go. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.