xctf 强网杯 2019 随便注

发布于 2020-09-07  149 次阅读


前置知识

SQl 预处理:

参考:https://www.cnblogs.com/geaozhang/p/9891338.html

"

1、即时 SQL
一条 SQL 在 DB 接收到最终执行完毕返回,大致的过程如下:
1. 词法和语义解析;
2. 优化 SQL 语句,制定执行计划;
3. 执行并返回结果;
如上,一条 SQL 直接是走流程处理,一次编译,单次运行,此类普通语句被称作 Immediate Statements (即时 SQL)。
2、预处理 SQL
但是,绝大多数情况下,某需求某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行了。
所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements。
预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。

"

解题过程

那么问题就归结到了如何进行sql注入。首先这与一般的sql有所不同,可以一次性执行多条sql语句,故可以进行堆叠注入,在php语言中对应为mysqli_multi_query语句。但是他设置筛选正则规则了select(不分大小写,所以应该想办法绕过,我就简述一种较为简单的解法,通过预处理来运算处理。

那首先就是编写要进行预处理的语句,之所以能够绕过select的是通过concat()这个函数把语句拼接起来。像这样:

set @sql=concat('selec','t flag from `1919810931114514`');

但是绕过了这个后仍然会发现其实也过滤了set,prepare,但是这两个都没有设置大小写的检查,所以,写个sEt,prEpare其实就行。

其他方法放在后面,可以慢慢看

https://blog.csdn.net/qq_26406447/article/details/90643951

#这个构思比较巧妙,首先要知道show也可以查字段,接下来通过将数据库和表名的将一开始只能查到的1替换成含有flag的那一列,很神奇。


我是谁?我在哪?我正在做什么?