建站
phpstudy建站
phpstudy创建网站(empire
)之后生成D:\phpstudy_pro\WWW\empire
文件夹,下面有两个文件
e
m
p
i
r
e
{
.
h
t
a
c
c
e
s
s
n
g
i
n
x
.
h
t
a
c
c
e
s
s
empire\begin{cases} .htaccess\\ nginx.htaccess \end{cases}
empire{.htaccessnginx.htaccess
如果用phpstorm
建立工程打开网站根目录的话则会自动生成.idea文件夹,那和网站没关系不管他了
.htaccess
文件的作用是覆盖Apache
主配置文件D:\phpstudy_pro\Extensions\Apache2.4.39\conf\httpd.conf
关于Apache
的配置还有.htaccess
的作用会研究,但不是现在
nginx.htaccess
显然是关于nginx服务器的,不关心
总的来说自动生成的东西我不知道是干啥的,现在也不想知道
MySQL数据库配置
创建一个名为empire的数据库,用户名密码都是administrator
在empire数据库中建立一个users表,有两列,用户名(字符串),密码(字符串)
mysql> USE empire;
Database changed
mysql> CREATE TABLE users(
-> username varchar(20),
-> password varchar(20)
-> );
Query OK, 0 rows affected (0.05 sec)
数据库就建立完毕了,测试插入
mysql> INSERT INTO empire.users(username,password) values("test","test");
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 3
Current database: empire
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO empire.users(username,password) values("admin","admin");
Query OK, 1 row affected (0.00 sec)
mysql> select * from empire.users;
+----------+----------+
| username | password |
+----------+----------+
| test | test |
| admin | admin |
+----------+----------+
2 rows in set (0.00 sec)
网站结构
这个网站的最初功能只有登录和注册两个功能,用户数据存储在MySQL数据库
WWW\
empire\
login.html
login.php
register.html
register.php
login.html
1.提供到register.html的链接
2.使用post方法将前端收集的表单发送给后端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<a href="register.html">register</a>
<form action="login.php" method="post">
<p>username: <input type="text" name="uname" /></p>
<p>password: <input type="password" name="psw" /></p>
<input type="submit" value="Submit" />
</form>
</body>
</html>
效果
这里使用明文传输的密码,如果被抓包就寄了
但是现在不是研究怎么加密传输的时候
login.php
1.验证是否有用户名输入
2.用用户给定的输入查询数据库
<?php
$uname="";
$psw="";
if(!isset($_POST["uname"])||$_POST["uname"]==""){//如果没有输入用户名则报错
die("no input");
}
else{
$uname=$_POST["uname"];
$psw=$_POST["psw"];
}
$servername="localhost";//服务端地址,这里使用本地地址
$username="administrator";//数据库用户名
$password="administrator";//数据库密码
$conn=new mysqli($servername,$username,$password);//创建数据库对象,面向对象风格的数据连接方式
if($conn->connect_error){
die("mysql connect failed");
}
$sql="SELECT * from empire.users WHERE username = '$uname' AND password= '$psw' ";//构造sql查询语句
$ans=$conn->query($sql);
if($ans->num_rows>0){//如果查询结果不为0
echo "login successfully";
}
else{
echo "wrong username or password";
}
$conn->close();
这样写显然是存在sql注入漏洞的,构造payload:
既可以通过后端检验报告登录成功,实际上是or true发挥的作用.
由于回显是固定的
if($ans->num_rows>0){ echo "login successfully"; } else{ echo "wrong username or password"; }
因此只能使用sql盲注猜测
比如当username输入
' union select * from empire.users#
时会回显login successfully但是当username输入
' union select * from empire.user#
时网页报错
但是现在不是研究怎么避免sql注入的时候
register.html
通过post方法将表单传送给后端register.php,要求两次输入密码一致
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<form action="register.php" method="post">
<p>username: <input type="text" name="uname" /></p>
<p>password: <input type="password" name="psw" /></p>
<p>rePassword:<input type="password" name="rePsw" /></p>
<input type="submit" value="Submit" />
</body>
</html>
效果
register.php
<?php
$uname="";
$psw="";
$repsw="";
if(!isset($_POST["uname"])||$_POST["uname"]==""){
die("no input");
}
else{
$uname=$_POST["uname"];
$psw=$_POST["psw"];
$repsw=$_POST["rePsw"];
}
$servername="localhost";
$username="administrator";
$password="administrator";
$conn=new mysqli($servername,$username,$password);
if($conn->connect_error){
die("mysql connect failed");
}
$sql="SELECT * from empire.users WHERE username = '$uname' ";//首先检查用户名是否被注册过
$ans=$conn->query($sql);
if($ans->num_rows>0){
echo "username already exist,please choose another username when register";
echo '<a href="register.html">register</a>';//如果被注册过则跳转register.html页面
}
else{
if($psw!=$repsw){//验证两次输入密码是否相同
echo "password is not the same,please input the same password when register";
echo '<a href="register.html">register</a>';
}
else{
$sql="INSERT INTO empire.users (username,password)values('$uname','$psw')";//数据库插入记录
if($conn->query($sql)){
echo "register successfully,please login<br>";
echo '<a href="login.html">register</a>';
}
else{
echo "register failed,please reregister";
echo '<a href="register.html">register</a>';
}
}
}
$conn->close();
1.sql注入问题不用说肯定存在
2.验证用户是否被注册过应该是在用户输入用户名之后,输入密码之前,使用javascript DOM将输入的用户名传给后端进行检查的,
但使用javaScript不是现在
php连接数据库的代码优化
1.后端login.php和register.php连接数据库时的代码可以提取出来另外建立一个文件使用,
原来的写法是在搞重复建设
这一点可以学习sqli-labs靶场
D:\phpstudy_pro\WWW\sqli-labs\sql-connections
这个文件夹下面有一个db-creds.inc
,是一个纯配置文件<?php //give your mysql connection username n password $dbuser ='root'; $dbpass ='sjh123456'; $dbname ="security"; $host = 'localhost'; $dbname1 = "challenges"; ?>
还有一个
sql-connect.php
这个是供其他关卡使用的连接设置<?php //including the Mysql connect parameters. include("../sql-connections/db-creds.inc"); @error_reporting(0); @$con = mysql_connect($host,$dbuser,$dbpass);//host,dbuser,dbpass都来自db-creds.inc // Check connection if (!$con) { echo "Failed to connect to MySQL: " . mysql_error(); } @mysql_select_db($dbname,$con) or die ( "Unable to connect to the database: $dbname"); $sql_connect = "SQL Connect included"; ############################################ # For Less-24 $form_title_in="Please Login to Continue"; $form_title_ns="New User"; $feedback_title_ns="New User"; $form_title_ns= "Less-24"; ############################################ # For Challenge series--- Randomizing the Table names. ?>
然后在其他关卡比如less-1中
include("../sql-connections/sql-connect.php");
这样引入该文件
改进之后的写法