vlambda博客
学习文章列表

Sql注入-1:sql注入基本原理


引言

sql注入-1

    在网络安全领域中,sql注入是一个无法被忽视的关键点,曾经多少的网站都因此被攻破,直到现在很多网站依旧存在很多sql注入的漏洞和风险点。Sql注入的原理简单,但变化和危害特别严重,属于“上有政策,下有对策”的风险点,也是从事渗透攻防必不可少的一个知识点。本人因近期学习渗透测试相关内容,特此记录学习过程中的笔记,若你也是刚入门渗透安全,或许会有帮助,也希望可以一起交流。

sql注入介绍

sql注入-1

    引用互联网对sql注入的介绍:SQL注入在英文中称为SQL Injection,是黑客对Web数据库进行攻击的常用手段之一。在这种攻击方式中,恶意代码被插入到查询字符串中,然后将该字符串传递到数据库服务器进行执行,根据数据库返回的结果,获得某些数据并发起进一步攻击,甚至获取管理员帐号密码、窃取或者篡改系统数据。


     通俗地说,即是在所有可供用户提交数据与数据库内部交互的过程中均存在sql注入的风险,我们平时经常会碰到登录界面的交互,当我们提交用户名和密码后,网站会将我们提交的数据作为sql查询语句的参数部分拼接成完整的sql查询语句执行,正常的情况下不会出现任何问题,但若有人恶意在输入中提交数据库的关键字语法,则数据库会将本来的输入误以为是sql语法并执行,则会造成恶意的结果,下面会详细介绍原理。

环境介绍

sql注入-1

    我本次所有的sql注入笔记都基于sqlilabs靶场进行演示,sqlilabs是一个印度程序员写的,用来学习 sql 注入的一个游戏,sqlilabs需要apache+php+mysql的环境,我在虚拟机kali linux上使用phpstudy搭建了集成环境,为了方便,我在本机连接虚拟机kali linux部署的网站和数据库进行操作演示。Sqlmap等软件可以方便地,高效地完成sql注入,但是只会使用工具而不了解原理会让我们无法拓展知识点,无法真正地学习sql注入,也无法在遇到问题时思考该如何克服当前障碍进行深一步的注入。因此我本次所有的笔记都基于原理出发,对于一些反复尝试的盲注,会采用python编写脚本来完全地理解注入的整个过程。

基本原理

sql注入-1

    首先让我们来看一个实例,这是sqlilabs的less-11中post注入的实例,也是我们平时碰到比较多的登录界面,其中一个正确的用户名密码对均为Dumb,当我们输入后显示登录成功。

Sql注入-1:sql注入基本原理

显然这背后的sql逻辑代码为:

SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1;

    其中users表是该数据库中存储用户登录信息的表,username和password对应数据库用户名和密码的字段,而$uname和$passwd则是php网页中传入用户名和密码的两个参数。对应于我们使用Dumb登录时,mysql处理的语句就变为:

SELECT username, password FROM users WHERE username='Dumb' and password='Dumb' LIMIT 0,1;

    这一句sql语句的含义为从users表中查询用户名和密码都为Dumb的用户(limit 0,1的含义则是控制查询结果,返回第一条记录),并把他的username和password字段值返回。在使用navicat连接部署的sqlilabs数据库查看后发现执行成功,返回了Dumb的用户名和密码。

Sql注入-1:sql注入基本原理

    mysql查询后返回给php进行逻辑判断,存在记录,因此登录成功,若用户名或密码不正确,则查询不到记录,因此无法登录,这就是登录界面的基本原理,在正常情况下不会出现任何问题。现在有一个计算机专业的同学张三,他只知道Dumb的用户名,而不知道他的密码,但是他想登录Dumb的账号,是不是没有任何办法了呢?可能有人会说用暴力破解,确实对于这个实例可以暴力破解,但是如果有验证码该怎么办呢,是不是也没有办法了呢?此时张三灵机一动,不按套路出牌,他往用户名输入了这样的一串字符“Dumb’ #”,而密码随便输入了“123456”,这样居然成功登录了,返回和前面一样的界面!这就是最简单的一个sql注入,让我们来看看这里面发生了什么吧。当张三提交输入后,sql语句变成了:

SELECT username, password FROM users WHERE username='Dumb’#' and password='123456' limit 0,1;
Sql注入-1:sql注入基本原理

    把这一句sql语句放到navicat中可以直观的看出“#”起到了注释的作用,将后面的语句全部注释,而’将前面username字段参数的区间闭合,因此构成了一个正确的sql语句,等同于:

SELECT username, password FROM users WHERE username='Dumb’;

    这一句sql语句的含义为从users表中查询用户名为Dumb的用户,且返回他的username和password字段值,这样屏蔽了对于密码的判断条件,因此成功登录。这便是最简单sql注入的原理了,那么让我们思考一下,既然上面实例可以屏蔽后面多余的sql语句而重新构造一个新的且正确的sql语句,那么我们是不是可以不只局限于登录?是否可以获取其他信息或者篡改服务器的其他数据呢?这些都是可以的,下图展示了一个获取数据库名称和mysql版本号的事例,从图中可以看到当前数据库名称为“security”,当前mysql版本为“5.7.27”。

Sql注入-1:sql注入基本原理

其中用到的payload为:

v' union select DATABASE(), VERSION() #

    其余的各种注入方式和类型都会在笔记中一一提到。

方式和类型

sql注入-1

    Sql注入的方式和分类很多,例如:基于报错信息、基于前端回显信息、sql盲注、基于时间、union查询、文件导入导出注入、宽字节注入、get、post和cookie注入、堆查询注入等等。Sql注入方式层出不穷,防御方式也在不断更新,而注入方式也在不断探寻,因此只有理解原理,才能真正地利用sql注入进行渗透测试,而目前已有的方式方法会在之后的笔记中记录。

感谢观看,理解有误之处,欢迎交流和指导!

刘杰寅

知乎|烈焰宝宝