
RuoYi-Vue के जनरेटर मॉड्यूल में प्रमाणित SQL इंजेक्शन, CVE-2024-57521 का स्टैटिक कोड ऑडिट, सोर्स-टू-सिंक विश्लेषण और %0b फ़िल्टर बायपास PoC के साथ।
चित्र 1: CVE-2024-57521 SQL इंजेक्शन भेद्यता डेटा प्रवाह ऑडिट आरेख
यह रिपॉज़िटरी केवल सुरक्षा अनुसंधान और शैक्षिक उद्देश्यों के लिए है। कृपया इस दस्तावेज़ में वर्णित तकनीकों का उपयोग अनधिकृत हमलों के लिए न करें। सभी परीक्षण स्थानीय स्थिर कोड ऑडिट वातावरण में पूर्ण किए गए हैं।
ruoyi-generator मॉड्यूल)ruoyi-generator/src/main/java/com/ruoyi/generator/controller/GenController.javaमुख्य कोड:
@PostMapping("/createTable")
public AjaxResult createTableSave(@RequestParam("sql") String sql, @RequestParam("tplWebType") String tplWebType)
{
try
{
SqlUtil.filterKeyword(sql); // 在进入业务前调用过滤器
विश्लेषण: बैकएंड व्यवस्थापक HTTP POST अनुरोध के sql पैरामीटर के माध्यम से मनमाना डेटाबेस तालिका निर्माण कथन पास कर सकता है। प्रवेश बिंदु उपयोगकर्ता इनपुट पर पर्याप्त प्रतिबंध नहीं लगाता और सीधे बाद के फ़िल्टर को सौंप देता है।
स्क्रीनशॉट साक्ष्य:

· फ़ाइल स्थान: ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java
मुख्य दोषपूर्ण कोड:
// 第16行:黑名单定义,注意关键词带有【尾随空格】
public static String SQL_REGEX = "\u0008|%0A|and |extractvalue|updatexml|sleep|information_schema|exec...";
// 第61-66行:过滤逻辑
String normalizedValue = value.replaceAll("\\p{Z}|\\s", ""); // 先清空了输入里的所有空格
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StringUtils.indexOfIgnoreCase(normalizedValue, sqlKeyword) > -1)
{
throw new UtilException("请求参数包含敏感关键词" + sqlKeyword + ",可能存在安全风险");
}
}
दोष विश्लेषण: फ़िल्टर सबसे पहले replaceAll("\p{Z}|\s", "") निष्पादित करके इनपुट से सभी श्वेत-स्थान वर्णों को हटा देता है। लेकिन ब्लैकलिस्ट SQL_REGEX में मौजूद कीवर्ड (जैसे "and ", "select ") में पीछे श्वेत-स्थान होता है। इसके कारण मिलान अनिवार्य रूप से विफल हो जाता है, और जैसे ही हमलावर कीवर्ड के बाद श्वेत-स्थान के स्थान पर %0b (लंबवत टैब) का उपयोग करता है, ब्लैकलिस्ट जाँच को पूरी तरह से बायपास किया जा सकता है।
स्क्रीनशॉट प्रमाण:
· फ़ाइल स्थान: ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml
मुख्य कोड:
<update id="createTable">
${sql}
</update>
विश्लेषण: MyBatis में ${} सीधे स्ट्रिंग को जोड़ता है, सुरक्षित प्रीकंपाइल #{} का उपयोग नहीं करता। इससे फ़िल्टर को बायपास कर चुका दुर्भावनापूर्ण SQL डेटाबेस में निष्पादन के लिए भेज दिया जाता है। यह विशिष्ट "ब्लैकलिस्ट फ़िल्टरिंग + असुरक्षित स्ट्रिंग संयोजन" संयुक्त भेद्यता है।
स्क्रीनशॉट साक्ष्य:
· विधि: हमलावर SQL कथन में स्पेस के स्थान पर %0b (MySQL का वर्टिकल टैब, जो \s मिलान सीमा में आता है) का उपयोग करता है।
· प्रोबिंग सिद्धांत: बूलियन ब्लाइंड इंजेक्शन के डिटेक्टर के रूप में IF(<शर्त>, 1, 1/0) का उपयोग करें। · शर्त असत्य: शून्य से भाग देने की त्रुटि उत्पन्न होती है, सर्वर HTTP 500 लौटाता है। · शर्त सत्य: सामान्य, कोई त्रुटि नहीं। · निष्कर्षण विधि: द्विआधारी खोज (बाइनरी सर्च) का उपयोग करके डेटाबेस डेटा को बिट-दर-बिट अनुमान लगाया जा सकता है।
यह भेद्यता विशिष्ट "अपूर्ण सुधार" के कारण हुए बायपास का उदाहरण है। डेवलपर ने पहले की समान SQL इंजेक्शन को ठीक करते समय ब्लैकलिस्ट तंत्र पेश किया, लेकिन यह भूल गए कि ब्लैकलिस्ट स्पेस पर निर्भर करती है, और स्पेस को हटाने वाला पूर्व-लॉजिक ब्लैकलिस्ट की मिलान शर्तों को तोड़ देता है, जिसके परिणामस्वरूप अंततः नया बायपास (CVE-2024-57521) हुआ।
· ब्लैकलिस्ट तंत्र को समाप्त करें: ब्लैकलिस्ट पर निर्भर न रहें, व्हाइटलिस्ट तंत्र ही सुरक्षा की नींव है। · प्रीकंपाइल का उपयोग करें: MyBatis में ${sql} को #{} प्रीकंपाइल विधि में बदलें। यदि गतिशील रूप से SQL पास करना आवश्यक हो (जैसे टेबल निर्माण, Order By), तो सख्त अमूर्त सिंटैक्स ट्री (AST) पार्सिंग या सख्त पैरामीटर सत्यापन का उपयोग करना चाहिए। · फ़िल्टर को पूर्ण करें: यदि ब्लैकलिस्ट का उपयोग करना अनिवार्य हो, तो ब्लैकलिस्ट कीवर्ड के अंत में स्पेस हटाएं, और तुलना से पहले एकरूप मानकीकरण करें (जैसे सभी को लोअरकेस में बदलें, %0b आदि को स्पेस से बदलें)।
· NVD - CVE-2024-57521 · RuoYi-Vue Gitee रिपॉज़िटरी
poc/poc_boolean.py (नोट: सुझाव है कि बाद में फ़ाइल नाम को poc_error_based.py में बदलें, ताकि यह वास्तविक लॉजिक के अनुरूप रहे)extractvalue() फ़ंक्शन का उपयोग करके XPath त्रुटि उत्पन्न करें, और रेगुलर एक्सप्रेशन से XPATH syntax error: '~...~' का मिलान करके डेटा निकालें। Payload में स्पेस के स्थान पर /**/ का उपयोग करके ब्लैकलिस्ट फ़िल्टरिंग को बायपास करें।
CREATE//table//{随机表名}//as//SELECT/**/extractvalue(1,concat(0x7e,({查询语句}),0x7e))
%0b द्वारा WAF बायपास और extractvalue त्रुटि-आधारित इंजेक्शन की व्यवहार्यता सफलतापूर्वक सत्यापित की गई; स्क्रिप्ट ने स्थिर रूप से MySQL संस्करण (5.7.26), वर्तमान डेटाबेस नाम (ry) और डेटाबेस कनेक्शन उपयोगकर्ता (root@localhost) निकाल लिया है।