關於ASP.net伺服器的入侵方法詳解

關於ASP.net伺服器的入侵方法詳解添加時間:2007-10-25 

有個朋友在QQ上問了我關於ASP.net伺服器的入侵方法我將ASP.net上的一些入侵常用手段告訴大家

1.ASP中常用的標準組件:FileSystemObject,這個組件為 ASP 提供了強大的文件系統訪問能力,可以對伺服器硬碟上的任何有許可權的目錄和文件進行讀寫、刪除、改名等操作。FSO對象來自微軟提供的腳本運行庫scrrun.dll中。使用下面的代碼就可以在ASP中創建一個FSO對象:Set fso = CreateObject("Scripting.FileSystemObject")我們使用fso對象包含的屬性和方法,如Drive、Drives、Folder、Floders、File、Files等對伺服器的磁碟、目錄和文件進行讀、寫、刪除等操作。這一強大的文件系統訪問能力給ASP共享空間提供者帶來了嚴重的安全問題,很多ASP空間的管理員都刪除此組件或將這個組件改名以避免用戶使用這一標準組件。刪除組件或組件改名確實是一個簡單的方法並且也很有效,但是卻使廣大用戶無法使用它的強大的功能。網路上還有一種看起來很美的方案,它允許用戶使用 FileSystemObject 組件又不影響伺服器的安全,即對每一個用戶都設置一個獨立的伺服器用戶和單個目錄的操作許可權。但是這種方法是有問題的。因為ASP和ASP.NET中在這方面的問題十分類似,所以我們將在ASP.NET的相應解決辦法部分詳加說明。在ASP.NET中我們發現這一問題仍然存在,並且變得更加難以解決。這是因為.NET中關於系統IO操作的功能變得更加強大,而使這一問題更嚴重的是ASP.NET所具有的一項新功能,這就組件不需要象ASP那樣必須要使用regsvr32來註冊了,只需將Dll類庫文件上傳到bin目錄下就可以直接使用了。這一功能確實給開發ASP.NET帶來了很大的方便,但是卻使我們在ASP中將此dll刪除或者改名的解決方法失去效用了,防範此問題就變得更加複雜。在討論解決方案之前,我們先來看一下怎麼來實現上述的危險的功能

2.文件系統

我們還要使用System.IO名稱空間的其他幾個類是:

System.IO.Directory:提供用於創建、移動和枚舉通過目錄和子目錄的靜態方法的類

System.IO.File:提供用於創建、複製、刪除、移動和打開文件的靜態方法的類

System.IO.FileInfo:提供創建、複製、刪除、移動和打開文件的實例方法的類

System.IO.StreamReader:實現一個 TextReader,使其以一種特定的編碼從位元組流中讀取字元。

每個我們所使用的類的屬性和方法的具體用法我們將以代碼注釋的方式在程序中加以說明。

System.IO名稱空間在 .NET FRAMEWORK提供的mscorlib.dll中,在使用VS.Net編程之前需要將此Dll引用到此項目中。

我們所編寫的程序都使用了Codebehind方式,即每一個aspx程序都有一個對應的aspx.cs程序,aspx程序中只是寫與頁面顯示相關的代碼,所有邏輯實現的代碼都放在相應的aspx.cs文件中,這樣就可以更好得做到顯示與邏輯的分離。由於我們的目的不是討論Codebehind技術,所以就不在對此多加討論了。

在這篇文章里,我們只介紹幾個主要的類及其關鍵方法的用法,詳細程序請查看附帶的源代碼。

程序一:顯示伺服器的當前信息和全部邏輯驅動器的名稱的程序listdrivers.aspx

主要方法1:我們使用 GetSysInf() 方法來得到伺服器的當前環境和平台的信息

//獲取系統信息的方法,此方法在listdrivers.aspx.cs文件中

public void GetSysInf () {

//獲取操作系統類型

qDrives = Environment.OSVersion.ToString();

//獲取系統文件夾

qSystemDir = Environment.SystemDirectory.ToString();

/*獲取映射到進程上下文的物理內存量,通過這一內存映射量可以了解ASP.NET程序在運行時需要多少系統物理內存,有助於更好的規劃我們的整個應用,因為物理內存量是以Byte為單位的,所以我們將此數值除以1024,可以得到單位為KB的物理內存量*/

qMo = (Environment.WorkingSet/1024).ToString();

//獲取當前目錄(即該進程從中啟動的目錄)的完全限定路徑

qCurDir = Environment.CurrentDirectory.ToString();

//獲取主機的網

絡域名

qDomName = Environment.UserDomainName.ToString();

//獲取系統啟動後經過的毫秒數

qTick = Environment.TickCount;

//計算得到系統啟動後經過的分鐘數

qTick /= 60000;

//獲取機器名

qMachine = Environment.MachineName;

//獲取運行當前進程的用戶名

qUser = Environment.UserName;

/*檢索此計算機上格式為"<驅動器號>:"的邏輯驅動器的名稱,返回字元串數組,這是下一步操作的關鍵所在*/

achDrives = Directory.GetLogicalDrives();

//獲取此字元串數組的維數,確定有多少個邏輯驅動器

nNumOfDrives = achDrives.Length;

} 系統信息不需要進行操作,我們簡單的用asp:Label將他們顯示出來就行了。邏輯驅動器的個數在不同的伺服器上是不定的,所以用不定長數組保存邏輯驅動器的名稱,而且邏輯驅動器的名稱也是我們下一步瀏覽目錄和文件的基礎,故我們採用了數據網格DataGrid來顯示和處理它。顯示和處理邏輯驅動器名稱的DataGrid的代碼(代碼在listdrivers.aspx文件):

<asp:DataGrid id="DriversGrid" runat="server" AutoGenerateColumns="false">

<Columns>

<asp:BoundColumn HeaderText="ID" DataField="ID" />

<asp:BoundColumn HeaderText="磁碟名" DataField="Drivers" />

<asp:HyperLinkColumn

HeaderText="詳細信息"

DataNavigateUrlField="Drivers" DataNavigateUrlFormatString="listdir.aspx?dir={0}"

DataTextField="Detail"

Target="_new" />

</Columns>

</asp:DataGrid> 前兩個BoundColumn列都是顯示序號和實際邏輯驅動器名稱的,需要說明的是第三列,我們在進入各個邏輯驅動器顯示目錄和文件之前需要將所選擇的邏輯驅動器的名稱傳遞到顯示目錄的文件去,所以需要一個特殊的超級鏈接行HyperLinkColumn,我們將DataNavigateUrlField設置為數據源中要綁定到 HyperLinkColumn 中的超級鏈接的 URL 的欄位,在此即邏輯驅動器名稱。然後將DataNavigateUrlFormatString設置為當 URL 數據綁定到數據源中的欄位時,此HyperLinkColumn中的超級鏈接的 URL 的顯示格式,即要鏈接到的下一級處理頁面,在此為listdir.aspx?dir={用戶點擊行的邏輯驅動器名稱}

1.ASP中常用的標準組件:FileSystemObject,這個組件為 ASP 提供了強大的文件系統訪問能力,可以對伺服器硬碟上的任何有許可權的目錄和文件進行讀寫、刪除、改名等操作。FSO對象來自微軟提供的腳本運行庫scrrun.dll中。使用下面的代碼就可以在ASP中創建一個FSO對象:Set fso = CreateObject("Scripting.FileSystemObject")我們使用fso對象包含的屬性和方法,如Drive、Drives、Folder、Floders、File、Files等對伺服器的磁碟、目錄和文件進行讀、寫、刪除等操作。這一強大的文件系統訪問能力給ASP共享空間提供者帶來了嚴重的安全問題,很多ASP空間的管理員都刪除此組件或將這個組件改名以避免用戶使用這一標準組件。刪除組件或組件改名確實是一個簡單的方法並且也很有效,但是卻使廣大用戶無法使用它的強大的功能。網路上還有一種看起來很美的方案,它允許用戶使用 FileSystemObject 組件又不影響伺服器的安全,即對每一個用戶都設置一個獨立的伺服器用戶和單個目錄的操作許可權。但是這種方法是有問題的。因為ASP和ASP.NET中在這方面的問題十分類似,所以我們將在ASP.NET的相應解決辦法部分詳加說明。在ASP.NET中我們發現這一問題仍然存在,並且變得更加難以解決。這是因為.NET中關於系統IO操作的功能變得更加強大,而使這一問題更嚴重的是ASP.NET所具有的一項新功能,這就組件不需要象ASP那樣必須要使用regsvr32來註冊了,只需將Dll類庫文件上傳到bin目錄下就可以直接使用了。這一功能確實給開發ASP.NET帶來了很大的方便,但是卻使我們在ASP中將此dll刪除或者改名的解決方法失去效用了,防範此問題就變得更加複雜。在討論解決方案之前,我們先來看一下怎麼來實現上述的危險的功能

2.文件系統

我們還要使用System.IO名稱空間的其他幾個類是:

System.IO.Directory:提供用於創建、移動和枚舉通過目錄和子目錄的靜態方法的類

System.IO.File:提供用於創建、複製、刪除、移動和打開文件的靜態方法的類

System.IO.FileInfo:提供創建、複製、刪除、移動和打開文件的實例方法的類

System.IO.StreamReader:實現一個 TextReader,使其以一種特定的編碼從位元組流中讀取字元。

每個我們所使用的類的屬性和方法的具體用法我們將以代碼注釋的方式在程序中加以說明。

System.IO名稱空間在 .NET FRAMEWORK提供的mscorlib.dll中,在使用VS.Net編程之前需要將此Dll引用到此項目中。

我們所編寫的程序都使用了Codebehind方式,即每一個aspx程序都有一個對應的aspx.cs程序,aspx程序中只是寫與頁面顯示相關的代碼,所有邏輯實現的代碼都放在相應的aspx.cs文件中,這樣就可以更好得做到顯示與邏輯的分離。由於我們的目的不是討論Codebehind技術,所以就不在對此多加討論了。

在這篇文章里,我們只介紹幾個主要的類及其關鍵方法的用法,詳細程序請查看附帶的源代碼。

程序一:顯示伺服器的當前信息和全部邏輯驅動器的名稱的程序listdrivers.aspx

主要方法1:我們使用 GetSysInf() 方法來得到伺服器的當前環境和平台的信息

//獲取系統信息的方法,此方法在listdrivers.aspx.cs文件中

public void GetSysInf () {

//獲取操作系統類型

qDrives = Environment.OSVersion.ToString();

//獲取系統文件夾

qSystemDir = Environment.SystemDirectory.ToString();

/*獲取映射到進程上下文的物理內存量,通過這一內存映射量可以了解ASP.NET程序在運行時需要多少系統物理內存,有助於更好的規劃我們的整個應用,因為物理內存量是以Byte為單位的,所以我們將此數值除以1024,可以得到單位為KB的物理內存量*/

qMo = (Environment.WorkingSet/1024).ToString();

//獲取當前目錄(即該進程從中啟動的目錄)的完全限定路徑

qCurDir = Environment.CurrentDirectory.ToString();

//獲取主機的網

tail"

HeaderText="詳細信息"

Target="_new"

/>

在兩個DataGrid(DirGrid,FileGrid)中我們分別設置了兩個HyperLinkColumn列來導航到不同的處理頁面。

在兩個DataGrid中我們都使用了一個刪除的按鈕列:

<asp:ButtonColumn HeaderText="刪除"

Text="刪除"

CommandName="Delete"

/>

由於添加、更新、刪除功能列都是DataGrid的默認模板列,所以可以在Vs.net中通過DataGrid的屬性生成器自動添加此列。

獲取上一頁面所傳遞來的參數的代碼:

因為在下面產生數據源的方法中需要使用由上一個頁面傳遞過來的參數來確定目錄和文件的名稱,所以在頁面的Page_Load方法里使用了下列代碼:

strDir2List = Request.QueryString["dir"];

字元串strDir2List即傳過來的目錄名或文件名。

因為我們使用了兩個DateGrid,就需要進行兩次數據綁定,就有兩個不同的生成數據源的方法。

生成目錄數據網格(DirGrid)數據源的方法:

//通過此方法返回一個集合形式的數據視圖DataView,用來初始化子目錄的DataGrid

ICollection CreateDataSourceDir() {

dtDir = new DataTable();

DataRow dr;

//向DataTable中添加新的數據列,共四列

dtDir.Columns.Add(new DataColumn("DirID", typeof(Int32)));

dtDir.Columns.Add(new DataColumn("DirName", typeof(string)));

dtDir.Columns.Add(new DataColumn("DelDir", typeof(string)));

dtDir.Columns.Add(new DataColumn("DirDetail", typeof(string)));

//根據傳入的參數(目錄名)得到此目錄下所有子目錄名的字元串數組

string [] DirEntries = Directory.GetDirectories(strDir2List);

//使用foreach循環可以對未知長度的數組進行遍歷循環

foreach(string DirName in DirEntries){

dr = dtDir.NewRow();

dr[0] = i;//序號

dr[1] = DirName;//文件夾名稱

dr[3] = "刪除";

dr[3] = "查看詳情";

dtDir.Rows.Add(dr);

i++;

}

DataView dvDir = new DataView(dtDir);

//返回得到的數據視圖

return dvDir;

}

生成文件數據網格(FileGrid)數據源的方法:

//通過此方法返回一個集合形式的數據視圖DataView,用來初始化文件的DataGrid

ICollection CreateDataSourceFile() {

dtFile = new DataTable();

DataRow dr;

dtFile.Columns.Add(new DataColumn("FileID", typeof(Int32)));

dtFile.Columns.Add(new DataColumn("FileName", typeof(string)));

dtFile.Columns.Add(new DataColumn("DelFile", typeof(string)));

dtFile.Columns.Add(new DataColumn("FileDetail", typeof(string)));

//根據傳入的參數(目錄名)得到此目錄下所有文件名的字元串數組

string [] FileEntries = Directory.GetFiles(strDir2List);

foreach(string FileName in FileEntries){

dr = dtFile.NewRow();

dr[0] = i;

dr[1] = FileName;

dr[2] = "刪除";

dr[3] = "查看詳情";

dtFile.Rows.Add(dr);

i++;

}

dvFile = new DataView(dtFile);

return dvFile;

}

我們編程實現了兩個DataSource只需在頁面的Page_Load方法里對兩個DataGrid進行數據綁定即可將得到的DataTable中的數據顯示在aspx頁面的DataGrid上。

數據綁定代碼://對子目錄數據列表DirGrid進行數據源定義和數據綁定

DirGrid.DataSource = CreateDataSourceDir();

DirGrid.DataBind();

//對文件數據列表FileGrid進行數據源定義和數據綁定

FileGrid.DataSource = CreateDataSourceFile();

FileGrid.DataBind();

通過我們上邊介紹的主要方法,我們實現了對某個邏輯驅動器或目錄中的所有子目錄和文件進行了列表顯示,並且可以根據顯示結果更進一步的瀏覽子目錄或者查看文件的屬性和內容提要。瀏覽子目錄仍然是通過listdir.aspx這個程序,沒有任何子目錄級別要求,沒有目錄深度限制。

刪除子目錄和文件的主要方法和代碼:

在刪除子目錄時,我們需要用到Directory.Delete (string,bool)方法,此方法有兩種:

1.public static void Delete(string);

從指定路徑刪除空目錄。

2.public static void Delete(string, boolean);

刪除指定的目錄並(如果指示)刪除該目錄中的任何子目錄,將boolean設置為true的話,則刪除此目錄下的所有子目錄和文件,否則將boolean設置為false。

在這裡我們使用了第二種方法,如果選擇刪除的話,將刪除此目錄下的所有子目錄和文件。

注意:Directory 類的所有方法都是靜態的,因而無需具有目錄Directory的實例就可被調用。

/*實現刪除子目錄的方法,此方法為VS.NET自動添加,注意DataGridCommandEventArgs e為DirGrid中 CommandName="Delete" 的ButtonColumn的事件,通過此事件,我們可以得到是那一行的ButtonColumn按鈕列被點擊,進而確定我們需要刪除的子目錄的名稱*/

private void DirGrid_DeleteCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e){

/*定義一個單元格,e.Item為此事件所發生行的所有項目,e.Item.Cells[1]為整個行的第二個單元格的內容,在此DataGrid中為子目錄的名稱

*/

TableCell ItemCell = e.Item.Cells[1];

//得到此子目錄的名稱的字元串

string item = ItemCell.Text;

//刪除此子目錄

Directory.Delete(item,true);

//刪除後進行數據綁定以更新數據列表

DirGrid.DataBind();

}

在刪除文件時,我們需要用到File.Delete(string path);

注意:File 類的所有方法都是靜態的,因而無需具有目錄的實例就可被調用。

private void FileGrid_DeleteCommand(object source,

System.Web.UI.WebControls.DataGridCommandEventArgs e) {

TableCell ItemCell = e.Item.Cells[1];

//得到此文件名稱的字元串

string item = ItemCell.Text;

//刪除此文件

File.Delete(item);

//刪除後進行數據綁定以更新數據列表

DirGrid.DataBind();

}

通過上邊的主要方法我們在頁面上實現了一個刪除某一個子目錄或者文件的功能,此功能在測試時需要慎重使用,一旦刪除無法通過常規方法恢復。其他如目錄或文件改名、修改內容等方法都可以在此程序基礎上添加相應的功能,實現方法也很簡單。各位愛好者可以通過添加相應功能,使之擴充為一個基於Web的伺服器文件管理系統。我們也可以由此看到這個程序的危害性,一個沒有對此安全隱患採取防範措施的伺服器的文件系統就都暴露在了使用此程序的用戶面前。


推薦閱讀:

秋季寶寶腹瀉高發,家庭該如何應對?
第四章盲派命里的看命方法第一節八字入手方法
《心經》(五):修持般若的方法
旺偏財運的七個方法
一次即可牢記易經64卦卦序的方法

TAG:伺服器 | 方法 | 入侵 | 關於 |