1. 程式人生 > >hacker第一步,SQL注入式攻擊及防止

hacker第一步,SQL注入式攻擊及防止

SQL注入式攻擊是指利用資料庫查詢語句的漏洞,在目標伺服器上執行特定SQL命令以進行其他方式的攻擊,部分因為設計的不嚴謹,導致動態生成的SQL語句沒能對使用者輸入的資料進行有效的驗證,使得攻擊者可以繞開驗證過程直接進入並進行攻擊。
下面以SQL server 為例:
例如,如果使用者使用的查詢語句為select*from tb_user where name='"&user&"'and password='"&pwd&"'
但如果輸入的使用者名稱為"1’or’1’='1"這樣恆為真的欄位時,查詢語句便會查詢所有使用者並跳過密碼直接可以登陸進入。對於想驗證一個網站是否存在SQL注入式漏洞,只需在url後新增恆為真或恆為假的欄位,例如or 1=1和or 1=2,輸入or 1=1後執行介面應該不會出現任何變化,如果輸入or 1=2這樣恆為假的欄位執行後頁面提示找不到所查詢頁面,說明輸入欄位被執行,即存在SQL注入式漏洞,後續便可繼續查詢或者“攻擊”。
當然發現SQL漏洞的目的當然不是為了進行攻擊,為了防止攻擊,應該對查詢語句引數進行處理,一般會使用儲存過程來進行引數傳遞,下面分別介紹兩種簡單辦法:
1.使用引數對查詢欄位進行傳值,程式碼如下:

 public void sqlpara()
        {
            SqlConnection sqlcon = new SqlConnection("server=;database=;uid=;pwd=");
            SqlDataAdapter sda = new SqlDataAdapter("select ID,Name from tb_employee where [email protected] and [email protected]",sqlcon);
            //為SQL語句中的引數傳參
            sda.
SelectCommand.Parameters.Add("@ID",SqlDbType.VarChar,20).Value=txt1.Text; sda.SelectCommand.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = txt2.Text; DataSet ds = new DataSet(); sda.Fill(ds); if (ds.Tables[0].Rows.Count > 0) { MessageBox.
Show("使用者登陸成功","!提示",MessageBoxButtons.OK,MessageBoxIcon.Information); else { MessageBox.Show("使用者登陸失敗","!使用者名稱或密碼錯誤",MessageBoxButtons.OK,MessageBoxIcon.Error); } } }

2.使用儲存過程來進行引數傳遞,c#程式碼如下:

private void btnAdd_Click(object sender, EventArgs e)
{
    sqlcon = getCon();                                                                //例項化資料庫連線類物件
    sqlcmd = new SqlCommand("proc_InsertEInfo", sqlcon);                      //例項化SqlCommend物件
    sqlcmd.CommandType = CommandType.StoredProcedure;                    //指定執行儲存過程
    //為儲存過程新增引數
    sqlcmd.Parameters.Add("@id", SqlDbType.VarChar, 20).Value = txtID.Text;
    sqlcmd.Parameters.Add("@name", SqlDbType.VarChar, 30).Value = txtName.Text;
    sqlcmd.Parameters.Add("@sex", SqlDbType.Char, 4).Value = cboxSex.Text;
    sqlcmd.Parameters.Add("@age", SqlDbType.Int).Value = Convert.ToInt32(txtAge.Text);
    sqlcmd.Parameters.Add("@tel", SqlDbType.VarChar, 20).Value = txtTel.Text;
    sqlcmd.Parameters.Add("@address", SqlDbType.VarChar, 100).Value = txtAddress.Text;
    sqlcmd.Parameters.Add("@qq", SqlDbType.BigInt).Value = Convert.ToInt32(txtQQ.Text);
    sqlcmd.Parameters.Add("@email", SqlDbType.VarChar, 50).Value = txtEmail.Text;
    SqlParameter returnValue = sqlcmd.Parameters.Add("@returnValue", SqlDbType.Int); //定義儲存過程的返回引數
    returnValue.Direction = ParameterDirection.ReturnValue;
    sqlcmd.ExecuteNonQuery();                                                         //執行儲存過程
    sqlcon.Close();                                                               //關閉資料庫連線
    int int_returnValue = (int)returnValue.Value;                                    //獲取儲存過程的返回值
    if (int_returnValue == 0)
        MessageBox.Show("已經存在該職工編號!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    else
        MessageBox.Show("職工資訊——新增成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
    dgvInfo.DataSource = SelectEInfo("","").Tables[0];
}

此button——click事件實現向資料庫中新增員工資訊功能,通過使用儲存過程來進行傳值,對應的SQL儲存過程程式碼如下:

create proc proc_InsertEInfo
(
@id varchar (20),
@name varchar (30),
@sex char (4),
@age int,
@tel varchar (20),
@address varchar (100),
@qq bigint,
@email varchar (50)
)
as
if exists (select * from tb_Employee where ID=@id)
   return 0
else 
begin
   insert into tb_Employee(ID,Name,Sex,Age,Tel,Address,QQ,Email)
            values(@id,@name,@sex,@age,@tel,@address,@qq,@email)
   return 1
end
GO

當然,現在應該很少有站點還存在SQL注入式漏洞這種問題了,反正我嘗試了很多沒有一次成功,這裡有一個小技巧,如果要驗證站點所使用的資料庫型別,可以在url後新增"and user>0"來進行測試,此語句恆為假,若執行後返回頁面看到user後對應有sa字樣,熟悉SQLserver的同學很清楚,這是資料庫的系統登入名,即可判斷站點為SQL server設計。