SQL注入 第一遍没看懂,或许你需要在来一遍

107 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1.为什么要去理解该知识点

2.原理

3.自己的理解和实践

4.CTF题目案例





声明一点以下可能说的不是很友好,所以如有敏感词汇请评论我,作者会改


日常吐槽: Sql注入你说难,其实不难,你说不难,它就挺难的,sql注入真的要考经验来说,学到一个新的sql注入payload我认为真的很需要用备忘录记录一下


为什么要去理解该知识点

联合注入其实有很多知识点,所以今天必须还得讲讲,憋在心里,可真难受 CTF联合注入,本人看的不多,但是也发现有一些共同点 1.过滤关键词 常见的关键词有哪些: 1.Union select 2.And 3.Or 4.From 5.空格 总而言之,联合注入的用到的代码就会都会进行过滤 所以有时就需要进行puzzing,查看哪些关键字没有被过滤 在后续我会查看大佬的writeup来copy一份fuzzing表(白嫖真好)







原理

大多数过滤其实都是php正则表达,或者有一个list表,可是就是这些真的让人苦不堪言
preg_replace('/or/i',"",$id);//过滤or

有些就会像上则这样进行过滤 这样的有很多种简单的方法绕过 1.大小混写随机组合(SelECt) 2.叠加(OorR) 3.等价替换 and(&&) or(||) 4.编码(如果空格被过滤了可以使用 %0A(\n)) 5.内联注释(/**/可替换空格) 6. 等价函数替换(version->@@version) 7.特殊符号(+,\\,’,@) 8.内联注释加!(/!union/) 9.缓冲区溢出 select * from users where id=1 and (select 1)=(Select 0xA1000) uNiOn SeLeCt 1,2,version();//自测成功,继续加油 0xA1000 指的是0XA后面的 "A" 重复1000次 一般来说对应用软件构成缓冲区溢出都需要比较大的测试长度 这里1000仅供参考,在一些情况下也可以更短 10.mysql特性绕过 select * from users where id=1 union select @test=user(),2,3;//1 select * from users where id=1 union select @test:=user(),2,3;//自测可用,继续加油,root select * from users where id=1 union select @,2,3;//NULL 11.黑魔法 在这里插入图片描述 12.空白符号绕过 MySQL空白符:%90,%0A,%0B,%0D,%20,%0C,%A0,/xxx/ 正则的空白符:%09,%0A,%0B,%0D,%20 Example-1:union%250Cselect Example-1:union%25A0select CTF一般都是打组合拳一起使用

下面开始讲解过滤原理

1.大小写混合 Mysql有一个特点就是不区分大小写,所以不管你怎么混写,他最后都会转换成小写或大写 普遍的是用list进行查找,所以会将大写和小写的 关键词导入list,其实这样的很麻烦,所以升级版就会现将sql语句统一小写或大写,然后在进行过滤,然后大小写混写就可能无效了 2.叠加 因为大小写无效了,所以那就下一步考虑,常见过滤就是将关键字设为””,这样其实很简单进行绕过,叠加就是其一,例如selec select t经过过滤函数自动将select转换为””,所以selecselectt->select,但是遇到升级版就很难受了,过滤函数可能把关键字设为其他的字符,那就要情况而定了,反正这种方法可能就失效了 3.等价 顾名思义用相同功能的进行替换,因为大部分用的是list,黑帽思维,禁掉常见常用的关键词,但是会疏忽一些类似的功能的函数,例如过滤了order但是group by同样也有类似功能 不过遇到升级版还是得难受,白帽思维只允许你用指定列表关键字,在后续会在大佬里面白嫖一些等价的函数单独列出来 4.编码 编码真的是很好的绕过方法如同叠加一样,urlencode或16进制某个关键词从而达到绕过因为在mysql中都会将其解码在执行,但是升级版也很强可以先解码在进行过滤,不过可以使用n次编码绕过 5.内联注释 内联注释主要是绕过那种组合过滤,即不能出现select union这样的字符串,不过可以也能用/**/代替空格,我也不知道mysql为什么可以这样,很迷 /!code/常常绕过不严谨的正则表达式,因为sql会执行/!code/里的代码 6.缓冲区溢出,mysql特性绕过,黑魔法 这些都是绕过WAF,CTF一般不会出吧 7.空白符号绕过 这个可能真的是重中之重,CTF常常就把空格给你过滤看你如何进行注入,无疑真的让人心累 但是与空格等价的还是有很多的 Mysql:%90因为ascall最大的为%8f,%90越界所以会表述不可看字符从而会可以代替空白 %0A,%0B,%0D就是特殊转义符号,换行,制表符,\r这些, 在正则的空白就有%09,%0A,%0B,%0D, 所以要判断是正则过滤还是php过滤函数过滤,但是还是可以用他们共同的 8.内置注释被过滤 可以尝试寻找特殊符号看是否能有特殊情况出现吗例如<>,+,{},[],*等这种题需要puzzing不然真的很难搞







CTF题目案例

i春秋WEB SQL

在这里插入图片描述 没有单引号所以应该是整形 尝试order by,and,or 发现都被过滤 此时可以用等价进行替换 Order by->group by And->&& Or->|| 1.回显,所以group没有被过滤 2.&&后面的代码都消失,说明&&被替换为# 3.||没有报错但是作用不大,|| 1=1 回显test,1=2没变化 也可以用叠加来判断是否转为”” 但是前面发现输入order会显示注入攻击的英文,所以此方法在此不可用 通过group by发现有3列 尝试union,select 发现select被过滤 由于本人知识点短,所以另想办法 尝试内置注释/!/发现被过滤 难搞,所以只能尝试特殊符号进行查看 <>,[],{},’’ 发现<>被替换为””,所以可以调用<>进行叠加 union s<>elect 1,2,3 在这里插入图片描述


/index.php?id=1+union+s<>elect+1,database(),3

查看当前数据库为sqli

index.php?id=1+union+s<>elect+1,(sel<>ect%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()),3

得到表名 info,users(尽量都尝试,不过前面有提示info) 然后爆列名 最后爆列名数据得flag 最后还是说一句,此类题还是挺好的建议亲自去尝试 老规矩可以参考这位大佬的writeup i春秋 WEB SQL