<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    SQL注入漏洞從發現到修復

    VSole2022-12-19 10:17:14

    發現漏洞

    一、環境準備

    1、在Linux主機上準備一套Xampp:模擬攻防

    2、在VSCode利用Remote Development進行遠程調試

    3、在Lampp的htdos目錄下創建security目錄,用于編寫服務器PHP代碼

    二、編寫Login.html

    三、編寫Login.php

    ";    echo "location.href='welcome.php'";}else{    // echo "login-fail
    ";    echo "location.href='login.html'";}//關閉數據庫mysqli_close($conn)?>
    

    四、編寫一個登錄后才能訪問的welcome.php

    ");}echo '歡迎來到安全測試平臺';?>
    

    五、進行登錄的滲透測試

    在登錄界面輸入一個單引號[']作為用戶名,Burp響應如下:

    Warning:  mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in /opt/lampp/htdocs/security/login.php
    

    以上響應出現MySQL報錯信息,上述報錯信息存在兩個漏洞:

    1、單引號可以成功引起SQL語句報錯,說明后臺沒有專門對單引號進行處理

    select * from user where username ='$username' and password = '$password'  正常情況:select * from user where username ='root' and password = '$password'  攻擊情況:select * from user where username =''' and password = '$password'    攻擊Payload:username:x' or userid=1#'    Post正文:             username=x' or+userid=1#'&password=111111&vcode=0000    select * from user where username ='x' or userid=1#'' and password = '$password'
    

    2、在報錯信息里泄露了敏感信息

    /opt/lampp/htdocs/security/login.php(當前代碼的絕對路徑)
    

    六、總結

    上述代碼一共發現了6個漏洞

    1、welcome.php頁面誰都可以訪問,沒有進行登錄判斷(中)

    2、在登錄界面輸入’作為用戶名,報錯信息存在login.php的絕對路徑,暴露了系統后臺的敏感信息(低)

    3、保存用戶信息的數據表中,密碼字段是明文保存的,不夠安全(中)

    4、登錄界面可以進行SQL注入,進而輕易實現登錄(高)

    5、login.php頁面使用了萬能驗證碼(中)

    6、登錄功能可以被爆破,沒有進行爆破防護(中)

    SQL注入-登錄漏洞-基礎修復

    一、使用Python進行注冊測試

    import requests# 利用Python對PHP的登錄界面進行Fuzz測試def login_fuzz():    # 先使用單引號進行測試    url = 'http://192.168.72.148/security/login.php'    data = {'username': "'", 'password': '666666', 'vcode': '0000'}    resp = requests.post(url=url, data=data)    if 'Warning' in resp.text:        print("本登錄功能可能存在SQL注入漏洞,可以嘗試")        # 如果單引號存在利用嫌疑,則繼續利用        payload_list = ["x' or id=1#", "x' or userid=1#", "x' or userid=2#"]        for username in payload_list:            data = {'username': username, 'password': '666666', 'vcode': '0000'}            resp = requests.post(url=url, data=data)            if "login-fail" not in resp.text:                print(f'登錄成功,payload為:{data}')    else:        print('通過試探,發現后臺界面對單引號不感興趣;')if __name__ == '__main__':    login_fuzz()
    

    二、任意訪問授權界面

    welcome.php頁面誰都可以訪問,沒有進行登錄判斷,該頁面是登錄后才能訪問,所以在該頁面需要進行登錄判斷,代碼修改為:

    1、在common.php中添加session_start(),讓其他頁面引入,便于直接使用Session

    php
    session_start();
    function create_connection(){
        // 連接數據庫
        $conn = mysqli_connect('127.0.0.1','root','123456','learn') or die("數據庫連接不成功!"); 
        // 設置數據庫的編碼格式
        mysqli_query($conn,"set names utf8;");
        mysqli_set_charset($conn,'utf8');
        return $conn;
    }
    ?>
    

    2、在welcome.php頁面中,源代碼修改為

    // OWASP-失效訪問控制
        // 修復方法:在顯示文本之前,先進行SESSION變量的驗證
    include "common.php";
    //isset() 函數用于檢測變量是否已設置并且非 NULL。
    if (!isset($_SESSION['islogin']) or $_SESSION['islogin'] != 'true'){
        die ("請登錄后再訪問此頁面
    ");
    }
    echo '歡迎來到安全測試平臺';
    ?>
    

    3、在login.php中,登錄成功后添加以下代碼

    if (mysqli_num_rows($result) == 1){
        echo "login-pass
    ";
        // 登錄成功后,記錄SESSION變量
        $_SESSION['username'] = $username;
        $_SESSION['islogin'] = 'true';
        echo "location.href='welcome.php'";
    }
    

    三、修復login.php暴露文件路徑

    當在用戶名輸入單引號時,會引起后臺報錯,一方面說明后臺沒有對單引號進行轉義處理,導致單引號可以被注入到SQL語句中,進而導致SQL語句中存在單獨的一個單引號,SQL語句無法有效閉合,發生錯誤。同時,還將該代碼的絕對路徑暴露出來,屬于敏感信息,應該將其屏蔽,修復代碼如下:

    $result = mysqli_query($conn,$sql) or die("SQL語句執行錯誤!") ;
    

    四、修改用戶表密碼為明文

    1、使用md5函數

    $source = 'YikJiang';
    echo md5($source);
    //提示一:user表中password字段必須是32+位
    //提示二:在用戶注冊時,必須使用md5函數將密碼加密保存
    

    SQL注入-登錄漏洞-SQL注入防護

    從代碼和SQL語句的邏輯層面進行考慮,不能輕易讓密碼對比失效

    基于將用戶輸入的引號(單引號和雙引號)進行轉義處理的前提,可以使用PHP內置函數addslashes進行強制轉義

    一、登錄SQL語句的邏輯問題

    1、該SQL語句在實現登錄操作時,存在嚴重的邏輯問題,用戶名和密碼的對比不應該放在同一條SQL語句中。

    2、應先通過用戶名查詢user表,如果確實找到一條記錄(用戶名唯一的情況下),找到記錄后再進行密碼的單獨對比。

    修復后的代碼如下:

    $sql = "select * from user where username ='$username'";$result = mysqli_query($conn,$sql) or die("SQL語句執行錯誤!") ;     //$result稱之為結果集// 以下代碼沒用進行爆破的防護(OWASP-認證和授權失敗)//如果用戶名真實存在,剛好找到一條,則再單獨進行密碼比較,即使用戶名出現SQL注入漏洞,但是只要密碼不正確,也無法登錄if (mysqli_num_rows($result) == 1){    // $row = mysqli_fetch_all($result,MYSQLI_ASSOC);       //索引數組+下標數組    // $row = mysqli_fetch_row($result);       //索引數組    $row = mysqli_fetch_assoc($result);     //下標數組    // var_dump($row);    if ($password == $row['password']){        echo "login-pass
    ";        // 登錄成功后,記錄SESSION變量        $_SESSION['username'] = $username;        $_SESSION['islogin'] = 'true';        echo "location.href='welcome.php'";    }    else{        echo "login-fail";    }}else{    echo "login-fail
    ";    echo "location.href='login.html'";}
    

    二、使用addslashes函數

    addslashes函數可以將字符串中的單引號、雙引號、反斜杠、NULL值自動添加轉義符,從而防止SQL注入中對單引號和雙引號的預防。

    原始SQL語句如下:

    select * from user where username ='$username' and password = '$password'
    

    如果用戶輸入x' or userid=1#',則SQL語句變成:

    select * from user where username ='x' or userid=1#'' and password = '$password'
    

    如果使用addslashes強制為用戶輸入添加轉義符,則變成:

    select * from user where username ='x\' or userid=1#\'' and password = '$password'
    

    上述SQL語句的用戶名為:x\’ or userid=1#\’

    三、使用MySQL面向對象方式

    1、面向過程方式

    使用PHP自帶的函數

    // 面向過程的方式function create_connection(){    // 連接數據庫    $conn = mysqli_connect('127.0.0.1','root','123456','learn') or die("數據庫連接不成功!");     // 設置數據庫的編碼格式    mysqli_query($conn,"set names utf8;");    mysqli_set_charset($conn,'utf8');    return $conn;}// 將數據庫查詢的結果集中的數據取出,保存到一個數組當中$row = mysqli_fetch_assoc($result);//mysqli_fetch_all默認使用索引數組,也可以設定參數強制使用關聯數組// $row = mysqli_fetch_all($result,MYSQLI_ASSOC);      // $row = mysqli_fetch_row($result);       //索引數組
    

    2、面向對象方式

    function create_connection_oop(){        $conn = new mysqli('127.0.0.1','root','123456','learn') or die("數據庫連接不成功!");    // 兩種方法設置字符集    // 1、$conn->query("set names utf8;")    // 2、    $conn->set_charset('utf8');    return $conn;}// 執行SQL語句function test_mysqli_opp(){    $conn = create_connection_oop();    $sql = "select * from user where userid < 6";    $result = $conn->query($sql);    //獲取結果集行數    echo $result->num_rows."
    ";    // 獲取結果集數組    // 使用關聯數組    $rows = $result->fetch_all(MYSQLI_ASSOC);    // var_dump($rows);    // 遍歷數組    foreach ($rows as $row){        echo "username:". $row['username'] . ",passwrod" . $row['password'] . "
    ";    }}
    

    四、使用MySQL預處理功能

    1、預處理功能的用法

    預處理的過程,就是先交給SQL數據庫進行SQL語句的準備,準備好后再將SQL語句中的參數進行值的替換,引號會進行轉義處理,將所有參數變成普通字符串,再進行第二次正式的SQL語句執行。MySQL的預處理既支持面向過程,也支持面向對象方式,但是我們后續直接使用面向對象的方式。

    $conn = create_connection_oop();$sql = "select userid,username,password,role from user where username= ?";$stmt = $conn->prepare($sql);$stmt->bind_param("s",$username);       // 綁定查詢參數$stmt->bind_result($userid,$username2,$password2,$role);    // 綁定結果參數$stmt->execute();       // 執行$stmt->store_result();  //調用結果
    

    2、使用預處理來防止SQL注入

    3、配置MySQL臨時日志查看SQL語句

    在MySQL數據庫中運行以下語句,開啟臨時日志,將日志信息保存到表格mysql數據庫的general_log表中。

    #開啟
    use mysql;
    set global log_output = 'TABLE';
    set global general_log = 'ON';
    #確認
    show variables like "general_log";
    MySQLi的預處理功能同樣支持面向過程和面向對象
    除了MySQLi用于處理數據庫外,在PHP中還有最傳統的MySQL和PDO兩種方式
    

    SQL注入-登錄漏洞-驗證碼處理

    一、驗證碼生成原理

    核心目的是確保是人在使用系統,圖片驗證碼、拖動驗證碼、拼圖驗證碼、問答驗證碼、計算驗證碼等。

    二、驗證碼代碼實現

    添加源代碼vcode.php,基于PHP繪制基礎圖片,生成驗證碼,然后將該驗證碼保存到Session變量

    三、修改HTML頁面調用驗證碼

    修改login.html

    input[name='vcode']{  width: 200px;}        
    YikJiang
    登錄
    

    四、登錄的驗證碼校驗

    修改login.php

    if(strtoupper($_SESSION['vcode'])  != strtoupper($vcode) ){
        die("vcode-error");    //向前端輸出一條消息同時結束代碼的運行
    

    驗證碼一旦生成后,不一定必須保存在Session中,任何可以存儲數據的方式均可以。比如數據庫、文件、內存中,或者保存在Redis緩存服務器中。比如短信驗證碼,通常會有一個時間限制(5分鐘內有效),最好的解決方案就是使用Redis緩存,并設置Key的過期時間

    sql注入單引號
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    未正確驗證用戶輸入的應用程序使它們容易受到 SQL 注入的攻擊。SQL 注入攻擊 發生在攻擊者能夠通過操縱用戶輸入數據將一系列惡意 SQL 語句插入“查詢”以供后端數據庫執行時。使用這種類型的威脅,應用程序可以很容易地被黑客入侵并被攻擊者竊取機密數據。
    數據庫注入提權總結
    2022-08-09 16:49:49
    select * from test where id=1 and ;布爾盲注常見的布爾盲注場景有兩種,一是返回值只有True或False的類型,二是Order by盲注。查詢結果正確,則延遲3秒,錯誤則無延時。笛卡爾積延時大約也是3秒HTTP頭注入注入手法和上述相差不多,就是注入點發生了變化HTTP分割注入常見場景,登錄處SQL語句如下
    0x00 前言好久沒寫真實漏洞挖掘案例了,今天寫一筆。直接發漏洞細節很生硬,大家也學不到什么,只有帶入感情,留下筆者的想法,才能產生共鳴,真正的幫助到別人。四個漏洞描述順序:存儲過程sql注入
    發現漏洞一、環境準備1、在Linux主機上準備一套Xampp:模擬攻防2、在VSCode利用Remote Development進行遠程調試3、在Lampp的htdos目錄下創建security目錄,用于編寫服務器PHP代碼二、編寫Login.html三、編寫Login.php"; echo "location.href='welcome.php'";}else{ // echo "login-fail. "; echo "location.href='login.html'";}//關閉數據庫mysqli_close?
    sql注入學習筆記
    2022-07-27 16:52:58
    sql注入學習筆記
    記錄一次本人CVE漏洞挖掘的過程,此漏洞已被分配編號:CVE-2023-36078
    各位師傅好,我是女鬼水妖,某高校大二學生,熱愛網絡安全,主攻紅隊方向。第一次投稿,也是第一次進行實戰演練。如果有寫的不好的地方,請師傅們指出,謝謝大家!
    url:http://******.com驗證:1.單引號返回物理路徑2.猜解當前表的列數,16列正確并正常
    0x01 %00繞過WAF輸入一個單引號頁面報錯首先閉合,這里用')閉合keywords=1') %23. order by x 被攔截,用--%0a代替空格即可直接上union select會一直卡著,沒有任何返回把空格都改為--%0a,成功響應,在 select 跟 1,2,3... 之間用兩個 --%0a 會無響應在 1 后面加上?并 url 編碼,原理是 waf 把空字節認為是結束導致了后面的語句可以繞過0x02 Base64繞WAF發現參數為 base64 編碼測試字符發現頁面報錯,使用報錯注入來出數據133 and updatexml. 這里可以使用16進制或者科學計數法0x1或1e1keywords=11'and-updatexml
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类