SQL注入基本步骤
什么是SQL注入
首先我们要知道的是SQL到底是什么。。。
sql语句百度百科
SQL注入介绍
在正式开始之前,我们先讲讲什么是SQL注入。还记得小学语文考试上的填空题吗?
我是,喜欢____
题目的意图明显是通过填空来了解答题者的名字和爱好。
如果填成下面这样呢?
我是调皮的小男孩子,专职撩妹子。,
喜欢_____________
这就是一个注入的例子,当出题者以为他已经定下了句子的主体结构,需要填空的内容是不会影响主体结构的,而填空者却通过填写的内容,修改了整句话的结构,这就是注入。
以王宝强马蓉两人为例,对于王宝强来说,请来的经纪人是工作上的一部分,这也是他定下来的人生结构。他却没有想到,经纪人除了完成经纪人所应做的事情,还在背后干起别的事情来。对于王宝强来说,经纪人做的事情,就是一种注入,改变了他定义的结构组织。
那什么是SQL注入就不言而喻了。当黑客通过精心构造的URL参数,或者表单提交的参数,拼接到预先定义好的SQL格式时,意外地改变了程序员预期的SQL结构时,SQL注入就构成了。执行该SQL语句已超出的程序员的意图。
普通SQL注入步骤
1.判断是否可以注入
如果要对一个网站进行SQL注入攻击,首先就需要找到存在SQL注入漏洞的地方,也就是寻找所谓的注入点。可能的SQL注入点一般存在于登录页面、查找页面或添加页面等用户可以查找或修改数据的地方(我单纯的认为SQL注入点就是我们可以注释掉一部分SQL查询语句,并且在浏览器界面修改查询语句,利用数据库报错,来寻找能够利用的信息)
最常用的寻找SQL注入点的方法,是在网站中寻找如下形式的页面链接:
其中“YY”可能是数字,也有可能是字符串,分别被称为整数(数字)类型数据或者字符型数据。在本章中我们主要针对整数型数据进行SQL注入讲解。(我暂时粗浅的认识是字符型注入和数字型注入区别在于id值后面是否用单引号包住,字符型需要,数字型不需要)
通常可以使用以下两种方法进行检测,判断该页面链接是否存在SQL注入漏洞。
(1)“加引号”法
在浏览器地址栏中的页面链接地址后面增加一个单引号,如下所示:
由于单引号在SQL语句中起闭合语句的作用,相当于yy后面会出现两个单引号,一个是人为添加的,一个是SQL语句中自带的,所以会导致SQL语句语法错误,网页无法显示,所以存在SQL注入点。
(2)“1=1和1=2”法
在浏览器地址栏中的网页链接地址后面增加分别增加and 1=1 和and 1=2,如下所示:
http://www.xxx.com/xxx.asp?id=YY and 1=1–+
http://www.xxx.com/xxx.asp?id=YY and 1=2–+
其中的–+意思是注释掉后面的SQL语句,防止出现语法错误(由于这次针对整型,所以id值后面没有添加单引号),这两个语句相当于给SQL增加了一个判定条件,and表示并,相信大家高中的时候都学过并集,只有当and左右两边都是正确的,答案才会正确(即页面显示正常),显然id=YY是正确的,那么只需要判定and后面的就可以了,1=1显然正确,所以页面正常,1=2反之,所以也可以说明存在SQL注入点。
2.获得字段数
这里就要讲到sql的order by子句了
微软解释order by子句:为select查询的列排序,如果同时制定了top关键词,order by子句在视图、内联函数、派生表和子查询中无效。
攻击者往往会注入order by子句来判断此表的列数(字段数)
通过数据库抛出异常,我们已经可以知道当前的SQL语句有几列存在了。
在这里我们一般在网页链接地址后面增加order by加数字来猜出列数,如下所示:
http://www.xxx.com/xxx.asp?id=YY order by 3 –+
通过不断地一次改变数字,看是否页面显示异常,来获得字段数。
3.获得显示位
这里我们要了解到SQL语句中的联合查询(union select百度百科:联合查询是可合并多个相似的选择查询的结果集。等同于将一个表追加到另一个表,从而实现将两个表的查询组合到一起,使用谓词为UNION或UNION ALL。)
这里的显示位就是能够在网页上直接可以看见的数据显示处,一般在网页链接后面加union select加你上一步获得的字段数从1开始依次排序,如下所示:
http://www.xxx.com/xxx.asp?id=YY union select 1,2,3
然后我们正常情况下会看见页面上会出现1,2,3三个字段数,说明已经获得显示位了,接下来我们就可以利用SQL注入在在几个显示位上获得我们想要的信息了。
4.获取数据库信息
现在来介绍几个在渗透测试中常用的几个函数和表库名。
数据库名:database()
数据库版本: version()
数据库用户: user()
操作系统: @@version_compile_os
系统用户名: system_user()
当前用户名: current_user
连接数据库的用户名:session_user()
读取数据库路径:@@datadir
MYSQL安装路径:@@basedir
load_file 转成16进制或者10进制 MYSQL读取本地文件函数
into outfile 写入函数
储存所有表名信息的表 : information_schema.tables
表名 : table_name
数据库名: table_schema
列名 : column_name
储存所有列名信息的表 : information_schema.columns
我们用一些我们想要了解的函数和数据库名代替之前的显位数(也就是上面一步的1,2,3),我们想要了解数据库名,版本和用户名,可以构造以下链接:
http://www.xxx.com/xxx.asp?id=YY union select database(),version(),user() –+
接着就可以在显示位上依次看到数据库名,数据库版本,用户名了,记住这些你想获取的信息。
5.获取当前数据库的表名
这里我用到了一个函数GROUP_CONCAT()
GROUP_CONCAT函数返回一个字符串结果,该结果由分组中的值连接组合而成。这样我们就可以在一个显示位上获得多个表名,而不是用limit子句去一个一个遍历了。
http://www.xxx.com/xxx.asp?id=YY union select group_concat(table_name),2,3 from
information_schema.tables where table_schema=0x73716C696E20
其中的information_schema这张数据表保存了MySQL服务器所有数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。再简单点,这台MySQL服务器上,到底有哪些数据库、各个数据库有哪些表,每张表的字段类型是什么,各个数据库要什么权限才能访问,等等信息都保存在information_schema表里面,我们在后面加上.tables就是存放了数据库中所有表名的元数据。后面的0x73716C696E20其实是当前数据库的hex值,我们可以通过一些网上在线的hex转码找到数据库名对应的hex值。
我们在网页显示位上可以看见我们想要的表名。
6.获取列名
假如我们选择了一个名叫user的表,那么我们就要开始从表中调取列名数据了,和上一步大同小异,我们构造如下URL:
http://www.xxx.com/xxx.asp?id=YY union select group_concat(column_name),2,3 from
information_schema.columns where table_name=0x75736572 –+
这样我们就获得了user表中的列名
7.爆数据
这里假如我们想要获取username列中的数据
http://www.xxx.com/xxx.asp?id=YY union select username,2,3 from user(表名) –+
数据就出来了。
后记
上面的总结只是我比较粗浅的理解,也借鉴了一些网上的教程,如有错误多多包涵。当然这只是最最基本的get注入,还有什么cookie注入、post注入、宽字节注入、盲注、延时注入等,我还没有去深入了解,等我学了再说吧。