web安全学习笔记(三) SQL注入

在上一节中,使用PHP搭建了简单的登陆界面,为了更加熟悉网站的配置,对网站的默认主页进行了修改,并且将网站的程序移动到了/home/tong/Downloads/目录下。
修改网站的默认主页,可以通过修改/etc/apache2/mods-enabled/dir.conf文件:
在这里插入图片描述
讲login.php移动到DirectoryIdex后面,则输入localhost时,默认跳转到登陆界面了:
在这里插入图片描述
移动网站路径,先讲所有的网站文件移动到/home/tong/Downloads 下,然后修改/etc/apache2/sites-available/php_website.conf,目录为移动后的目录:
在这里插入图片描述
除此之外,还需要修改/etc/apache2/apache2.conf中的路径:
在这里插入图片描述
(这个文件比较长,可以输入/,再输入关键字快速定位到需要修改的位置。

接下来就是进行sql注入的测试了:
程序的登陆逻辑如下:

<?php

$conn = new mysqli("localhost","phpadmin", "ppzz4869","PHP");
if ($conn->connect_error){
    die("connection fail" . $conn->connect_error);
}
$name = trim($_POST['username']);
$psw = trim($_POST['password']);
$sql="select * from user where name='$name' and psw='$psw'";
$res = $conn->query($sql);
if ($res->num_rows > 0){
    setcookie('username',$name,time()+3600);
    header("Location:index.php");
} else{
    echo "login fail,<a href=\"login.php\">Please re-login</a>";
}

在程序中,对接收的关键字username 和 password做了trim()处理,即过滤掉字符串中的所有空格。那么如果不加trim(), 会发生什么情况呢?
假如我们这里去掉了对username的trim()处理,用户名输入’or 1=1-- (注意–后有一个空格),密码为空,不输入。
在这里插入图片描述
点击登陆,竟然发现登陆成功了:
在这里插入图片描述
打开phpstorm调试,在$sql 处设置断点:
在这里插入图片描述
可以看到,这里的sql语句根据输入变成了:

select * from user where name=''or 1=1-- 'and psw='";

在MySQL中,注释符有#,-- ,和/* */ 被注释掉的代码不会被执行
所以sql语句变为了:

select * from user where name=''or 1=1;

1=1 始终为true,那么where后的表达式,也始终为true,数据库则会返回所有的行。所以,$res->num_rows > 0条件满足,cookie被设置并且自动跳转到登陆界面。
如果对username做了空格的过滤后,则发现登陆失败。因为MySQL中注释–后必须跟有空格。
万能密码登陆的一个思路就是,闭合sql语句中的单引号,并且使where后的表达式恒为一。那么如果用户名和密码字段都不允许出现空格该如何登陆?
在MySQL中,注释符号不仅有-- ,还有# 和 /**/,所以构造用户名:
username=‘or’1’=‘1’#
在这里插入图片描述
显示登陆成功。
上面的两个例子,都使用到了MySQL的注释符,然而在很多系统中,注释符号往往被系统过滤掉了,那么可以进行如下的构建:
username=adasd’=’
password=adasd’=’
登陆成功:
在这里插入图片描述
还是按照刚才的思路,sql语句被构建成了:

select * from user where username='adasd'='' and password='adasd'=''

username=‘adasd’返回值为空,判断空=’’,成立,所以and的左右两侧都为1,
查询返回所有用户的信息,num_row>0,登陆成功。

假设现在index界面有一个查询功能,输入用户名,可以返回在数据库的用户名,如果不存在,则返回空。修改后的代码如下:

<?php
$cookie = $_COOKIE['username'];
if (!isset($_COOKIE['username']))
{
    echo 'Illegal login!<a href="login.php">please login</a>';
    exit();
} else{
    echo "Welcome  " , $cookie;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <title> Hello World! </title>
    <meta charset="UTF-8">
</head>
<body>
<form name="input" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    user: <br /><label>
        <input type="text" name="username">
        <input type="submit" value="query">
    </label><br>

</form>

<?php
$conn = new mysqli("localhost","phpadmin","ppzz4869","PHP");
if ($conn->connect_error){
    echo "connection fail";
}
$name = $_POST['username'];
$sql = "select * from user where name = '$name'";
$res = $conn->query($sql);
if ($res->num_rows > 0){
    while ($row = $res->fetch_row()){
        echo $row[0] , "\t";
    }
} else {
    echo "no such user";
}
?>

</body>
</html>

查询用户tong,存在:
在这里插入图片描述
查询用户aaaaaaa:
在这里插入图片描述
这里的查询语句是:

select * from user where name = '$name'

可以知道,如果我们让where后为真,那么查询则会返回所有用户的数据:
在这里插入图片描述
由此我们可以得知,数据库的user表中,共有四行。
如何知道后端的sql语句查询了多少个字段呢?
在数据库查询中,有时会用到order by命令,order by 命令对查询结果进行排序。
假设我们注册的用户用户名为a,那么:
在这里插入图片描述
结果正常返回,
在这里插入图片描述
依然正常返回,
在这里插入图片描述
当 order by 3 时,可以发现提示 no such user, 说明查询出错,select 语句一共查询了两个字段,当按第三列进行排序时,就会报错了。
或是使用union查询也可以达到相同的效果,例如:
在这里插入图片描述
不同的是,使用union查询时,只有匹配到正确的行数,程序才可以返回正常。
union查询也可以查看查询返回的信息属于第几个字段,比如在MySQL中,支持这样的union查询:

select * from user where name = '$name' union select 1,2;

我们可以构建类似的SQL注入:
在这里插入图片描述
可以发现,返回的结果是a 1,说明查询返回的结果是第一个字段。
通过UNION查询,利用MySQL自带的系统函数,可以查询到许多想要的信息。
例如,@@datadir 可以返回数据库的路经,@@basedir可以返回MySQL的安装路经,通过UNION查询返回出来。
在这里插入图片描述
在这里插入图片描述
还有一些函数,例如user()返回当前数据库的用户名:
在这里插入图片描述
由于在搭建网站的过程中,对数据库的账户的权限进行了限制,如果登陆数据库的账户具有File 权限时,可以读取服务器中的文件,甚至可以写文件,生成一句话木马。由于这个网站在搭建过程中,对用户做了权限的限制,没有FILE权限,不可以达到这些目的。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值