diff --git a/pwned.pl b/pwned.pl new file mode 100755 index 0000000..bac9fec --- /dev/null +++ b/pwned.pl @@ -0,0 +1,140 @@ +#!/usr/bin/perl + +# This is a perl version of the original pwned-search created by Dr. Mike Pound +# This program is a free software. You are free to use it under the terms of +# GNU GPL license either version 3 or, at your choice, any later version. +# Copyright 2019 Lucas V. Araujo +# Required module: WWW::Curl::Easy (libwww-curl-perl) + +use strict; +use warnings; +use Getopt::Long; +use WWW::Curl::Easy; +use Digest::SHA qw(sha1_hex); + +use vars qw ( $VERSION ); + +$VERSION = "2019.1208.0012"; + +sub request +{ + # Performs an http request to a given url using the WWW::Curl::Easy module + # and returns, if successful, the received page. + + #gets the url passed as argument + my $url = shift; + my $prxy = shift; + #initialize a new instance of Curl::Easy + my $curl = WWW::Curl::Easy->new(); + #define the HEADER option as true + $curl->setopt(CURLOPT_HEADER, 1); + #define the target url + $curl->setopt(CURLOPT_URL, $url); + #declare a variable to hold the returned page + my $data = undef; + #define the variable as a filehandle to store the data into + $curl->setopt(CURLOPT_WRITEDATA, \$data); + #sets the proxy to be used, if any + $curl->setopt(CURLOPT_PROXY, $prxy) if $prxy; + #performs the request + my $err = $curl->perform(); + + #checks if successfull + unless ($err) + { + return $data; + } + else + { + print("error: $err ".$curl->strerror($err)."\n".$curl->errbuf."\n"); + return ""; + } +} + + +sub lookup_password +{ + #Given a plain password, gets the hash and search for it on the database + #using the especified proxy + + my $plain = shift; + my $proxy = shift; + #get the SHA-1 hashed password + my $hashed = sha1_hex($plain); + #separate the hash into a head containing the first 5 bytes, and a tail + #containing the rest + $hashed =~ /([\d\w]{5})([\d\w]*)/; + my $head = $1; + my $tail = $2; + #format the head into a url to be requested + my $url = "https:\/\/api.pwnedpasswords.com\/range\/$head"; + #realize the request and get the response + my $resp = request($url, $proxy); + #if nothing is found, it is considered that the number of times it leaked + #(for all we know) was 0 + my $count = 0; + #match the response against a regular expression to extract the number of + #times that the password was been leaked + if ($resp =~ /$tail\:([\d]*)/i ) + { + $count = $1; + } + #returns an array with the hash and the count + return ($hashed, $count); +} + +sub main +{ + my $version = 0; + my $proxy = undef; + my $help = 0; + my $tor = 0; + + + GetOptions( + "version!" => \$version, + "proxy=s" => \$proxy, + "help!" => \$help, + "tor!" => \$tor, + ); + + if ($version) + { + print "$VERSION\n"; + exit(0); + } + + if ($help || !(scalar @ARGV)) + { + print "pwned-search - Pwned Password API lookup tool\n\n" . + "usage: pwned.pl [options] ... \n\n" . + "Options:\n" . + "-v, --version show program's version number and exit\n" . + "-h, --help show this help message and exit\n" . + "-p, --proxy define a proxy to be used in requests\n" . + " (the proxy must be in format TYPE://ADDRESS[:PORT])\n" . + "-t, --tor use tor proxy\n" . + " (same as --proxy=socks5://127.0.0.1:9050)\n\n" . + "This is a perl version of the pwned-search by Dr. Mike Pound\n" . + "Copyright (C) 2019 Lucas V. Araujo \n" . + "GitHub: https://github.com/LvMalware/pwned-search \n"; + exit(0); + } + + $proxy = "socks5://127.0.0.1:9050" if $tor; + + for my $password (@ARGV) + { + my ($hash, $count) = lookup_password($password, $proxy); + if ($count > 0) + { + print "$password was found with $count occurrences (hash: $hash)\n"; + } + else + { + print "$password was not found\n"; + } + } +} + +main();