Last active
February 24, 2024 17:21
-
-
Save m0rb/96a6dda65ddaae3dc30228dd8c9199e5 to your computer and use it in GitHub Desktop.
virustotal auto-uploader for stupid botnet droppers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
use strict; | |
use warnings; | |
use utf8; | |
use DateTime; | |
use JSON; | |
use File::Tail; | |
use File::Basename; | |
use LWP::UserAgent; | |
use URL::Encode qw(encode_entities); | |
use HTML::Entities; | |
use Sys::Syslog; | |
use Data::Dumper; | |
use Digest::SHA; | |
use Parallel::ForkManager; | |
binmode(STDOUT,":utf8"); | |
my $forky = Parallel::ForkManager->new(4); | |
my $pid = $$; | |
my ($next,$debug,$timeout,@files,@i,%h); | |
my $apikey = ""; | |
my $vtbase = "https://www.virustotal.com/api/v3/files"; | |
my $basedir = "malware/"; | |
my $mal = LWP::UserAgent->new(agent=> "Mozilla/5.0",show_progress=>1); | |
$mal->proxy([qw(http https)] => 'socks://127.0.0.1:9050'); | |
my $vt = LWP::UserAgent->new(show_progress=>1); | |
$vt->default_header('x-apikey'=>$apikey); | |
push(@files,File::Tail->new(name=>"/var/log/nginx/access.log",debug=>$debug,reset_tail=>0)); | |
while (1) { | |
my ($nfound,$timeleft,@pending) = File::Tail::select(undef,undef,undef,$timeout,@files); | |
unless ($nfound) {} else { | |
foreach (@pending) { | |
my $line = $_->read; | |
unless ( $line =~ /192\.168\./ ) { | |
if ( $line =~ /((wget|curl).*?(?=\;))/ ) { | |
my $out = url_decode_utf8($1); $out =~ s/(wget|curl -O )//; $out =~ s/\$\{IFS\}//; | |
$out =~ s/-O.*//; $out =~ s/(\ |\;.*)//g; | |
push @i,$out; | |
} | |
FORKY: | |
foreach ( my @u = grep { ! $h{ $_ }++ } @i) { | |
my $fn = basename($_); $fn =~ s/\ //g; | |
my $time = DateTime->now->epoch; | |
my $dir = $basedir.$time; | |
mkdir $dir; | |
my $file = "$dir/$fn"; | |
$forky->start and next FORKY; | |
my $resp = $mal->get($_, ":content_file" => "$dir/$fn" ); | |
if ( $resp->is_success ) { | |
my $sha256 = Digest::SHA->new(256)->addfile("$dir/$fn")->hexdigest; | |
openlog($pid.'[BOT]','nowait','LOG_LOCAL0'); | |
syslog("NOTICE","Alert! Grabbed $_ ($time/$fn : $sha256)"); | |
print "$_ : $sha256\n"; | |
my $vtquery = $vt->get($vtbase."/".$sha256); | |
unless ($vtquery->is_success) { | |
if ($vtquery->content =~ /NotFoundError/i) { | |
my $idiot = $vt->post($vtbase, Content_Type => | |
"form-data", Content => [ file => [ "$dir/$fn" ] ] ); | |
$line =~ s/\"(\d.*)\"$//g; | |
my %compost = (data=>{type=>"comment",attributes=>{text=>encode_entities($line)}}); | |
select(undef,undef,undef,15); | |
my $comment = $vt->post($vtbase."/".$sha256."/comments", Content => encode_json(\%compost) | |
); | |
syslog("NOTICE","Uploaded $sha256 to VirusTotal"); | |
} | |
} else { | |
print "$sha256 is already on VT.\n"; | |
} | |
closelog; | |
} | |
} | |
$forky->finish; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment