使用 WSDL 文件對 SOAP Web 服務運行 Acunetix 掃描查找漏洞

API和Web服務似乎不如websites和Web應用程序受歡迎,但事實并非如此。早在2018年,API就已占全球網絡流量的83%。大多數復雜的應用程序都基于微服務,而微服務基本上是使用API相互通信的Web應用程序。Web服務和API容易遭受與Web應用程序相同的漏洞。因此,為了確保它們的安全,您需要知道如何掃描它們。
在本文中,我們將向您展示如何使用WSDL文件對SOAP Web服務運行Acunetix掃描。您將學習如何執行以下操作:
- 構建一個簡單的Web服務
- 掃描Web服務
- 識別漏洞
- 緩解和/或解決漏洞
- 重新掃描Web服務以確認解決方案
階段1:構建簡單的Web服務
在本部分中,您將學習如何執行以下操作:
- 在Web服務器上創建數據庫以存儲數據
- 構建一個/var/www/hello/config.php文件以存儲連接到數據庫的參數
- 為服務的基本支持功能構建一個/var/www/hello/functions.php文件
- 為該Web服務將提供的API函數構建/var/www/hello/hello_server.php文件;在此示例中,我們將提供一個名為doGetUserName的 API函數。
- 構建一個/var/www/hello/hello_client.php文件,該文件將向用戶顯示一個輸入表單,并使用Web服務檢索請求的信息。
- 構建一個/var/www/hello/hello.wsdl以描述Web服務
注意:在實際情況中,上面列表的最后一步通常是第一步。在某些開發環境中,開發人員首先使用可視化工具來創建Web服務的結構,然后生成基本結構以及WSDL文件。在我們的示例中,我們正在手動執行此操作,因此這是最后一步。
步驟1.在Web服務器上創建數據庫
從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', 'john@example.com');
MariaDB [hellodb]> INSERT INTO users (name, email) VALUES ('Jane Doe', 'jane@example.com');
步驟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.構建您的Web服務服務器文件
使用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.構建Web應用程序用戶界面
使用nano創建一個/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.創建您的Web服務定義文件
使用nano創建一個/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.掃描您的Web服務
在此示例中,我們的Web服務定義在siptesting.net/hello/hello.wsdl。要使用Acunetix掃描Web服務,請執行以下操作:
- 使用URL siptesting.net/hello/hello.wsdl 創建一個新目標
- 將PHP AcuSensor部署到您的Web服務
- 對您的Web服務啟動全面掃描,然后等待其完成
階段3.確定Web服務中的漏洞
檢查目標漏洞列表

我們將集中討論此練習的跨站點腳本和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();
注意:有關更多信息,請閱讀有關防止PHP中的SQL注入的文章。
階段5.重新掃描以確認解決方案
我們可以轉到掃描漏洞列表,然后選擇我們已調整的漏洞。

現在,單擊“重新測試”按鈕-這將創建一個新的掃描,以再次測試所選的漏洞。結果表明,我們已經成功解決了這些漏洞。