由于Unix是Internet最流行的服务器操作系统,因此它的安全性倍受关注。这种安全主要靠口令实现。Unix的口令仅仅存储在一个加密后的文本文件中,文件一般储存在/etc目录下,名称为passwd。历史上,Unix口令加密算法曾经历过几次修正,现在普遍采用DES算法。用DES算法对口令文件进行25次加密。而对每次DES加密产生的结果,都要用2的56次方次查找与匹配才能进行一次遍历,所以理论上要破解这样的口令,其工作量是很大的。
本文先介绍Unix 口令文件的格式以及口令加密的原理;接着讲述如何构造一个口令Crack程序;最后以John the Ripper做口令攻击的测试,分析实验结果,并给出口令安全的建议。
1.1 Unix 口令文件的格式及安全机制
/etc/passwd文件是Unix安全的关键文件之一,在不同的Unix系统中,它的存储路径略有不同,参见表5.1。该文件用于用户登录时校验用户的口令,仅对root权限可写。
表1.1 不同Unix系统中口令文件的存储路径
Unix系统
路径
UNICOS /etc/udb
Ultrix4 /etc/auth
SystemV Release 4.2 /etc/security
SystemV Release 4.0 /etc/shadow
SunOS 5.0 /etc/shadow
SCOUnix /tcb/auth/files/
OSF/1 /etc/passwd
Linux1.1 /etc/shadow
HP-UX /.secure/etc/passwd
BSD4.3 /etc/master.passwd
AIX3 /etc/security/passwd
IRIX5 /etc/shadow
口令文件中每行代表一个用户条目,格式为:
LOGNAME : PASSWord: UID : GID : USERINFO : HOME : SHELL
每行的头两项是登录名和加密后的口令,后面的两个数是UID和GID,接着的一项是系统管理员想写入的有关该用户的任何信息,最后两项是两个路径名:一个是分配给用户的Home目录,第二个是用户登录后将执行的shell(若为空格则缺省为/bin/sh)。例如,在口令文件中,它的 Root用户的条目为:
root : xyDfccTrt180x,M.y8 : 0 : 0 : admin : / : /bin/sh
则,它的含义如表1.2所示。
表1.2 /etc/passwd文件中各个域的含义
域
含义
Root 用户名
XyDfccTrt180x,M.y8 加密的口令
0 用户ID(UID)
0 用户的组ID(GID)
Admin 用户的全名
/ 用户的主目录
/bin/sh 用户的Shell
在目前的多数Unix系统中,口令文件都做了Shadow变换,即把/etc/passwd文件中的口令域分离出来,单独存在/etc /shadow文件中,并加强对shadow的保护,以增强口令安全。因而,在破解时,需要做UnShadow变换,将/etc/passwd与/etc /shadow文件合二为一。
1.1.1 口令加密的机理
Unix系统使用一个单向函数crypt(),来加密用户的口令。单向函数crypt()从数学原理上保证了从加密的密文得到加密前的明文是不可能的或是非常困难的。当用户登录时,系统并不是去解密已加密的口令,而是将输入的口令明文字符串传给加密函数,将加密函数的输出与/etc /passwd文件中该用户条目的PASSWORD域进行比较,若匹配成功,则允许用户登录系统。
Crypt()的加密算法基于资料加密标准DES,它将用户输入的口令作为密钥,加密一个64bit的0/1串,加密的结果又使用用户的口令再次加密;重复该过程,一共进行25次。最后的输出为一个11byte的字符串,存放在/etc/passwd的PASSWORD域。
Morris和Thompson修改了crypt()函数的实现。现在Unix系统中使用的加密函数原型如下:
Char *crypt(char *salt, char *passwd)
Salt是一个12位长的数字,取值范围为0到4095。它略改变了DES的输出,4096个不同的salt值使同一个口令产生不同的输出。当改变口令时,系统选择当天的一个时间,得到一个salt数值。该salt被存放在加密口令的最前面。因此,passwd文件存放的密文口令是13 位。一些Unix系统,例如:HP-UX,Ultrix和BSD4.4,使用了16位或更长的salt值,这种算法称为bigcrypt()或 crypt16()。
1.1.2 口令时效
/etc/passwd文件的格式使系统管理员能要求用户定期地改变他们的口令。在口令文件中可以看到,有些加密后的口令有逗号,逗号后有几个字符和一个冒号。如:root : xyDfccTrt180x,M.y8 : 0 : 0 : admin : / : /bin/sh
ruan : pomJk109Jky41,.1 : 0 : 0 : admin : / : /bin/sh dcs : xmotTVoyumjls : 0: 0 : admin : / : /bin/sh
可以看到,yjb的口令逗号后有4个字符,ruan有2个,dcs没有逗号。逗号后第一个字符是口令有效期的最大周数,第二个字符决定了用户再次修改口令之前,原口令应使用的最小周数(防止用户修改新口令后立刻又改回成老口令)。其余字符表明口令最新修改时间。要能读懂口令中逗号后的信息,必须首先知道如何用passwd_esc计数,计数的方法是: . = 0,/ = 1,0-9 = 2-11,A-Z = 12-37,a- z= 38-63。
系统管理员必须将前两个字符放进 /etc/passwd文件,以要求用户定期的修改口令,另外两个字符当用户修改口令时,由passwd命令填入。若想让用户修改口令,可在最后一次口令被修改时,放两个".",则下一次用户登录时将被要求修改自己的口令。
有两种特殊情况:
1. 最大周数(第一个字符)小于最小周数(第二个字符),则不允许用户修改口令,仅超级用户可以修改用户的口令。
2. 第一个字符和第二个字符都是".",这时用户下次登录时被要求修改口令,修改口令后,passwd命令将"."删除,此后再不会要求用户修改口令。
1.1.3 UID和GID
/etc/passwd中UID信息很重要,系统使用UID而不是登录名区别用户。一般来说,用户的UID应当是独一无二的,其它用户不应当有相同的UID数值。根据惯例,从0到99的UID保留用作系统用户的UID(root,bin,uUCp等)。如果在/etc/passwd文件中有两个不同的入口项有相同的UID,则这两个用户对相互的文件具有相同的存取权限。
/etc/group文件含有关于用户组的信息,/etc/passwd中的每个GID在本文件中应当有相应的入口项,入口项中列出了组名和组中的用户。这样可方便地了解每个组的用户,否则必须根据GID在/etc/passwd文件中从头至尾地寻找同组用户。
/etc/group文件对组的许可权限的控制并不是必要的,因为系统用UID,GID(取自/etc/passwd)决定文件存取权限,即使/etc/group文件不存在于系统中,具有相同的GID用户也能够以组群的存取许可权限共享文档。
用户组与登录用户一样可以拥有口令。如果/etc/group文件入口项的第二个域为非空,则将被认为是加密口令,newgrp命令将要求用户给出口令,然后将口令加密,再与该域的加密口令比较。
给组建立口令一般不是个好作法。第一,如果组内共享文档,若有某人猜着组口令,则该组的所有用户的文件就可能泄漏;其次,管理组口令很费事,因为对于组没有类似的passwd命令。可用/usr/lib/makekey生成一个口令写入/etc/group。
以下情况必须建立新组:
1. 可能要增加新用户,该用户不属于任何一个现有的组。
2. 有的用户可能时常需要独自为一个组。
3. 有的用户可能有一个SGID程序,需要独自为一个组。
4. 有时可能要安装运行SGID的软件系统,该软件系统需要建立一个新组。
要增加一个新组,必须编辑该文件,为新组加一个入口项。 由于用户登录时,系统从/etc/passwd文件中取GID,而不是从/etc /group中取GID,所以group文件和口令文件应当具有一致性。对于一个用户的组,UID和GID应当是相同的。多用户组的GID应当不同于任何用户的UID,一般为5位数,这样在查看/etc/passwd文件时,就可根据5位资料的GID识别多用户组,这将减少增加新组、新用户时可能产生的混淆。
1.2 构造一个Crack程序
在口令的设置过程中,有许多个人因素在起作用,可以利用这些因素来帮助解密。由于口令安全性的考虑,禁止把口令写在纸上,因此很多人都设法使自己的口令容易记忆,这就给黑客提供了可乘之机。
贝尔实验室的计算机安全专家R.Morris和K.Thompson提出了这样一种攻击的可能性:可以根据用户的信息建立一个他可能使用的口令的字典,比如:个人的姓名、生日或姓名,街道的号码等。然后,每次取出一个条目经过crypt()函数变换,并与口令文件的密文口令匹配,若一致,口令就被破解了。一般说来,这种攻击策略是很有效的。
1.2.1 蛮力攻击与字典攻击
构造一个Crack程序,有两种方法可选择,一种是使用蛮力攻击,另一种是字典攻击。下面,分别估算一下它们的效率。
Unix一共是 [0x00~0xff] 共128个字符,小于0x20 的都是控制符,不能输入为 口令, 0x7f 为转义符, 不能输入。 那么总共128- 32 - 1 = 95 个字符可作为口令的字符。 即10(数字)+33(标点符号)+26*2(大小写字母) = 95 个。
首先估算蛮力攻击的尝试次数。很显然,该值为m的n次幂。其中,基数m为可能使用的字符集的大小;幂次n为口令的长度。分下面几种情形讨论:
仅使用字母的组合序列,则m = 26*2 = 52。
使用字母数字的组合序列,则m = 52 + 10 = 62。
使用字母数字以及特殊字符的组合序列,则m = 95
表1.3列举几个例子,计算所需的尝试次数K,对其数值大小得到一个较确切的印象。
表1.3 不同字符集与长度的口令尝试次数
M
N
K
52
5
38,0204,032
52
6
19,770,609,664
52
7
1,028,071,702,528
62
5
916,132,832
62
6
56,800,235,584
62
7
3,521,614,606,208
95
5
7,737,809,375
95
6
735,091,890,625
95
7
69,833,729,609,375
从该表中可以看出,随着字符集的扩大与口令长度的增大,所需的尝试次数明显增加。选择尽量大的字符集和较长的口令,能获得较高的口令安全。
但如果5个字母是一个常用汉字的拼音或英文单词,估算一下设常用词10000条, 从10000个常用词中取一个词与任意一个数字字符组合成口令,即:10000* 10 = 100000 (10万种可能性)。因此,借助于资料字典的帮助,可以使Crack的效率大大提高。
1.2.2 数据字典
目前,在因特网上,有一些数据字典可以下载,包含的条目从1万到几十万条。数据字典一般囊括了常用的单词。
也许有人认为:我的口令毫无规律可言,字典中不会有,因此,计算机是破译不了的,那就大错特错了。有很多专门生成字典的程序,比如:Dictmake、txt2dict等等。以dictmake为例:启动程序后,计算机会要求输入最小口令长度、最大口令长度、口令包含的小写字符、大写字符、数字、有没有空格、含不含标点符号和特殊字符等一系列的问题。当回答完了计算机提出的问题后,计算机就会按照给定的条件自动将所有的组合方式列出来并存到文件中,而这个文件就是资料字典。
1.2.3 读写口令文件的一组子程序
为了对/etc/passwd文件进行方便的存取,我编写了一组访问/etc/passwd文件的子程序。可读取文件的用户条目入口项或写入新的用户条目等。这组子程序可用于编写Crack程序。
Getpwuid()函数即可从/etc/passwd文件中获取指定的UID的用户条目。Getpwnam()函数则对于指定的登录名,在/etc/passwd文件检索用户条目。getpwent(),setpwent(),endpwent()等函数则可对口令文件作后续处理。
Getpwuid()与Getpwnam()返回一指向passwd结构的指针,该结构定义如下:
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(),可打开/etc/passwd文件并返回指向文件中第一个用户条目的指针,并保持调用之间文件的打开状态,再调用 getpwent()便可顺序地返回口令文件中的各用户条目。而调用setpwent() 又可把口令文件的指针重新置为文件的开始处,最后使用完口令文件后调用endpwent() 可关闭口令文件。
1.2.4 构造Crack程序
综上所述,构造一个Crack工具只需以下步骤:
1、下载或自己生成一个字典文件。
2、取出字典文件中的每一条目,对每个单词运用一系列规则。规则可以多种多样,典型的规则包括:
3、使用几个单词和数字的组合。
4、大小写交替使用。
5、把单词正向、反向拼写后,接在一起。
6、在每个单词的开头或结尾加上一些数字。当然,使用的规则越多,破译所需时间就越长。但是,规则越多,破译成功的可能性也越大。
7、调用系统的crypt() 函数对使用规则生成的字符串进行加密变换。
8、再用上述的一组子程序打开口令文件,取出密文口令,与crypt() 函数的输出进行比较。
循环重复2-3步,直至口令破解成功。
1.3口令Crack实验分析
目前,最著名的口令Crack 工具是John the Ripper 与L0pht Crack。其中,John the Ripper 用来破解Unix 系统口令,L0phtCrack 破解NT系统口令,它们有运行于不同平台的多个版本。我获取了运行于Windows 98/NT的最新版本:John the Ripper 1.6和L0phtCrack 2.5。并分别进行了口令Crack 的实验,因为实验方案基本相同,所以仅做 John the Ripper 口令Crack 实验的分析。
首先,使用Turbo Linux 4.2 建立了三个用户组,每组4个用户帐号,总共12个帐号;分别是:A5,A6,A7,A8;B5,B6,B7,B8;C5,C6,C7,C8。其中,A代表该用户的口令只包含字母,B代表该用户的口令包含字母与数字,C代表该用户的口令包含字母、数字及特殊字符。5-8代表该用户的口令长度是5-8个字符。这些帐号的GID均被设为500。
实验用的计算机配置为:PentiumIII 500,128M内存,操作系统为Windows98第二版。先进行系统测试,运行"John -test",结果显示如下:
Benchmarking: Standard DES [48/64 4K]... DONE
Many salts: 18581 c/s
Only one salt: 30792 c/s
Benchmarking: BSDI DES (x725) [48/64 4K]... DONE
Many salts: 1054 c/s
Only one salt: 971 c/s
Benchmarking: FreeBSD MD5 [32/32]... DONE
Raw: 732 c/s
Benchmarking: OpenBSD Blowfish (x32) [32/32]... DONE
Raw: 41.2 c/s
Benchmarking: Kerberos AFS DES [48/64 4K]... DONE
Short: 32540 c/s
Long: 92064 c/s
Benchmarking: NT LM DES [48/64 4K]... DONE
Raw: 230855 c/s
可以看出,使用标准DES加密变换的速率为:18581 字符/秒(使用多个Salt时)与30792 字符/秒(使用单个Salt时),这是实验运行时的加密变换速率。
John the Ripper 的使用方法为:
Usage: file://D/HACKER/CRACK/JOHN-16/RUN/john [OPTIONS] [PASSWORD-FILES]
它有多个使用选项,参见表1.4。
表1.4 John the Ripper使用选项含义
选项 意义
-rules
破解规则
-wordfile:FILE
字典文件
-incremental
增量方式
-restore[:FILE]
恢复已存储的进度
-session:FILE
存储当前进度
-show
显示当前进度
-makechars:FILE
字符集
-users:[-]LOGINUID[,..]
指定想破解的用户
-groups:[-]GID[,..]
指定想破解的用户组
由于Turbo Linux使用了Shadow文件,得先进行Unshadow处理:
Unshadow passwd shadow >pass
得到Unshadow的口令文件pass,再输入:
John -groups:500 -show pass
开始Crack过程。进行10个小时后,得到如表5.5所示的结果。其中,单位精确到分,没有Crack成功的标为"NO"。
表1.5 使用John the Ripper的Crack实验结果
花费时间 花费时间 花费时间
A5 00:12 B5 02:16 C5 NO
A6 02:25 B6 NO C6 NO
A7 01:38 B7 05:21 C7 NO
A8 04:54 B8 NO C8 NO
可以看出,A组的成功率为:100%,B组的成功率为:50%,C组的成功率为:0%。因此,随着字符集的扩大,破解的难度明显增大。所以,安全的口令必须包含特殊字符。
还有一点值得注意,即在整体上口令越长,破译所需的时间越多,但A7比A6的破译时间短,这说明John the Ripper并不是先尝试完n个字符的口令,再尝试长为n+1的口令;而是运用了复杂的规则进行匹配。各个Crack程序的具体实现有差异,它们运用了不同的规则,使得它们破译口令的所需时间不一样。
1.4 口令安全的建议
每个人都应该重视保护自己帐户的口令,降低被他人截取的可能性,从而保护个人的资料资料以及系统的安全。保护口令安全的要点如下:
不要将口令写下来。
不要将口令存于计算机文件中。
口令要容易记住。
不要用字典中有的词作为自己的口令。
不要用诸如自己的生日、电话号码、寻呼机号码、纯数字或纯字母做口令。
口令应包含特殊字符。
口令应该在允许的范围内尽可能取长一点。
不要在不同系统上使用同一口令。
为防止眼明手快的人窃取口令,在输入口令时应确认没有人偷窥。
定期改变口令,至少6个月要改变一次。
最后这点是十分重要的,永远不要对自己的口令过于自信,也许就在无意当中泄露了口令。定期地改变口令,会使自己遭受hacker攻击的风险降到一定限度之内。一旦发现自己的口令不能进入计算机系统,应立即向系统管理员报告,由管理员来检查原因。
以上分析的是传统的保障口令安全的方法。当前,也出现了一些新型的口令安全机制,例如:动态口令和利用使用者的生物唯一识别信息作为口令验证。
动态口令是周期性的改变口令,以减少口令被破解的机会、增强口令安全的机制,动态口令卡是一种最常见的应用。在口令卡和服务器中都存储同一口令种子(Seed)。验证口令时,口令卡取出当前时间与口令种子,经过单向函数的变换,计算出一个口令,服务器也采用同样的方法得到一个口令,比较这两个口令,得到验证。动态口令卡与服务器之间的时间同步是确保准确验证的前提。目前,一些安全方面的著名公司,如:RSA、HP等推出了动态口令卡产品。本实验室也研制成功了动态口令卡(DID卡),并广泛运用于银行、军队和政府部门。
利用使用者的生物唯一识别信息作为口令验证,这一先进的安全认证机制正在积极的研究与完善中,将逐渐应用于多种场合。可以利用的识别信息包括指纹、视网膜等,这些特征信息是个人唯一的,提取这些特征,可以用于个人的身份验证。提取的识别信息数据量过多,存在存储开销大、传输效率低等缺陷;数据量过少,又可能出现误判。因而如何准确的提取识别信息,是当前的一个研究热点。
阅读(686) | 评论(0) | 转发(0) |