@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );while (<>) { if (/(password|md5)\s+7\s+([\da-f]+)/io) { if (!(length($2) & 1)) { $ep = $2; $dp = ""; ($s, $e) = ($2 =~ /^(..)(.+)/o); for ($i = 0; $i < length($e); $i+=2) { $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++]; } s/7\s+$ep/$dp/; } } print;}# eof
while (<>) { if (/(password|md5)\s+7\s+([\da-f]+)/io) {
Quadz, why do you like Ruby as opposed to Perl.
while(<>) This is the magical input loop, it reads stdin. This allows it to accept command line arguments or file input if the command line specifies a file. The script can be commanded, fed files, or piped and it won't care.if (!(length($2) & 1))This is the kind of idom that makes me want to puke when I see perl code. It is taking the second product of the pattern match and determining if it's length is odd or not. The inversion of the result makes it even more difficult to decide which path is the odd path and which is the not-odd path in the block. gag, retch, puke.
#grabbing line in router config with encrypted password, and operating on the encrypted pass by running the original algorithm in reverse@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );#sending script config file as input,as usual perl reads in files, arguments and <> will operate on them, they are concactanated to inputwhile (<>) {#test for "password or md5, plus a space, plus 7 zero or more times, plus one or more spaces, plus a hex character one or more times, i modifier = case insenstivie, o modifier = compile regex once if (/(password|md5)\s+7\s+([\da-f]+)/io) {#testing the second sub match ($2), length is run on the match of hex values, so FFFF=4, we are making sure 4 is NOT odd. 1 & 1 returns true, 2 & 1 returns false...... if (!(length($2) & 1)) { $ep = $2; $dp = ""; ($s, $e) = ($2 =~ /^(..)(.+)/o); for ($i = 0; $i < length($e); $i+=2) { $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++]; } s/7\s+$ep/$dp/; } } print;}# eof
Because the output of (length(abc) & 1) is 1 and (length(abcd) & 1) is 0, so the inversion is redundant and only serves to make the script harder to read and maintain.
Regarding your comment about running the algorithm in reverse, MD5 is a hash, it is a one-way function and cannot be reversed. You can apply passwords and compute their hash. If two MD5 hashes match, the password is the same.
The scheme used by IOS for user passwords was never intended to resist adetermined, intelligent attack; it was designed to avoid casual"over-the-shoulder" password theft. The threat model was someone reading apassword from an administrator's screen. The scheme was never supposed toprotect against someone conducting a determined analysis of theconfiguration file.Because of the weak encryption algorithm, it has always been Cisco'sposition that customers should treat any configuration file containingpasswords as sensitive information, the same way they would treat acleartext list of passwords.Enable Secret Passwords- -----------------------Enable secrets are hashed using the MD5 algorithm. As far as anyone atCisco knows, it is impossible to recover an enable secret based on thecontents of a configuration file (other than by obvious dictionaryattacks).Note that this applies only to passwords set with "enable secret", *not*to passwords set with "enable password". Indeed, the strength of theencryption used is the only significant difference between the twocommands.
Interesting, I mainly write scripts, which i'm sure Ruby is good at, does it work with text as well as perl?
I'm wondering what the advantages of perl might be, i'm guessing maybe all the CPAN modules. I do like the interactive shell. The OO stuff i'm just getting familiar with, I believe in perl 5 the OO stuff is pretty built in and up to standards (so I read), but I don't know much about that. Other than reading:dog->speak "a dog goes bark"cat->speak "a cat goes meow,"
could also send and recieve the status like this:perl -e 'print "\xFF\xFF\xFF\xFFstatus\0"' | netcat -u tastyspleen.net 27912
I give the script the hash, and it certainly does come back with the password. Maybe the same thing will happen with MD5 eventually, you'll link to the quantom Amazon.com supercomputer or whatever : )
Objects in perl are easy enough to use; but I find classes and methods tedious to implement in perl. Tedious to the point where I would sometimes grudgingly fall back to writing procedural code in places where I really wanted an object, but felt it was too much of a PITA to bother with.
Quote from: quadzcould also send and recieve the status like this:perl -e 'print "\xFF\xFF\xFF\xFFstatus\0"' | netcat -u tastyspleen.net 27912Sure, or:ruby -e 'print "\xFF\xFF\xFF\xFFstatus\0"' | netcat -u tastyspleen.net 27912But that's more showcasing netcat rather than ruby or perl.
Always good for some nugget.http://www.codeproject.com/script/Surveys/Results.aspx?srvid=891Hardly, scientific. Never a large enough population of responders IMO but it might give a general indication of the trend in the industry.BTW, the FCS (Flight Control System) in the F-22 is written in C++ to very strict requirements for style, usage and test.
#!/usr/bin/perl#grabbing the lines in the router configuration file with the encrypted passwords, and operating on the encrypted pass by running the original algorithm in a reverse manner#hardcoded hex values with which we will XOR our password with to create the encrypted password@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53 , 0x55, 0x42 );while (<>) { if (/(password|md5)\s+7\s+([\da-f]+)/io) { #test for the lines with the encrypted pass "password 7 HEXSTRING" if (!(length($2) & 1)) { #testing that "HEXSTRING" is even, doing bit anding and want 1 returned for test $ep = $2; $dp = ""; #dp is going to be our password, ep is our encrypted pass ($s, $e) = ($2 =~ /^(..)(.+)/o); #place the first two chars of the encrypted pass in s, and the rest in e#s is our key, it's where we start in the translate table. who knows where it's originally derived from, the password or random. either way there are only 26 possible values#up to the length of the encrypted pass (not the first two chars of it, that's the key), loop through in increments of 2 for ($i = 0; $i < length($e); $i+=2) { $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++]; #take two chars of the encrypted pass at a time (starting two chars into the encrypted pass, $e) ,convert them to hex, and XOR them against the a hex value in the xlat array, specifically the index of the xlate array based on the first two chars of the encrypted pass. assign the ascci character representation, of the resulting XOR binary data to dp, keep adding to dp through the loop till the full pass is generated }#woooah, got the real pass!, take the line with the encrypted pass and replace it with the real deal s/7\s+$ep/$dp/; } }#print it out print;}# eof
<?echo "<div style=\"font-family:monospace\">";// encrypted: fdgsdfgsdfgdsgf1// real: adsfasfd$xlat = array( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53, 0x55, 0x42 );echo "<p>".nl2br(print_r($xlat,1))."</p>";$encrypted = '082Fasdfasfdas';$realpass = 'asdfasdf';$key = substr($encrypted,0,2);$startkey = base_convert($key,16,10);echo "<p>$key:$startkey</p>";$pass = str_split(substr($encrypted,2),2);echo "<p>".print_r($pass,1)."</p>";$newpass = '';foreach ($pass as $key=>$val) { $newpass .= chr(base_convert($val,16,10)^$xlat[$key+$startkey]); echo "<p>character $key: $val (",base_convert($val,16,10),"), xlat: ",$xlat[$key+$startkey],", converted: $newpass</p>";}echo "<p>----------REVERSE</p>";//$startkey = 8;$startkey = rand(0,25);$startpass = str_split($realpass);echo "<p>",print_r($startpass,1),"</p>";$encpass = str_pad(base_convert($startkey,10,16),2,"0",STR_PAD_LEFT);echo "<p>$encpass</p>";foreach ($startpass as $key=>$val) { $actualkey = $startkey + $key; if ($actualkey > 25) { $actualkey -= 26; } $thischar = str_pad(base_convert(ord($val)^$xlat[$actualkey],10,16),2,"0",STR_PAD_LEFT); $encpass.=$thischar; echo "step $key: $encpass<br />";}?>