0x01 前言

转载于:https://mp.weixin.qq.com/s/QREh2nOo2pcd0dydiKX3hQ
参考文章:https://forum.butian.net/share/1559

0x02 预编译是啥

预编译的过程中,会将SQL语句和参数分开处理,SQL语句中的参数用占位符代替,传递进来的参数会使用参数绑定技术绑定在占位符上,哪怕你传进来恶意的参数,也不会作为代码处理,而是成为了字符串,主要用来预防SQL注入。

0x02 预编译的局限性

预编译对于宽字节注入和在orderby、like位置存在一定的局限性

宽字节注入

如果加个单引号,看看数据库日志是怎么样的

图片

可以看到,单引号被反斜杠转义了,因此,在预编译参数绑定的过程中,会对参数值的引号(单双引号都会)进行转义

宽字节注入是因为编码问题导致的注入,例如数据库使用了GBK编码,它认为两个字节为一个字符,%df\为一个字符,转义就失效了,导致SQL注入依然存在

如果我们插入%df%27%20union%20select%201,database();%23

图片

可以看到,反斜杠已经被"吃掉"了

orderby位置注入

order by后面接的是字段,如果使用了预编译的话,就会变成字符串,导致排序失败,出来的不是按字段排序的结果(有区别的,字段是不用引号包裹的,否则就是字符串了),为了功能正常,开发者也是大概率用SQL语句拼接的形式,导致存在注入

图片

图片

利用的话,采用延时注入和报错注入:

order by 1 and 1=updatexml(0,concat('~',version(),'~'),1)``order by updatexml(0,concat('~',version(),'~'),1)``order by if(条件,sleep(3),0)

like位置注入

图片

如果直接使用上面语句,like位置是无法传参进来的,所以一些开发者可能会直接拼接SQL语句,数据库日志如下:

图片

其实like位置也是可以做预编译的,只是要更改下写法,想了解具体防御,可以看前言给出的原作者文章链接

图片

上面是一些开发者可能的写法,但是这种写法等同于拼接参数,会在like处产生注入,注意看前后代码截图的差异

插入%27%20union%20select%201,version()%23,发现回显了

图片