[ Undefined subroutine]: Net::Frame::Dump::Online: Must be EUID 0 - perl

I am new using Perl language, and I am following a book to begin with some advanced scanning network (as that's why I am learning Perl for)
so the program looks like that:
#!/usr/bin/perl -w
use strict;
use Net::Pcap qw( :functions );
use Net::Frame::Device;
use Net::Netmask;
use Net::Frame::Dump::Online;
use Net::ARP;
use Net::Frame::Simple;
my $err = "";
my $dev = pcap_lookupdev(\$err); # from Net::Pcap
my $devProp = Net::Frame::Device->new(dev => $dev);
my $ip = $devProp->ip;
my $gateway = $devProp->gatewayIp;
my $netmask = new Net::Netmask($devProp->subnet);
my $mac = $devProp->mac;
my $netblock = $ip . ":" . $netmask->mask();
my $filterStr = "arp and dst host ".$ip;
my $pcap = Net::Frame::Dump::Online->new(
dev => $dev,
filter => $filterStr,
promisc => 0,
unlinkOnStop => 1,
timeoutOnNext => 10 # waiting for ARP responses
);
$pcap->start;
print "Gateway IP: ",$gateway,"\n","Starting scan\n";
for my $ipts ($netmask->enumerate){
Net::ARP::send_packet(
$dev,
$ip,
$ipts,
$mac,
"ff:ff:ff:ff:ff:ff", # broadcast
"request");
}
until ($pcap->timeout){
if (my $next = $pcap->next){ # frame according to $filterStr
my $fref = Net::Frame::Simple->newFromDump($next);
# we don’t have to worry about the operation codes 1, or 2
# because of the $filterStr
print $fref->ref->{ARP}->srcIp," is alive\n";
}
}
END{ print "Exiting\n"; $pcap->stop; }
However, when I run ./script.pl I am getting this error:
Undefined subroutine &main::pcap_lookupdev called at ./scan_ARP.pl line 13.
Exiting
Can't call method "stop" on an undefined value at ./scan_ARP.pl line 48.
END failed--call queue aborted.
and as mentionned in the book, I can replace my $dev = pcap_lookupdev(\$err); directly with my $dev = "wlp0s20f3" (wlp0s20f3; is the name of my network interface), but when I do that, I get:
[-]: Net::Frame::Dump::Online: Must be EUID 0 (or equivalent) to open a device for live capture
Exiting
Can't kill a non-numeric process ID at /usr/share/perl5/Net/Frame/Dump/Online.pm line 363.
END failed--call queue aborted.

So I found out that to solve the problem, I have to run the script as a root.

Related

perl mismatched tag, problem = XML::Simple module?

when i try to run this script to send my ip to cpanel...
#!/usr/bin/perl
# -------------------------------------------------------------------------------
# dns_update_script.pl
#
# Version 1.0 - 16.01.2012
#
# PERL script to dynamically update the IP of a host via the cPanel-API. This
# script was written to work with the Finnish hoster Neobitti but it might work
# with other hosters which use cPanel too.
#
# Copyright (C) 2012 Stefan Gofferje - http://stefan.gofferje.net/
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# -------------------------------------------------------------------------------
use strict;
use LWP::UserAgent;
use MIME::Base64;
use XML::Simple;
use Data::Dumper;
# --- Command line parameters ------------------------------------------------
my $param_domain=$ARGV[0];
my $param_host=$ARGV[1];
my $param_ip=$ARGV[2];
# --- cPanel information -----------------------------------------------------
# Storing passwords in clear text is ugly!
my $cpanel_domain = "yourdomain.com";
my $user = "yourcpaneluser";
my $pass = "yourcpanelpassword";
my $auth = "Basic " . MIME::Base64::encode( $user . ":" . $pass );
# --- Deactivate SSL certificate validation ----------------------------------
# This is ugly but neccessary because Neobitti uses self-signed SSL
# certificates which will fail validation
my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
# --- Find out the linenumber for the A-record we want to change -------------
sub getlinenumber_a {
my $domain=$_[0];
my $hostname=$_[1].".";
my $xml = new XML::Simple;
my $request = HTTP::Request->new( GET => "https://$cpanel_domain:2083/xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&cpanel_xmlapi_func=fetchzon
e&domain=$domain" );
$request->header( Authorization => $auth );
my $response = $ua->request($request);
my $zone = $xml->XMLin($response->content);
my $linenumber="";
if ($zone->{'data'}->{'status'} eq "1") {
my $count = #{$zone->{'data'}->{'record'}};
my $oldip="";
for (my $item=0;$item<=$count;$item++) {
my $name=$zone->{'data'}->{'record'}[$item]->{'name'};
my $type=$zone->{'data'}->{'record'}[$item]->{'type'};
if ( ($name eq $hostname) && ($type eq "A") ) {
$linenumber=$zone->{'data'}->{'record'}[$item]->{'Line'};
$oldip=$zone->{'data'}->{'record'}[$item]->{'record'};
print "Found $hostname in line $linenumber with IP $oldip.\n"; # DEBUG
}
}
} else {
$linenumber="0";
print $zone->{'event'}->{'data'}->{'statusmsg;'}
}
return($linenumber);
}
# --- Change the IP address record for a certain linenumber ------------------
sub setip {
my $domain=$_[0];
my $linenumber=$_[1];
my $newip=$_[2];
my $result="";
my $xml = new XML::Simple;
my $request = HTTP::Request->new( GET => "https://$cpanel_domain:2083/xml-api/cpanel?cpanel_xmlapi_module=ZoneEdit&cpanel_xmlapi_func=edit_zone_record&domain=$domain&line=$linenumber&address=$newip" );
$request->header( Authorization => $auth );
my $response = $ua->request($request);
my $reply = $xml->XMLin($response->content);
if ($reply->{'data'}->{'status'} eq "1") {
$result="1";
} else {
$result=$reply->{'data'}->{'statusmsg'};
}
return($result);
}
# --- Main procedure ---------------------------------------------------------
print "Trying to find the linenumber for $param_host in $param_domain...\n";
my $line=getlinenumber_a($param_domain,$param_host);
if ( ($line ne "0") && ($line ne "") ) {
print "Trying to update IP...\n";
my $result=setip ($param_domain,$line,$param_ip);
if ($result eq "1") {
print "Update successful!\n";
} else {
print "$result\n";
}
} else {
print "Error - check domain and hostname!\n";
}
... I get this error:
mismatched tag at line 37, column 2, byte 4634 at /usr/lib/arm-linux-gnueabihf/perl5/5.28/XML/Parser.pm line 187.
XML::Simple called at dns_update_script.pl line 55.
in the cPanel information section I have filled in my cpanel username, password and domain in my file (not this one). I have filled this in in open text like a noob and ignored this thing:
my $auth = "Basic " . MIME::Base64::encode( $user . ":" . $pass );
but i dont think this is the problem.
I think the problem is in the XML::Simple module because the script stops when that module is called it seems like to me but idk. pls help.
You are getting that error because the string you pass to XMLin isn't valid XML. You will need to fix the input to be valid XML.
While I strongly recommend against using XML::Simple, it's not because of problems parsing XML. The underlying parser used in this situation (expat via XML::Parser) isn't known for wrongly claiming valid XML is invalid.
Your program should be checking if the request is successful ($response->is_success). I suspect you are getting some kind of error (e.g. 403 Forbidden). $response->status_line is useful to add to your error message.
(If the request is successful, perhaps you should print out $response->as_string to examine the response to get a better idea of what is happening.)
I just used this shell script instead and hooked it up to my crontab and now it runs the script every hour and it works fine.
https://github.com/CpanelInc/cpanel-dynamicdns-tools
for my raspberry pi web server

Sybase Warning messages from perl DBI

I am connecting to sybase 12 from a perl script and calling storedprocs, I get the following warnings
DBD::Sybase::db prepare failed: Server message number=2401 severity=11 state=2 line=0 server=SERVER_NAME text=Character
set conversion is not available between client character set 'utf8' and server character set 'iso_1'.
Server message number=2411 severity=10 state=1 line=0 server=SERVER_NAME text=No conversions will be done.
at line 210.
Now, I understand these are only warnings, and my process works perfectly fine, but I am calling my stored proc in a loop and throughout the day and hence it creates a lot of warning message in my log files which causes the entire process to run a bit slower than expected. Can someone help me how can i suppress these please?
You can use a callback to handle the messages you want ignored. See the DBD::Sybase docs. The below is derived from the docs. You specify the message numbers you would like to ignore.
%blocked_msgs = map { $_ => 1 } ( 2401, 2411 );
sub err_handler {
my($err, $sev, $state, $line, $server, $proc, $msg, $sql, $err_type) = #_;
if ( exists $blocked_msgs{$err} ) { # it's a blocked message
return 0; # This is not an error
}
return 1;
}
This is how you might use it:
$dbh = DBI->connect('dbi:Sybase:server=troll', 'sa', '');
$dbh->{syb_err_handler} = \&err_handler;
$dbh->do("exec someproc");
$dbh->disconnect;

Examples from Net::RabbitMQ not working

I'm trying to learn RabbitMQ for a project I'm working on. My research showed two libraries to use, Net::RabbitMQ and AnyEvent::RabbitMQ. AnyEvent::RabbitMQ seems overly baroque for my needs but Net::RabbitMQ does not appear to work as the examples show it should.
Below is some example code I found, it matches what I saw in the POD, but it isn't working.
#!/usr/bin/env perl
use strict;
use warnings;
use Net::RabbitMQ;
{
# closure to return a new channel ID every time we call nextchan
my $nextchan = 1;
sub nextchan { return $nextchan++ }
}
### BEGIN CONFIGURABLE PARAMETERS ######################################
my $qserver = q{xx.xx.xx.xx};
my %qparms = ();
my $qname = q{gravity.checks};
my $message = q{Test injection};
### NO CONFIGURABLE PARAMETERS BELOW THIS LINE #########################
my $mq = Net::RabbitMQ->new();
my $chanID = nextchan();
$message .= " " . scalar(localtime);
print STDERR qq{Will try to send message "$message" through channel $chanID};
$mq->connect( $qserver, %qparms );
It errors out :
$. / send . pl
Will try to send message "Test injection Fri Nov 14 06:50:44 2014" through channel 1 Usage : Net::RabbitMQ::connect( conn, hostname, options ) at . /send.pl line 28.
The problem is that the %qparams need to be passed by reference and not directly. The change line 28 to :
$mq->connect($qserver, \%qparms) ;
Solved my problem.
It doesn't error out. It prints to STDERR without checking if an error occured. It says I'll try and then it does:
$mq->connect( $qserver, %qparms );
This is just an information, not an error.

Perl SSH connection to execute telnet

I tried the following to access a router via a central admin server as "ssh hop" server
#!/usr/bin/perl -X
use strict;
use Net::OpenSSH;
use Net::Telnet;
my $lhost = "linuxserver";
my $luser = "linuxuser";
my $lpass = "linuxpassword";
my $chost = "routername";
my $cpass = "Routerpassword";
my $prompt = '/(?:Password: |[>])/m';
my #commands = ("show users\r");
my $ssh = Net::OpenSSH->new($lhost,
'user' => $luser,
'password' => $lpass,
'master_opts' => [ '-t' ],
#'async' => 1 # if enabled then password cannot be set here
);
my ($pty, $err, $pid) = $ssh->open2pty("telnet $chost");
my $t = new Net::Telnet(
-telnetmode => 0,
-fhopen => $pty,
-prompt => $prompt,
-cmd_remove_mode => 1,
-output_record_separator => "\r",
#-dump_log => "debug.log",
);
my $end = 0;
while (!$end) {
my ($pre, $post) = $t->waitfor($prompt);
if ($post =~ /Password: /m) {
# send password
$t->print("$cpass");
}
elsif ($post =~ /[>#]/ && #commands) {
my $cmd = shift(#commands);
if ($cmd !~ /[\r\n]/) {
$t->print($cmd);
}
else {
print $t->cmd($cmd);
}
}
else {
$end = 1;
$t->cmd("exit");
}
}
#close $pty;
$t->close();
Unfortunately I always get the following error:
read error: Input/output error at test.pl line 71
Can somebody help me please or is there a better solution only to test if a telnet connection via the "hop" server is possible or not?
The connection looks like:
workstation --ssh-> server --telnet-> router
Thanks in advance.
I think best option is to make an SSH-tunnel to your admin server and use it for telnetting to the router.
Getting Net::Telnet to work over Net::OpenSSH sometimes is not as easy as it should be and it requires some experimentation to get to the right combination of flags and calls that make it work.
For instance, instead of telneting to the target host, use netcat to open a raw connection (or Net::OpenSSH support for TCP forwarding if tunnels are allowed on the proxy).
Expect + Net::OpenSSH may be a better option.

Why does Perl's Net::Msmgr hang when I try to authenticate?

There's Net::Msmgr module on CPAN. It's written clean and the code looks trustworthy at the first glance. However this module seems to be beta and there is little documentation and no tests :-/
Has anyone used this module in production? I haven't managed to make it run by now, because it requires all event loop processing to be done in the application and as I've already said there is little documentation and no working examples to study.
That's where I've gone so far:
#!/usr/bin/perl
use strict;
use warnings;
use Event;
use Net::Msmgr::Object;
use Net::Msmgr::Session;
use Net::Msmgr::User;
use constant DEBUG => 511;
use constant EVENT_TIMEOUT => 5; # seconds
my ($username, $password) = qw/my.username#live.com my.password/;
my $buddy = 'your.username#live.com';
my $user = Net::Msmgr::User->new(user => $username, password => $password);
my $session = Net::Msmgr::Session->new;
$session->debug(DEBUG);
$session->login_handler(\&login_handler);
$session->user($user);
my $conv;
sub login_handler {
my $self = shift;
print "LOGIN\n";
$self->ui_state_nln;
$conv = $session->ui_new_conversation;
$conv->invite($buddy);
}
our %watcher;
sub ConnectHandler {
my ($connection) = #_;
warn "CONNECT\n";
my $socket = $connection->socket;
$watcher{$connection} = Event->io(fd => $socket,
cb => [ $connection, '_recv_message' ],
poll => 're',
desc => 'recv_watcher',
repeat => 1);
}
sub DisconnectHandler {
my $connection = shift;
print "DISCONNECT\n";
$watcher{$connection}->cancel;
}
$session->connect_handler(\&ConnectHandler);
$session->disconnect_handler(\&DisconnectHandler);
$session->Login;
Event::loop();
That's what it outputs:
Dispatch Server connecting to: messenger.hotmail.com:1863
Dispatch Server connected
CONNECT
Dispatch Server >>>VER 1 MSNP2 CVR0
--> VER 1 MSNP2 CVR0
Dispatch Server >>>USR 2 MD5 I my.username#live.com
--> USR 2 MD5 I my.username#live.com
Dispatch Server <<<VER 1 CVR0
<-- VER 1 CVR0
And that's all, here it hangs. The handler on login is not being triggered. What am I doing wrong?
Hope these documents will help you out
1) Net::Msmgr documentation
2) Net::Msmgr::Session