[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 安全技術 > 加密與破解 > 正文
運用CrackLib構建安全的Unix口令
本文出自:http://www.computerworld.com.cn 作者: (2002-02-05 07:15:00)
作為Internet上最流行的服務器操作系統,UNIX安全性倍受關注。Unixd的安全性主要
靠口令實現,因此,Unix口令加密算法幾度改進,現在普遍採用DES算法對口令文件進
行25次加密,而對每次DES加密產生的結果,都要用2的56次方次查找與匹配才能進行
一次遍歷,要破解這樣的口令,其工作量是巨大的,所以從理論上說這種口令是相當安
全的。然而不幸的是我們仍然不時聽道口令被攻破的消息。這些口令是如何被攻破的,
我們又怎樣才能保証口令的安全呢。下面將對這一問題進行探討。 
Unix 口令文件的格式及安全機制 
Unix的口令文件passwd是一個加密的文本文件,儲存在/etc目錄下。該文件用用戶
登錄時校驗用戶的口令,僅對root權限可寫。口令文件中每行代表一個用戶條目,格式
為:LOGNAME : PASSWORD : UID : GID : USERINFO : HOME : SHELL。每行的頭兩項是
登錄名和加密的口令,UID和GID是用戶的ID號和用戶所在組的ID號,USERINFO是系統
管理員寫入的有關該用戶的信息,HOME是一個路徑名,是分配給用戶的主目錄,SHELL
是用戶登錄將執行的shell(若為空格則缺省為/bin/sh)。目前多數Unix系統中,口
令文件都做了Shadow變換,即把/etc/passwd文件中的口令域分離出來,單獨存在
/etc/shadow文件中,並加強對shadow的保護,以增強口令安全。 
Unix系統使用一個單向函數crypt()來加密用戶的口令。Crypt()是基DES的加密算法,
它將用戶輸入的口令作為密鑰,加密一個64bit的0/1串,加密的結果又使用用戶的口令
再次加密;重復該過程,一共進行25次。最的輸出為一個13byte的字符串,存放在
/etc/passwd的PASSWORD域。單向函數crypt()從數學原理上保証了從加密的密文得到加
密前的明文是不可能的或是非常困難的。當用戶登錄時,系統並不是去解密已加密的口
令,而是將輸入的口令明文字符串傳給加密函數,將加密函數的輸出與/etc/passwd文件
中該用戶條目的PASSWORD域進行比較,若匹配成功,則允許用戶登錄系統。 
口令破解原理 
口令破解通常有蠻力攻擊和字典攻擊兩種方式。Unix中一共有 [0x00∼0xff] 共128個字
符,其中 95個字符(10(數字)+33(標點符號)+26*2(大小寫字母) )可作為口令的字
符。假設m為可能使用的字符集的大小,n為口令的長度,則可生成的口令數為m的n次冪,
隨著字符集的擴大與口令長度的增加,口令攻擊嘗試次數將迅速增加。 如口令長度為6,
取字母和數字組合,可能性是62 的6次冪56,800,235,584。但如果5個字母是一個常用漢
字的拼音或英文單詞,估算一下常用詞約為10000條, 從10000個常用詞中取一個詞與任
意一個數字字符組合成口令,則僅10000* 10 = 100000 (10萬種可能)。在口令的設置過
程中,還有許多個人因素在起作用,為使自己的口令容易記憶,許多人往往將個人的姓
名、生日、電話號碼、街道的號碼等作為口令,這樣便為口令的破解留下了方便之門。 
貝爾實驗室的計算機安全專家R.Morris和K.Thompson提出了這樣一種攻擊的可能性:可
以根據用戶的信息建立一個他可能使用的口令的字典。比如:他父親的名字、女朋友的
生日或名字,街道的名字等等。然對這個字典進行加密,每次拿出一個經過加密計算
的條目與口令文件比較,若一致,口令就被猜到了。 
也許有人認為口令毫無規律可言,字典中不會有,計算機是破譯不了的,那就大錯特錯
了。有很多專門生成字典的程序,比如:Dictmake、txt2dict、xkey等等。以dictmake
為例:啟動程序,計算機會要求輸入最小口令長度、最大口令長度、口令包含的小寫
字符、大寫字符、數字、有沒有空格、含不含標點符號和特殊字符等一系列的問題。當
回答完了計算機提出的問題,計算機就會按照給定的條件自動將所有的組合方式列出
來並存到文件中,而這個文件就是資料字典。目前,在因特網上,有一些數據字典可以
下載,包含的條目從1萬到幾十萬條。數據字典一般囊括了常用的單詞。 
攻擊者一旦通過某種途徑獲得了passwd文件,破譯過程便只需一個簡單的C程序即可完成。
Unix中有一組子程序可對/etc/passwd文件進行方便的存取。getpwuid()函數可從
/etc/passwd文件中獲取指定的UID的入口項。getpwnam()函數可在/etc/passwd文件中
獲取指定的登錄名入口項。這兩個子程序返回一指向passwd結構的指針,該結構定義在
/usr/include/pwd.h中,定義如下: 
struct passwd {  
char * pw_name; /* 登錄名 */  
char * pw_passwd; /* 加密的口令 */  
uid_t pw_uid; /* UID */  
gid_t pw_gid; /* GID */  
char * pw_age; /* 代理信息 */  
char * pw_comment; /* 注釋 */  
char * pw_gecos;  
char * pw_dir; /* 主目錄 */  
char * pw_shell; /* 使用的shell */  
char * pw_shell; /* 使用的shell */  
}  
getpwent(),setpwent(),endpwent()等函數可對口令文件作續處理。首次調用
getpwent()可打開/etc/passwd文件並返回指向文件中第一個用戶條目的指針,再次調
用getpwent()便可順序地返回口令文件中的各用戶條目,setpwent() 可把口令文件的
指針重新置為文件的開始處,endpwent() 可關閉口令文件。 
由此可見,攻擊者只需建立一個字典文件,然調用現成的cryp()加密例程來加密字典
文件中的每一條目,再用上述函數打開口令文件,進行循環比較就很容易破解密碼了。 
實際上Internet網上有很多現成的密碼破解軟件工具,過簡單的口令很容易破解。那
,我們用什方法來保証用戶口令是一個安全的口令呢?運用CrackLib來構建安全的
Unix口令是一個較好的辦法。 
CrackLib原理及應用 
CrackLib是一個用UNIX系統下的函數庫, 它可以用編寫和口令有關的程序。 其基本
思想就是通過限制用戶使用使用過簡單、容易被猜測出來或容易被一些工具搜索到的
密碼,來提高系統的安全性。 
CrackLib並不是一個可以直接運行使用的程序, 它只是一個函數庫, 可以利用其中的函 
數寫自己的程序或是加入其它程序中以提高安全性,如可以改寫passwd 使用戶在選擇密
碼時受到限制。CrackLib使用一個字典, 它查找字典以判斷用戶所選密碼是不是安全的
密碼。用戶也可以加入其它信息, 使用自己的字典。CrackLib通過建立索引和二元查找,
效率非常高,其字典大小通常只有同等字典數的一半。下面介紹如何運用CrackLib。 
1、構建cracklib字典 
CrackLib可以很容易的在Internet上找到, 現在使用的版本多是2.7, 首先要確定字典安
裝的路徑,即給DICTPATH賦值,形式為:目錄+字典文件名(不包括綴),如: 
DICTPATH=/usr/local/lib/pw_dict.。該變量值將在所有調用CrackLib函數的程序中用到, 
字典文件通常包括 /usr/local/lib/pw_dict.pwd,/usr/local/lib/pw_dict.pwi,
/usr/local/lib/pw_dict.hwm三個文件。 
CrackLib 字典可直接從網上下載,也可以用它提供的工具生成。如果想加入其它信息, 
使用自己的字典,可將含有新詞的文件放到SOURCEDICT目錄如"/usr/dict/words"下,
CrackLib會將所有文件合並起來,刪除多余的詞,將其壓縮成字典文件,通常只有原文件
40%-60%的大小。 
2、在程序中調用函數 
CrackLib函數可以被應用很多地方, 只需加入簡單的幾行源碼, 就可以得到非常好的效
果。 char *FascistCheck(char *pw, char *dictpath) 是CrackLib中最常用的函數。其
中 pw是用戶選擇的密碼, 將被驗証是不是安全的,dictpath是字典所在路徑。
FascistCheck() 返回一個空指針,說明口令很安全,否則返回診斷出的字符串。下面是
一個口令設置的簡單示例, 用以說明CrackLib函數用法. 
 
#ifndef CRACKLIB_DICTPATH  
#define CRACKLIB_DICTPATH "/usr/local/lib/pw_dict" 
#endif  
... 
... 
...  
char *msg; 
 
while(1) { 
passbuf = getpass("請設定新密碼:"); 
if (!*passbuf) { 
(void)printf("密碼設定取消, 繼續使用舊密碼\n"); 
break; 

 
if (strlen(pussbuf) <= 4 || !strcmp( passbuf, newuser.userid ) ) { 
(void)printf("密碼太短或與使用者代號相同, 請重新輸入\n "); 
continue; 

if (msg = (char*) FascistCheck(passbuf, CRACKLIBPATH)) { 
printf("請另選密碼! (%s)\n",msg); 
continue; 

 
strncpy( newuser.passwd, passbuf, PASSLEN ); 
passbuf = getpass("請再輸入一次你的密碼 ); 
if( strncmp( passbuf, newuser.passwd, PASSLEN ) != 0 ) { 
prints("密碼輸入錯誤, 請重新輸入密碼.\n") ; 
continue; 

passbuf[8] = '\0' ; 
break; 

這樣通過限制用戶使用不安全的密碼, 可以極大地提高系統的安全性。 
(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
運用CrackLib構建安全的Unix口令 (2002-02-05 07:15:00)
用戶及口令 (2001-08-25 08:05:00)
C源碼:生成一個自己的口令字典 (2001-08-22 16:36:31)
用戶口令檢查(/etc/passwd) (2001-07-24 07:00:00)
幾種網絡配置信息及口令的清除方法 (2001-06-26 18:08:00)
Samba-HOWTO最新匯集--2. Samba 2.x中的LanMan和NT口令加密 (2001-05-31 11:00:00)
如何恢復MYSQL的ROOT口令 (2001-05-16 15:41:43)
一個簡單的口令保護程式 (2001-05-12 10:57:18)
如何用FTP獲取Solaris中Shadow 口令文件 (2001-05-11 15:04:09)
CISCO 2500、1600系列路由器使用手冊--口令的安全管理 (2001-05-02 01:18:52)

===更多相關===
 

★  樊強制作 歡迎分享  ★