魚皮的靶場開源了!
魚皮自制交互式網(wǎng)絡(luò)安全自學(xué)網(wǎng),助你成為網(wǎng)絡(luò)安全達(dá)人!
大家好,我是鲏。
據(jù)說互聯(lián)網(wǎng)是沒有記憶的,那不知道大家是否還記得,很久很久以前,我有一個網(wǎng)站叫 “面試鴨”。這個網(wǎng)站上線之初,遭受了各種各樣的網(wǎng)絡(luò)攻擊,也一度給我的心態(tài)造成了巨大的影響。
在很多網(wǎng)友看來網(wǎng)站攻擊只是個玩笑,但只有站長本人才知道那種無力和痛苦。
經(jīng)歷過網(wǎng)站攻擊后,更加意識到網(wǎng)絡(luò)安全意識的重要性,所以當(dāng)時我做了一個幫助大家學(xué)習(xí)網(wǎng)絡(luò)安全的免費(fèi)網(wǎng)站 —— 測試(逝)鴨。
這個網(wǎng)站可不是傳統(tǒng)的教程網(wǎng)站,掛個課、掛個電子書就結(jié)束了,而是一個 交互式 自學(xué)網(wǎng)站。魚皮結(jié)合自己遭受網(wǎng)站攻擊的經(jīng)歷和教訓(xùn),給網(wǎng)站設(shè)置了 30 多個漏洞。
大家需要通過自由探索和種種提示,發(fā)現(xiàn)這些漏洞并對網(wǎng)站造成攻擊 ??,從而在實(shí)戰(zhàn)中學(xué)習(xí)到網(wǎng)絡(luò)安全知識,主打一個輕松愉快!
有網(wǎng)友評論說:我建了個免費(fèi)的靶場。
這么說倒也對哈哈,不過可能沒那么專業(yè),更多地還是教學(xué)向。
我希望通過這個網(wǎng)站,大家都能意識到網(wǎng)絡(luò)安全的重要性,并且在開發(fā)網(wǎng)站時提升安全防護(hù)意識。
記??!學(xué)習(xí)這些知識是為了更好地防范,而不要利用技術(shù)去違法作惡!??!
這兩天我在整理自己的代碼,無意中又發(fā)現(xiàn)了這個項(xiàng)目,覺得還是可以給大家學(xué)習(xí)的。
所以直接 100% 開源到 GitHub 上!再給大家一個免費(fèi)的項(xiàng)目。
下面給大家簡單介紹一下這個開源項(xiàng)目。
在線體驗(yàn):http://ceshiya.yupi.icu
開源地址:https://github.com/liyupi/ceshiya
20 秒學(xué)會使用
1)第一次進(jìn)入主頁時,會自動彈出新手引導(dǎo),教你如何攻擊本網(wǎng)站,跟著引導(dǎo)點(diǎn)擊下一步即可
2)頁面上的任何一個按鈕、任何一個輸入框都有可能暗藏玄機(jī)。比如瘋狂地點(diǎn)擊 “收藏” 按鈕,不給系統(tǒng)反應(yīng)的機(jī)會,然后 Bug 就出現(xiàn)了。
每當(dāng)你找到一個 Bug,站長魚皮的血鴨值都會極速上升,并且你還可以看到魚皮給出的小知識點(diǎn),以及一張魚皮的高清無碼發(fā)飆圖,據(jù)說總共有 5 張,集齊之后也許不能召喚神龍,但魚皮會請你喝茶。
3)可以通過右下角的工具包幫助自己攻擊網(wǎng)站:
比如上圖的請求工具,可以幫助你繞過前端界面,直接從網(wǎng)站后臺獲取數(shù)據(jù) ??。
4)點(diǎn)擊右下角的 Bug 圖標(biāo)彈出游戲面板,可以查看得分情況、已發(fā)現(xiàn)的 Bug、獲取提示、查看自己的排名等等。
1 分鐘本地啟動
由于項(xiàng)目采用純前端實(shí)現(xiàn),本地啟動項(xiàng)目非常簡單!
在線訪問人數(shù)較多,可能會卡頓,所以更推薦大家自己在本地使用~
1)下載本項(xiàng)目代碼
2)進(jìn)入項(xiàng)目根目錄,執(zhí)行 npm install 安裝項(xiàng)目依賴
3)執(zhí)行 npm run dev 本地啟動即可
功能和特性
-
完整的面試刷題網(wǎng)站前端
-
搜索題目 -
創(chuàng)建題目 -
用戶登錄注冊 -
個人頁面 -
題目選取 -
題目分類 -
遇到題目 -
收藏點(diǎn)贊 -
30+ 交互式 Bug 關(guān)卡
-
游戲工具箱
-
游戲面板
技術(shù)選型
本項(xiàng)目采用 純前端實(shí)現(xiàn) ,不需要任何后端的前置知識~
Q:為什么采用純前端實(shí)現(xiàn)?
A:該網(wǎng)站更側(cè)重前端交互,無需后臺存儲;同時也能減少攻擊風(fēng)險 + 省錢
-
開發(fā)框架:React、Umi -
腳手架:Ant Design Pro -
組件庫:Ant Design、Ant Design Components -
語法擴(kuò)展:TypeScript、Less -
打包工具:Webpack -
代碼規(guī)范:ESLint、StyleLint、Prettier -
工具庫:Intro.js(引導(dǎo)提示)
核心設(shè)計
1、網(wǎng)站改造流程
本網(wǎng)站是由一個完整前后端項(xiàng)目 面試鴨 改造而成的純前端網(wǎng)站,這里分享下通用的網(wǎng)站改造流程,大家可以嘗試把自己做的項(xiàng)目也變成交互式教學(xué)網(wǎng)站。
步驟如下:
1)完整前端頁面開發(fā)(已有項(xiàng)目的話這一步默認(rèn)已完成)
2)頁面數(shù)據(jù)靜態(tài)化:創(chuàng)建 mock 目錄,存放人為編寫的假數(shù)據(jù);然后將和后端交互的 service 層代碼全部改造為操作和獲取 mock 目錄中的假數(shù)據(jù)。
3)創(chuàng)建游戲機(jī)制:具體實(shí)現(xiàn)方式見下
2、游戲機(jī)制實(shí)現(xiàn)
首先遵循組件化的思想,把所有和游戲相關(guān)的代碼封裝到 games 目錄中,并且提供一個 GameBox 組件供前端頁面引入,而不是直接侵入現(xiàn)有的業(yè)務(wù)代碼:
怎么實(shí)現(xiàn)在用戶執(zhí)行了某個操作后,觸發(fā)完成對應(yīng)的關(guān)卡呢?
這里采用的實(shí)現(xiàn)思想類似于前端監(jiān)控業(yè)務(wù)中的 “埋點(diǎn)”。
首先我們在 gameUnit.ts 中定義游戲的關(guān)卡(此處稱為 unit 單元),示例代碼如下:
/**
* 游戲單元類型
*/
export type GameUnitType = {
key: string;
desc: string;
type: string;
score: number;
knowledge: string;
no?: number; // 題號
href?: string; // 更多知識的鏈接
};
/**
* 游戲單元列表
*/
const GAME_UNIT_LIST: GameUnitType[] = [
{
key: 'favourInfinite',
desc: '收藏按鈕可以無限點(diǎn)擊',
type: '邏輯漏洞',
score: 1,
knowledge: '網(wǎng)頁前端和后端都要對收藏狀態(tài)進(jìn)行控制,防止收藏數(shù)異常',
},
{
key: 'thumbUpInfinite',
desc: '點(diǎn)贊可以無限點(diǎn)擊',
type: '邏輯漏洞',
score: 1,
knowledge: '網(wǎng)頁前端和后端都要對點(diǎn)贊狀態(tài)進(jìn)行控制,防止點(diǎn)贊數(shù)異常',
},
];
然后我們編寫一個全局游戲狀態(tài)存儲文件 gameState.tsx ,用于記錄用戶已經(jīng)完成的關(guān)卡、分?jǐn)?shù)、游戲配置等信息:
/**
* 游戲全局狀態(tài)類型
* @author https://yuyuanweb.feishu.cn/wiki/Abldw5WkjidySxkKxU2cQdAtnah yupi
*/
export type GameStateType = {
init: boolean; // 是否為初始化
score: number; // 當(dāng)前分?jǐn)?shù)
gameTip: boolean; // 是否開啟提示
succeedUnitList: string[]; // 已通過的關(guān)卡
};
并且提供一個上報過關(guān)通知的函數(shù) doGameUnitSucceed ,參數(shù)為上面定義的關(guān)卡單元的 key,在該函數(shù)中改變當(dāng)前用戶的過關(guān)狀態(tài),并給出過關(guān)彈窗提示。
示例代碼如下:
/**
* 完成游戲
* @param key
*/
const doGameUnitSucceed = (key: string) => {
// 已經(jīng)完成
if (gameState.succeedUnitList.includes(key)) {
return;
}
gameState.succeedUnitList.push(key);
const unit = GAME_UNIT_MAP[key];
gameState.score += unit.score;
setTimeout(() => {
Modal.success({
title: `太棒了,魚皮的血鴨又高了!?? ${gameState.score - unit.score} +${unit.score}`,
content: ...,
okText: '繼續(xù)加油!',
});
}, 1000);
updateGameState(gameState);
};
之后,我們只需要在對應(yīng)的頁面和功能代碼中,增加一段過關(guān)邏輯,符合條件的話就調(diào)用 doGameUnitSucceed(關(guān)卡key) 過關(guān)通知函數(shù),就能實(shí)現(xiàn)過關(guān)狀態(tài)的更新和通知了。
比如下面的代碼,是在點(diǎn)贊功能中添加過關(guān)判斷邏輯:
const doThumbUp = async (id: string) => {
setThumbLoading(true);
const res = await thumbUpComment(id);
if (res === 1 || res === -1) {
comment.thumbNum = (comment.thumbNum ?? 0) + res;
// 點(diǎn)贊數(shù) > 9 則過關(guān)
if (comment.thumbNum > 9) {
// 注意這行代碼是關(guān)鍵,觸發(fā)過關(guān)
doGameUnitSucceed('thumbUpInfinite');
}
}
};
3、新手指引
引入 Intro.js 庫,在 GameBox 游戲組建中定義引導(dǎo)階段,然后通過 LocalStorage 判斷是否首次進(jìn)入游戲需要展示引導(dǎo)即可。
示例引導(dǎo)階段代碼如下:
const [steps] = useState([
{
title: '歡迎來到測逝鴨 ??',
intro: '這是一個鍛煉你網(wǎng)絡(luò)安全能力的破站,準(zhǔn)備好旅程了么????????',
position: 'top',
},
{
title: '目標(biāo) ??',
intro:
'你要做的就是運(yùn)用你的智慧和強(qiáng)大的洞察力,盡可能多地發(fā)現(xiàn)并利用該網(wǎng)站的 Bug、對網(wǎng)站造成破壞!??',
nextLabel: '應(yīng)該的應(yīng)該的',
},
...
]
4、工具箱實(shí)現(xiàn)
工具箱(ToolBox.tsx )本質(zhì)上就是集成了特定過關(guān)方法的頁面,算是一種定制化開發(fā)。每種工具都作為單獨(dú)的頁面,存放在 tools 目錄下。
大概就介紹到這里,更多的玩法大家感興趣的話可以自行探索,如果覺得項(xiàng)目還不錯,也歡迎給個 star~
往期推薦
