#!/usr/bin/env perl use MIME::Base64; # # example Outlook 2010 AUTH NTLM strings and decoding # pi -at- opsec.eu, Mon Nov 1 17:18:26 CET 2010 # format decoded according to # http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NLMP%5D.pdf # and # http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NLMP%5D.pdf # $inp='TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAFASgKAAAADw=='; $inp='TlRMTVNTUAACAAAAAAAAAAAoAAABggAAbQ91RfU/iQAAAAAAAAAAAAAAAAAAAAAA'; $res = decode_base64($inp); $sig = substr($res,0,7); # has to be NTLMSSP\0 if ( $sig ne 'NTLMSSP' ) { print "sig bad: '$sig'\n"; } else { print "sig good: '$sig'\n"; } @msgtype = split(//,substr($res,8,4)); if ( ord($msgtype[0]) >= 1 && ord($msgtype[0]) < 4 ) { print "msgtype good: "; if ( ord($msgtype[0]) == 1 ) { print "NEGOTIATE "; $type = 1; } elsif ( ord($msgtype[0]) == 2 ) { print "CHALLENGE "; $type = 2; } elsif ( ord($msgtype[0]) == 3 ) { print "AUTHENTICATE "; $type = 3; } } else { print "msgtype bad: "; } foreach $c ( @msgtype ) { print ord($c).' '; } print "\n"; @msg = split(//,substr($res,12,12)); if ( $type == 1 ) { print "negflags: "; foreach $i ( 0..3 ) { print ord($msg[$i]).' '; } print "\n"; $bits = unpack("b32",substr($res,12,4)); print "bits: $bits\n"; if ( substr($bits,0,1) eq '1' ) { print "\tNEGOTIATE_56\n"; } if ( substr($bits,1,1) eq '1' ) { print "\tNEGOTIATE_KEY_EXCH\n"; } if ( substr($bits,2,1) eq '1' ) { print "\tNEGOTIATE_128\n"; } if ( substr($bits,3,1) eq '1' ) { print "\terror: r1-should-be-0\n"; } if ( substr($bits,4,1) eq '1' ) { print "\terror: r2-should-be-0\n"; } if ( substr($bits,5,1) eq '1' ) { print "\terror: r3-should-be-0\n"; } if ( substr($bits,6,1) eq '1' ) { print "\tNEGOTIATE_VERSION\n"; } if ( substr($bits,7,1) eq '1' ) { print "\terror: r4-should-be-0\n"; } if ( substr($bits,8,1) eq '1' ) { print "\tNEGOTIATE_TARGET_INFO\n"; } if ( substr($bits,9,1) eq '1' ) { print "\tREQUEST_NON_NT_SESSION_KEY\n"; } if ( substr($bits,10,1) eq '1' ) { print "\terror: r5-should-be-0\n"; } if ( substr($bits,11,1) eq '1' ) { print "\tNEGOTIATE_IDENTITY\n"; } if ( substr($bits,12,1) eq '1' ) { print "\tNEGOTIATE_EXTENDED_SESSIONSECURITY\n"; } if ( substr($bits,13,1) eq '1' ) { print "\terror: r6-should-be-0\n"; } if ( substr($bits,14,1) eq '1' ) { print "\tTARGET_TYPE_SERVER\n"; } if ( substr($bits,15,1) eq '1' ) { print "\tTARGET_TYPE_DOMAIN\n"; } if ( substr($bits,16,1) eq '1' ) { print "\tNEGOTIATE_ALWAYS_SIGN\n"; } if ( substr($bits,17,1) eq '1' ) { print "\terror: r7-should-be-0\n"; } if ( substr($bits,18,1) eq '1' ) { print "\tNEGOTIATE_OEM_WORKSTATION_SUPPLIED\n"; } if ( substr($bits,19,1) eq '1' ) { print "\tNEGOTIATE_OEM_DOMAIN_SUPPLIED\n"; } if ( substr($bits,20,1) eq '1' ) { print "\tconnection should be anonumous\n"; } if ( substr($bits,21,1) eq '1' ) { print "\terror: r8-should-be-0\n"; } if ( substr($bits,22,1) eq '1' ) { print "\tNEGOTIATE_NTLM\n"; } if ( substr($bits,23,1) eq '1' ) { print "\terror: r9-should-be-0\n"; } if ( substr($bits,24,1) eq '1' ) { print "\tNEGOTIATE_LM_KEY\n"; } if ( substr($bits,25,1) eq '1' ) { print "\tNEGOTIATE_DATAGRAM\n"; } if ( substr($bits,26,1) eq '1' ) { print "\tNEGOTIATE_SEAL\n"; } if ( substr($bits,27,1) eq '1' ) { print "\tNEGOTIATE_SIGN\n"; } if ( substr($bits,28,1) eq '1' ) { print "\terror: r10-should-be-0\n"; } if ( substr($bits,29,1) eq '1' ) { print "\tREQUEST_TARGET\n"; } if ( substr($bits,30,1) eq '1' ) { print "\tNEGOTIATE_OEM\n"; } if ( substr($bits,31,1) eq '1' ) { print "\tNEGOTIATE_UNICODE\n"; } print "DomainNameFields: "; foreach $i ( 4..11 ) { print ord($msg[$i]).' '; } print "\n"; } elsif ( $type == 2 ) { $len = length($res); print "length: $len\n"; print "TargetNameFields: "; @t = split(//,substr($res,12,8)); foreach $i ( 0..7 ) { print ord($t[$i]).' '; } print "\n"; print "NegotiateFlags: "; @t = split(//,substr($res,20,4)); foreach $i ( 0..3 ) { print ord($t[$i]).' '; } print "\n"; print "ServerChallenge: "; @t = split(//,substr($res,24,8)); foreach $i ( 0..7 ) { print ord($t[$i]).' '; } print "\n"; print "Reserved: "; @t = split(//,substr($res,32,8)); foreach $i ( 0..7 ) { print ord($t[$i]).' '; } print "\n"; print "TargetInfoFields: "; @t = split(//,substr($res,40,8)); foreach $i ( 0..7 ) { print ord($t[$i]).' '; } print "\n"; print "Version: "; @t = split(//,substr($res,48,8)); foreach $i ( 0..7 ) { print ord($t[$i]).' '; } print "\n"; }