看雪編輯按:曾問過一位搞
WEB 安全的人為什麼 PHP 是世界上最好的語言,他的回答是 PHP 網站漏洞多,有飯吃。結合目前黑灰產中藉助 WEB
漏洞進行各種薅羊毛的現狀,這不禁觸發了我們的深切反思。問題究竟出在什麼地方,為什麼網站會存在 SQL 注入、XSS 跨站、CSRF
這些漏洞,我們應該如何避免在程式碼中產生這些錯誤?本次議題是由中國婚博會的 PHP 高階工程師湯青松為我們帶來的“淺析 WEB
安全程式設計”,作為開發人員你會發現其中有許多點是值得我們學習借鑑的,安全問題必須引起每一位開發者的重視。以下內容為湯青松演講實錄,由看雪學院(微信公眾號:ikanxue)整理。
湯青松
中國婚博會PHP高階工程師、安全顧問。擅長安全測試工具的研發,web滲透測試,在處理web漏洞中積累有大量經驗,2014年任職於烏雲,負責眾測開發工作;2015年在網利寶擔任研發以及安全建設。目前正專注於PHP的編碼安全,PHP安全編碼方面的書籍正在撰寫中。
他常常活躍在SegmentFault講堂以及GitChat,多次分享了WEB安全方面的議題。曾在2017 PHP開發者大會上發表演講《PHP安全開發:從白帽角度做安全》。
***
常見漏洞有哪些?
湯青松:非常高興跟大家交流這個看雪編碼的問題,我是湯青松。說到安全開發的話題,其實我一直是開發者,開發我是專業,安全我是業餘,但是安全開發我還是專業的。在場的各位,對於關鍵詞都有清晰的瞭解,我列舉了一些安全的關鍵詞,我們先來看一下。
常見程式碼注入、CSRF、O元支付、簡訊轟炸這些都是非常常見的漏洞,今天由於時間關係我講不了那麼多,我列舉其中幾個點跟大家分享一下,希望大家聽了以後可以舉一反三,在大腦中形成自己的安全意識,從而提高這個安全編碼的能力。
今天要分享的是五個點:SQL隱碼攻擊、XSS跨佔,請求偽造,越權漏洞以及支付漏洞。
SQL隱碼攻擊
我們看一下SQL隱碼攻擊,首先是漏洞成因,攻擊方式以及防禦方案。漏洞成因我們可以這兩句話,使用使用者引數拼接這個SQL語句,這個引數改變了原有的SQL結構,改變了這個SQL的注入。
我們看下面一張PPT,左邊這是一個資料庫,白色部分的字型是我們在程式碼中寫到的SQL結構,黑色部分就是攻擊者可能會傳入的引數。當我們把這個SQL結構拼接出來之後形成了一個新的結構,這個結構被執行之後把整張表所有的資料傳輸出來,資料庫比較大的訪問更多請求,整個可能就掛了,還造成一些資料洩漏的情況,這些就是SQL的注入成因,引數改變了原有的SQL結構。
攻擊者通常有哪幾種攻擊方式?我把它分為了三種型別:一種是回顯注入,一種是報錯注入,一種是盲注。
這裡面有兩張圖,第一張圖是傳入ID是正常的正型數字,返回的結果是使用者的一個資訊傳入ID等於1,上面把這個引數修改了一下,等於1,然後加了
or
1=‘1,當它拼接到之後,跟前面一樣把整個表的資料傳輸出來,這邊看到整個使用者表的資料都被列舉出來了。利用漏洞可以改變這個頁面的資料我們叫做回顯注入,這個駭客可以直接把這個資料下載下來。
報錯注入,這張圖非常清楚可以看到URL上面這個部分是正常URL加上攻擊者利用的供給程式碼,其實這上面的供給程式碼也是執行不了,放到資料庫當中,最後會造成資料庫變為異常碼,然後把異常碼丟擲來了,把這個使用者名稱展示出來了,這是非常敏感的資訊,我們寫程式碼的時候需要把這個資料庫丟擲來的錯誤遮蔽掉,不要可以讓前臺顯示出來,透過報錯顯示了一些敏感資訊,我們稱之為報錯注入。
盲注,連線起來稍微可能複雜一點,它和回顯注入以及報錯注入不一樣,我們沒有辦法透過這個頁面資料看到它的區別,可以透過兩種方式,比如說步爾盲注和時間盲注,下面的部分是正常URL,紅色部分是布林注入的表示式,前面加一個and擷取一個字元,判斷一下這個第一個字元是不是大於這個字母A,如果當它成立整個條件都是成立,這個時候頁面是有反饋資料的。
如果不成立這個頁面返回不了資料,這就是布林資料,我們可以看到有資料和沒有資料的情況,當字母A不斷變換的時候,也可以把這個資料庫裡面的資料猜測出來。
時間盲注,下面藍色區域部分,我們知道資料庫裡面可以用一些IF函式,也是擷取第一個字元,如果這個不成立就到五秒鐘返回,透過這個頁面返回的時間可以判斷這個地方是不是有注入的,也可以把這個資料都給下載下來。
剛剛說到攻擊者碰到三種攻擊方式,下面看一下怎麼樣檢測頁面當中有沒有什麼注入?現在有非常多的工具,如果對注入瞭解不是太深,也是有快速檢測的方法。
我們可以看到這是一個CMD視窗,上面是我寫到的檢測表示式,Splmap.py以及我們需要檢測的UI,需要有這個註冊點它會告訴你有哪些注入,比如說這個頁面是我在本地測試的結果,它就告訴了有回顯注入、錯誤注入以及一些盲注。
開發者最關心的就是怎麼樣防範伺服器的安全?
編碼的過程中有三點建議,值得借鑑。
引數會改變SQL的結構,我們會讓這個引數當中不但有這個SQL的結構,當我知道這個引數是整型的時候,我們就把這個引數轉型為整型,整型肯定不包括這個SQL的結構,無法改變結構的目的,哪就不存在著SQL隱碼攻擊。
有的時候我們無法預測它傳什麼引數,比如說我們去論壇回覆一個帖子,我們肯定沒有辦法控制的,這個時候我們可以用PDO預處理,這也是最常見的方法,也是一個最好的方法。但是有的時候我們會寫一些複雜社會語句,我們會會用第一種方法,我們適前定義好這個SQL的語句結構,再把我們的引數放進去,這個時候是無法達到更改SQL語句處理的目的。
當這個業務比較大的時候,這個日誌是非常多的,可以找一些SQL的取模軟體,可以把這個取模一下,取模之後並不太多的,如果直接看的話是海量的日誌,是沒法看的。
XSS跨站
看一下漏洞成因、攻擊場景以及防禦方法。畫了一張圖,上面有一個URL,下面是一個頁面返回的HTML程式碼,我們可以看到白色部分HTML是我們事先定義好,黑色部分引數是想使用者想搜尋的關鍵詞,當我們搜尋了test+Div最後等於123,對後反饋頁面一般搜尋會告訴你使用者搜尋了什麼關鍵詞,結果如何等等。
這個地方如果沒有做好轉移,可能會造成XSS跨站,我們可以看到藍色部分是我們事先定義好的結構,被攻擊者利用之後它先把這個DIV結束了,最後加上一個script標籤,它也有可能不跟體談標籤,直接傳送到它的伺服器上。引數未經過安全過濾,然後惡意角本被放到網頁當中被執行了,使用者瀏覽的時候執行了這個指令碼。
XSS也分好幾種型別,比如說這裡有三種型別,反射型、儲存型以及DOM型。
反射型:這個截圖當中是專門訓練一些WEB漏洞的練習頁面,我們可以輸入自己的名字,輸入之後會把我們的名字在這裡顯示了出來,我們輸入了一個張三123,這個時候彈出來了一個123,在那邊顯示了一個張三,但是script標籤沒有出來,因為這個標籤被執行了。
接著來說說儲存型的漏洞,儲存型的XSS,我們可以看一下這個URL上面並沒有程式碼,但是依然彈出了一個“1”其實也是中了XSS程式碼,這是怎麼樣做到的?
我看了漏洞的帖子。它是發現個人資料頁的時候有一個XSS漏洞,它就在個性簽名的位置填入了一個XSS標籤,彈出了一個1,把這個地址發給了別人,別人看到這個地址並沒有什麼程式碼以為這個頁面是安全,結果一開啟就插入了這個XSS程式碼。
儲存型的XSS的攻擊危害比較大,因為它的頁面當中是看不到這個Script的程式碼,別人防不勝防。只要管理員沒有發現,下一個使用者或者下一個使用者一直接發它的,反射型需要使用者主動點選的。
還有一種是Dom型的XSS,一般是一些有安全意識的開發者弄出來。比如說接受引數會做一些過濾,把一些字元轉義一下,但是轉義之後依然會存在著XSS的情況,比如說這個圖上我們上面輸入的可以看到這行程式碼奪了規律,把這個大括號以及小括號以及雙頁號進行轉移,按理說轉移之後它應該不會再作為它的標籤存在,不會存在XSS的程式碼。
我們可以看到下面在Script透過ID獲得的這個值,複製到了這個DIV上,經過DOM操作之後,之前轉義的字元就變為的它的標籤,所以經過DOM的操作XSS我們稱之為DOMXSS,有可能透過URL傳播,也有可能透過伺服器的傳播。
透過XSS有一些建議:
有一些時候根本就不需要考慮到它是不是HTML有標籤,我們有的時候根本用不到HTML標籤,只保留文字部分這是一勞永逸的,但是有一些我們還是需要展示這個標籤,比如說程式論壇當中我要貼一個程式碼不能把這個程式碼部分幹掉,這個時候我們需要用一些轉移,它會把這個大括號、小括號以及雙引號都可以做一個轉意,做為一個字元,就無法執行這個標籤型,後面加一個引數,有時候單引號也會造成一席XSS。
一個訊號當中有那麼多的地方存在著這個輸入以及檢測的地方,可能就有一些地方漏掉了,只要有一個地方漏掉了,使用者的cookie資訊就被盜取了。
伺服器發生使用者資訊的時候我們需要加上一個httponly之後,這個程式碼無法讀取到cookie的資訊,那麼攻擊者也是得不到這個資訊的,對於使用者來說也是非常好的保護。比如說張三在我們網站上登陸了一下使用者明,李四他特意發生了一個攻擊請求,他拿不到這個使用者ID,就冒充不了這個張三。
越權漏洞
我們再來看看越權漏洞,在一些系統當中如果存在著多種使用者角色,每一種角色有不同的許可權。操作業務適合如果許可權不嚴格可能會發生越權漏洞。越權分為垂直越權和平衡越權。
我們先來看一下平行越權。經常在WEB系統當中有商城,這個商城當中必不可少就有訂單,訂單肯定是有一個店鋪ID,我們通常把它設定為一個自增長的ID,這個ID是一個數字型的,在URL上面如果我有一個訂單ID就是100,我是一個攻擊者我會嘗試一下,100+1,當它ID等於101或者99的時候能否訪問到。
如果能否訪問到就看一下這個訂單資訊不是我的,這個地方就存在著一個漏洞。張三可以看到李四的訂單資訊,這個時候就存在著越權。張三和李四是平級的使用者,我是普通使用者,他也是普通使用者,他們兩個許可權是一樣,互相可以看平臺資訊這叫做平級越權。
這個有什麼危害?比如說這個網站有的漏洞,如果是競爭對手他就可以知道使用者在我的平臺上下過訂單的行為,然後去營銷一下,還有一下我們把這個訂單ID直接暴露出來,還有一種可能就是競爭對手會根據我們的訂單IP的增長量,判斷我們的增長量,就知道我們一天到底有多少訂單。
平行越權防禦方法,我們查詢的時候必須加上當前使用者的ID,就是orderID加上UID,這樣不會出現張三可以看到李四的訂單了。
接下來我們再看一下垂直越權,這是一個普通使用者進入到後臺管理系統當中,他的許可權就擴大化了,這個時候可以一些其他的操作,他有更多的許可權了,通常發現這種情況原因,通常後臺會整合到更多的控制器來統一管理。依然有一些郵件就漏掉了,沒有整合到,就會出發這種情況。
駭客不會一個一個找,會透過一些掃描器發現了,他就可以進去了。不要把自增長ID暴露出來,可以做對稱加密或者非對稱加密都可以,先轉換為一個字母型的,讓別人看不到你的數字型的ID是多少。別人就沒有辦法去透過這個加一減一的方式越權,也看不到你的一天業務增長量。
我看到一些程式碼在前臺和後臺會供應到長介面,前臺和後臺是有一些區別,前臺有一個訂單列表不會+UID,造成程式碼一直寫寫,前臺也不會加入這個UID,我建議儘量把這個前臺的方法和後臺的方法區分開來。越權,其實不僅僅限於展示,我們剛剛看到了這個訂單,張三可以看到李四的訂單資訊是檢視,但是有的時候我們修改訂單的時候也會主線這個問題。所以在讀寫的時候我們都需要注意一下這個越權的問題。
CSRF跨站請求偽造
CSRF,這個通常會配合XSS使用。服務端錯把瀏覽器發起的應請求當使用者發起的請求,會造成XSS的問題。比如說我開啟了張三的網站,登陸了一個使用者資訊,李四網站上有一個攻擊程式碼,向張三這個網站發起請求,張三的網站會以為你本人發起的請求,他實際上是瀏覽器發出的請求。
比如PPT中有一張圖片,圖片有一個表單,左邊是它的原始碼,我們可以看到表單每一項都在,但是從安全的角度上考慮它是少了一樣東西,沒有一些驗證碼或者TOKEN等等一些相關資訊。服務端如果沒有驗證這個問題,就會造成這個CSRF的攻擊。如何檢測我們的系統當中是否存在這個CSRF?
可以其掉token資訊看一下能否提交,把Referer能否提交成功,以及替代POST請求,如果都存在它就存在著CSRF。我們有一些建議,一定要驗證Reeferer資訊,Token的驗證,圖片驗證碼等等。根據我們的業務安全等級越高,最基礎的我們可以用這個refefe需要驗證,再高一級就是token,再高一級就是圖片驗證。
支付漏洞
接著我們來看看支付漏洞,在這張圖中,我搜尋了”漏洞
低價 線報”,搜尋到一批QQ群;
我嘗試加入過這些QQ群中觀察,在群中看到有人在賣低價支付購買商品的漏洞,在跟其中的一個群友哪裡瞭解到有很多做黑產的會把一些漏洞的資訊賣到群裡面去,其他的人就會去把這個漏洞給利用起來。
之前看到一個新聞,有一個浙江的老闆,他想做線上找人做了一個網站,這個網站存在著一些支付漏洞,一週之後他發現這個訂單量極速上升,賣了70多萬,結果看了一下帳戶餘額只有幾千塊錢,報警之後才查到原因,但是貨物已經發出去了。
造成這些漏洞原因有很多,比如說支付金額是由前端提交的資料,不是後端計算的,而且沒有對這個金額做校驗,直接信任的前端提交的金額,導致這個攻擊者可以隨即修改這個金額,比如說修改為一分錢,這是非常典型的可以隨意更改這個金額。
上面的金額是94元,這個表單裡面改為一分錢,最後提交的時候是一分錢,這是非常好的漏洞,也是非常典型的。
還有一個問題是數量的限制,一個價格是26元,一個是27元,把這個數量變為負一之後,一提交變為一塊錢了。這是之前資料包的漏洞,他充值了一塊錢,他發現有一個資料包向網站傳送,他就把這個資料包反覆重放,就加了好幾次,實際上只充值了一塊錢。
如何防範?我們限制這個低價購買產品,比如說負數的時候肯定不行,等於零的商品的根據業務情況也是需要多注意的。限制免費商品獲得金錢和積分的情況。有一些商品免費了,但是它可以獲得一些積分,那就存在著刷積分的情況。
最後這個腦圖這是我畫的這次講解的內容,大家可以下載看一下。我的演講到此結束。
本演講PPT 下載:
[原創]淺析WEB安全程式設計(看雪2017安全開發者峰會演講回顧0x3)-『茶餘飯後』-看雪安全論壇