深入浅出sql注入(1)——初识sql注入

为什么会出现sql注入?究竟什么是sql注入?让我们来看一个简单的例子

$username = $_POST['username']; //获取用户提交的用户名
$password = md5($_POST['password']); //获取用户提交的密码,并且进行哈希处理
$user = $db->query("SELECT * FROM account WHERE username='$username' and password='$password'");
if (empty($user)) {
    exit('user not exists or wrong password');
} else {
    //login success
}

上面是一个很普通的登录相关的代码,看上去为了避免像CSDN明文密码那样子的惨剧再次上演,程序员还贴心地对密码做了一次哈希。如果一切正常,比如用户填写的用户名是admin,密码是123456,那么我们拼接后提交给数据库的sql应该就是

SELECT * FROM account WHERE username='admin' AND password='e10adc3949ba59abbe56e057f20f883e'

看上去非常正常,和我们想要的完全一样。可是,如果用户提交的用户名不是『admin』,而是『admin’– 』,那么会发生什么呢?让我们再拼接一次sql试试看。

SELECT * FROM account WHERE username='admin'-- ' and password='e10adc3949ba59abbe56e057f20f883e'

从高亮来看似乎出了点问题。为什么?『– 』在很多数据库中都代表这注释(注意最后有一个空格),要知道数据库是不会去区分一条sql语句里哪部分是你自己编码的,哪部分是用户提交的,对它来说,你最后给它的一定是一个字符串。根据上面这个字符串,数据库忠实地返回了那个叫admin的用户的信息,因此入侵者成功地绕过了我们的限制,登入了系统QAQ

其实上面说到的最后给数据库的一定是一个字符串,这并不完全正确,因为有预处理语句的存在,具体的知识我们会在后面谈防御sql注入的时候介绍

什么?你说你很机智的用户名不叫admin而是叫xiami,所以完全没有关系?那你有没有思考过如果用户提交的用户名是『’ or 1=1– 』怎么办(→_→)

嗯,是不是觉得上面的例子太低级了?但在大概01年左右,基本上所有带登录功能的系统,似乎都存在着这个问题。。。

 

sql注入除了可以绕过登录,在更多的时候是用来获取信息(比如用户的用户名密码、个人隐私信息等),为后续的渗透做铺垫,那么这又是如何做到的呢?再来举个栗子

$post_id = $_GET['id'];
$post = $db->query("SELECT title, author, content FROM posts WHERE id=$post_id");
//将$post内容展示在页面上

有了上面的铺垫,我们可以猜到这儿的$post_id肯定不会乖乖的是一些数字了,那可以传一些什么呢?我们来试试看获取用户的账号吧。提交『-1 UNION SELECT username,  password FROM account』试试看

SELECT title, content FROM posts WHERE id=-1 UNION SELECT username, password FROM account

这儿的-1只是为了确保找不到这么一篇文章。因为如果填写一篇存在的文章的id,那么我们后面union出来的结果就无法展示出来了(因为文章详情页基本上只会取第一行的结果进行展示)

如果这儿没看懂,没关系,因为接下来我们会针对每一种sql注入一个个进行分析和介绍。

发表评论

电子邮件地址不会被公开。 必填项已用*标注