OpenVMS Source Code Demos
PASSWORD-SEARCH-102.BAS
1000 %title "password_search_xxx.bas"
%ident "version_102"
!====================================================================================================
! title : password_search_xxx.bas
! author : Neil Rieck (Waterloo, Ontario, Canada)
! : (https://neilrieck.net) (mailto:n.rieck@bell.net)
! purpose: search for a lost password (just to see if I could do it)
! history:
! who ver when what
! NSR 100 010823 1. original program
! NSR 101 010824 1. added a sequential password generator (this was a quick hack)
! NSR 102 010827 1. improved performance of the password generator (still needs a rewrite)
!====================================================================================================
option type=explicit ! no kid stuff
option size = (real double)
set no prompt
declare long my_count, time1, time2
time1 = time(0)
!
declare string constant ! &
k_version$ = "password_search_102" , ! program title &
k_error_severity$ = "WSEIF???" , ! error severity &
k_pass_chars$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$" ! legal password chars
!
! <<< system declarations >>>
!
%include "starlet" %from %library "sys$library:basic$starlet" ! system services
%include "$ssdef" %from %library "sys$library:basic$starlet" ! ss$
%include "$uaidef" %from %library "sys$library:basic$starlet" ! uai$
!
%if %declared (%ITEMREC) = 0 %then
record ItemRec ! structure of item record
variant
case
group one
word BuffLen
word ItemCode
long BuffAddr
long RtnLenAdr
end group one
case
group two
long List_Terminator
long Junk1
long Junk2
end group two
end variant
end record ItemRec
%let %ITEMREC = 1
%end %if
!
! <<< my variable declarations >>>
!
declare basic$quadword hashed_password ,&
trial_hash ,&
ItemRec myItems(9) ,&
long rc% ,&
rc_bits% ,&
cur_pos% ,&
max_pos% ,&
hit% ,&
min_pwd_length% ,&
max_pwd_length% ,&
i% ,&
double seed ,&
max_seed ,&
string trial_password$ ,&
user_name$ ,&
junk$ ,&
word salt ,&
byte encrytion_type% ,&
min_pwd_length_uaf%
!
! chunk$ + pieces occupy the same memory location
!
map(overlay1)string chunk$=32 ! 1-32
map(overlay1)byte pieces(31) ! 0-31
!
map(tally)long tally(31) ! 0-31
!
map(my_data)byte my_data(38) ! 1-38 (we'll ignore subscript 0)
!
!====================================================================================================
!
! <<< Main >>>
!
print k_version$
print string$(len(k_version$),45%)
input "user name? (default=quit) ";user_name$
user_name$ = edit$(user_name$,32%+4%+2%)
print "user=",user_name$
!
myItems(0)::BuffLen = 4% ! size of encrytion_type% in bytes
myItems(0)::ItemCode = UAI$_ENCRYPT !
myItems(0)::BuffAddr = loc(encrytion_type%) ! addr of encrytion_type%
myItems(0)::RtnLenAdr = 0% ! bytes returned (don't care)
!
myItems(1)::BuffLen = 8% ! size of hashed_password in bytes
myItems(1)::ItemCode = UAI$_PWD !
myItems(1)::BuffAddr = loc(hashed_password) ! addr of hashed_password
myItems(1)::RtnLenAdr = 0% ! bytes returned (don't care)
!
myItems(2)::BuffLen = 2% ! size of salt in bytes
myItems(2)::ItemCode = UAI$_SALT !
myItems(2)::BuffAddr = loc(salt) ! addr of salt
myItems(2)::RtnLenAdr = 0% ! bytes returned (don't care)
!
myItems(3)::BuffLen = 1% ! size of salt in bytes
myItems(3)::ItemCode = UAI$_PWD_LENGTH !
myItems(3)::BuffAddr = loc(min_pwd_length_uaf%) ! addr of min_pwd_length_uaf
myItems(3)::RtnLenAdr = 0% ! bytes returned (don't care)
!
myItems(4)::List_Terminator = 0%
!
! SYS$GETUAI [nullarg] ,[contxt] ,usrnam ,itmlst ,[nullarg] ,[nullarg] ,[nullarg]
!
rc% = sys$getuai(,,user_name$,myItems(0),,,)
rc_bits% = (rc% and 7%)
if rc_bits% <> 1% then
print "$getuai-"+ mid$(k_error_severity$, rc_bits%+1%, 1%) +"-rc: "+str$(rc%)
goto sortie
end if
!
print "minimum password length from SYSUAF : "+ str$(min_pwd_length_uaf%)
print "starting password length ? (01-32,default=quit): ";
input junk$
when error in
min_pwd_length% = integer(junk$)
use
min_pwd_length% = 0%
end when
select min_pwd_length%
case 1% to 32%
case else
print "-e- bad value, exiting"
goto sortie
end select
!
print "ending password length ? ("+ format$(min_pwd_length%,"<0>#") +"-32,default=quit): ";
input junk$
when error in
max_pwd_length% = integer(junk$)
use
max_pwd_length% = 0%
end when
select max_pwd_length%
case min_pwd_length% to 32%
case else
print "-e- bad value, exiting"
goto sortie
end select
!
! <<< generate a sequence of possible passwords >>>
!
hit% = 0% !
chunk$ = "" ! zap chunk (and pieces)
mat tally = zer ! zap tally array
my_data(0%) = 0% !
for i% = 1% to 38% !
my_data(i%) = asc( mid$(k_pass_chars$, i%, 1%) ) ! populate my_data
next i% !
max_pos% = 0% !
for i% = 0% to min_pwd_length%-1% !
tally(i%) = 1% ! wrap around (but skip 0)
pieces(i%)= my_data( tally(cur_pos%) ) !
next i% !
cur_pos% = min_pwd_length%-1% !
max_pos% = cur_pos% !
goto first_pass !
!
! tally sequences examples: 31 ... 4 3 2 1 0
! 1 0 0 0 0 1-38
! 2.a 0 0 0 1-38 1
! 2.b 0 0 0 1-38 2
! .
! 2.c 0 0 0 1-38 38
! 3.a 0 0 1-38 1 1
!
loop1:
cur_pos% = 0% ! start in position #0
loop2:
if tally(cur_pos%) < len(k_pass_chars$) ! do we have room to incr this column?
then ! yes
tally(cur_pos%) = tally(cur_pos%) + 1% !
pieces(cur_pos%)= my_data( tally(cur_pos%) ) !
else ! no, so wrap, then move on
tally(cur_pos%) = 1% ! wrap around (but skip 0)
pieces(cur_pos%)= my_data( tally(cur_pos%) ) !
cur_pos% = cur_pos% + 1% ! advance cur_pos%
max_pos% = max(cur_pos%, max_pos%) ! remember highest column
goto loop2 if cur_pos% <= max_pwd_length%-1% ! if we haven't done max columns...
print "-e-password not found" !
goto sortie !
end if !
first_pass:
!~~~ trial_password$ = edit$(chunk$,128%) x
trial_password$ = left$(chunk$,max_pos%+1%) ! possibly more efficient...
!
! SYS$HASH_PASSWORD pwd ,alg ,[salt] ,usrnam ,hash
!
my_count = my_count + 1%
if my_count = 1000000% then
time2 = time(0)
print time2 - time1
end if
try_passwords:
rc% = sys$hash_password(trial_password$,encrytion_type%,salt,user_name$,trial_hash)
rc_bits% = (rc% and 7%)
if rc_bits% <> 1% then
print "$hash_password-"+ mid$(k_error_severity$, rc_bits%+1%, 1%) +"-rc: "+str$(rc%)
goto sortie
end if
if trial_hash = hashed_password then
print "-s- match: ";trial_password$
goto sortie
end if
goto loop1
!
! <<< adios... >>>
!
sortie:
end
Back to
Home
Neil Rieck
Waterloo, Ontario, Canada.