作者:Y4er
原文鏈接:https://y4er.com/post/from-hop-by-hop-to-cve-2022-1388/
前言
最近爆出來的bigip的CVE-2022-1388漏洞,涉及到一個知識點就是hop by hop,對這個東西沒了解過,所以有了此文。
回顧CVE-2021-22986
CVE-2021-22986原理是因為apache和jetty之間的鑒權不當導致的權限繞過。
當不存在Authorization basic認證頭時,由apache做權限校驗,判斷basic認證頭是否存在,此時response中的server頭為apache

當給一個錯誤的basic認證頭時仍返回apache的401認證,注意這里給的是一個admin:空密碼的admin用戶。

當給一個空的X-F5-Auth-Token認證頭時,由jetty處理返回401,報錯信息為Authorization failed: no user authentication header or token detected.

當兩個請求頭都存在時,繞過了權限校驗,rce。

由此得出結論,當存在X-F5-Auth-Token頭時apache不檢查basic認證頭,而jetty只會判斷用戶名,而不判斷密碼是否正確。
思考為什么權限校驗不起作用?
查看apache的配置文件/config/httpd/conf/httpd.conf發現

/mgmt/請求被轉發到8100端口,并且啟用了AuthPAM_Enabled,啟用auth會調用/usr/lib/httpd/modules/mod_auth_pam.so判斷鑒權,在這個so中

判斷是否存在X-F5-Auth-Token頭

然后接著拿一些其他的請求頭

最終邏輯就是如果存在轉發給jetty處理。
而在jetty中 f5.rest.jar
com.f5.rest.workers.authz.AuthzHelper#decodeBasicAuth

從header中拿到basic認證的用戶名和密碼,在com.f5.rest.common.RestOperationIdentifier#setIdentityFromBasicAuth中設置用戶身份

因為basic不為空,所以進入com.f5.rest.common.RestOperation#setIdentityData

因為 userName!=null && userReference==null,所以處理完之后用戶的身份變為
identityData.userName = 'admin';
identityData.userReference = 'http://localhost/mgmt/shared/authz/users/admin'
identityData.groupReference = null;
接著在鑒權的地方 com.f5.rest.workers.EvaluatePermissions#completeEvaluatePermission

setBasicAuthFromIdentity之后拿到userRef,此時userRef即上文處理完之后的用戶身份。在判斷AuthzHelper.isDefaultAdminRef(userRef)時

先拿到默認的AdminReference和當前用戶身份匹配,在getDefaultAdminReference()中拿到admin用戶的身份new一個RestReference

UrlHelper.buildPublicUri(UrlHelper.buildUriPath(new String[]{WellKnownPorts.AUTHZ_USERS_WORKER_URI_PATH, DEFAULT_ADMIN_NAME}))`最終構建出來的url還是`http://localhost/mgmt/shared/authz/users/admin
所以此時我們在basic中將用戶名設置為admin則可以滿足defaultReference != null && defaultReference.equals(userReference)至此繞過權限認證。
然后就是找一個命令執行的點

對應的就是util下的路由功能點

調用bash執行命令即可

另外此處文檔中也有提到
https://f5-sdk.readthedocs.io/en/latest/_modules/f5/bigip/tm/util/bash.html
CVE-2021-22986的修復
在上文中,我們傳遞了一個X-F5-Auth-Token為空的header頭,所以completeEvaluatePermission函數會賦給我們一個默認的用戶身份。而修復補丁在mod_auth_pam.so判斷當X-F5-Auth-Token為空直接返回401

所以我們無法傳遞給jetty一個空的X-F5-Auth-Token請求頭。
那么CVE-2022-1388就是對其的繞過,這里引申出本文的重點hop by hop。
hop by hop
先解釋下這是什么東西。根據RFC 2612,HTTP/1.1 規范默認將以下標頭視為逐跳:Keep-Alive、Transfer-Encoding、TE、Connection、Trailer、Upgrade、Proxy-Authorization和Proxy-Authenticate。當在請求中遇到這些標頭時,代理服務器會處理這些標頭,并且不會將其轉發到下一個節點。
以推特@jinonehk的一張圖來看

第一次嘗試導出用戶時返回403,因為不是環路ip,而當加上Connection: close, X-Real-IP時,導出用戶成功,說明此時后端服務獲取不到X-Real-IP請求頭,認為是本地請求所以可以導出用戶。
更具體一點,我在這里找到了一個ctf的題目 https://github.com/ritsec/RITSEC-CTF-2019/tree/master/Web/hop-by-hop
在verify函數中嘗試獲取xff頭,如果獲取不到則默認為direct。

而前置服務為apache,根據逐跳原則,當Connection中加了其他標頭X-Forwarded-For,那么在apache轉發給下一跳時,會移除X-Forwarded-For頭,導致在verify函數中request.headers['X-Forwarded-For']拋出異常,由此拿到flag。

可以自己本地搭一個反代試試,我這有一個springboot的項目,只有一個controller

apache 80端口反代springboot 9091端口
先開啟反代功能
LoadModule proxy_module modules/mod_proxy.so
配置virtualhost
<VirtualHost *:80>
ProxyRequests Off
ProxyPreserveHost On
<Proxy>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:9091
ProxyPassReverse / http://localhost:9091
</VirtualHost>
正常傳token,springboot可以獲取到token頭

當connection加上Token時,springboot獲取的token為null

由此可見CVE-2022-1388
CVE-2022-1388
在CVE-2022-1388中使用Connection加上X-F5-Auth-Token讓jetty接收到的X-F5-Auth-Token為null以此來繞過權限認證。

另外需要注意的一個地方為host賦值為localhost,不然host為ip時報錯

因為CVE-2021-22986之后,在com.f5.rest.common.RestOperationIdentifier#setIdentityFromBasicAuth中

當host為localhost或者127.0.0.1時,會賦予用戶身份。另外這里還可以賦值host為127.4.2.1然后basic用戶名為f5hubblelcdadmin,或者通過Connection加上X-Forwarded-Host也可以rce,就不截圖了。
hop by hop的適用面
我本地測試了apache、nginx、openresty、HAProxy,其中只有apache會消費掉Connection中的請求頭,其他的要單獨測試了。
參考鏈接
看了太多資料了,用到了但是沒貼上來的請原作者見諒。
- 漏洞百出
- https://twitter.com/jinonehk/status/1420413477521301507
- https://nathandavison.com/blog/abusing-http-hop-by-hop-request-headers
- RFC 2616
- https://y4y.space/2021/03/19/cve-2021-22986-f5-rest-unauthenticated-rce-analysis/
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
- https://nosec.org/home/detail/4722.html
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1908/
暫無評論