Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 3

Hello and welcome back to this course so

far in this course we've been talking about collecting passwords


from compromised systems. And so there's a couple of
different ways to do that and the results that we collect can
vary from one system to another and based off of where we're
grabbing this information from. So in some cases we might get
legitimate passwords for a system, in others we might just
get password hashes. And so in this video, going to look
at cracking Linux password hashes and so we'll talk through the format of what
you might grab if you pull a password hash from let's say shadow and
then how to crack it using python. So our code here is shown in the note pad
plus plus across the top of the screen. And so for this we're going to
be using the passlib library. And so the reason for
this is that the crypt library that you might use on your Linux system
only works on Linux systems. So for running on say Windows,
we need to use something designed for Windows like passlib. So just for more
universal usage. So we're going to pull in passlib and
then from passlib.hash we're going to import the sha512
hash function as 512. And so, the reason why we're
using sha512 is that's what was default on some Linux systems. We'll talk through
how to determine which
hash function to use in just a moment. And so here, down at the bottom
if you've looked at C shadow, you should have seen something
that looks a little bit like this. So user two sample password
hashes pulled from a boon two system for
user one and user too. And so reading through this format,
let's break this down. So we have our user name here. So user one and user two,
separated
with the colon from what we really want which is the stuff that's
between this next pair of colons. And so this tells us everything we
need to know about cracking this particular Linux password hash. So the first thing
we
have here is number 6, in this case this tells us that
our hash algorithm is sha512. And so up here in our crack hash function
we see that we do a test for the algorithm and see if it's a value of 6, and
that's why we imported sha512 up here. So in different cases you might
have different values here and there are look up tables
online that will tell you for this particular algorithm value, this is
the algorithm that you should be using. So this section is delimited
by dollar signs, and so our next value of interest is right here. And so this is
called our password salt. So if you're not familiar
with cryptography and password hashing, a salt is a random but public value that's
mixed in with
the password before hashing it. And so the reason why we use salts is
that hash functions are deterministic. You put the same input in, you're
always going to get the same input out. And so some people found this out, and
there decided well we know that
there are some common passwords or we know there's only so many potential
inputs to this hash function. Let's just make up a look up table called
a rainbow table for this particular hash function saying, this is what we put in,
and this is what comes out. And so that way instead of going through
all the bother of trying to crack a password hash, if we steal a hash we can
just compare it to this look up table and immediately get the password. So we're
doing more work up front
to speed things up later on. Salts break this because a salt is a
unique part of the input to each password. Notice that the first salt and
the second salt here are different, and so if you want to generate a rainbow
table for a modern password database, you're going to have to
generate a rainbow table for every combination of salt and password and
that quickly becomes infeasible. And so that helps to protect
against rainbow tables. And so here we're going to need to
provide this salt value when we're hashing our password because
it's part of the password hash. Our third value here is
the output of the hash function. And so notice that neither the salt nor this look
much like a random
string of bits, reason why is everything is encoded to make
it printable and easier to view. So see here, we'll decode this and
the salt when we pass them into the hash function and that will give us
the lengths that we're expecting. So I shouldn't have said that this
is going into the hash function, this actually is what our output is. So we'll be
testing against this, because
one of the properties of hash functions that makes them useful for password
management is that they're one way. You can just put an input at and
get an output out but you can't go from output to input. The best way to crack a
hash or
get a password from a hash is to try all the possible passwords
until you get a correct output. So if you've got a nice strong password, that brute
force search isn't going to
work and so nobody can get your password. In this case, in this demonstration,
we're going to assume that
people used stupid passwords. So we're going to try some
variations on the word password using some of
the password munging and capabilities that we talked
about in an earlier video. So things like substituting in
a different character for a letter. So something like an art symbol or a number 4
instead of a lowercase or
uppercase. And so our crack hash function
here is going to do all the heavy lifting of cracking
are Linux passwords for us. We're going to pass in h
which is our output here, the salt value which
we've grabbed from here, our algorithm which is right here,
and then a list of passwords to try. And so in this case we're just
assuming that the algorithm is 6, because that's the one
that we're using here and all that changes is which hash
function we're going to be using. And so we're using 512,
you could also use MD5, sha256 etcetera. So it's important to look up which one
is used on the system or check this. And so once we've chosen our algorithm
we're going to loop over our list of passwords and generate a hash for
that particular password. So we'll call sha512, tell to hash
will give it the password that we're looking at the salt value that we've
extracted from here in a number of rounds. So in this case system is using
5000 rounds of the hash and the whole point of those rounds is to make
it harder to perform password cracking. So around is just in the first
round will take the password, the hash that produced output,
the second round will take the output of that previous one, and hash it to
produce the output of round two. Since hash functions are unpredictable,
the only way to get from the initial password to the final output is to go
through that 5000 hash operations. And so if you only need to do it once
because you're legitimate user and pass again the right password that
5000 hashes doesn't take that long. But if like us,
you need to test a lot of passwords, having to do 5000 hashes rather than
a single hash starts adding up time, and so it makes cracking
a little bit more difficult. And so as a result of this we're going
to get something very similar to what we have here, this dollar sign with the
algorithm, the salt and the hash output. So we're going to split that
on our dollar signs, and if the hash output that
I've got highlighted here, matches the one that we've generated on
a particular password, then we're going to return that password because that's the
password for that particular user account. And so down here in our main function,
we've generated all of our variations of passwords
using those character substitution. And we're going to loop
over these two hashes that we've extracted from the machine. We'll split them on
the colons, so that we can get this section here
that we care about, will store the user name which is the first value
that we pull out from vowels here. And then we'll reset vowels to be
each of the three values we get here, the algorithm, the salt and
the hash output. Well then call crash,
crack crash with those three values and the password list that we get from
genVariations and if we get a result, that means that we found a hash that matches
our hash so we'll have that password. And so we'll print out the user name and
the associated password. And so now let's give this a run. So we'll use python
crack Linux.py,
execute it and so this is going to take
a couple of seconds to run. And the reason why is first we
need to take this password and generate every single variation
of it using substitution. It's going to create a few 1000 passwords
after that were then running this crack hash function. So for a few 1000 passwords,
for
each one of them we need to run 5000 rounds of hashing to get the final
hash output that will be comparing. And so we see here that were
successful in both cases. So both of these user accounts used
a variation of password as their password. First one used just the word password
and
the 2nd 1 used character substitution. So we have a capital P,
a art symbol couple of dollar signs, and a 0 but were able to determine
the correct passwords for those user accounts
using this python code. And so just important to note here that
our success comes down to the fact that we had a pretty good guess for what
the passwords for those accounts were. And essentially, we were just looking at
simple password
munging of a single base password. If we had more passwords to test and
munge, the list of passwords is going to go up
significantly, so does the amount of time. If we're actually looking at account
where someone used a strong password, then the password storage
system works as intended, we're not going to be able to guess it. Say if you've got
like a 12 character,
completely random password using upper case, lower case numbers, symbols,
etc, then this isn't going to work. But if we can get a good guess on what the
password might be, maybe from performing some of that password analysis we
talked about in an earlier video, we've determined that this is how
a user build their passwords. This is their basic algorithm. Then we could pass in
the results of that
analysis into this to see which one is the right one. Thank you.

You might also like