sql注入攻擊初探與例項分析
阿新 • • 發佈:2019-02-20
來看看錶的結構:
mysql> show create table zzz; +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | zzz | CREATE TABLE `zzz` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(64) NOT NULL, `password` varchar(64) NOT NULL, `score` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 | +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql>
表內容:
mysql> select * from zzz;
+----+-------+----------+-------+
| id | name | password | score |
+----+-------+----------+-------+
| 1 | taoge | 123 | 100 |
+----+-------+----------+-------+
1 row in set (0.00 sec)
mysql>
要說明的是, 把密碼明文儲存起來, 本身就是不安全的。 即使用密文儲存, 也不安全, 應該考慮用加鹽雜湊。 但本文為了簡便起見, 先不討論這個問題。
現在假設有一個頁面, 需要使用者輸入name和password, 然後查詢score的值, 頁面請求傳送到後臺, 後臺查詢虛擬碼為:
string strName = ... ;
string strPassword = ... ;
select * from zzz where name=strName and password=strPassword ...
此時,如果taoge自己查詢, 那麼輸入name(taoge)和password(123)後, 執行的查詢操作是:
mysql> select * from zzz where name='taoge' and password='123'; +----+-------+----------+-------+ | id | name | password | score | +----+-------+----------+-------+ | 1 | taoge | 123 | 100 | +----+-------+----------+-------+ 1 row in set (0.00 sec) mysql>
可以正確查到自己的分數, 合情合理。
但是, 上面的程式碼有sql注入風險, 假設Jack想查詢taoge的分數, 但又不知道taoge的密碼, 怎麼辦呢? 還是可以查詢到的: Jack在頁面分別輸入
使用者名稱: taoge' or 1 = 1 ; #
密碼:hehe
那麼, 經頁面傳到後臺後, 後臺執行的操作是:
mysql> select * from zzz where name='taoge' or 1 = 1 ; #' and password='hehe';
+----+-------+----------+-------+
| id | name | password | score |
+----+-------+----------+-------+
| 1 | taoge | 123 | 100 |
+----+-------+----------+-------+
1 row in set (0.00 sec)
可見, 即使Jack不知道taoge的密碼123, 也是可以通過sql注入的方式得逞的。 在上面語句中, #充當了註釋符號的作用, 而1=1永遠為真, 所以,這相當於繞過了後臺的密碼校驗邏輯。
後臺系統該怎麼對抗這種sql注入攻擊呢?
1. 對每個引數進行嚴格校驗
2. mysql_real_escape_string搞起
3. 防緩衝區溢位
......
有關sql的注入攻擊, 後面也會繼續介紹。