Determining the hash type I am working with for use in hashcat - brute-force

I am trying to crack some hashed information because the passcode was lost to us. I have the hashed information in the database, and the code that was used to encrypt it. It goes through cryptastic which appears to use rijndael-256 and pbkdf2, as far as my ignorant self can tell:
public function encrypt($msg, $k, $base64 = false)
{
# open cipher module (do not change cipher/mode)
if (!$td = mcrypt_module_open('rijndael-256', '', 'ctr', ''))
return false;
$msg = serialize($msg); # serialize
$iv = mcrypt_create_iv(32, MCRYPT_RAND); # create iv
if (mcrypt_generic_init($td, $k, $iv) !== 0) # initialize buffers
return false;
$msg = mcrypt_generic($td, $msg); # encrypt
$msg = $iv . $msg; # prepend iv
$mac = $this->pbkdf2($msg, $k, 1000, 32, 'sha256'); # create mac
$msg .= $mac; # append mac
mcrypt_generic_deinit($td); # clear buffers
mcrypt_module_close($td); # close cipher module
if ($base64)
$msg = base64_encode($msg);# base64 encode?
return $msg; # return iv+ciphertext+mac
}
And in the end looks like this: wWTWLPvXT9YRz2Zj+Og0EwTTSEiZGdjAQ1TRhycJA9jusjQ2mTpptw3hSM1XJ9yPw+4XvsvFASe08AbLr3BT0LFnvGsYPrq87yI= (I know this to be a 3 digit number if that helps at all)
So I am trying to use hashcat to recover our information and I am not certain I am using the correct hash-type. I am checking this page here: https://hashcat.net/wiki/doku.php?id=example_hashes and searching for 'pbkdf2' and looking at all the hits.
The best match as far as I can tell is 9200/Cisco-IOS $8$ (PBKDF2-SHA256) except that that seems to have a header of $8$, and none of my information has any headers at all, and no $ characters. Everything else with PBKDF2 in it doesn't seem to be a match either so I find myself kind of lost before I've even gotten started.
I also noticed my hashed info always had == on the end, but only for the longer information being encrypted, in the list Juniper IVE seems to fit that format but the name doesn't match anything I can see in cryptastic.
I'm mostly ready to go aside from this as far as I can tell, I have my custom rules set up since I know how we create the initial passcodes and the hashes are in a file to be read, it's just this hash-type selection that is blocking me.
Any help appreciated!

Related

"sh: 1: file: not found" thrown in Perl

So this is an issue I see thrown around on several coding help-sites that always have a slight variation. I'm not entirely familiar with what it means, and what's even more curious is that this error is thrown midway through a larger Upload.pm script, and does not cause any sort of fatal error. It gets tossed into my error log somewhere during this unless conditional snippet
# If this is the first slice, validate the file extension and mime-type. Mime-type of following slices should be "application/octet-stream".
unless ( defined $response{'error'} ) {
if ( $slice->{'index'} == 1 ) {
my ($filename, $directory, $extension) = fileparse($path.$parent_file, qr/\.[^.]*/);
unless ( is_valid_filetype($slice->{'tmp_file'}, $extension) ) {
$response{'error'} = "Invalid file type.";
$response{'retry'} = 0;
}
}
}
Now, let me be perfectly honest. I don't really understand the error message, and I could really use some help understanding it, as well as solving it.
Our Perl based web app has refused to let us upload files correctly since upgrading to Debian Bullseye, and I've been stuck debugging this code I didn't write for a few days now. I'm wondering if the upgrade depreciated some Perl modules, or if the directories to said modules are no longer working?
I'm testing this in a Ubuntu based Docker environment running Debian Bullseye on an Apache 2 server.
If you need any more context, clarification, etc, please let me know.
is_valid_filetype() looks like this:
sub is_valid_filetype
{
my ($tmp_file, $extension) = #_;
if ( $tmp_file && $extension ) {
# Get temp file's actual mime-type.
my $mime = qx/file --mime-type -b '${tmp_file}'/;
$mime =~ s/^\s+|\s+$//g;
# Get valid mime-types matching this extension.
my $dbh = JobTracker::Common::dbh or die("DBH not available.");
my $mime_types = $dbh->selectrow_array('SELECT `mime_types` FROM `valid_files` WHERE `extension` = ?', undef, substr($extension, 1));
if ( $mime && $mime_types ) {
if ( $mime_types !~ /,/ ) {
# Single valid mime-type for this extension.
if ( $mime eq $mime_types ) {
return 1;
}
} else {
# Multiple valid mime-types for this extension.
my %valid_mimes = map { $_ => 1 } split(/,/, $mime_types);
if ( defined $valid_mimes{$mime} ) {
return 1;
}
}
}
}
return 0;
}
It's a message from sh (not Perl). It concerns an error on line 1 of the script, which was apparently an attempt to run the file utility. But sh couldn't find it.
The code in question executes this command using
qx/file --mime-type -b '${tmp_file}'/
Install file or adjust the PATH so it can be found.
Note that this code suffers from a code injection bug. It will fail if the string in $tmp_path contains a single quote ('), possibly resulting in the unintentional execution of code.
Fixed:
use String::ShellQuote qw( shell_quote );
my $cmd = shell_quote( "file", "--mime-type", "-b", $tmp_file" );
qx/$cmd/
Debian Bullseye was reading our CSV files as the wrong mime-type. It was interpreting the file command as application/csv, despite obviously not being an application.
This may be an actual bug in Bullseye, because both my boss and I have scoured the internet with no lucky finding anyone else with this issue. I may even report to Bullseye's devs for further awareness.
The fix was manually adding in our own mime-types that interpreted this file correctly.
It took us dumping the tmp directory to confirm the files existed, and triple checking I had my modules installed.
This was such a weird and crazy upstream issue that either of us could not have imaged it would be the file type interpretation at an OS level in Bullseye.
I really hope this helps someone, saves them the time it took us to find this.

Instagram Real-time API duplicate requests

I have an issue where when I create a real-time subscription I get duplicate notifications from different Instagram IP addresses. I have it set up so that when I get a notification, I send a request for latest updates using the min_tag_id setting. I store that in my db to use it for the next request. I don't always get duplicates, but when I do, everything about the notification is the same (time, object,changed_aspect), except I can tell they are different from my debugging output which lists two almost identical requests... the only differing info being a different IP address and the REQUEST_TIME_FLOAT is different by about 1/10th of a second. They even have the same HTTP_X_HUB_SIGNATURE value.
My general algorithm is:
process_subscription_update($data){
# get old min_id
$min_tag_id = mysqli_fetch_object(mysqli_query($dbconnecti,sprintf("SELECT instagram_min_id+0 as instaid FROM xxxx WHERE xxxx=%d",$_GET['xxxx'])));
$min_id = $min_tag_id->instaid;
# make api call
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, 'https://api.instagram.com/v1/tags/'.$_GET['tag'].'/media/recent?client_id=xxxx&min_tag_id='.$min_id.($min_id==0?'&count=1':''));
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$result = curl_exec($ch);
curl_close($ch);
$i = json_decode($result);
if ($min_id == $i->pagination->min_tag_id) { exit; }
# write new min_id to db
record_min_id($i->pagination->min_tag_id);
$data2 = $i->data;
foreach($data2 as $d) {
process_instagram($d);
}
// debugging output: ****************
$file = file_get_contents($_SERVER['DOCUMENT_ROOT'].'instagram/updates.txt');
$foo = "\n";
foreach($_SERVER as $key_name => $key_value) {
$foo .= $key_name . " = " . $key_value . "\n";
}
$fulldata = $file . "\n\n\n" . $result . "\n min_id = " . $min_id . $foo;
$fulldata .= "\nTIME:".$data[0]->time;
$fulldata .= "\nOBJECT:".$data[0]->object;
$fulldata .= "\nCHANGED_ASPECT:".$data[0]->changed_aspect;
file_put_contents($_SERVER['DOCUMENT_ROOT'].'instagram/updates.txt', $fulldata);
// end debugging output *************
}
I'd like to avoid checking if the instagram message id already exists in my db within the process_instagram function, and with the duplicates only coming 1/10th of a second apart, I don't know if that would work anyway.
Anybody else experience this and/or have a solution?
I solved this. I don't think there is anything I can do about receiving the duplicate notifications. So, when writing the Instagram to my db, I have a field for the Instagram id and put a unique constraint on the field. After doing the mysqli INSERT, I check to see if the errno = 1062, and if it does, I exit.
mysqli_query($dbconnecti,"INSERT INTO xxx (foo, etc, instagram_id ...")
if ($dbconnecti->errno==1062) { exit; }
...
// more script runs here if we don't have a duplicate.

ReCaptcha Implementation in Perl

To implement recaptcha in my website.
One option is google API . But for that i need to signup with domain name to get API key.
Is there any other way we can do it ?
You don't necessarily need a domain name to sign up, per se.
They have a concept of a "global key" where one single domain key would be used on several domains. When signing up, select the "Enable this key on all domains (global key)" option, and use a unique identifier (domainkey.abhilasha.com) and this will be fine, you can use the key from any domain in the end.
One way: add this code to your perl file that is called by an html form:
Simplified of course
my #field_names=qw(name branch email g-recaptcha-response);
foreach $field_name (#field_names)
{
if (defined param("$field_name"))
{
$FIELD{$field_name} = param("$field_name");
}
}
$captcha=$FIELD{'g-recaptcha-response'};
use LWP::Simple;
$secretKey = "put your key here";
$ip = remote_host;
#Remove # rem to test submitted variables are present
#print "secret= $secretKey";
#print " and response= $captcha";
#print " and remoteip= $ip";
$URL = "https://www.google.com/recaptcha/api/siteverify?secret=".$secretKey."&response=".$captcha."&remoteip=".$ip;
$contents = get $URL or die;
# contents variable takes the form of: "success": true, "challenge_ts": "2016-11-21T16:02:41Z", "hostname": "www.mydomain.org.uk"
use Data::Dumper qw(Dumper);
# Split contents variable by comma:
my ($success, $challenge_time, $hostname) = split /,/, $contents;
# Split success variable by colon:
my ($success_title, $success_value) = split /:/, $success;
#strip whitespace:
$success_value =~ s/^\s+//;
if ($success_value eq "true")
{
print "it worked";
}else{
print "it did not";
}
If you are just trying to block spam, I prefer the honeypot captcha approach: http://haacked.com/archive/2007/09/10/honeypot-captcha.aspx
Put an input field on your form that should be left blank, then hide it with CSS (preferably in an external CSS file). A robot will find it and will put spam in it but humans wont see it.
In your form validation script, check the length of the field, if it contains any characters, do not process the form submission.

Perl mechanize Find all links array loop issue

I am currently attempting to create a Perl webspider using WWW::Mechanize.
What I am trying to do is create a webspider that will crawl the whole site of the URL (entered by the user) and extract all of the links from every page on the site.
But I have a problem with how to spider the whole site to get every link, without duplicates
What I have done so far (the part im having trouble with anyway):
foreach (#nonduplicates) { #array contain urls like www.tree.com/contact-us, www.tree.com/varieties....
$mech->get($_);
my #list = $mech->find_all_links(url_abs_regex => qr/^\Q$urlToSpider\E/); #find all links on this page that starts with http://www.tree.com
#NOW THIS IS WHAT I WANT IT TO DO AFTER THE ABOVE (IN PSEUDOCODE), BUT CANT GET WORKING
#foreach (#list) {
#if $_ is already in #nonduplicates
#then do nothing because that link has already been found
#} else {
#append the link to the end of #nonduplicates so that if it has not been crawled for links already, it will be
How would I be able to do the above?
I am doing this to try and spider the whole site to get a comprehensive list of every URL on the site, without duplicates.
If you think this is not the best/easiest method of achieving the same result I'm open to ideas.
Your help is much appreciated, thanks.
Create a hash to track which links you've seen before and put any unseen ones onto #nonduplicates for processing:
$| = 1;
my $scanned = 0;
my #nonduplicates = ( $urlToSpider ); # Add the first link to the queue.
my %link_tracker = map { $_ => 1 } #nonduplicates; # Keep track of what links we've found already.
while (my $queued_link = pop #nonduplicates) {
$mech->get($queued_link);
my #list = $mech->find_all_links(url_abs_regex => qr/^\Q$urlToSpider\E/);
for my $new_link (#list) {
# Add the link to the queue unless we already encountered it.
# Increment so we don't add it again.
push #nonduplicates, $new_link->url_abs() unless $link_tracker{$new_link->url_abs()}++;
}
printf "\rPages scanned: [%d] Unique Links: [%s] Queued: [%s]", ++$scanned, scalar keys %link_tracker, scalar #nonduplicates;
}
use Data::Dumper;
print Dumper(\%link_tracker);
use List::MoreUtils qw/uniq/;
...
my #list = $mech->find_all_links(...);
my #unique_urls = uniq( map { $_->url } #list );
Now #unique_urls contains the unique urls from #list.

Perl - Net::DNS to create PTR record

First, the relevant xkcd comic: http://xkcd.com/979/
Next, the 10-year old thread on PerlMonks: http://www.perlmonks.org/?node_id=210422
Basically, I'm failing in my attempts to use Net::DNS::Update to create a PTR record and I'd like to see how others have manged this.
Below is what I'm trying. $hst is the hostname that I already have an A record for. $rev is the backwards IP address in-addr.arpa thingy.
# Create the update packet:
my $update = Net::DNS::Update->new($OURDOMAIN);
# Add the PTR record:
$update->push(update => rr_add("$rev 3600 PTR $hst"));
# Send the update to the zone's primary master.
my $res = Net::DNS::Resolver->new;
$res->nameservers("$OURNMSERV");
If $OURDOMAIN is your main domain name, you need to know that you can't put PTR records into your own domain, they have to be put in the right .in-addr.arpa zone.
That zone is most likely being run by your ISP, and they're unlikely to support dynamic updates from end users.
Another ten years later, http://xkcd.com/979/ is still relevant. Having read the question and answer and also the linked PerlMonks thread, it was still unclear to me how to properly add PTR records using Net::DNS.
Well, 'when in Rome do as the Romans do' the saying goes. Having noticed that nsupdate can add PTR records to our internal DNS system just fine without me specifying the reverse zone, I was trying to find out what it does to send valid updates. Turned out it actually sends a SOA query first to figure out what the reverse zone is. Copying this behavior seems to be a somewhat robust way to add PTR records via Net::DNS:
use Net::DNS;
my $hostname = 'somehost.example.com.';
my $ip = '10.11.12.13';
my $primary_ns = 'primary.example.com';
# First, construct the reverse name based on the IP address
my #octets = split /\./, $ip;
my #rev_octs = reverse(#octets);
my $rev_name = join(".", #rev_octs) . '.in-addr.arpa.';
# Then, query the SOA record for the constructed reverse name
my $resolver = Net::DNS::Resolver->new();
$resolver->nameservers($primary_ns);
# Note: Need to use 'send' rather than 'query' since we are interested
# in the 'authority section' of the reply only.
my $packet = $resolver->send($rev_name, 'SOA');
my $zone;
if ($packet) {
# We expect only one authority record
my $len = $packet->authority;
if ($len == 0) {
# Server might not be authorative for reverse lookup zone.
warn "No authority section in reply.\n";
exit 1;
}
my $auth = ($packet->authority)[0];
$zone = $auth->name;
} else {
warn 'query failed: ', $resolver->errorstring, "\n";
exit 1;
}
# Armed with this information, we can finally add the PTR records
my $update = Net::DNS::Update->new($zone);
# Make sure that the PTR record does not already exist
$update->push( pre => nxrrset("$rev_name PTR") );
$update->push( update => rr_add("$rev_name 1200 PTR $hostname") );
my $reply = $resolver->send($update);
if ($reply) {
if ($reply->header->rcode eq 'NOERROR') {
print "Successfully added PTR record!\n";
} else {
print 'Update failed: ', $reply->header->rcode, "\n";
}
} else {
print 'Update failed: ', $resolver->errorstring, "\n";
}