-- get passwords from a database -- V1.00 -- by Alexander Kornbrust Red-Database-Security GmbH -- -- detects passwords in tables -- detects different hashing algorithms (MD2/MD4/MD5, SHA1, SHA2) -- detects different encodings -- detects salt/no-salt -- detecs cesar chiffre -- set serveroutput on size 1000000 declare samelength integer; isMD5 integer; isSHA1 integer; isSHA2 integer; isBASE64 integer; ishex integer; hasSALT integer; numpasswords integer; vc1 varchar2(256); vc2 varchar2(256); -- haslo = polish -- MDP= mot de passe = french -- mot de passe = french -- clave = spanish -- senha = portugese -- lozinka = croatian -- jelszó = hungarian -- wachtwoord = dutch -- wagword = africaans -- lösen = swedish -- fjalëkalim = albanian -- parool = estonian -- drowssap = hebrew -- sandi = indonesian -- parole = latvian -- geslo = slovene -- -- -- cursor custpasswords is select owner,table_name,column_name,data_type, data_length from dba_tab_columns where ( upper(column_name) like 'PWD' or upper(column_name) like 'PASS' or upper(column_name) like 'MDP' or upper(column_name) like 'MOTSDEPASSE' or upper(column_name) like 'HASLO' or upper(column_name) like 'CLAVE' or upper(column_name) like 'SENHA' or upper(column_name) like 'JELZO' or upper(column_name) like 'LOZINKA' or upper(column_name) like 'HASLO' or upper(column_name) like 'WACHTWOORD' or upper(column_name) like 'WAGWORD' or upper(column_name) like 'PAROOL' or upper(column_name) like 'PAROLE' or upper(column_name) like 'DROWSSAP' or upper(column_name) like 'SANDI' or upper(column_name) like 'GESLO' or upper(column_name) like 'PASSWORT' or upper(column_name) like 'PASSWORTHASH' or upper(column_name) like 'PASSWORDHASH' or upper(column_name) like 'KENNWORT' or upper(column_name) like 'PASSW' or upper(column_name) like 'PASSWD' or upper(column_name) like 'PASSWORD' or upper(column_name) like 'PWORD' or upper(column_name) like 'PSW' or upper(column_name) like 'USERPASSWORD' or upper(column_name) like 'USER_PASSWORD' or upper(column_name) like 'PASSWORDS' or upper(column_name) like 'ZPASSWORD' or upper(column_name) like 'PROXYPASSWORD' or upper(column_name) like 'PROXY_PASSWORD' or upper(column_name) like 'PC_PASSWORD' or upper(column_name) like 'REMOTE_PASSWORD' or upper(column_name) like 'WALLET_PASSWORD' --or upper(column_name) like 'WEB_PASSWORD' --or upper(column_name) like 'WEB_PASSWORD2' ) and (owner not in ('SYS','WKSYS','SH')) and (data_type in ('CHAR','VARCHAR2','VARCHAR','NCHAR','NVARCHAR2')); pwcandidates custpasswords%ROWTYPE; begin dbms_output.put_line('BEGIN'); open custpasswords; -- open cursor loop fetch custpasswords into pwcandidates; -- retrieve owner, tablename, data_type and password begin dbms_output.put_line('select '||pwcandidates.column_name||' from '||pwcandidates.owner||'.'||pwcandidates.table_name); dbms_output.put_line('Typ='||pwcandidates.data_type||'('||pwcandidates.data_length||')' ); -- if value >1 then no hashing scheme is used -- fix sql injection execute immediate 'select count(*) from (select len,count(*) from (select length('||pwcandidates.column_name||') LEN from '||pwcandidates.owner||'.'||pwcandidates.table_name||') group by len)' into samelength; --dbms_output.put_line('number='||to_char(samelength)); execute immediate 'select count(*) from '||pwcandidates.owner||'.'||pwcandidates.table_name||' where '||pwcandidates.column_name||' is not null' into numpasswords; dbms_output.put_line('number of passwords='||to_char(numpasswords)); -- analayze if the password is hex execute immediate 'select max(nvl(length(translate( upper('||pwcandidates.column_name||'),''$0123456789ABCDEF'',''$'')),0)) from '||pwcandidates.owner||'.'||pwcandidates.table_name||' where '||pwcandidates.column_name||' is not null' into ishex; if (ishex = 0) then dbms_output.put_line('Password string is hex'); end if; if (ishex > 0) then dbms_output.put_line('Password string is NOT always hex'); end if; if (samelength=1) then dbms_output.put_line('HASH algorithm detected'); execute immediate 'select '||pwcandidates.column_name||' from '||pwcandidates.owner||'.'||pwcandidates.table_name||' where '||pwcandidates.column_name||' is not null and rownum=1' into vc1; dbms_output.put_line('hash='||vc1); if length(vc1)=32 then dbms_output.put_line('possible MD2/MD4 or MD5'); END IF; if length(vc1)=40 then dbms_output.put_line('possible SHA-1'); END IF; if length(vc1)=64 then dbms_output.put_line('possible SHA-2 (256)'); END IF; if length(vc1)=96 then dbms_output.put_line('possible SHA-2 (384)'); END IF; if length(vc1)=128 then dbms_output.put_line('possible SHA-2 (512)'); END IF; if length(vc1)=1024 then dbms_output.put_line('possible RSA Key'); END IF; if length(vc1)=2048 then dbms_output.put_line('possible RSA Key'); END IF; -- check for salt --select count(*) from (select password, count(*) anzahl from us1.password where password is not null group by password having count(*) > 1) execute immediate 'select count(*) from (select password, count(*) anzahl from us1.password where password is not null group by password having count(*) > 1)' into hasSALT; if (hasSALT>0) then dbms_output.put_line('No salt in use'); end if; if (hasSALT=0) then dbms_output.put_line('Possibly salt is used'); end if; end if; if (samelength>1) then dbms_output.put_line('No hash algorithm detected'); --dbms_output.put_line('substr='||substr(); -- check for BASE64 --select substr(passwort,length(passwort),1) from us1.mytable2; execute immediate 'select substr('||pwcandidates.column_name||',length('||pwcandidates.column_name||'),1) from '||pwcandidates.owner||'.'||pwcandidates.table_name||' where '||pwcandidates.column_name||' is not null and rownum=1' into vc1; if (vc1='=') then dbms_output.put_line('possible BASE64'); END IF; END IF; --execute immediate 'select length(*) from '|| pwcandidates.owner||'.'||pwcandidates.table_name||'' exit when custpasswords%NOTFOUND; dbms_output.put_line('++++++++++++++++++++++++++++++++'); exception when others then null; end; end loop; close custpasswords; dbms_output.put_line('END'); end; /