天天看點

【黑馬程式員】連接配接資料庫時的注入漏洞攻擊

---------------------- ASP.Net+Android+IOS開發、.Net教育訓練、期待與您交流! ----------------------

在使用ADO.Net連接配接資料庫時,我們有時會要求從界面輸入登入名和密碼,然後把登入名和密碼傳入資料庫進行驗證,以确定使用者是否可以登入。如下面就是一個簡單的登入程式。

static void Main(string[] args)
        {
            string connStr = "Data Source = .;Initial Catalog = MySchoolBase;User Id = sa;Pwd = 1234;";

            Console.WriteLine("請輸入使用者名:");
            string username = Console.ReadLine();
            Console.WriteLine("請輸入密碼:");
            string password = Console.ReadLine();
            using (SqlConnection conn = new SqlConnection(connStr)) 
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = "select count(*) from Admin where LoginName = '" + username +
                        "' and LoginPwd = '" + password + "'";
                    int result = (int)cmd.ExecuteScalar();
                    if (result == 1)
                    {
                        Console.WriteLine("登陸成功!");
                    }
                    else
                    {
                        Console.WriteLine("登陸失敗!");
                    }
                }
            }

            Console.ReadKey();
        }
           

運作這個程式,結果如下:

【黑馬程式員】連接配接資料庫時的注入漏洞攻擊
【黑馬程式員】連接配接資料庫時的注入漏洞攻擊

乍一看上去,密碼輸入正确,登入成功,密碼輸入錯誤,登入失敗!這個登入程式已經很完美了。其實不然,看下面的兩圖:

【黑馬程式員】連接配接資料庫時的注入漏洞攻擊

當我們再輸入一串怪異的字元串時,我們仍然會登入成功。這是怎麼回事呢?我們先檢查一下資料庫MySchoolBase裡面的Admin表,看看是否有這樣的使用者名和密碼:

【黑馬程式員】連接配接資料庫時的注入漏洞攻擊

我們可以看到,資料庫裡面并沒有這樣的登入名和密碼,這種現象就是注入漏洞攻擊。當我們輸入1' or '1' = '1 這樣怪異字元串之後,經過調試,可以看到指令語句變成了select count(*) from Admin where LoginName = '1' or '1' = '1' and LoginPwd =  '1' or '1' = '1' ,這就造成了where語句永遠成立,然後就可以登入成功了。

那該怎麼辦呢?可以防止這樣的漏洞嗎?當然可以,因為那樣進行拼接的字元串在執行的時候,程式會把它當作一條語句來執行,這條語句裡的字元串就是那幾個1。我們隻要把使用者輸入的怪異字元串整體當成一個真正的字元串指派給LoginName和LoginPwd進行處理,就可以避免這種漏洞。VS給我們提供了一個參數化查詢:SqlParameter,通過它,我們可以把使用者輸入的字元串參數化,把它整體當作一個參數傳遞給指令語句。具體用法見代碼:

static void Main(string[] args)
        {
            string connStr = "Data Source = .;Initial Catalog = MySchoolBase;User Id = sa;Pwd = 1234;";

            Console.WriteLine("請輸入使用者名:");
            string username = Console.ReadLine();
            Console.WriteLine("請輸入密碼:");
            string password = Console.ReadLine();
            using (SqlConnection conn = new SqlConnection(connStr)) 
            {
                conn.Open();
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    //使用@占位符形式寫sql語句
                    cmd.CommandText = "select count(*) from Admin where LoginName = @LN and LoginPwd = @LP";
                    //以使用者輸入的字元串建立參數對象後添加到指令語句的參數集合
                    cmd.Parameters.Add(new SqlParameter("LN", username));
                    cmd.Parameters.Add(new SqlParameter("LP", password));
                    int result = (int)cmd.ExecuteScalar();
                    if (result == 1)
                    {
                        Console.WriteLine("登陸成功!");
                    }
                    else
                    {
                        Console.WriteLine("登陸失敗!");
                    }
                }
            }

            Console.ReadKey();
        }
           

運作後,我們繼續輸入那個怪異字元串,結果如圖所示:

【黑馬程式員】連接配接資料庫時的注入漏洞攻擊

這樣就可以有效的防止這種注入漏洞攻擊!

---------------------- ASP.Net+Android+IOS開發、.Net教育訓練、期待與您交流! ----------------------

繼續閱讀