常見web攻擊
SQL注入
非法讀取、篡改、刪除資料庫中的數據。
盜取用戶各類敏感信息,以此來獲取非法利益!
通過修改資料庫修改網頁內容。
注入木馬。
SQL注入是黑客對資料庫進行攻擊的最常見手段,因為隨著現在B/S模式開發的發展,用B/S開發的系統越來越多,但是由於軟體工程師的水平和經驗參差不齊,所以說相當大一部分軟體工程師在編寫代碼的時候沒有對用戶的輸入沒有做合法性的判斷而是直接用,所以說用戶在提交這些表單的時候,如果用戶在這些表單裡面提交了sql語法的話,就會一定程度影響我們sql執行情況。
下面我們用python和django演示一個存在很大漏洞的登錄邏輯。
import MySQLdbnclass LoginUnsafeView(View):n def get(self, request):n return render(request, login.html, {})n def post(self, request):n user_name = request.POST.get(username, )n pass_word = request.POST.get(password, )n conn = MySQLdb.connect(host=127.0.0.1, user=root,n passwd=root, db=dbname, charset=utf8)n cursor = conn.cursor()n sql_select = "SELECT * FROM `users_userprofile` " n "WHERE email={0} AND password={1}".format(user_name, pass_word)n result = cursor.execute(sql_select)n for row in cursor.fetchall():n # 查詢到用戶n pass n
這一段代碼乍一看好像能正常查詢用戶啊,但是其實有著很大的隱患!
比如我們如果在登錄操作頁面我們這樣輸入:
用戶名: OR 1=1#n密碼: 1234n
按照上面的用戶名和密碼,一直執行到sql_select的時候,就很明顯的發現問題了!
這時候sql_select會是這樣:
sql_select = {str}select * from `users_userprofile` n where email= OR 1=1# and password=1234"n
有什麼問題?我們看where email= OR 1=1# and password=1234"這一段,
實際上email等於空字元串,然後OR 1=1#,到這裡實際上是斷開了,OR 1=1之後實際上根本就不執行,那麼這句where語句就為真,因為1=1在任何情況下都成立!所以一旦這個SQL語句執行了,那它肯定是能查詢到我們所有的用戶的!所以這就繞過了SQL語句的檢查,
它通過在我們用戶名輸入框中構建一個SQL語句,來達到我們在執行SQL語句的時候永遠為真的效果!那這樣就可以直接偽裝用戶登陸。像我們這樣的代碼,根本沒有對用戶輸入的用戶名和密碼做安全性驗證!比如你驗證用戶名填寫不能出現單引號,比如規定用戶只能輸入合法的郵箱或者手機號碼!所以正是因為我們沒有對用戶輸入進行驗證,就留下了這樣的漏洞,讓SQL注入有機可趁!
還有很多地方我們取post,我們這種取用戶傳遞過來的post的地方,如果也出現上面那種單引號那種情況或者出現1=1,那麼就把這個SQL語句插入到了資料庫當中,這就是SQL注入攻擊的完整過程。當然SQL注入不光是在登陸的時候可以攻擊你,它在任何url中包含get參數中,實際上也可以在裡面添加特殊字元的。
如果用django開發,盡量用到django的orm我們就沒必要對這些參數做檢查了,不然我們自己做的時候要對這些參數做檢查,就像上面的代碼,我們要對username做參數檢查,比如我們用正則表達式來匹配看他是不是一個郵箱的郵箱或者手機號碼,如果我們做這些驗證,那用戶是沒法在我們剛才的username中完成攻擊的。
XSS攻擊 - xss跨站腳本攻擊(Cross Site Scripting)
盜取各類用戶賬號,如用戶網銀賬號、各類管理員賬號。
盜取企業重要的具有商業價值的資料。
非法轉賬。
控制受害者機器向其他網站發起攻擊,注入木馬。
xss攻擊流程
受害者首先向網站發起請求,然後網站響應請求返回數據,但是現在存在一種情況就是伺服器存在一個xss的漏洞,假設有這樣的一個產品列表頁:
http://www.bank.com/product/list/?name=iphone7n
這個列表頁面存在一個問題,當用戶傳入一個名字,比如name=iphone7的時候,伺服器會把這個 name顯示到我們的頁面當中,看起來沒什麼問題,他會原樣的把name顯示給用戶,但實際上如果對這個name不做參數檢查的話,他會有一個重大漏洞,比如現在黑客發現了我們的這個url,它是一個xss的漏洞,他怎麼做?他將我們的url改變一下!怎麼改變?他會把url改成一段含有js代碼的新的url:
http://www.bank.com/product/list/?name=<script>x=document.cookie;alert(x);</script>n
他傳遞的name是一段js代碼,這段代碼中他只是取出了用戶的cookie,然後進行alert,這個看起來很簡單,正式因為伺服器沒有對name進行檢查而是直接回顯給用戶,所以用戶可以在這個name里傳遞進一段js代碼。那麼黑客如何利用xss漏洞構建的這個url進行攻擊呢?
首先黑客發現我們的漏洞,他向我們的受害者發送一個鏈接,當然這是一個bank的鏈接,只是其中加上了一段js代碼,然後受害者看到這個鏈接是來自http://bank.com的鏈接,那麼受害者就會信任這個url,當然這個發送會有很多種方式,比如郵件,社交平台消息等等,反正各種各樣的方式,只要受害者能後接收到,受害者看到這個鏈接之後他會點擊這個url,因為他對來自bank的鏈接已經信任了,所以他很大可能就會直接點擊url,然後伺服器就會執行這段代碼,然後把這段代碼原模原樣返回到受害者瀏覽器當中,如果這段js的腳本是指向黑客伺服器上的一段腳本,這樣的話這段js代碼中可以寫入任何js的邏輯,比如說他把我們受害者的cookie值發送給了黑客,黑客就會拿到受害者的session的id,比如以django為例,django的伺服器會發送一段session_id保存到我們的瀏覽器當中的,同樣的我們大部分網站都會發送session的id保存到客戶端的瀏覽器當中,既然黑客讓你執行了這段js的代碼,他就可以把你的cookie當中的所有的內容全部發送給黑客的伺服器,比如說他在這段js的腳本中加入了發送本地cookie到另外一個伺服器的邏輯,實際上這就是一個跨域的攻擊,他通過在你的這個bank的伺服器里加入了黑客自己的一段js代碼,通過執行這段js代碼就可以拿到受害者的cookie信息,因為拿到這個cookie信息之後就可以發送給黑客,然後黑客拿到這個cookie之後就可以偽裝受害者向bank伺服器發起請求,比如黑客要進入個人中心,因為黑客有了受害者的session的id,伺服器就會把受害者的所有的信息全部返回給我們的黑客,這樣的話黑客就冒充受害者去訪問bank的伺服器!這就是xss攻擊的完整流程,可想而知這樣的漏洞造成的危害有多大!!
這裡面關鍵的就是伺服器存在這樣的xss漏洞,比如對name不加判斷的直接回顯給用戶,這其實就是xss的漏洞,這正是bank伺服器沒有對用戶傳輸過來的信息做校驗,才造成這樣的xss漏洞,那麼我們如何來防範這種xss攻擊呢?
xss攻擊防護
xss攻擊的細節很多,這裡我們主要介紹三點。
1、首先代碼里對用戶輸入的地方和變數都需要仔細檢查長度和對"<",">",";",""等字元做過濾;對這些html敏感的東西給他做一下過濾,或者做轉義給他encode,這樣即使傳入進來的是js的代碼,也會因為少了這些關鍵字元而無法執行
2、避免直接在cookie中泄露用戶隱私,例如email,密碼等等通過使cookie和系統ip綁定來降低cookie泄露後的危險
3、盡量采POST而非GET來提交表單,比如剛才我們的http://bank.com裡面允許用戶在url中加入name的欄位,這樣就造成了黑客可以將他自己構建的url發送給我們的用戶,用戶看到鏈接就會點擊,但是如果是POST方法的話,發送給用戶的鏈接的時候是無效的,因為我們後台在取的時候是POST的參數,黑客不可能發送一個自己的頁面來POST數據,因為發送自己的post的頁面的話,一般的受害者是不會相信的,所以我們後台盡量使用POST而不是GET。
csrf攻擊-csrf跨站請求偽造(Cross-site request forgery)
以受害者的名義發送郵件。
盜取受害者的賬號。
冒充受害者購買商品。
虛擬貨幣轉賬。
比如我們用戶現在向信任的銀行網站A發送請求,首先用戶信任並登陸A,然後伺服器A返回sessionid給用戶保存在用戶本地cookie當中,登錄成功之後,無論用戶訪問伺服器A的任何url,瀏覽器都會把剛才伺服器返回的sessionid帶上發送給伺服器A,這是我們正常的一個流程,然後如果這個時候我們的用戶又訪問了我們的危險伺服器B,假設這個危險伺服器B是黑客的網站,這個時候用戶又打開了黑客的網站,用戶事先不知道這是黑客網站,然後打開了網站,打開之後他就會訪問伺服器B,然後用戶在訪問了伺服器B的時候他在html中帶了一個url,這個url是指向A的一個url,比如說這個url是一個轉賬的url,然後用戶實際上就會執行這個命令,這個過程中用戶並沒有向A發起一個轉賬的請求url,這個請求是伺服器B告訴A讓A發的,A是看不到的,因為他在瀏覽器中比如在一個image圖片中加上一段url,這個url是一個轉賬的url,用戶事先並不知情,用戶就會向A發起一個請求,發起請求的時候由於用戶比如說他沒有關閉A伺服器,他訪問B伺服器的時候另起了一個窗口,然後瀏覽器就自動帶上這個sessionid以及這個url請求去訪問A,然後A就會誤認為用戶要轉賬。這些其實就完成了一個跨站請求偽造,因為用戶並沒有向A請求,他是訪問了B伺服器,B伺服器裡面有個url讓用戶瀏覽器請求了A,這其實就是B伺服器偽造用戶去向A伺服器發起了請求,那麼他能完成這個跨站請求偽造的根本原因是因為用戶的瀏覽器訪問A伺服器的時候是會自動帶上sessionid的。
我們拿一個具體的事例進行說明。
比如說黑客伺服器給我們用戶返回html的時候,html中黑客插入了一個圖片,這個圖片的html代碼如下:
<img src=http://www.mybank.com/Transfer/toBankId=11&money=10000>n
這段代碼實際上向mybank的url發起了一個轉賬,實際上是向11這個賬戶轉10000塊錢,這樣的話,用戶在不知情的情況下因為瀏覽器要載入這張圖片,瀏覽器就會默認發送這個請求,這樣的話什麼情況下可以生效,比如現在在瀏覽器中訪問http://mybank.com,假設這就是我們之前信任的網站A,這個時候用戶再添加一個新標籤頁然後訪問危險的網站,這個危險網站在給我們返回html代碼的時候,實際上這裡面就插入了我們剛才說的邏輯,也就是上面那段代碼,實際上這段代碼對mybank來說,實際上就會認為是你需要轉賬給11這個賬戶,這樣的話就完成了一次攻擊,這段代碼里有兩個關鍵點,首先用戶在一個標籤頁打開了一個信任的網站,然後另開啟了一個新的標籤頁,因為有可能用戶關閉標籤cookie可能就失效,這一點很關鍵,cookie不能失效,如果cookie一旦失效,實際剛才哪個image的url攻擊就失效了,因為瀏覽器帶過去的cookie已經失效了,實際上就不會完成轉賬的操作,同樣的現在這種情況我打開了一個標籤頁訪問mybank,同時開了一個新的標籤頁訪問攻擊網站,這個網站是支持cookie這種模式的,他才能完成csrf攻擊,實際上這樣對後來說是一個很大的隱患,因為後台支持這種GET的操作,那如果我的這個介面只支持POST操作,攻擊者有沒有可能完成攻擊?當然還是有可能的。看下面的這段代碼。
這段代碼實際上就是攻擊網站的源碼,我們看代碼,他其實會自定義一個form,然後在用戶載入完這個url之後,自動執行script中的post代碼,所以即使後台用POST來做,他同樣會對你造成攻擊,,那我們如何來解決這個問題呢?
比如在django中,當你提交表單的時候,我們必須添加一個{% csrf_token %},這個是我們django後台傳過來的,是一次性的,這樣的話我們在提交表單的時候每次都要把這個csrf_token給帶過去,我們才能完成我們表單提交,這樣他就能防止csrf攻擊,因為黑客網站是沒法生成這樣一個csrf_token的,即使黑客網站生成的,他也沒法完成我們後台驗證,django就通過這樣的方法防止了csrf攻擊。
結束
推薦閱讀:
※金石人才培養計劃導師公布啦!——你敢說你不認識他們嗎?!
※淺談DDos攻擊與防禦
※網路掃黃,從技術上如何實現?
※XPwn 2016 | 做安全就做未來安全
※Hacking Tools搜羅大集合(上)