基本上,參加的安全測試(滲透測試)的網站,可能或多或少存在下面幾個漏洞:SQL注入漏洞、跨站腳本攻擊漏洞、登錄後臺管理頁面、IIS短文件/文件夾漏洞、系統敏感信息泄露。javascript
這些安全性測試,據瞭解通常是先收集數據,而後進行相關的滲透測試工做,獲取到網站或者系統的一些敏感數據,從而可能達到控制或者破壞系統的目的。html
第一步是信息收集,收集如IP地址、DNS記錄、軟件版本信息、IP段等信息。能夠採用方法有:
1)基本網絡信息獲取;
2)Ping目標網絡獲得IP地址和TTL等信息;
3)Tcptraceroute和Traceroute 的結果;
4)Whois結果;
5)Netcraft獲取目標可能存在的域名、Web及服務器信息;
6)Curl獲取目標Web基本信息;
7)Nmap對網站進行端口掃描並判斷操做系統類型;
8)Google、Yahoo、Baidu等搜索引擎獲取目標信息;
9)FWtester 、Hping3 等工具進行防火牆規則探測;
10)其餘。java
第二步是進行滲透測試,根據前面獲取到的數據,進一步獲取網站敏感數據。此階段若是成功的話,可能得到普通權限。採用方法會有有下面幾種程序員
1)常規漏洞掃描和採用商用軟件進行檢查;
2)結合使用ISS與Nessus等商用或免費的掃描工具進行漏洞掃描;
3)採用SolarWinds對網絡設備等進行搜索發現;
4)採用Nikto、Webinspect等軟件對Web常見漏洞進行掃描;
5)採用如AppDetectiv之類的商用軟件對數據庫進行掃描分析;
6)對Web和數據庫應用進行分析;
7)採用WebProxy、SPIKEProxy、Webscarab、ParosProxy、Absinthe等工具進行分析;
8)用Ethereal抓包協助分析;
9)用Webscan、Fuzzer進行SQL注入和XSS漏洞初步分析;
10)手工檢測SQL注入和XSS漏洞;
11)採用相似OScanner的工具對數據庫進行分析;
12)基於通用設備、數據庫、操做系統和應用的攻擊;採用各類公開及私有的緩衝區溢出程序代碼,也採用諸如MetasploitFramework 之類的利用程序集合。
13)基於應用的攻擊。基於Web、數據庫或特定的B/S或C/S結構的網絡應用程序存在的弱點進行攻擊。
14)口令猜解技術。進行口令猜解能夠採用 X-Scan、Brutus、Hydra、溯雪等工具。web
第三步就是嘗試由普通權限提高爲管理員權限,得到對系統的徹底控制權。在時間許可的狀況下,必要時從第一階段從新進行。採用方法正則表達式
1)口令嗅探與鍵盤記錄。嗅探、鍵盤記錄、木馬等軟件,功能簡單,但要求不被防病毒軟件發覺,所以一般須要自行開發或修改。
2)口令破解。有許多著名的口令破解軟件,如 L0phtCrack、John the Ripper、Cain 等sql
以上一些是他們測試的步驟,不過咱們不必定要關注這些過程性的東西,咱們可能對他們反饋的結果更關注,由於可能會爆發不少安全漏洞等着咱們去修復的。shell
1)SQL注入定義:數據庫
SQL注入攻擊是黑客對數據庫進行攻擊的經常使用手段之一。隨着B/S模式應用開發的發展,使用這種模式編寫應用程序的程序員也愈來愈多。可是因爲程序員的水平及經驗也良莠不齊,至關大一部分程序員在編寫代碼的時候,沒有對用戶輸入數據的合法性進行判斷,使應用程序存在安全隱患。用戶能夠提交一段數據庫查詢代碼,根據程序返回的結果,得到某些他想得知的數據,這就是所謂的SQL Injection,即SQL注入。windows
SQL注入有時候,在地址參數輸入,或者控件輸入都有可能進行。如在連接後加入’號,頁面報錯,並暴露出網站的物理路徑在不少時候,很常見,固然若是關閉了Web.Config的CustomErrors的時候,可能就不會看到。
另外,Sql注入是很常見的一個攻擊,所以,若是對頁面參數的轉換或者沒有通過處理,直接把數據丟給Sql語句去執行,那麼可能就會暴露敏感的信息給對方了。以下面兩個頁面可能就會被添加註入攻擊。
①HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestD ... type='U' and status>0)>0 獲得第一個用戶創建表的名稱,並與整數進行比較,顯然abc.asp工做異常,但在異常中卻能夠發現表的名稱。假設發現的表名是xyz,則
②HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestDB.dbo.sysobjects& ... tatus>0 and name not in('xyz'))>0 能夠獲得第二個用戶創建的表的名稱,同理就可獲得全部用創建的表的名稱。
爲了屏蔽危險Sql語句的執行,可能須要對進行嚴格的轉換,例如若是是整形的,就嚴格把它轉換爲整數,而後在操做,這樣能夠避免一些潛在的危險,另外對構造的sql語句必須進行Sql注入語句的過濾,如個人框架(Winform開發框架、Web開發框架等)裏面就內置了對這些有害的語句和符號進行清除工做,因爲是在基類進行了過濾,所以基本上子類都不用關心也能夠避免了這些常規的攻擊了。
/// <summary> /// 驗證是否存在注入代碼(條件語句) /// </summary> /// <param name="inputData"></param> public bool HasInjectionData(string inputData) { if (string.IsNullOrEmpty(inputData)) return false; //裏面定義惡意字符集合 //驗證inputData是否包含惡意集合 if (Regex.IsMatch(inputData.ToLower(), GetRegexString())) { return true; } else { return false; } } /// <summary> /// 獲取正則表達式 /// </summary> /// <returns></returns> private static string GetRegexString() { //構造SQL的注入關鍵字符 string[] strBadChar = { //"select\\s", //"from\\s", "insert\\s", "delete\\s", "update\\s", "drop\\s", "truncate\\s", "exec\\s", "count\\(", "declare\\s", "asc\\(", "mid\\(", "char\\(", "net user", "xp_cmdshell", "/add\\s", "exec master.dbo.xp_cmdshell", "net localgroup administrators" }; //構造正則表達式 string str_Regex = ".*("; for (int i = 0; i < strBadChar.Length - 1; i++) { str_Regex += strBadChar[i] + "|"; } str_Regex += strBadChar[strBadChar.Length - 1] + ").*"; return str_Regex; }
上面的語句用於判別常規的Sql攻擊字符,我在數據庫操做的基類裏面,只須要判別便可,以下面的一個根據條件語句查找數據庫記錄的函數。
/// <summary> /// 根據條件查詢數據庫,並返回對象集合 /// </summary> /// <param name="condition">查詢的條件</param> /// <param name="orderBy">自定義排序語句,如Order By Name Desc;如不指定,則使用默認排序</param> /// <param name="paramList">參數列表</param> /// <returns>指定對象的集合</returns> public virtual List<T> Find(string condition, string orderBy, IDbDataParameter[] paramList) { if (HasInjectionData(condition)) { LogTextHelper.Error(string.Format("檢測出SQL注入的惡意數據, {0}", condition)); throw new Exception("檢測出SQL注入的惡意數據"); } ........................... }
以上只是防止Sql攻擊的一個方面,還有就是堅持使用參數化的方式進行賦值,這樣很大程度上減小可能受到SQL注入攻擊。
Database db = CreateDatabase(); DbCommand command = db.GetSqlStringCommand(sql); command.Parameters.AddRange(param);
跨站腳本攻擊,又稱XSS代碼攻擊,也是一種常見的腳本注入攻擊。例如在下面的界面上,不少輸入框是能夠隨意輸入內容的,特別是一些文本編輯框裏面,能夠輸入例如<script>alert('這是一個頁面彈出警告');</script>這樣的內容,若是在一些首頁出現不少這樣內容,而又不通過處理,那麼頁面就不斷的彈框,更有甚者,在裏面執行一個無限循環的腳本函數,直到頁面耗盡資源爲止,相似這樣的攻擊都是很常見的,因此咱們若是是在外網或者頗有危險的網絡上發佈程序,通常都須要對這些問題進行修復。
XSS代碼攻擊還可能會竊取或操縱客戶會話和 Cookie,它們可能用於模仿合法用戶,從而使黑客可以以該用戶身份查看或變動用戶記錄以及執行事務。
[建議措施]
清理用戶輸入,並過濾出 JavaScript 代碼。咱們建議您過濾下列字符:
[1] <>(尖括號)
[2] "(引號)
[3] '(單引號)
[4] %(百分比符號)
[5] ;(分號)
[6] ()(括號)
[7] &(& 符號)
[8] +(加號)
爲了不上述的XSS代碼攻擊,解決辦法是可使用HttpUitility的HtmlEncode或者最好使用微軟發佈的AntiXSSLibrary進行處理,這個更安全。
微軟反跨站腳本庫(AntiXSSLibrary)是一種編碼庫,旨在幫助保護開發人員保護他們的基於Web的應用不被XSS攻擊。
編碼方法 |
使用場景 |
示例 |
---|---|---|
HtmlEncode(String) |
不受信任的HTML代碼。 | <a href=」http://www.cnblogs.com」>Click Here [不受信任的輸入]</a> |
HtmlAttributeEncode(String)
|
不受信任的HTML屬性 | <hr noshade size=[不受信任的輸入]> |
JavaScriptEncode(String) |
不受信任的輸入在JavaScript中使用 | <script type=」text/javascript」> … [Untrusted input] … </script> |
UrlEncode(String)
|
不受信任的URL | <a href=」http://cnblogs.com/results.aspx?q=[Untrusted input]」>Cnblogs.com</a> |
VisualBasicScriptEncode(String) |
不受信任的輸入在VBScript中使用 | <script type=」text/vbscript」 language=」vbscript」> … [Untrusted input] … </script> |
XmlEncode(String) |
不受信任的輸入用於XML輸出 | <xml_tag>[Untrusted input]</xml_tag> |
XmlAttributeEncode(String)
|
不 受信任的輸入用做XML屬性 | <xml_tag attribute=[Untrusted input]>Some Text</xml_tag> |
protected void Page_Load(object sender, EventArgs e) { this.lblName.Text = Encoder.HtmlEncode("<script>alert('OK');</SCRIPT>"); }
例如上面的內容,賦值給一個Lable控件,不會出現彈框的操做。
可是,咱們雖然顯示的時候設置了轉義,輸入若是要限制它們怎麼辦呢,也是使用AntiXSSLibrary裏面的HtmlSanitizationLibrary類庫Sanitizer.GetSafeHtmlFragment便可。
protected void btnPost_Click(object sender, EventArgs e) { this.lblName.Text = Sanitizer.GetSafeHtmlFragment(txtName.Text); }
這樣對於特殊腳本的內容,會自動剔除過濾,而不會記錄了,從而達到咱們想要的目的。
經過猜解,可能會得出一些重要的網頁文件地址,如可能在/Pages/Security/下存在UserList.aspx和MenuList.aspx文件。
[建議措施]
1)禁止url中使用「~」或它的Unicode編碼。
2)關閉windows的8.3格式功能。
修復能夠參考下面的作法,或者找相關運維部門進行處理便可。
http://sebug.net/vuldb/ssvid-60252
http://webscan.360.cn/vul/view/vulid/1020
http://www.bitscn.com/network/security/200607/36285.html
若是頁面繼承通常的page,而沒有進行Session判斷,那麼可能會被攻擊者獲取到頁面地址,進而獲取到例如用戶名等重要數據的。
通常避免這種方式是對於一些須要登陸才能訪問到的頁面,必定要進行Session判斷,可能很容易給漏掉了。如我在Web框架裏面,就是繼承一個BasePage,BasePage 統一對頁面進行一個登陸判斷。
public partial class UserList : BasePage { protected void Page_Load(object sender, EventArgs e) { ...............
/// <summary> /// BasePage 集成自權限基礎抽象類FPage,其餘頁面則集成自BasePage /// </summary> public class BasePage : FPage { /// <summary> /// 默認構造函數 /// </summary> public BasePage() { this.IsFunctionControl = true;//默認頁面啓動權限認證 } /// <summary> /// 檢查用戶是否登陸 /// </summary> private void CheckLogin() { if (string.IsNullOrEmpty(Permission.Identity)) { string url = string.Format("{0}/Pages/CommonPage/Login.aspx?userRequest={1}", Request.ApplicationPath.TrimEnd('/'), HttpUtility.UrlEncode(Request.Url.ToString())); Response.Redirect(url); } } /// <summary> /// 覆蓋HasFunction方法以使權限類判斷是否具備某功能點的權限 /// </summary> /// <param name="functionId"></param> /// <returns></returns> protected override bool HasFunction(string functionId) { CheckLogin(); bool breturn = false; try { breturn = Permission.HasFunction(functionId); } catch (Exception) { Helper.Alerts(this, "BasePage調用權限系統的HasFunction函數出錯"); } return breturn; } protected override void OnInit(EventArgs e) { Response.Cache.SetNoStore(); //清除緩存 base.OnInit(e); CheckLogin(); }
不然可能會受到攻擊,並經過抓包軟件發現頁面數據,得到一些重要的用戶名或者相關信息。
還有一個值得注意的地方,就是通常這種不是很安全的網絡,最好要求輸入比較複雜一點的密碼(強制要求),例如不能所有是數字密碼或者不能是純字符,對位數也要求多一點,由於不少人輸入12345678,123456,123這樣的密碼,很容易被猜出來並登陸系統,形成沒必要要的損失。
針對上面發現的問題,提出下面幾條建議。
1)在服務器與網絡的接口處配置防火牆,用於阻斷外界用戶對服務器的掃描和探測。
2)限制網站後臺訪問權限,如:禁止公網IP訪問後臺;禁止服務員使用弱口令。
3)對用戶輸入的數據進行全面安全檢查或過濾,尤爲注意檢查是否包含SQL 或XSS特殊字符。這些檢查或過濾必須在服務器端完成。
4)關閉windows的8.3格式功能。
5)限制敏感頁面或目錄的訪問權限。
撰寫人:伍華聰