قد تبدو واجهات برمجة التطبيقات وخدمات الويب أقل شيوعًا من مواقع الويب وتطبيقات الويب ولكن هذا ليس صحيحًا. بالفعل في عام 2018 ، كانت واجهات برمجة التطبيقات مسؤولة عن 83٪ من زيارات الويب حول العالم. تعتمد معظم التطبيقات المعقدة على الخدمات الدقيقة والخدمات الصغيرة هي في الأساس تطبيقات ويب تتواصل مع بعضها البعض باستخدام واجهات برمجة التطبيقات. تتعرض خدمات الويب وواجهات برمجة التطبيقات لنفس نقاط الضعف مثل تطبيقات الويب. لذلك ، للحفاظ على أمانها ، تحتاج إلى معرفة كيفية مسحها ضوئيًا.
في هذه المقالة ، سنوضح لك كيفية تشغيل فحص Acunetix لخدمة ويب SOAP مع ملف WSDL. سوف تتعلم كيفية:
- بناء خدمة ويب بسيطة
- تفحص خدمة الويب
- تحديد نقاط الضعف
- تخفيف و / أو حل نقاط الضعف
- إعادة فحص خدمة الويب لتأكيد الحل
المحتويات
المرحلة 1: بناء خدمة ويب بسيطة
في هذا الجزء سوف تتعلم كيفية:
- إنشاء قاعدة بيانات على خادم الويب الخاص بك لتخزين البيانات الخاصة بك
- القيام بالبناء /var/www/hello/config.php ملف لتخزين المعلمات للاتصال بقاعدة البيانات
- القيام بالبناء /var/www/hello/functions.php ملف لوظائف الدعم الأساسية للخدمة للعمل
- القيام بالبناء /var/www/hello/hello_server.php ملف لوظائف API التي ستوفرها خدمة الويب ؛ في هذا المثال سنقدم وظيفة API واحدة تسمى doGetUserName
- القيام بالبناء /var/www/hello/hello_client.php الذي سيقدم نموذج إدخال إلى المستخدم ويستخدم خدمة الويب لاسترداد المعلومات المطلوبة
- القيام بالبناء /var/www/hello/hello.wsdl لوصف خدمة الويب
ملحوظة: في مواقف الحياة الواقعية ، غالبًا ما تكون الخطوة الأخيرة من القائمة أعلاه هي الخطوة الأولى. في حالة بعض بيئات التطوير ، يستخدم المطورون أولاً الأدوات المرئية لإنشاء هيكل خدمة الويب ثم إنشاء البنية الأساسية جنبًا إلى جنب مع ملف WSDL. في مثالنا ، نقوم بذلك يدويًا ، ومن ثم فهي الخطوة الأخيرة.
الخطوة 1. إنشاء قاعدة بيانات على خادم الويب الخاص بك
قم بتشغيل الأوامر التالية من موجه الجذر MariaDB أو MySQL:
MariaDB [(none)]> create user 'hellouser'@'localhost' identified by 'hellouserpass';
MariaDB [(none)]> create database hellodb;
MariaDB [hellodb]> GRANT ALL PRIVILEGES ON hellodb.* TO 'hellouser'@'localhost';
MariaDB [(none)]> use hellodb;
MariaDB [hellodb]> CREATE TABLE `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(30) DEFAULT NULL, `email` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `UNIQUE_email` (`email`) );
MariaDB [hellodb]> INSERT INTO users (name, email) VALUES ('John Doe', '[email protected]');
MariaDB [hellodb]> INSERT INTO users (name, email) VALUES ('Jane Doe', '[email protected]');
الخطوة 2. بناء ملف التكوين الخاص بك
باستخدام nano ، قم بإنشاء ملف /var/www/hello/config.php ملف على النحو التالي:
<?php
$db_host="localhost";
$db_name="hellodb";
$db_user="hellouser";
$db_pass="hellouserpass";
الخطوة 3. قم ببناء ملف الوظائف الخاص بك
باستخدام nano ، قم بإنشاء ملف /var/www/hello/functions.php ملف على النحو التالي:
<?php
include 'config.php';
function function_response($response_string) : int {
$response_value = intval(substr($response_string,0,3));
return $response_value;
}
function function_payload($response_string) : string {
$response_value = substr($response_string,4);
return $response_value;
}
function user_get_name($useremail) : string {
global $db_host, $db_user, $db_pass, $db_name;
try{
$db_conn = new PDO('mysql:host=".$db_host.";dbname=".$db_name, $db_user, $db_pass);
$db_qry = "SELECT count(name) FROM users WHERE email = "" . $useremail ."'";
$db_act = $db_conn->prepare($db_qry);
$db_act->execute();
$db_rows = $db_act->fetchColumn();
if ($db_rows>0) {
$retval="";
$db_qry = "SELECT name FROM users WHERE email="" . $useremail . """;
$db_act = $db_conn->prepare($db_qry);
$db_act->execute();
$rows = $db_act->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if ($retval=="") {
$retval = $row['name'];
} else {
$retval = $retval . ", " . $row['name'];
}
}
$db_conn = null;
return "200 " . $retval;
} else {
$db_conn = null;
return "404 Not Found";
}
}
catch(PDOException $e) {
error_log('PDOException - ' . $e->getMessage(),0);
$db_conn->close();
return "500 Database Unavailable";
}
}
الخطوة 4. إنشاء ملف خادم خدمة ويب الخاص بك
باستخدام nano ، قم بإنشاء ملف /var/www/hello/hello_server.php ملف على النحو التالي:
<?php
include 'config.php';
require_once 'functions.php';
if(!extension_loaded("soap")){
dl("php_soap.dll");
}
ini_set("soap.wsdl_cache_enabled","0");
$server = new SoapServer("hello.wsdl");
function doGetUserName($emailaddr){
return function_payload(user_get_name($emailaddr));
}
$server->addFunction("doGetUserName");
$server->handle();
?>
الخطوة 5. قم ببناء واجهة مستخدم تطبيق الويب
باستخدام نانو ، قم بإنشاء /var/www/hello/hello_client.php ملف على النحو التالي:
<?php
include 'config.php';
require_once 'functions.php';
$emailaddr = $_POST["useremail"];
if (!empty($emailaddr)) {
try{
$sClient = new SoapClient('https://siptesting.net/hello/hello.wsdl');
$response = $sClient->doGetUserName($emailaddr);
echo "<h1>This is the Full Name of the user registered with email address: ".$emailaddr.":</h1><br>";
echo $response;
} catch(SoapFault $e){
var_dump($e);
}
} else {
echo "<form action="/hello/hello_client.php" method="post">";
echo "Enter User Email to search for: <input type="text" name="useremail"><br>";
echo "<input type="submit">";
echo "</form>";
echo "<br><br><a href="/">Home Page</a>";
}
?>
الخطوة 6. إنشاء ملف تعريف خدمة ويب الخاص بك
باستخدام نانو ، قم بإنشاء /var/www/hello/hello.wsdl ملف على النحو التالي:
<?xml version="1.0"?>
<definitions name="HelloWorld" targetNamespace="urn:HelloWorld" xmlns:tns="urn:HelloWorld" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Hello">
<xsd:element name="getUserName" type="xsd:string" />
<xsd:element name="getUserNameResponse" type="xsd:string" />
</xsd:schema>
</types>
<message name="doGetUserName">
<part name="emailAddress" type="tns:getUserName" />
</message>
<message name="doGetUserNameResponse">
<part name="return" type="tns:getUserNameResponse" />
</message>
<portType name="HelloPort">
<operation name="doGetUserName">
<input message="tns:doGetUserName" />
<output message="tns:doGetUserNameResponse" />
</operation>
</portType>
<binding name="HelloBinding" type="tns:HelloPort">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="doGetUserName">
<soap:operation soapAction="urn:GetUserNameAction" />
<input>
<soap:body use="encoded" namespace="urn:Hello" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" namespace="urn:Hello" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
<service name="HelloService">
<port name="HelloPort" binding="tns:HelloBinding">
<soap:address location="https://siptesting.net/hello/hello_server.php" />
</port>
</service>
</definitions>
المرحلة 2. تفحص خدمة الويب الخاصة بك
في هذا المثال ، يتم تعريف خدمة الويب الخاصة بنا على https://siptesting.net/hello/hello.wsdl. لمسح خدمة الويب باستخدام Acunetix:
- قم بإنشاء هدف جديد باستخدام URL https://siptesting.net/hello/hello.wsdl
- انشر PHP AcuSensor على خدمة الويب الخاصة بك
- قم بتشغيل فحص كامل مقابل خدمة الويب الخاصة بك وانتظر حتى يكتمل
المرحلة 3. تحديد نقاط الضعف في خدمة الويب الخاصة بك
افحص قائمة نقاط الضعف لهدفك
يجب أن نركز على البرمجة النصية عبر المواقع ونقاط ضعف إدخال SQL في هذا التمرين.
البند 1. البرمجة النصية عبر المواقع
- يظهر Acunetix تفاصيل الهجوم – تم ملء حقل الإدخال بنص برمجي خبيث محتمل.
- يسلط Acunetix الضوء على كود البرنامج النصي للاستغلال في ملف استجابة HTTP الجزء. هذا يعني أن البيانات المدرجة في حقل الإدخال لا يتم التحقق منها بشكل صحيح.
البند 2. حقن SQL
- يُظهر Acunetix تفاصيل الهجوم – تم ملء حقل الإدخال ببيانات ضارة محتملة تم إنشاؤها بطريقة لإجبار قاعدة البيانات على إظهار البيانات التي لم يكن المقصود عرضها ، مما يسمح للمتسلل الضار بصياغة طلبات إضافية ربما لاسترداد كميات كبيرة من البيانات.
- يسلط Acunetix الضوء على بيانات الاستغلال في ملف استجابة HTTP القسم – كان قادرا على استرداد أسماء مستخدمين متعددين. هذا يعني أن البيانات المدرجة في حقل الإدخال لا يتم التحقق منها بشكل صحيح.
المرحلة 4. حل نقاط الضعف
البند 1. البرمجة النصية عبر المواقع
السبب الجذري لهذه الثغرة يكمن داخل هذا الخط داخل hello_client.php ملف:
echo "<h1>This is the Full Name of the user registered with email address: ".$emailaddr.":</h1><br>";
ال $ emailaddr يحتوي على محتوى لم يتم التحقق من صحته لحقل إدخال المستخدم ويتم إرسال هذا مرة أخرى إلى المتصفح ، مما يعني أنه يمكن إجبار المتصفح على تنفيذ كود البرنامج النصي. نحتاج إلى تعقيم محتويات هذا المتغير قبل إرساله إلى المتصفح ، وتعديل الكود كما يلي:
echo "<h1>This is the Full Name of the user registered with email address: ".htmlspecialchars($emailaddr).":</h1><br>";
البند 2. حقن SQL
نظرة سريعة على hello_server.php يمكن أن يكشف الملف عن السبب الجذري. يتم إنشاء الاستعلامات باستخدام سلسلة متسلسلة:
$db_qry = "SELECT count(name) FROM users WHERE email="" . $useremail .""";
$db_act = $db_conn->prepare($db_qry);
$db_act->execute();
$db_qry = "SELECT name FROM users WHERE email="" . $useremail . """;
$db_act = $db_conn->prepare($db_qry);
$db_act->execute();
ال $ emailaddr يتم ربط المتغير ببساطة بسلسلة الاستعلام بدون أي تحقق. نحن بحاجة إلى تعديل الكود عن طريق تحديد معلمة سلسلة الاستعلام ، والتأكد من أن أي معلمات تم تمريرها يتم تجاوزها بشكل صحيح وتغليفها ، مع منع المزيد من عمليات الاستغلال. ستبدو مقتطفات التعليمات البرمجية الجديدة كما يلي:
$db_qry = "SELECT count(name) FROM users WHERE email = :useremail";
$db_act = $db_conn->prepare($db_qry);
$db_act->bindParam(':useremail', $useremail);
$db_act->execute();
$db_qry = "SELECT name FROM users WHERE email = :useremail";
$db_act = $db_conn->prepare($db_qry);
$db_act->bindParam(':useremail', $useremail);
$db_act->execute();
المرحلة 5. إعادة فحص لتأكيد القرار
يمكننا الذهاب إلى قائمة الثغرات من أجل الفحص وتحديد الثغرات التي قمنا بتعديلها.
الآن انقر فوق إعادة الاختبار زر – سيؤدي ذلك إلى إنشاء فحص جديد لاختبار نقاط الضعف المحددة مرة أخرى. ستظهر النتائج أننا قد نجحنا في حل الثغرات الأمنية.
احصل على أحدث محتوى حول أمان الويب
في بريدك الوارد كل أسبوع.