Network Monitor: Don't Show Same Line Immediately Twice [duplicate] - macos

I am writing a network monitoring script in bash. The base command I am using is ettercap -T -M ARP -i en1 // //. Then I pipe egrep --color 'Host:|GET' into it.
A sample output I am getting looks like this:
GET /images/srpr/logo11w.png HTTP/1.1.
Host: www.google.com.
GET /en-us/us/products HTTP/1.1.
Host: www.caselogic.com.
My desired output is this:
Title: logo11w.png
URL: www.google.com/images/srpr/logo11w.png HTTP/1.1.
Title: Products - Case Logic
URL: www.caselogic.com/en-us/us/products
Things to notice: HTTP/1.1. and the . at the end of the host are gone. They also are formed into one URL and there is a blank line after each Title/URL listing. I attempted forming them into one URL by parsing the commands output into a variable with
var=`sudo ettercap -T -M ARP -i en1 // // | egrep --color 'Host:|GET'` | echo $var
but obviously that doesn't work because the input to the variable is a command the isn't done until the user requests a stop (CTRL + C).
To get the title of an HTML page, I use the command wget -qO- 'https://url.goes/here' | perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'. If it is something that doesn't have a title, such as an image, no title is fine.
Any help is greatly appreciated, and sorry if what I wrote is hard to read, feel free to ask questions.

Try this:
title_host.pl
#!/usr/bin/env perl
use warnings;
use strict;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new();
my ($get,$host,$title);
while (<>) {
if (m|^GET (\S+) |) {
$get = $1;
} elsif ( m|^Host: (\S+)\.| ) {
$host = $1;
} else {
# Unrecognized line...reset
$get = $host = $title = '';
}
if ($get and $host) {
my ($title) = $get =~ m|^.*\/(.+?)$|; # default title
my $url = 'http://' . $host . $get;
$mech->get($url);
if ($mech->success) {
# HTML may have title, images will not
$title = $mech->title() || $title;
}
print "Title: $title\n";
print "URL: $url\n";
print "\n";
$get = $host = $title = '';
}
}
input
GET /images/srpr/logo11w.png HTTP/1.1.
Host: www.google.com.
GET /en-us/us/products HTTP/1.1.
Host: www.caselogic.com.
now just pipe your input into the perl script:
cat input | perl title_host.pl
output:
Title: logo11w.png
URL: http://www.google.com/images/srpr/logo11w.png
Title: Products - Case Logic
URL: https://www.caselogic.com/en-us/us/products

Related

Include a perl variable inside a bash command in a perl script

For example:
#!/usr/bin/perl
...
my $host = $db_conf->{host};
my #cmd = ('date',$host);
system(#cmd);
So the results i am expecting is:
Fri Aug 11 15:41:28 CST 2017 db-test-1
With db-test-1 being the hostname.
Here is my entire code:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use DBI;
use Encode;
use IO::File;
use JSON;
use utf8;
BEGIN {
binmode STDERR, ':utf8';
binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
}
INIT {
my #databases = </kkcorp/kksecret/db-*/db.json>;
foreach my $filename (#databases) {
my $fh = IO::File->new($filename, 'r') or croak $!;
my #buf = <$fh>;
my $str = join '', #buf;
$fh->close;
my $db_conf = decode_json $str;
my $entry = int(rand(scalar(#{$db_conf})));
$db_conf = $db_conf->[$entry]->{writer}->{params};
my $host = $db_conf->{host};
my $dbname = $db_conf->{dbname};
my $password = $db_conf->{password};
my $username = $db_conf->{username};
my $wsrep_check = `mysql -h $host -u $username -p$password < /authdir/auto_inc_script.sql`;
$hosti
if (index($wsrep_check, 'Value: Synced') != -1) {
my #cmd = ('date ${host}');
system(#cmd);
my #wsrep_check_lines = split /\n/, $wsrep_check;
my #table_name = grep { /Synced/ } #wsrep_check_lines;
for my $line (#table_name){
say STDERR $line;
}
say '';
}
}
}
__END__
So what i am trying to achieve in in the two statements right after the beginning of the "if" statement. The code runs fine, but ignored the ${host} variable without displaying any output for it.
Below is my results:
Fri Aug 11 17:13:19 CST 2017
ok Value: Synced
Fri Aug 11 17:13:20 CST 2017
ok Value: Synced
system is very powerful but also very dangerous. It is easy to make disasters, consider, if you feed it with an rm, better if you make absolutely clear what parameters rm gets before running system.
For this reason I always follow this practice:
create the commad string
print the command string
check if print representation is what i want to send to the shell
add the system part
Here is an example, from the command line:
perl -e ' $var = "Hello"; $cmd = qq(echo $var); print "The command: $cmd \n";'
Next, add system:
perl -e ' $var = "Hello"; $cmd = qq(echo $var); print "the command: $cmd \n"; system($cmd);'

Passing bash variable into inline perl script

Reference the 2nd to last line in my script. For some reason Perl is not able to access the variable $perlPort how can I fix this? Note: $perlPort is a bash variable location before my perl script
perl -e '
{
package MyWebServer;
use HTTP::Server::Simple::CGI;
use base qw(HTTP::Server::Simple::CGI);
my %dispatch = (
"/" => \&resp_hello,
);
sub handle_request {
my $self = shift;
my $cgi = shift;
my $path = $cgi->path_info();
my $handler = $dispatch{$path};
if (ref($handler) eq "CODE") {
print "HTTP/1.0 200 OK\r\n";
$handler->($cgi);
} else {
print "HTTP/1.0 404 Not found\r\n";
print $cgi->header,
$cgi->start_html("Not found"),
$cgi->h1("Not found"),
$cgi->end_html;
}
}
sub resp_hello {
my $cgi = shift; # CGI.pm object
return if !ref $cgi;
my $who = $cgi->param("name");
print $cgi->header,
$cgi->start_html("Hello"),
$cgi->h1("Hello Perl"),
$cgi->end_html;
}
}
my $pid = MyWebServer->new($perlPort)->background();
print "Use 'kill $pid' to stop server.\n";'
export perlPort
perl -e '
...
my $pid = MyWebServer->new($ENV{perlPort})->background();
'
You can use -s switch to pass variables. See http://perldoc.perl.org/perlrun.html
perl -se '
...
my $pid = MyWebBrowser->new($perlPort)->background();
...' -- -perlPort="$perlPort"
You can still pass command line arguments to your script. Replace $perlPort with $ARGV[0], then call you script as
perl -e $' ...
my $pid = MyWebServer->new($ARGV[0])->background();
print "Use \'kill $pid\' to stop server.\n";' "$perlPort"
Note the other problem: You can't include single quotes inside a single-quoted string in bash. You can work around this by using a $'...'-quoted string as the argument to Perl, which can contain escaped single quotes. If your script doesn't need to read from standard input, it would be a better idea to have perl read from a here-document instead.
perl <<'EOF' "$perlPort"
{
package MyWebServer;
use HTTP::Server::Simple::CGI;
...
my $pid = MyWebServer->new($ARGV[0])->background();
print "Use 'kill $pid' to stop server.\n";
EOF
The best idea is to simply use a script file instead of trying to construct the script on the command line.
perl -e '
...
my $pid = MyWebServer->new('$perlPort')->background();
...

Can't locate WWW/Mechanize.pm: Using cpanm doesn't work

I know this is a duplicate, but my question was not answered in any other threads. the output of sudo cpanm WWW::Mechanize is to long to put in tread. pastebin: 3BYUtSss
I tried executing a perl script, and I get this error:
Can't locate WWW/Mechanize.pm in #INC (#INC contains: /opt/local/lib/perl5/site_perl/5.16.3/darwin-thread-multi-2level /opt/local/lib/perl5/site_perl/5.16.3 /opt/local/lib/perl5/vendor_perl/5.16.3/darwin-thread-multi-2level /opt/local/lib/perl5/vendor_perl/5.16.3 /opt/local/lib/perl5/5.16.3/darwin-thread-multi-2level /opt/local/lib/perl5/5.16.3 /opt/local/lib/perl5/site_perl /opt/local/lib/perl5/vendor_perl .) at io.pl line 5.
In case you need it, here is my perl script's contents:
#!/usr/bin/env perl
use warnings;
use strict;
use WWW::Mechanize;
my $mech = WWW::Mechanize->new();
my ($get,$host,$title);
while (<>) {
if (m|^GET (\S+) |) {
$get = $1;
} elsif ( m|^Host: (\S+)\.| ) {
$host = $1;
} else {
# Unrecognized line...reset
$get = $host = $title = '';
}
if ($get and $host) {
my ($title) = $get =~ m|^.*\/(.+?)$|; # default title
my $url = 'http://' . $host . $get;
$mech->get($url);
if ($mech->success) {
# HTML may have title, images will not
$title = $mech->title() || $title;
}
print "Title: $title\n";
print "URL: $url\n";
print "\n";
$get = $host = $title = '';
}
}
These look to be the key lines in the output from cpanm, down at the bottom.
! Installing the dependencies failed: Installed version (3.59) of CGI is not in range '4.08'
! Bailing out the installation for WWW-Mechanize-1.75.
Looks like you need to install a higher version of the CGI distribution.
The key lines in the cpanm output are:
Building and testing CGI-4.21 ... FAIL
! Installing CGI failed. See /Users/skylerspaeth/.cpanm/work/1440436409.90704/build.log for details. Retry with --force to force install it.
So look in /Users/skylerspaeth/.cpanm/work/1440436409.90704/build.log and see what the problem is. If that log is no longer there, you may need to run cpanm again, which will generate another build.log.
You find the key lines in cpanm output by searching for "fail". Usually, it'll point you at a build.log file for further details.

Spider a website and retrieve all links that contain a keyword

How do I make a Bash script that will copy all links (non-download website). The function is only to get all the links and then save it in a txt file.
I've tried this code:
wget --spider --force-html -r -l1 http://somesite.com | grep 'Saving to:'
Example: there are download links within a website (for example, dlink.com), so I just want to copy all words that contain dlink.com and save it into a txt file.
I've searched around using Google, and I found none of it useful.
Using a proper parser in Perl:
#!/usr/bin/env perl -w
use strict;
use LWP::UserAgent;
use HTML::LinkExtor;
use URI::URL;
my $ua = LWP::UserAgent->new;
my ($url, $f, $p, $res);
if(#ARGV) {
$url = $ARGV[0]; }
else {
print "Enter an URL : ";
$url = <>;
chomp($url);
}
my #array = ();
sub callback {
my($tag, %attr) = #_;
return if $tag ne 'a'; # we only look closer at <a href ...>
push(#array, values %attr) if $attr{href} =~ /dlink\.com/i;
}
# Make the parser. Unfortunately, we don’t know the base yet
# (it might be diffent from $url)
$p = HTML::LinkExtor->new(\&callback);
# Request document and parse it as it arrives
$res = $ua->request(HTTP::Request->new(GET => $url),
sub {$p->parse($_[0])});
# Expand all URLs to absolute ones
my $base = $res->base;
#array = map { $_ = url($_, $base)->abs; } #array;
# Print them out
print join("\n", #array), "\n";

How can I check if stdin exists in PHP ( php-cgi )?

Setup and Background
I am working on script that needs to run as /usr/bin/php-cgi instead /usr/local/bin/php and I'm having trouble checking for stdin
If I use /usr/local/bin/php as the interpreter I can do something like
if defined('STDIN'){ ... }
This doesn't seem to work with php-cgi - Looks to always be undefined. I checked the man page for php-cgi but didn't find it very helpful. Also, if I understand it correctly, the STDIN constant is a file handle for php://stdin. I read somewhere that constant is not supposed to be available in php-cgi
Requirements
The shebang needs to be #!/usr/bin/php-cgi -q
The script will sometimes be passed arguments
The script will sometimes receive input via STDIN
Current Script
#!/usr/bin/php-cgi -q
<?php
$stdin = '';
$fh = fopen('php://stdin', 'r');
if($fh)
{
while ($line = fgets( $fh )) {
$stdin .= $line;
}
fclose($fh);
}
echo $stdin;
Problematic Behavior
This works OK:
$ echo hello | ./myscript.php
hello
This just hangs:
./myscript.php
These things don't work for me:
Checking defined('STDIN') // always returns false
Looking to see if CONTENT_LENGTH is defined
Checking variables and constants
I have added this to the script and run it both ways:
print_r(get_defined_constants());
print_r($GLOBALS);
print_r($_COOKIE);
print_r($_ENV);
print_r($_FILES);
print_r($_GET);
print_r($_POST);
print_r($_REQUEST);
print_r($_SERVER);
echo shell_exec('printenv');
I then diff'ed the output and it is the same.
I don't know any other way to check for / get stdin via php-cgi without locking up the script if it does not exist.
/usr/bin/php-cgi -v yields: PHP 5.4.17 (cgi-fcgi)
You can use the select function such as:
$stdin = '';
$fh = fopen('php://stdin', 'r');
$read = array($fh);
$write = NULL;
$except = NULL;
if ( stream_select( $read, $write, $except, 0 ) === 1 ) {
while ($line = fgets( $fh )) {
$stdin .= $line;
}
}
fclose($fh);
Regarding your specific problem of hanging when there is no input: php stream reads are blocking operations by default. You can change that behavior with stream_set_blocking(). Like so:
$fh = fopen('php://stdin', 'r');
stream_set_blocking($fh, false);
$stdin = fgets($fh);
echo "stdin: '$stdin'"; // immediately returns "stdin: ''"
Note that this solution does not work with that magic file handle STDIN.
stream_get_meta_data helped me :)
And as mentioned in the previous answer by Seth Battin stream_set_blocking($fh, false); works very well 👍
The next code reads data from the command line if provided and skips when it's not.
For example:
echo "x" | php render.php
and php render.php
In the first case, I provide some data from another stream (I really need to see the changed files from git, something like git status | php render.php.
Here is an example of my solution which works:
$input = [];
$fp = fopen('php://stdin', 'r+');
$info = stream_get_meta_data($fp);
if (!$info['seekable'] && $fp) {
while (false !== ($line = fgets($fp))) {
$input[] = trim($line);
}
fclose($fp);
}
The problem is that you create a endless loop with the while($line = fgets($fh)) part in your code.
$stdin = '';
$fh = fopen('php://stdin','r');
if($fh) {
// read *one* line from stdin upto "\r\n"
$stdin = fgets($fh);
fclose($fh);
}
echo $stdin;
The above would work if you're passing arguments like echo foo=bar | ./myscript.php and will read a single line when you call it like ./myscript.php
If you like to read more lines and keep your original code you can send a quit signal CTRL + D
To get parameters passed like ./myscript.php foo=bar you could check the contents of the $argv variable, in which the first argument always is the name of the executing script:
./myscript.php foo=bar
// File: myscript.php
$stdin = '';
for($i = 1; $i < count($argv); i++) {
$stdin .= $argv[$i];
}
I'm not sure that this solves anything but perhaps it give you some ideas.

Resources