LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-16-2021, 04:53 PM   #1
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
Question PERL: Not a HASH reference at /usr/local/bin/vt.pl line 169.


hello all.

one prog that i am making has a bug in it.

it dies with error message :
Code:
Not a HASH reference at /usr/local/bin/vt.pl line 169.
https://i.ibb.co/smFvx9x/vt.png

this program sends to virustotal.com suricata's filestore files that could be malicious. it uses vt api v2.


it dies when it tries to get reply from virustotal.com
"Your resource is queued for analysis." <-- after that message.
the whole code of it is here :
Code:
#!/usr/bin/perl
# vt.pl
use warnings;
use strict;
use File::Find;
use File::Remove 'remove';
use LWP::UserAgent;
use JSON;
use Term::ANSIColor qw(:constants); # for colorful output
use Getopt::Std;                    # for options
use Data::Dumper;

use vars qw( @fullpaths $duration $end_time $time $deletefile $filepath $ua $url $key $key1 $key2 $key3 $response $result $results $json $decjson $sha $num );

use vars qw( $opt_h );
getopts('h');

if ($opt_h) {
print q(
       -h Usage. just start the program with perl /usr/local/bin/vt.pl
       
/);
exit(0);
};

my $path = "/var/log/suricata/filestore/";

find( \&pathfinder , "$path" );

# main function.
sub pathfinder {
	
$path = $_[0];
	
	if ( $File::Find::dir =~ '/[0-f]{2}$' || length($_) =~ 64 ) {
		
		push(@fullpaths, ($File::Find::name));
		
	}		
	
	foreach $filepath (@fullpaths) {
		# delete foo.json files
		if ($filepath =~ /((.*)\.json$)/) {
		
			pop(@fullpaths);
			deleter($filepath);
		
		} else {
			
			if ($filepath =~ //) {
			
				print '		Pathfinder() : No files to upload.\n';
				exit(0);
			}
			
			print BLUE, '		Pathfinder() : Countdown to feed Uploadtovt() with file_sha256 path -> Uploadtovt().', RESET;
			countdown(15); print "\n";
			
			uploadtovt($filepath); 
			pop(@fullpaths);
			
		}
	}
}

sub countdown($) {
    
	($duration) = @_;
	$end_time = time + $duration;
	$time = time;
	while ($time < $end_time) {
		$time = time;
		printf("\r%02d:%02d:%02d", ($end_time - $time) / (60*60), ($end_time - $time) / (60) % 60,($end_time - $time) % 60);
		$|++;
		sleep 1;
    }
}

# deletes sha256 file from filestore.
sub deleter {
	
$deletefile = $_[0];

if ($deletefile =~ /((.*)\.json$)/) {
	
	remove("$1");
	
	#print RED, " DEL json ", RESET, YELLOW, "$deletefile", RESET, "\n";
	#print "---------------------------------------------------------------------------------------------------------------\n";

	}
	
	elsif ($deletefile =~ /((.*)[a-z0-9]{64}$)/) {
		
		remove("$1");
		
		print RED, " DEL sha256 : ", RESET, YELLOW, "$deletefile", RESET, "\n";
		print "---------------------------------------------------------------------------------------------------------------\n";

	}
}
# uploads sha256 file to virustotal.
sub uploadtovt {
	
$filepath       = $_[0];

	$ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
	$url='https://www.virustotal.com/vtapi/v2/file/scan';
	$key='<your api key here>';

	$response = $ua->post( $url,
	Content_Type => 'multipart/form-data',
	Content => ['apikey' => $key,
	'file' => ["$filepath"]]
	);
	die "$url error: ", $response->status_line
	unless $response->is_success;
	$results = $response->content;

	print BLUE, '		Uploadtovt() : Countdown to send file_sha256 to Virustotal -> Downloader().', RESET;
	countdown(5); print "\n";
	
	downloader($key, $sha);

}

# downloads report of sha256 file.
sub downloader {

$key = $_[0];
$sha = $_[1];
$num = $_[2];
	
	$ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
	$key='ee6e69074a21711e1125bbe678b595e40b2cc82ff3f82cd923a9100f7d50e77b';
	$url='https://www.virustotal.com/vtapi/v2/file/report';
	
	if (defined $num) {
		
		print BLUE, '		Downloader() : Second try - Countdown to pull results of file_sha256 from Virustotal -> Printer().', RESET;
		countdown(30); print "\n";
		
	} else {
		
		print BLUE, '		Downloader() : Countdown to pull results of file_sha256 from Virustotal -> Printer().', RESET;
		countdown(45); print "\n";
		
	}
	
	#pulls the sha256 value out of the JSON response
	#Note: there are many other values that could also be pulled out
	$json = JSON->new->allow_nonref;   
	$decjson = $json->decode( $results);
	$sha = $decjson->{"sha256"};
	#print "	$sha", "\n\n";

	$response = $ua->post( $url,
	['apikey' => $key,
	'resource' => $sha]
	);
	die "$url error: ", $response->status_line
	unless $response->is_success;
	$results=$response->content;
	
	#processes the JSON
	$json = JSON->new->allow_nonref;   
	$decjson = $json->decode($results);
	
	printer($decjson->{'verbose_msg'},$decjson->{'scan_date'},$decjson->{'positives'},$decjson->{'total'},$filepath,$results,$sha,$key);
	
}
# prints information about file_sha256.
sub printer {

$decjson->{'verbose_msg'} = $_[0];
$decjson->{'scan_date'}   = $_[1];
$decjson->{'positives'}   = $_[2];
$decjson->{'total'}       = $_[3];
$filepath                 = $_[4];
$results                  = $_[5];
$sha                      = $_[6];
$key                      = $_[7];
$num = '1';

if ($results =~ /"Your resource is queued for analysis"/i) {
	# if queued go to Downloader.
    print YELLOW,"		", $decjson->{'verbose_msg'},".", RESET; print "\n";
    print BLUE,'		Printer() : Waiting for results from Virustotal -> Downloader().', RESET; print "\n";
	downloader($key, $sha, $num);
    
} else {
	
		if ($results =~ /"Scan finished, information embedded"/i) {
			print "---------------------------------------------------------------------------------------------------------------\n";
			# print selected values from the json file
			print YELLOW, " Sample name: ". $filepath. RESET"\n";
			print YELLOW, " Scan Date:  ".$decjson->{"scan_date"}. RESET"\n";
			print RED, " Detection rate: ", RESET, WHITE, $decjson->{"positives"}, RESET, "/", RED, $decjson->{"total"}, RESET, "\n";
			deleter($filepath);
		}
	}	
}
i know i am asking kinda a lot, but if someone could give some instructions how to solve this i would be grateful.

thanks.

Last edited by //////; 02-16-2021 at 04:55 PM.
 
Old 02-16-2021, 08:42 PM   #2
rnturn
Senior Member
 
Registered: Jan 2003
Location: Illinois (SW Chicago 'burbs)
Distribution: openSUSE, Raspbian, Slackware. Previous: MacOS, Red Hat, Coherent, Consensys SVR4.2, Tru64, Solaris
Posts: 2,818

Rep: Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550Reputation: 550
Quote:
Originally Posted by ////// View Post
hello all.

one prog that i am making has a bug in it.

it dies with error message :
Code:
Not a HASH reference at /usr/local/bin/vt.pl line 169.
https://i.ibb.co/smFvx9x/vt.png

this program sends to virustotal.com suricata's filestore files that could be malicious. it uses vt api v2.


it dies when it tries to get reply from virustotal.com
"Your resource is queued for analysis." <-- after that message.
the whole code of it is here :
Code:
#!/usr/bin/perl
# vt.pl
use warnings;
use strict;
use File::Find;
use File::Remove 'remove';
use LWP::UserAgent;
use JSON;
use Term::ANSIColor qw(:constants); # for colorful output
use Getopt::Std;                    # for options
use Data::Dumper;

use vars qw( @fullpaths $duration $end_time $time $deletefile $filepath $ua $url $key $key1 $key2 $key3 $response $result $results $json $decjson $sha $num );

<snip>
i know i am asking kinda a lot, but if someone could give some instructions how to solve this i would be grateful.

thanks.
If anyone's going to be able to find a bug in your source code, it'd be a big help if you could repost the code with line numbers:
Code:
$ cat -n vt.pl > vt.pl.numbered
$ cat vt.pl.numbered
and cut-n-paste the contents of "vt.pl.numbered" in the code tags. Note: I pasted your code into Kate, though, so...

This error is occurring right after issuing "vt.pl", right? This seems like it's "use strict" doing what it does: point out undeclared variables.

In line 169, you're using "$decjson" as a hash but up at the top of your script you've "declared" it to be a plain (scalar) variable. Line 169 is where you begin referencing it as though it's an associative array.

You might be able to resolve this by declaring "%decjson" in your "use vars" statement but I can't really tell just what you're doing down around line 169 (and just before that, actually). I'm just not sure of the syntax you're using (multivalued hash entries?)---braces cry out "associative array" or "hash", though. And it's not declared as one.

HTH...
 
1 members found this post helpful.
Old 02-16-2021, 11:56 PM   #3
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Original Poster
Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
here is that code with line numbers.
ill try what you told me to.

Code:
    1	#!/usr/bin/perl
     2	# vt.pl
     3	use warnings;
     4	use strict;
     5	use File::Find;
     6	use File::Remove 'remove';
     7	use LWP::UserAgent;
     8	use JSON;
     9	use Term::ANSIColor qw(:constants); # for colorful output
    10	use Getopt::Std;                    # for options
    11	use Data::Dumper;
    12
    13	use vars qw( @fullpaths $duration $end_time $time $deletefile $filepath $ua $url $key $key1 $key2 $key3 $response $result $results $json $decjson $sha $num );
    14
    15	use vars qw( $opt_h );
    16	getopts('h');
    17
    18	if ($opt_h) {
    19	print q(
    20	       -h Usage. just start the program with perl /usr/local/bin/vt.pl
    21
    22	/);
    23	exit(0);
    24	};
    25
    26	my $path = "/var/log/suricata/filestore/";
    27
    28	find( \&pathfinder , "$path" );
    29
    30	# main function.
    31	sub pathfinder {
    32
    33	$path = $_[0];
    34
    35	        if ( $File::Find::dir =~ '/[0-f]{2}$' || length($_) =~ 64 ) {
    36
    37		                push(@fullpaths, ($File::Find::name));
    38
    39	        }
    40
    41	        foreach $filepath (@fullpaths) {
    42		                # delete foo.json files
    43		                if ($filepath =~ /((.*)\.json$)/) {
    44
    45		                        pop(@fullpaths);
    46		                        deleter($filepath);
    47
    48		                } else {
    49
    50		                        if ($filepath =~ //) {
    51
    52			                                print '	Pathfinder() : No files to upload.\n';
    53			                                exit(0);
    54		                        }
    55
    56		                        print BLUE, '	        Pathfinder() : Countdown to feed Uploadtovt() with file_sha256 path -> Uploadtovt().', RESET;
    57		                        countdown(15); print "\n";
    58
    59		                        uploadtovt($filepath);
    60		                        pop(@fullpaths);
    61
    62		                }
    63	        }
    64	}
    65
    66	sub countdown($) {
    67
    68	        ($duration) = @_;
    69	        $end_time = time + $duration;
    70	        $time = time;
    71	        while ($time < $end_time) {
    72		                $time = time;
    73		                printf("\r%02d:%02d:%02d", ($end_time - $time) / (60*60), ($end_time - $time) / (60) % 60,($end_time - $time) % 60);
    74		                $|++;
    75		                sleep 1;
    76	    }
    77	}
    78
    79	# deletes sha256 file from filestore.
    80	sub deleter {
    81
    82	$deletefile = $_[0];
    83
    84	if ($deletefile =~ /((.*)\.json$)/) {
    85
    86	        remove("$1");
    87
    88	        #print RED, " DEL json ", RESET, YELLOW, "$deletefile", RESET, "\n";
    89	        #print "---------------------------------------------------------------------------------------------------------------\n";
    90
    91	        }
    92
    93	        elsif ($deletefile =~ /((.*)[a-z0-9]{64}$)/) {
    94
    95		                remove("$1");
    96
    97		                print RED, " DEL sha256 : ", RESET, YELLOW, "$deletefile", RESET, "\n";
    98		                print "---------------------------------------------------------------------------------------------------------------\n";
    99
   100	        }
   101	}
   102	# uploads sha256 file to virustotal.
   103	sub uploadtovt {
   104
   105	$filepath       = $_[0];
   106
   107	        $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
   108	        $url='https://www.virustotal.com/vtapi/v2/file/scan';
   109	        $key='ee6e69074a21711e1125bbe678b595e40b2cc82ff3f82cd923a9100f7d50e77b';
   110
   111	        $response = $ua->post( $url,
   112	        Content_Type => 'multipart/form-data',
   113	        Content => ['apikey' => $key,
   114	        'file' => ["$filepath"]]
   115	        );
   116	        die "$url error: ", $response->status_line
   117	        unless $response->is_success;
   118	        $results = $response->content;
   119
   120	        print BLUE, '	        Uploadtovt() : Countdown to send file_sha256 to Virustotal -> Downloader().', RESET;
   121	        countdown(5); print "\n";
   122
   123	        downloader($key, $sha);
   124
   125	}
   126
   127	# downloads report of sha256 file.
   128	sub downloader {
   129
   130	$key = $_[0];
   131	$sha = $_[1];
   132	$num = $_[2];
   133
   134	        $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 1 });
   135	        $key='<api-key here>';
   136	        $url='https://www.virustotal.com/vtapi/v2/file/report';
   137
   138	        if (defined $num) {
   139
   140		                print BLUE, '	        Downloader() : Second try - Countdown to pull results of file_sha256 from Virustotal -> Printer().', RESET;
   141		                countdown(30); print "\n";
   142
   143	        } else {
   144
   145		                print BLUE, '	        Downloader() : Countdown to pull results of file_sha256 from Virustotal -> Printer().', RESET;
   146		                countdown(45); print "\n";
   147
   148	        }
   149
   150	        #pulls the sha256 value out of the JSON response
   151	        #Note: there are many other values that could also be pulled out
   152	        $json = JSON->new->allow_nonref;
   153	        $decjson = $json->decode( $results);
   154	        $sha = $decjson->{"sha256"};
   155	        #print "	$sha", "\n\n";
   156
   157	        $response = $ua->post( $url,
   158	        ['apikey' => $key,
   159	        'resource' => $sha]
   160	        );
   161	        die "$url error: ", $response->status_line
   162	        unless $response->is_success;
   163	        $results=$response->content;
   164
   165	        #processes the JSON
   166	        $json = JSON->new->allow_nonref;
   167	        $decjson = $json->decode($results);
   168
   169	        printer($decjson->{'verbose_msg'},$decjson->{'scan_date'},$decjson->{'positives'},$decjson->{'total'},$filepath,$results,$sha,$key);
   170
   171	}
   172	# prints information about file_sha256.
   173	sub printer {
   174
   175	$decjson->{'verbose_msg'} = $_[0];
   176	$decjson->{'scan_date'}   = $_[1];
   177	$decjson->{'positives'}   = $_[2];
   178	$decjson->{'total'}       = $_[3];
   179	$filepath                 = $_[4];
   180	$results                  = $_[5];
   181	$sha                      = $_[6];
   182	$key                      = $_[7];
   183	$num = '1';
   184
   185	if ($results =~ /"Your resource is queued for analysis"/i) {
   186	        # if queued go to Downloader.
   187	    print YELLOW,"	        ", $decjson->{'verbose_msg'},".", RESET; print "\n";
   188	    print BLUE,'	        Printer() : Waiting for results from Virustotal -> Downloader().', RESET; print "\n";
   189	        downloader($key, $sha, $num);
   190
   191	} else {
   192
   193		                if ($results =~ /"Scan finished, information embedded"/i) {
   194		                        print "---------------------------------------------------------------------------------------------------------------\n";
   195		                        # print selected values from the json file
   196		                        print YELLOW, " Sample name: ". $filepath. RESET"\n";
   197		                        print YELLOW, " Scan Date:  ".$decjson->{"scan_date"}. RESET"\n";
   198		                        print RED, " Detection rate: ", RESET, WHITE, $decjson->{"positives"}, RESET, "/", RED, $decjson->{"total"}, RESET, "\n";
   199		                        deleter($filepath);
   200		                }
   201	        }
   202	}
   203
[root@arch vile]#
error happens when i call this :
Code:
   169		printer($decjson->{'verbose_msg'},$decjson->{'scan_date'},$decjson->{'positives'},$decjson->{'total'},$filepath,$results,$sha,$key);
this is what Dumper says :
Code:
	print Dumper($decjson->{'verbose_msg'},$decjson->{'scan_date'},$decjson->{'positives'},$decjson->{'total'},$filepath,$results,$sha,$key);

$VAR1 = 'Your resource is queued for analysis';
$VAR2 = undef;
$VAR3 = undef;
$VAR4 = undef;
$VAR5 = '/var/log/suricata/filestore/62/628f488e1de98e6e16bcc5b5b484833734f383e7f5a4fa21eb080634d81906bf';
$VAR6 = '{"response_code": -2, "resource": "628f488e1de98e6e16bcc5b5b484833734f383e7f5a4fa21eb080634d81906bf", "scan_id": "628f488e1de98e6e16bcc5b5b484833734f383e7f5a4fa21eb080634d81906bf", "verbose_msg": "Your resource is queued for analysis"}';

Last edited by //////; 02-17-2021 at 01:42 AM.
 
Old 02-17-2021, 05:22 AM   #4
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,627

Rep: Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556

The error suggests you're trying to read an undefined value from an object/struct/hashmap - presumably it's [the first of] those undefined values causing it.

I assume Perl has a null coalescing operator, in which case, use that to define a fallback value for any fields which the API may or not return.

Or pass all of decjson into the printer function as a single argument and, if/when you need the values from it, check they exist before trying to use them, and output a suitable message if they don't.

 
1 members found this post helpful.
Old 02-17-2021, 05:54 AM   #5
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Original Poster
Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
Quote:
Originally Posted by boughtonp View Post
Or pass all of decjson into the printer function as a single argument and, if/when you need the values from it, check they exist before trying to use them, and output a suitable message if they don't.
ill try that first.
 
Old 02-17-2021, 05:55 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,035

Rep: Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344Reputation: 7344
you need to check if that decoding was successful (line 167)
 
Old 02-17-2021, 08:00 AM   #7
//////
Member
 
Registered: Nov 2005
Location: Land of Linux :: Finland
Distribution: Arch Linux && OpenBSD 7.4 && Pop!_OS && Kali && Qubes-Os
Posts: 824

Original Poster
Rep: Reputation: 350Reputation: 350Reputation: 350Reputation: 350
guess what, it worked, thanks man.

Code:
...
		#processes the JSON
		$json = JSON->new->allow_nonref;   
		$decjson = $json->decode($results);
				
		printer($results,$sha,$key,$filepath);

	}
}
# prints information about file_sha256.
sub printer {

$results    = $_[0];
$sha        = $_[1];
$key        = $_[2];
$filepath   = $_[3];
...
Quote:
you need to check if that decoding was successful (line 167)
ill check that too.

thanks guys.
 
  


Reply

Tags
log, perl, suricata, virustotal



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Automatically my static ip changes to 169.254.169.254 Arunkumar Goge Linux - Networking 2 04-01-2013 05:19 PM
Error: Cannot find 'ssh-keygen' in '/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin' venu.navat Linux - Software 3 03-08-2012 04:00 AM
Perl Hash of Hash reference query kdelover Programming 1 02-19-2011 04:47 AM
echo $PATH = /home/g3rc4n/bin:/usr/local/bin:/usr/bin:/bin:/usr/games ? i_heart_pandas Linux - Software 7 09-18-2009 08:33 AM
The nvidia driver 169.09 was working fine, until I upgraded it to 169.12 dv502 Linux - General 1 03-22-2008 05:09 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:50 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration