<dd id="sga4y"><optgroup id="sga4y"></optgroup></dd>
<nav id="sga4y"><code id="sga4y"></code></nav>
  • <optgroup id="sga4y"></optgroup>

    原文地址:http://drops.wooyun.org/papers/483

    “安全是一個整體,保證安全不在于強大的地方有多強大 而在于真正薄弱的地方在哪里”--劍心

    從很多的滲透大型企業內網的案例來看,入侵者大多數是從Web上找到漏洞,從而利用漏洞進一步進行提權,滲透入侵。

    WooYun: 時代互聯上傳漏洞多臺數據庫可控

    WooYun: 網易某系統未授權訪問可導致內網被滲透

    WooYun: 網易某系統未授權訪問續—內網滲透

    WooYun: 搜弧某分站XFF注射&配置不當導致源碼泄漏等重大漏洞

    梧桐雨的大型互聯網系列

    腳本安全就像你家的防盜門,你家門都沒關,你家能安全嗎?

    烏云上最常見的腳本漏洞莫過于SQL注入和XSS。

    腳本安全的本質就是腳本接受了不安全的變量輸入,又沒得到有效的過濾,最后進入一些對敏感的函數就會對安全造成威脅。

    比如出現在mysql_query()函數可能就會造成SQL注入漏洞,出現在eval()以及preg_replace()中可能導致代碼的執行。

    這里我用DVWA演示SQL,XSS ,任意代碼執行漏洞的原理

    然后用各種修復方法進行修復,附帶講解一些修復方法的弊端。

    DVWA下載地址: https://github.com/RandomStorm/DVWA/archive/v1.0.8.zip

    DVWA sql調用的文件/vulnerabilities/sqli/目錄下,分為low,medium,high三個等級

    SQL注入原理

    #!php
    //Low.php
    
    if(isset($_GET['Submit'])){
    
        // Retrieve data
    
        $id = $_GET['id'];
    
        $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";//這里$id變量沒有經過任何的過濾,直接傳入了sql語句,造成字符型注入
        $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );//執行SQL
    

    原SQL中

    SELECT first_name, last_name FROM users WHERE user_id = '$id'
    

    中的$id可被用戶控制,當黑客把$id變成

    ' union select user,password from users#
    

    那么這條語句就會變成

    SELECT first_name, last_name FROM users WHERE user_id = '' union select user,password from users#
    

    這樣導致了數據庫中其他數據被黑客查詢。 ?

    enter image description here

    #!php
    //medium.php中
    if (isset($_GET['Submit'])) {
    
        // Retrieve data
    
        $id = $_GET['id'];
        $id = mysql_real_escape_string($id);
    
        $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
    
        $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
    
        $num = mysql_numrows($result);
    

    雖然$id經過了mysql_real_escape_string轉義了’,可是因為后面的SQL語句$id沒有單引號保護,會被系統認為是數值型,導致數值型注入

    構造SQL注入語句

    1 union select user,password from users
    

    SQL語句就變成了

    SELECT first_name, last_name FROM users WHERE user_id = 1 union select user,password from users ?
    

    enter image description here

    SQL注入修補方法

    字符型注入漏洞修補方法:

    PHP5.3之前版本在php.ini中設置

    magic_quotes_gpc=On; 
    

    magic_quotes_quotes_gpc會對傳入的$_POST,$_GET,$_SERVER里的 ‘,”,\進行轉義。

    但是PHP5.4之后,magic_quotes_quotes_gpc就被廢除了。

    還要使用mysql_real_escape_string()或addslashes()對傳入參數進行過濾,或者使用str_replace()對一些關鍵詞進行替換。

    例:

    #!php
    if(isset($_GET['Submit'])){
    
    // Retrieve data
    
    $id = addslashes($_GET['id']);
    
    $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
    $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
    
    $num = mysql_numrows($result);
    

    修補后進行SQL注入

    enter image description here

    但是addslashes()和mysql_real_escape_string()在數據庫字符集設為GBK時是可能被繞過的。

    PHP字符編碼繞過漏洞參考文http://huaidan.org/archives/2268.html

    如果數據庫字符集是GBK的情況下,可以把

    $mysqli->query('SET NAMES gbk'); 
    

    修改為:

    $mysqli->set_charset('gbk');
    

    數值型注入:

    數值型注入比較好修補,只需要判斷傳入的變量是否為數值型就可以了(或者強行改成字符型)

    例:

    #!php
    $id = $_GET['id'];
    $id = intval ($id);
    
    $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
    
    $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
    
    $num = mysql_numrows($result);
    

    修補后效果

    enter image description here

    XSS漏洞原理

    黑客往Web頁面里插入惡意html代碼,當用戶瀏覽該頁之時,嵌入其中Web里面的html代碼會被執行,從而達到黑客的特殊目的,比如竊取用戶cookies.或者進行其他操作。 在

    #!php
    //low.php
    <?php
    if(isset($_POST['btnSign']))
    {
    
       $message = trim($_POST['mtxMessage']);
       $name    = trim($_POST['txtName']);
    
       // Sanitize message input
       $message = stripslashes($message);//stripslashes() 函數刪除由 addslashes() 函數添加的反斜杠。
       $message = mysql_real_escape_string($message);//mysql_real_escape_string() 函數轉義 SQL 語句中使用的字符串中的特殊字符。
    
       // Sanitize name input
       $name = mysql_real_escape_string($name);
    
       $query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
    
       $result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' ); } 
    ?> 
    

    從上面程序可以看出,$message,$name兩個變量從$_POST傳入,只是經過一些特殊字符的轉換。并沒有對尖括號進行轉義,所以還是造成了XSS的產生。

    直接插入XSS語句

    <script>alert(1)<script>
    

    就執行了

    而medium.php中,雖然對$message進行了尖括號轉義,而且對<script>進行了替換,但是$name沒有進行轉義,而且跨站腳本可以用多種標簽,如<img />,等…。Name的<input />限制了maxlength=‘10’的長度,但是我們的防御對象是精通技術的黑客。這種html下的長度限制是可以直接通過瀏覽器修改..然后通過大小寫成功繞過str_replace(),插入XSS.

    <SCript>alert(1)</SCript>
    

    ?

    enter image description here

    #!php
    <?php
    
    if(isset($_POST['btnSign']))
    {
    
       $message = trim($_POST['mtxMessage']);
       $name    = trim($_POST['txtName']);
    
       // Sanitize message input
       $message = trim(strip_tags(addslashes($message)));
       $message = mysql_real_escape_string($message);
       $message = htmlspecialchars($message);
    
       // Sanitize name input
       $name = str_replace('<script>', '', $name);  //一個大小寫就可以繞過,或者<img />
       $name = mysql_real_escape_string($name);
    
       $query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
    
       $result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );
    
    }
    
    ?>
    

    XSS漏洞修補方法

    使用htmlspecialchars()在輸出時對輸出內容就行轉義。

    瞌睡龍說:在輸出時進行轉義比輸入時進行轉義效果更好,因為可以確保數據在入庫時是完整的….不然丟失數據。

    例:

    #!php
    <?php
    
    if(isset($_POST['btnSign']))
    {
    
       $message = trim($_POST['mtxMessage']);
       $name    = trim($_POST['txtName']);
    
       // Sanitize message input
       $message = stripslashes($message);
       $message = mysql_real_escape_string($message);
       $message = htmlspecialchars($message);
    
       // Sanitize name input
       $name = stripslashes($name);
       $name = mysql_real_escape_string($name); 
       $name = htmlspecialchars($name);
    
       $query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
    
       $result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );
    
    }
    
    ?>
    

    修補后效果,可以看到尖括號已經被轉義了,html代碼已經不執行

    enter image description here

    任意命令執行漏洞原理

    任意命令執行可謂是web里最高危的漏洞了,有可能可以直接寫下shell或者直接添加用戶。

    任意命令執行漏洞的產生大多是因為變量可以被用戶輸入控制,而沒有經過任何的判斷和過濾處理就進入了高危的函數。

    #!php
    <?php
    
    if( isset( $_POST[ 'submit' ] ) ) {
    
        $target = $_REQUEST[ 'ip' ];
    
        // Determine OS and execute the ping command.
        if (stristr(php_uname('s'), 'Windows NT')) { 
    
            $cmd = shell_exec( 'ping  ' . $target );
            $html .= '<pre>'.$cmd.'</pre>';
    
        } else { 
    
            $cmd = shell_exec( 'ping  -c 3 ' . $target );
            $html .= '
    
      <pre>'.$cmd.'</pre>';
    
        }
    
    }
    ?>
    

    由于$target沒有經過處理就進入shell_exec函數,導致黑客可以構造特殊的變量執行批處理命令。

    我輸入可 0 | dir

    那么執行的命令的命令就是 ping -c 0 | dir

    enter image description here

    假如黑客在利用時輸入的是

    0|net user hacker/add
    

    那么造成的后果將不堪設想

    以下是可能會造成任意命令執行的函數

    system|passthru|exec|popen|proc_open|move_uploaded_file|eval|copy|shell_exec|assert
    

    任意命令執行漏洞修補辦法

    在寫程序時盡量地使變量不能被用戶所控制!且注意變量初始化的問題。

    使用str_replace對“%”,”|”,“>”進行替換

    進入函數前判斷變量是否合法。

    暴力破解漏洞

    這個是漏洞?算是吧…

    祭上神器Burp Suite,Burp suite運行后,Burp suite,Proxy 開起默認的8080 端口作為本地代理接口。

    使用Burp suite通過置一個web 瀏覽器使用其代理服務器,見下圖 ? enter image description here

    然后打開你要暴力破解的后臺,隨便輸入一個賬號密碼…把抓到的包send to intruder ? ?enter image description here

    enter image description here

    enter image description here

    Start attack~~~

    然后就對面返回包的大小,知道密碼

    enter image description here

    暴力破解漏洞修補方法

    加個google驗證碼,保證沒有程序能識別出來…

    文件包含漏洞

    文件包含漏洞分為兩種,一種是遠程包含,一種是本地包含。

    服務器通過php的特性(函數)去包含任意文件時,由于要包含的這個文件來源過濾不嚴,從而可去調用并執行一個文(木)件(馬),而我們可以構造這個文(木)件(馬)來達到邪惡的目的。

    涉及到的危險函數,include(),require()和include_once(),require_once()

    現在遠程包含的漏洞已經不多了,但是遠程包含的危害是最大,相當于一個命令執行。

    而本地包含,有時配合一下解析漏洞往往可以getshell.

    例:

    #!php
    <?php 
    
        $file = $_GET['page']; //The page we wish to display  
    
    ?>
    

    Include.php內容:

    #!php
    <?php 
    echo "hello world\n";
    ?>
    

    總結

    在編寫程序時,應有良好的代碼習慣,如使用變量前初始化。

    做安全的過濾在全局里做,或者寫在類里。

    不要相信數據,所有輸入在得到證明之前都是不可信的,所有從用戶上輸入的數據都應該加以判斷。

    不返回過多錯誤的原因,如一個黑客進行sql注入。

    多上wooyun看漏洞

    97av