標籤:安全 sql注入 php mysql
摘要:
基於php+mysql平台的sql注入攻防的實操,提供較詳細的ubuntu平台上的操作步驟,方便練手。
使用的平台:
Ubuntu 12.04,php 5.3.10, mysql Ver 14.14, Apache/2.2.22
步驟:
1. 在ubuntu上安裝Apache,mysql,具體過程自行百度;
2.1 首先熟悉如何再mysql中建立資料表?包括使用者名稱和對應的密碼;並且熟悉其中的查詢命令;完成查詢測試;
2.2 完成php端的代碼,完成php和mysql的連結;完成連結查詢測試;
2.3 基於瀏覽器端的sql攻擊測試;
2.1首先是對mysql的操作:
a)建立user資料庫:create database user;
b)切換到user資料庫:use user;
c)建立account表:create table account(name VARCHAR(20), password VARCHAR(20));裡麵包含使用者的名字和密碼;
d)在account表中插入資料:
insert into account values
(‘aaa‘, ‘111‘),
(‘bbb‘, ‘222‘);
即完成在資料庫user的account表中插入兩個使用者的使用者名稱和密碼;
2.2 如何將php與mysql相聯結?
mysql端需要設定許可權,將user資料庫的訪問權授予findme,並且密碼為findmeifyoucan.
grant select, delete on user.* to findme identified by ‘findmeifyoucan‘;
在php後端需要建立連結的代碼如下:
$db = new mysqli(‘localhost‘, ‘findme‘, ‘findmeifyoucan‘, ‘user);
2.3下面分別是瀏覽器端和php後端的對應的代碼(顯示原理為主,代碼盡量簡化);瀏覽器端的html代碼login.html:
<html><head><title>Please log in.</title></head><body><form action="result.php" method="post">Enter your user name:<br /><input name="user" type="text" size="40" /><br />Enter your password:<br /><input name="psd" type="text" size="40" /><br /><input type="submit" name="submit" value="search" /></form></body></html>
下面是php端的代碼result.php:
<span style="font-size:14px;"><html><head><title>see if you can login</title></head><body><h1>Check wether you can login in or not?</h1><?phpfunction check($db){$name = $_POST["user"];$password = $_POST["psd"];$result = $db->query("select count(*) from account where name = '$name' and password = '$password'");$row = $result->fetch_assoc();if($row['count(*)'] != 0){echo 'you login in';}else{echo 'you not login';}}$db = new mysqli('localhost', 'findme', 'findmeifyoucan', 'user');if(mysqli_connect_errno()){echo 'Error: could not connect to database user. Please try again.';exit;}check($db);$db->close();?></body></html></span>在瀏覽器中,訪問localhost/login.html,再輸入登陸的使用者名稱和密碼即進行測試。上面的代碼不能抵禦下面sql注入攻擊:如果輸入user:aaa, password:111;則順利登陸;這不奇怪,但是在password處輸入下面的代碼:112‘ or ‘1‘=‘1, 也可以正常登陸,此時的sql語句如下:select count(*) from account where name=‘aaa‘ and password=‘112‘ or ‘1‘=‘1‘;後面的‘1‘=‘1‘邏輯成立,所以返回不為0。
那怎麼應對這種情況呢?常見的解決方式是對輸入的值進行轉義符操作;具體的操作方式如下:$name=addslashes($name);$password=addslash3s($password);這樣的操作後,就可以規避112‘ or ‘1‘=‘1的攻擊;原因也很簡單,因為select查詢語句變為如下:select count(*) from account where name=‘aaa‘ and password=‘112\‘ or \‘1\‘=\‘1‘;
資料庫中使用者‘aaa‘的密碼明顯不可能是‘112\‘而且\‘1\‘=\‘1‘也不成立,所以就起到防禦作用。
結論:1. 上述代碼雖然簡單,但是本人也不是一次就寫對,還是藉助了php的調試功能,需要區分php在開發和生產階段的調試設定的不同;2. 實踐過程再一次證明:只要系統可觀察,就可以理解;
基於php+mysql的sql注入攻防實操