1. 簡介
如今,互聯網的使用急劇上升,但絕大多數互聯網用戶沒有安全知識背景。大多數的人都會使用互聯網通過郵件Email的方式和他人進行通信。出於這個原因,大 多數網站允許他們的用戶聯系他們,向網站提供建議,報告一個問題,或者要求反饋,用戶將會發送反饋給網站管理員的電子郵件。
不 幸的是,大多數web開發人員對安全編碼Code-Security沒有足夠的認識,其中的一些程序猿使用現成的庫或框架,這些庫受到許多已知的漏洞。這 些漏洞是已經公布,廠商並已經對其進行了修補,並且相應的攻擊源代碼poc都在互聯網上可下載的,但大多數開發人員都懶得升級到最新版本。
今天我們要談論電子郵件注射,攻擊者可以使用你的郵件服務器來發送垃圾郵件。
2. 郵件注入
From Wikipedia:
電子郵件注入是一個安全漏洞,這種漏洞廣泛存在於在互聯網電子郵件收發應用中。這是電子郵件注射和HTTP頭注射類似。和SQL注入攻擊類似,這種漏洞是一類常見的的漏洞,發生在當一個編程語言是嵌入到另一個,例如MYSQL嵌入到PHP中。
當一個可以提交數據到一個Web應用程序表單被添加到一個Web頁面,惡意用戶可能會利用MIME格式添加額外的信息到要發送的消息中 (POST/GET),比如一個新的收件人列表或一個完全不同的消息體。因為MIME格式使用回車分隔在數據包中信息(HTTP數據包中的每一行之間都有 一個換行符,在POST和HTTP HEADER之間有兩個換行符),通過添加回車提交表單數據(使用FB的一些插件可以很容易的做到),可以允許一個簡單的留言板是用來發送成千上萬的消 息。同樣,一個垃圾郵件發送者可以使用這種戰術的惡意發送大量的匿名消息。
電子郵件注入是針對PHP內置郵件功能的一種攻擊類型。它允許惡意攻擊者注入任何郵件頭字段,BCC、CC、主題等,它允許黑客通過注入手段從受害者的郵 件服務器發送垃圾郵件。由於這個原因,這種攻擊稱為電子郵件注入,或者郵件形式濫發。這個漏洞是不限於PHP。它可能會影響任何從用戶UI接收消息並發送 電子郵件消息的應用程序。這種攻擊的主要原因是不適當的用戶輸入驗證或應用程序根本沒有驗證和過濾機制。
3. 郵件注入的攻擊原理
中國古話說得好: 知其然才能知其所以然。
為了解釋郵件注入的工作原理,我們必須先了解PHP Email函數的工作原理。下面是從PHP Manual中找到API解釋
- mail():
- http://www.php.net/manual/en/function.mail.php
- bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )
你可以注意到,這需要三個必填參數(”目的地、主題和消息”)和其他一些可選參數和函數返回一個布爾值。
那麼讓我們來看看一個帶漏洞的代碼來演示這個漏洞:
- <?php
- $to="[email protected]";
- if (!isset($_POST["send"]))
- {
- ?>
- <form method="POST" action="<?php echo $_SERVER['PHP_SELF'];?>">
- From: <input type="text" name="sender">
- Subject : <input type="text" name="subject">
- Message :
- <textarea name="message" rows="10" cols="60" lines="20"></textarea>
- <input type="submit" name="send" value="Send">
- </form>
- <?php
- }
- else
- {
- // the form has been submitted
- $from=$_POST['sender'];
- // send mail :
- if (mail($to,$_POST['subject'],$_POST['message'],"From: $fromn"))
- {
- echo "Your mail has been sent successfully";
- }
- else
- {
- echo "An error has been occured !";
- }
- }
- ?>
前面的代碼將用於演示目的和解釋我們的攻擊原理。我們將前面的代碼分成三個部分:
第一部分
- <?php
- $to="[email protected]";
- if (!isset($_POST["send"])){
- ?>
這段代碼將檢查表單提交或不是。用戶點擊提交按鈕和普通訪問這個頁面腳本的響應將是不同的, 如果這段代碼返回True(if語句中的判斷最終結果為true)這意味著表單沒有提交。表單將出現,等待用戶輸入。另一方面,如果它返 回"False",這意味著表單已經提交,所以電子郵件將被發送。
第二部分
- <form method="POST" action="<?echo $_SERVER['PHP_SELF'];?>">
- From: <input type="text" name="sender">
- Subject : <input type="text" name="subject">
- Message :
- <textarea name="message" rows="10" cols="60" lines="20"></textarea>
- <input type="submit" name="send" value="Send">
- </form>
第二部分是一個HTML表單標記,這要求用戶輸入。
第三部分
- <?php
- }
- else
- {
- // the form has been submitted
- $from=$_POST['sender'];
- // send mail :
- if (mail($to,$_POST['subject'],$_POST['message'],"From: $fromn"))
- {
- echo "Your mail has been sent successfully";
- }
- else
- {
- echo "An error has been occured !";
- }
- } ?>
在前面的代碼中我們可以特別注意這一行 mail($to,$_POST['subject'],$_POST['message'],”From: $fromn”), PHP的mail()函數需要subject, message, from 這些參數。如果函數執行成功,由PHP引擎發送郵件後,將打印出成功提示 "Your mail has been sent successfully"。如果出現錯誤,將提示相應信息 "An error has been occurred
但是有朋友要問了,問題在哪裡?主要的問題對用戶的輸入沒有做必要的驗證和過濾,正如《白帽子講web安全》裡說到的,任何的安全問題可以歸結為信任的問 題,這裡存在的問題就是程序代碼對用戶的輸入無限制的信任。正如你所看到的在第三部分代碼,發送郵件功能代碼從用戶接收輸入(包括郵件主題、消息和來源 等),參數沒有過濾和驗證。因此,惡意攻擊者可以任意控制這些參數的值,用戶發送inject攻擊。