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
Welcome to
LinuxQuestions.org , a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free.
Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please
contact us . If you need to reset your password,
click here .
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a
virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month.
Click here for more info.
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
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 .
02-16-2021, 08:42 PM
#2
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
Quote:
Originally Posted by
//////
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.
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
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 .
02-17-2021, 05:22 AM
#4
Senior Member
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,627
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.
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
Quote:
Originally Posted by
boughtonp
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.
02-17-2021, 05:55 AM
#6
LQ Addict
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,035
you need to check if that decoding was successful (line 167)
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
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.
All times are GMT -5. The time now is 01:50 AM .
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know .
Latest Threads
LQ News