Oracle default password checker script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DECLARE | |
TYPE t_table_of_vc30 IS TABLE OF VARCHAR2(30); | |
-- A bunch of obvious / default passwords, most of which are taken from | |
-- Pete Finnigan's list: | |
-- <http://www.petefinnigan.com/default/default_password_list.htm> | |
l_base_weak_passwords t_table_of_vc30 := t_table_of_vc30( | |
'dev' | |
, 'dev1' | |
, 'st' | |
, 'st1' | |
, 'uat' | |
, 'uat1' | |
, '6071992' | |
, '199220706' | |
, '0racl3' | |
, '0racl38' | |
, '0racl38i' | |
, '0racl39' | |
, '0racl39i' | |
, '0racle' | |
, '0racle8' | |
, '0racle8i' | |
, '0racle9' | |
, '0racle9i' | |
, 'abm' | |
, 'adgangskode' | |
, 'adldemo' | |
, 'admin' | |
, 'administrator' | |
, 'ahl' | |
, 'ahm' | |
, 'airoplane' | |
, 'ak' | |
, 'akf7d98s2' | |
, 'alr' | |
, 'ams' | |
, 'amv' | |
, 'anonymous' | |
, 'ap' | |
, 'applmgr' | |
, 'applsys' | |
, 'applsyspub' | |
, 'apppassword' | |
, 'apps' | |
, 'aq' | |
, 'aqdemo' | |
, 'aqjava' | |
, 'aquser' | |
, 'ar' | |
, 'asf' | |
, 'asg' | |
, 'asl' | |
, 'aso' | |
, 'asp' | |
, 'ast' | |
, 'audiouser' | |
, 'ax' | |
, 'az' | |
, 'bar' | |
, 'bc4j' | |
, 'ben' | |
, 'bic' | |
, 'bil' | |
, 'bim' | |
, 'bis' | |
, 'biv' | |
, 'bix' | |
, 'blewis' | |
, 'bom' | |
, 'brio_admin' | |
, 'bsc' | |
, 'bug_reports' | |
, 'catalog' | |
, 'cct' | |
, 'cdemo82' | |
, 'cdemo83' | |
, 'cdemocor' | |
, 'cdemorid' | |
, 'cdemoucb' | |
, 'cdouglas' | |
, 'ce' | |
, 'centra' | |
, 'central' | |
, 'change_on_install' | |
, 'cids' | |
, 'cis' | |
, 'cisinfo' | |
, 'clave' | |
, 'clerk' | |
, 'cloth' | |
, 'cn' | |
, 'company' | |
, 'compiere' | |
, 'crp' | |
, 'cs' | |
, 'csc' | |
, 'csd' | |
, 'cse' | |
, 'csf' | |
, 'csi' | |
, 'csl' | |
, 'csmig' | |
, 'csp' | |
, 'csr' | |
, 'css' | |
, 'ctxdemo' | |
, 'ctxsys' | |
, 'cua' | |
, 'cue' | |
, 'cuf' | |
, 'cug' | |
, 'cui' | |
, 'cun' | |
, 'cup' | |
, 'cus' | |
, 'cz' | |
, 'd_syspw' | |
, 'd_systpw' | |
, 'dbsnmp' | |
, 'dbvision' | |
, 'demo' | |
, 'demo8' | |
, 'demo9' | |
, 'des' | |
, 'des2k' | |
, 'dev2000_demos' | |
, 'dip' | |
, 'discoverer_admin' | |
, 'dmsys' | |
, 'dpfpass' | |
, 'dsgateway' | |
, 'dssys' | |
, 'dtsp' | |
, 'eaa' | |
, 'eam' | |
, 'east' | |
, 'ec' | |
, 'ecx' | |
, 'ejb' | |
, 'ejsadmin' | |
, 'ejsadmin_password' | |
, 'emp' | |
, 'eng' | |
, 'eni' | |
, 'estore' | |
, 'event' | |
, 'evm' | |
, 'example' | |
, 'exfsys' | |
, 'extdemo' | |
, 'extdemo2' | |
, 'fa' | |
, 'fem' | |
, 'fii' | |
, 'finance' | |
, 'finprod' | |
, 'flm' | |
, 'fnd' | |
, 'fndpub' | |
, 'fpt' | |
, 'frm' | |
, 'fte' | |
, 'fv' | |
, 'gl' | |
, 'gma' | |
, 'gmd' | |
, 'gme' | |
, 'gmf' | |
, 'gmi' | |
, 'gml' | |
, 'gmp' | |
, 'gms' | |
, 'gpfd' | |
, 'gpld' | |
, 'gr' | |
, 'hades' | |
, 'hcpark' | |
, 'hlw' | |
, 'hobbes' | |
, 'hr' | |
, 'hri' | |
, 'hvst' | |
, 'hxc' | |
, 'hxt' | |
, 'iba' | |
, 'ibe' | |
, 'ibp' | |
, 'ibu' | |
, 'iby' | |
, 'icdbown' | |
, 'icx' | |
, 'idemo_user' | |
, 'ieb' | |
, 'iec' | |
, 'iem' | |
, 'ieo' | |
, 'ies' | |
, 'ieu' | |
, 'iex' | |
, 'ifssys' | |
, 'igc' | |
, 'igf' | |
, 'igi' | |
, 'igs' | |
, 'igw' | |
, 'imageuser' | |
, 'imc' | |
, 'imedia' | |
, 'imt' | |
, 'instance' | |
, 'inv' | |
, 'invalid' | |
, 'ipa' | |
, 'ipd' | |
, 'iplanet' | |
, 'isc' | |
, 'itg' | |
, 'ja' | |
, 'je' | |
, 'jetspeed' | |
, 'jg' | |
, 'jl ' | |
, 'jmuser' | |
, 'john' | |
, 'jtf' | |
, 'jtm' | |
, 'jts' | |
, 'kwalker' | |
, 'l2ldemo' | |
, 'laskjdf098ksdaf09' | |
, 'lbacsys' | |
, 'manag3r' | |
, 'manager' | |
, 'manprod' | |
, 'mddata' | |
, 'mddemo' | |
, 'mddemo_mgr' | |
, 'mdsys' | |
, 'me' | |
, 'mfg' | |
, 'mgr' | |
, 'mgwuser' | |
, 'migrate' | |
, 'miller' | |
, 'mmo2' | |
, 'mmo3' | |
, 'moreau' | |
, 'mot_de_passe' | |
, 'mrp' | |
, 'msc' | |
, 'msd' | |
, 'mso' | |
, 'msr' | |
, 'mt6ch5' | |
, 'mtrpw' | |
, 'mts_password' | |
, 'mtssys' | |
, 'mumblefratz' | |
, 'mwa' | |
, 'mxagent' | |
, 'names' | |
, 'neotix_sys' | |
, 'nneulpass' | |
, 'oas_public' | |
, 'ocitest' | |
, 'ocm_db_admin' | |
, 'odm' | |
, 'ods' | |
, 'ods_server' | |
, 'odscommon' | |
, 'oe' | |
, 'oem_temp' | |
, 'oemadm' | |
, 'oemrep' | |
, 'okb' | |
, 'okc' | |
, 'oke' | |
, 'oki' | |
, 'oko' | |
, 'okr' | |
, 'oks' | |
, 'okx' | |
, 'olapdba' | |
, 'olapsvr' | |
, 'olapsys' | |
, 'ont' | |
, 'oo' | |
, 'openspirit' | |
, 'opi' | |
, 'oracache' | |
, 'oracl3' | |
, 'oracle' | |
, 'oracle8' | |
, 'oracle8i' | |
, 'oracle9' | |
, 'oracle9i' | |
, 'oradbapass' | |
, 'oraprobe' | |
, 'oraregsys' | |
, 'orasso' | |
, 'orasso_ds' | |
, 'orasso_pa' | |
, 'orasso_ps' | |
, 'orasso_public' | |
, 'orastat' | |
, 'ordcommon' | |
, 'ordplugins' | |
, 'ordsys' | |
, 'osm' | |
, 'osp22' | |
, 'ota' | |
, 'outln' | |
, 'owa' | |
, 'owa_public' | |
, 'owf_mgr' | |
, 'owner' | |
, 'ozf' | |
, 'ozp' | |
, 'ozs' | |
, 'pa' | |
, 'panama' | |
, 'paper' | |
, 'parol' | |
, 'passwd' | |
, 'passwo1' | |
, 'passwo2' | |
, 'passwo3' | |
, 'passwo4' | |
, 'password' | |
, 'patrol' | |
, 'paul' | |
, 'perfstat' | |
, 'perstat' | |
, 'pjm' | |
, 'planning' | |
, 'plex' | |
, 'pm' | |
, 'pmi' | |
, 'pn' | |
, 'po' | |
, 'po7' | |
, 'po8' | |
, 'poa' | |
, 'pom' | |
, 'portal_demo' | |
, 'portal_sso_ps' | |
, 'portal30' | |
, 'portal30_admin' | |
, 'portal30_demo' | |
, 'portal30_ps' | |
, 'portal30_public' | |
, 'portal30_sso' | |
, 'portal30_sso_admin' | |
, 'portal30_sso_ps' | |
, 'portal30_sso_public' | |
, 'portal31' | |
, 'pos' | |
, 'powercartuser' | |
, 'primary' | |
, 'psa' | |
, 'psb' | |
, 'psp' | |
, 'pub' | |
, 'pubsub' | |
, 'pubsub1' | |
, 'pv' | |
, 'qa' | |
, 'qdba' | |
, 'qp' | |
, 'qs' | |
, 'qs_adm' | |
, 'qs_cb' | |
, 'qs_cbadm' | |
, 'qs_cs' | |
, 'qs_es' | |
, 'qs_os' | |
, 'qs_ws' | |
, 're' | |
, 'rep_owner' | |
, 'repadmin' | |
, 'reports' | |
, 'rg' | |
, 'rhx' | |
, 'rla' | |
, 'rlm' | |
, 'rmail' | |
, 'rman' | |
, 'rrs' | |
, 'sample' | |
, 'sampleatm' | |
, 'sap' | |
, 'sapr3' | |
, 'sdos_icsap' | |
, 'secdemo' | |
, 'senha' | |
, 'serviceconsumer1' | |
, 'sh' | |
, 'shelves' | |
, 'si_informtn_schema' | |
, 'siteminder' | |
, 'slidepw' | |
, 'snowman' | |
, 'spierson' | |
, 'ssp' | |
, 'starter' | |
, 'steel' | |
, 'strat_passwd' | |
, 'supersecret' | |
, 'support' | |
, 'swordfish' | |
, 'swpro' | |
, 'swuser' | |
, 'sympa' | |
, 'sys' | |
, 'sys_stnt' | |
, 'sysadm' | |
, 'sysadmin' | |
, 'sysman' | |
, 'syspass' | |
, 'system' | |
, 'systempass' | |
, 'tahiti' | |
, 'tdos_icsap' | |
, 'tectec' | |
, 'test' | |
, 'test_user' | |
, 'testpilot' | |
, 'thinsamplepw' | |
, 'tibco' | |
, 'tiger' | |
, 'tigger' | |
, 'tip37' | |
, 'trace' | |
, 'travel' | |
, 'tsdev' | |
, 'tsuser' | |
, 'turbine' | |
, 'ultimate' | |
, 'um_admin' | |
, 'um_client' | |
, 'unknown' | |
, 'user' | |
, 'user0' | |
, 'user1' | |
, 'user2' | |
, 'user3' | |
, 'user4' | |
, 'user5' | |
, 'user6' | |
, 'user7' | |
, 'user8' | |
, 'user9' | |
, 'utility' | |
, 'utlestat' | |
, 'vea' | |
, 'veh' | |
, 'vertex_login' | |
, 'videouser' | |
, 'vif_dev_pwd' | |
, 'viruser' | |
, 'vrr1' | |
, 'vrr2' | |
, 'webcal01' | |
, 'webdb' | |
, 'webread' | |
, 'welcome' | |
, 'west' | |
, 'wfadmin' | |
, 'wh' | |
, 'wip' | |
, 'wk_test' | |
, 'wkadmin' | |
, 'wkproxy' | |
, 'wksys' | |
, 'wkuser' | |
, 'wms' | |
, 'wmsys' | |
, 'wob' | |
, 'wood' | |
, 'wps' | |
, 'wsh' | |
, 'wsm' | |
, 'www' | |
, 'wwwuser' | |
, 'xademo' | |
, 'xdp' | |
, 'xla' | |
, 'xnc' | |
, 'xni' | |
, 'xnm' | |
, 'xnp' | |
, 'xns' | |
, 'xprt' | |
, 'xtr' | |
, 'xxx' | |
, 'yes' | |
, 'your_pass' | |
, 'zwerg' | |
); | |
l_username_passwords t_table_of_vc30; | |
l_test_10g_passwords t_table_of_vc30; | |
l_test_11g_passwords t_table_of_vc30; | |
l_temp t_table_of_vc30 := t_table_of_vc30(); | |
l_counter_for_summary PLS_INTEGER := 0; | |
l_10g_pwd_count PLS_INTEGER; | |
l_not_upgraded_pwd_count PLS_INTEGER; | |
-- SHA1 hashes the password mimicking the Oracle 11g implementation | |
FUNCTION password_hash ( | |
p_password VARCHAR2 | |
, p_salt VARCHAR2 | |
) | |
RETURN VARCHAR2 | |
IS | |
BEGIN | |
RETURN dbms_crypto.hash( | |
src => utl_raw.cast_to_raw(p_password)||hextoraw(p_salt) | |
, typ => dbms_crypto.HASH_SH1 | |
); | |
END password_hash; | |
-- Builds up the spare4 column syntax (as per 11g password storage model) | |
FUNCTION generate_spare4 ( | |
p_password VARCHAR2 | |
, p_salt VARCHAR2 | |
) | |
RETURN VARCHAR2 | |
IS | |
BEGIN | |
RETURN 'S:' || password_hash(p_password, p_salt) || p_salt; | |
END generate_spare4; | |
-- Builds up an Oracle 10g (and prior) password hash | |
-- Derived from Pete Finnigan's password cracking routines: | |
-- <http://www.petefinnigan.com/oracle_password_cracker.htm> | |
FUNCTION generate_10g_password ( | |
p_username VARCHAR2 | |
, p_password VARCHAR2 | |
) | |
RETURN VARCHAR2 | |
IS | |
DES_KEY CONSTANT RAW(128) := HEXTORAW('0123456789ABCDEF'); | |
l_username_password VARCHAR2(70); | |
l_username_password_length PLS_INTEGER; | |
l_encoded_string VARCHAR2(124); | |
l_length_modulus PLS_INTEGER; | |
l_username_password_raw RAW(2048); | |
l_des_first_pass_raw RAW(2048); | |
l_key2 RAW(128); | |
l_password_hash_raw RAW(2048); | |
l_hex_str VARCHAR2(2048); | |
l_hex_str_length PLS_INTEGER; | |
l_10g_password_hash VARCHAR2(16); | |
BEGIN | |
l_username_password := UPPER(p_username) || UPPER(p_password); | |
l_username_password_length := LENGTH(l_username_password); | |
-- Pad each character in the string with a zero byte sequence | |
FOR i IN 1 .. l_username_password_length LOOP | |
l_encoded_string := l_encoded_string || CHR(0) || SUBSTR(l_username_password, i, 1); | |
END LOOP; | |
-- Pad the whole string so it aligns to an 8 byte boundary | |
l_length_modulus := MOD(LENGTH(l_encoded_string), 8); | |
IF l_length_modulus > 0 THEN | |
l_encoded_string := RPAD(l_encoded_string, LENGTH(l_encoded_string) + 8 - l_length_modulus, CHR(0)); | |
END IF; | |
-- Cast the encoded string as a RAW for DES | |
l_username_password_raw := utl_raw.cast_to_raw(l_encoded_string); | |
-- First pass DES | |
l_des_first_pass_raw := dbms_obfuscation_toolkit.DESEncrypt( | |
input => l_username_password_raw | |
, key => DES_KEY | |
); | |
l_hex_str := RAWTOHEX(l_des_first_pass_raw); | |
l_hex_str_length := LENGTH(l_hex_str); | |
l_key2 := HEXTORAW(SUBSTR(l_hex_str, (l_hex_str_length - 16 + 1), 16)); | |
-- Second pass DES | |
l_password_hash_raw := dbms_obfuscation_toolkit.DESEncrypt( | |
input => l_username_password_raw | |
, key => l_key2 | |
); | |
l_hex_str := HEXTORAW(l_password_hash_raw); | |
l_hex_str_length := LENGTH(l_hex_str); | |
l_10g_password_hash := SUBSTR(l_hex_str,(l_hex_str_length - 16 + 1),16); | |
RETURN l_10g_password_hash; | |
END generate_10g_password; | |
BEGIN | |
-- Check for instances where password is a username (not necessarily the same user) | |
SELECT username | |
BULK COLLECT INTO l_username_passwords | |
FROM dba_users; | |
-- 10g passwords are case insensitive, so just add the usernames to the set (they'll all get UPPER'd anyway) | |
l_test_10g_passwords := l_base_weak_passwords MULTISET UNION DISTINCT l_username_passwords; | |
-- Now lower, upper, initcap each password for some crude variations for 11g password storage checks (case sensitive) | |
FOR idx IN l_test_10g_passwords.FIRST .. l_test_10g_passwords.LAST LOOP | |
l_temp.EXTEND(3); | |
l_temp(l_temp.COUNT - 2) := LOWER(l_test_10g_passwords(idx)); | |
l_temp(l_temp.COUNT - 1) := UPPER(l_test_10g_passwords(idx)); | |
l_temp(l_temp.COUNT) := INITCAP(l_test_10g_passwords(idx)); | |
END LOOP; | |
l_test_11g_passwords := l_test_10g_passwords MULTISET UNION DISTINCT l_temp; | |
<<user_loop>> | |
FOR r_user IN ( | |
SELECT | |
usr.name | |
, usr.password | |
, usr.spare4 | |
, SUBSTR(usr.spare4,-20) salt | |
FROM sys.user$ usr | |
WHERE EXISTS ( | |
SELECT 1 | |
FROM dba_users dusr | |
WHERE dusr.username = usr.name | |
AND dusr.account_status = 'OPEN' | |
) | |
ORDER BY usr.name | |
) | |
LOOP | |
-- Only check the 10g hash if an 11g hash isn't stored, no need to check both | |
IF r_user.spare4 IS NULL AND r_user.password IS NOT NULL THEN | |
<<test_10g_password_loop>> | |
FOR idx IN l_test_10g_passwords.FIRST .. l_test_10g_passwords.LAST LOOP | |
IF r_user.password = generate_10g_password(r_user.name, l_test_10g_passwords(idx)) THEN | |
dbms_output.put_line('User ' || r_user.name || ' has a predictable password (NB: stored in less secure 10g format)'); | |
l_counter_for_summary := l_counter_for_summary + 1; | |
CONTINUE user_loop; | |
END IF; | |
END LOOP; | |
END IF; | |
-- Always check the 11g hashes if they are present | |
IF r_user.spare4 IS NOT NULL THEN | |
<<test_11g_password_loop>> | |
FOR idx IN l_test_11g_passwords.FIRST .. l_test_11g_passwords.LAST LOOP | |
IF r_user.spare4 = generate_spare4(l_test_11g_passwords(idx), r_user.salt) THEN | |
dbms_output.put_line('User ' || r_user.name || ' has a predictable password'); | |
l_counter_for_summary := l_counter_for_summary + 1; | |
CONTINUE user_loop; | |
END IF; | |
END LOOP; | |
END IF; | |
END LOOP user_loop; | |
SELECT | |
COUNT(*) | |
, SUM(CASE WHEN usr.spare4 IS NULL THEN 1 ELSE 0 END) | |
INTO | |
l_10g_pwd_count | |
, l_not_upgraded_pwd_count | |
FROM sys.user$ usr | |
WHERE EXISTS ( | |
SELECT 1 | |
FROM dba_users dusr | |
WHERE dusr.username = usr.name | |
AND dusr.account_status = 'OPEN' | |
) | |
AND usr.password IS NOT NULL; | |
IF l_counter_for_summary = 0 THEN | |
dbms_output.put_line('** No unlocked users found with weak passwords'); | |
ELSIF l_counter_for_summary > 0 THEN | |
dbms_output.put_line('** Number of users with weak passwords: ' || l_counter_for_summary); | |
END IF; | |
IF l_10g_pwd_count > 0 THEN | |
dbms_output.put_line('** Number of users with password stored in 10g format: ' || l_10g_pwd_count); | |
dbms_output.put_line('** Number of users with password stored *only* in 10g format: ' || l_not_upgraded_pwd_count); | |
dbms_output.put_line('** If you do not require 10g compatibility, you should NULL out the old hashes from sys.user$ ("password" column) to increase security.'); | |
END IF; | |
END; | |
/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment