整合營銷服務(wù)商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          「運維」記錄一起網(wǎng)站劫持事件

          「運維」記錄一起網(wǎng)站劫持事件

          事很短,處理也簡單。權(quán)當(dāng)記錄一下,各位安全大大們手下留情。

          最近一位客戶遇到官網(wǎng)被劫持的情況,想我們幫忙解決一下(本來不關(guān)我們的事,畢竟情面在這...還是無償?shù)貐f(xié)助一下),經(jīng)過三四輪“謙讓”最終這個任務(wù)還是落到了我這個不精通安全的人的頭上()。

          客戶說通過百度跳轉(zhuǎn)官網(wǎng),首頁加載到一半時發(fā)生另一次跳轉(zhuǎn),跳到一個“賭球”網(wǎng)站去(歐洲杯最近大熱),但直接輸入域名就不會發(fā)生跳轉(zhuǎn)。

          我初步嘗試了一下,除了 PC 端有這種情況外,移動端也會觸發(fā)這種跳轉(zhuǎn)...首先不要被現(xiàn)象迷惑,從首頁能夠加載到一半的情況可知,這種惡意跳轉(zhuǎn)應(yīng)該是通過代碼觸發(fā)的。

          因為如果是在網(wǎng)絡(luò)層面又或者 Http Server 轉(zhuǎn)發(fā),根本就不會讓官網(wǎng)首頁出現(xiàn),因此排查的方向應(yīng)聚焦到代碼層面。

          其次,通過百度訪問會觸發(fā)惡意跳轉(zhuǎn),但域名訪問不會。這不禁讓我想到對方有可能是通過 Header 中的 Referer 進行來源判斷。于是我嘗試使用 bing 搜索引擎對官網(wǎng)進行訪問,結(jié)果證實了我的想法,在 bing 訪問是不會發(fā)生跳轉(zhuǎn)的。

          好了,既然是通過代碼跳轉(zhuǎn)的,那么它總要發(fā)生請求吧。究竟是從哪發(fā)生的請求呢?

          為了防止跳轉(zhuǎn)過快的情況,先在百度頁面中復(fù)制一個鏈接,打開一個新的窗口并且打開開發(fā)者模式,再將鏈接復(fù)制到瀏覽器進行訪問。如下圖:

          這時候就能夠?qū)⑹状卧L問的所有請求獲取到,并且在準(zhǔn)備發(fā)生自動跳轉(zhuǎn)之前你有足夠的時間來取消頁面請求,就能夠得到上圖的輸出。通過上圖的網(wǎng)絡(luò)輸出可知,其他都是正常的官網(wǎng)請求,唯獨 data.joysoo.xyz 是一個不知來路的域名。而且請求的 JavaScript 文件也足夠可疑,連名字都是經(jīng)過加密的樣子。

          嗯...在截獲了當(dāng)前的信息后,讓其跳轉(zhuǎn)看看還有什么網(wǎng)絡(luò)輸出,如下圖:

          噢,這個網(wǎng)站也嘗試加載 data.joysoo.xyz 的 DL1iBa6yb(這里與官網(wǎng)的 JavaScript 已經(jīng)不一樣了)。至此,從信息層面能夠通過 data.joysoo.xyz 域名可以將兩個網(wǎng)站的關(guān)聯(lián)串聯(lián)起來了,那么接下來就可通過這個域名進行代碼搜索。

          將客戶網(wǎng)站的 PHP 代碼放入 VSCode 中進行全局搜索。如下圖:

          這個域名恰巧只有一個 php 文件匹配成功。從這里也可以看出為什么無論從哪個頁面跳轉(zhuǎn)都會進行惡意跳轉(zhuǎn),因為這個腳本是直接植入到頁面的 ICP banner 模塊中的,而由于 ICP banner 每個頁面都內(nèi)嵌的,因此無論哪個頁面都會發(fā)生跳轉(zhuǎn)。

          那么這個腳本是從哪里植入的呢?

          從上圖可知,在 log 文件中也找到兩條與這個域名相關(guān)的記錄,如下圖:

          呃...這里有一條 update 語句將這個腳本寫入到數(shù)據(jù)庫里面,估計是被 SQL注入了吧。

          至此,整個解決思路也形成了。由于當(dāng)前的 PHP 框架會在網(wǎng)頁訪問時自動生成新的頁面,因此只需要重新更新數(shù)據(jù)庫內(nèi)容即可恢復(fù)。但是,這樣也只是治標(biāo)不治本,最最重要的還是加強對云服務(wù)器以及應(yīng)用的防護才是重中之重,不然問題還是會重新出現(xiàn)。

          菜鳥入門,各位大佬輕噴,如有謬誤之處歡迎討論建議,也歡迎各位道友與我同行

          "不積跬步,無以至千里;不積小流,無以成江海"

          繼續(xù)

          續(xù)接上篇文章,我們實現(xiàn)了一個簡單的登陸界面,但是我們的表單提示,例如用戶名等,是用的文字在按鈕上方提示的

          那我們?nèi)绾稳崿F(xiàn)一個提示框用于提示呢?然后再自動聚焦到輸入框中呢?

          提示框的實現(xiàn)

          // 是否顯示彈窗的標(biāo)識
          @State private var showAlert:Bool=false;
          
          // 在登陸按鈕之后放置彈窗
          Button("登陸"){
              // 切換要顯示Alert
              showAlert.toggle();
              // 省略一部分操作。。。
          }.alert(isPresented: $showAlert){ // 這里 isPresented 綁定 showAlert變量
              Alert(
                  title: Text("提示"), // 頂部的標(biāo)題
                  message: Text(res), // 彈窗的內(nèi)容,需要是一個Text,調(diào)用了我們之前定義的提示文本
                  primaryButton: .default(Text("取消")){// 第一個按鈕是默認類型樣式,顯示取消
                      // 第一個按鈕點擊后的操作
                  },
                  secondaryButton: .destructive(Text("確定")){
                  
                  }
              )
          }

          以上的代碼運行后得到如下結(jié)果

          在這里插入圖片描述

          focus 到TextField

          以上的彈出框提示已經(jīng)解決,那么接下來需要實現(xiàn)的是彈出之后哪一個字段沒填,就讓它自動聚焦,讓用戶可以直接填寫那個字段 添加如下的代碼

          // 是否聚焦到用戶名字段,注意@符號后面跟的是 FocusState,不然用到focused里面會報錯,并且不能設(shè)置默認值
          @FocusState private var focusUser:Bool;
          HStack{
              Text("用戶名")
              Spacer()
              TextField("請輸入用戶名",text:$userName)
                  .multilineTextAlignment(.center)
                  // 給用戶名字段的 focused 綁定 focusUser 變量
                  .focused($focusUser)
              }.padding(.all)
          }
          /// ... 省略部分代碼
          Button("登陸"){
              // 切換要顯示Alert
              showAlert.toggle();
              if(userName==""){
                  // 如果沒填 userName 那么切換 focusUser 的值
                  focusUser.toggle()
              }
              // 省略一部分操作。。。
          }
          // 。。。 省略Alert部分

          此處的代碼實現(xiàn)了,如果在點擊登陸按鈕后用戶名沒有填,自動聚焦到用戶名字段

          在本頁面中,共有三個字段,可以定義三個變量的形式來進行判定聚焦

          但是如果有很多個字段的話就不合適了,我們可以使用枚舉的方式來進行定義

          以下貼出本頁面完整的代碼

          import SwiftUI
          
          struct ContentView: View {
              // 用戶名
              @State private var userName:String="";
              // 密碼
              @State private var passWord:String="";
              // 驗證碼
              @State private var code:String="";
              // 提示語
              @State private var res:String="請輸入。。。";
              // 提示語的顏色,color類型
              @State private var color:Color=.red;
              
              // 是否顯示彈窗標(biāo)識
              @State private var showAlert:Bool=false;
              
              // 聚焦到哪一個字段?
              @FocusState private var focus:FocusField?;
              
              // 定義一個 Hashable 的枚舉,因為 focused 的第二個參數(shù)需要一個hashable的參數(shù)
              enum FocusField:Hashable{
                  case name;
                  case password;
                  case code;
                  case clear;
              };
              
              var body: some View {
                  // 整體縱向布局
                  VStack {
                      // 頁面標(biāo)題,加粗,標(biāo)題字體
                      Text("登陸界面").fontWeight(.bold).font(.title)
                      // 分隔占位,有點類似html中flex的flex:1,具體怎么用之后再看
                      Spacer()
                      // 一個橫向布局,表單項名稱-分隔占位-以及表單項
                      // 給一個 .all 的 padding,不然不好看
                      HStack{
                          Text("用戶名")
                          Spacer()
                          TextField("請輸入用戶名",text:$userName)
                              .multilineTextAlignment(.center)
                              // focused 綁定 focus變量,當(dāng)該變量為 .name 時
                              .focused($focus,equals: .name)
                      }.padding(.all)
                      
                      HStack{
                          Text("密碼")
                          Spacer()
                          // secure field 跟 TextField基本類似,只是隱藏輸入的內(nèi)容
                          SecureField("請輸入密碼",text:$passWord)
                              .multilineTextAlignment(.center)
                              .focused($focus, equals: .password)
                      }.padding(.all)
                      
                      HStack{
                          Text("驗證碼")
                          Spacer()
                          TextField("請輸入驗證碼",text:$code)
                              .multilineTextAlignment(.center)
                              .focused($focus, equals: .code)
                      }.padding(.all)
                      
                      Spacer()
                      // 提示語和button在一起
                      Text(res).foregroundColor(color)
                      
                      Button("登陸"){
                          showAlert.toggle();
                          color=.red
                          // button 的點擊事件action,做一個簡單的判斷
                          // 修改 res 的名稱,以及res的顏色
                          if(userName==""){
                              res="請輸入用戶名!";
                              return ;
                          }
                          if(passWord==""){
                              res="請輸入密碼!"
                              return ;
                          }
                          if(code==""){
                              res="請輸入驗證碼";
                              return ;
                          }
                          color=.green;
                          res="登陸成功"
                          // 清空表單數(shù)據(jù)
                          userName="";
                          passWord="";
                          code="";
                      }.buttonStyle(.bordered)
                      .alert(isPresented: $showAlert){
                          Alert(
                              title: Text("提示"),
                              message: Text(res),
                              primaryButton: .default(Text("取消")),
                              secondaryButton: .destructive(Text("確定")){
                                  if(res=="請輸入用戶名!"){
                                      // 沒有用戶名
                                      focus=.name
                                  }
                                  if(res=="請輸入密碼!"){
                                      focus=.password
                                  }
                                  if(res=="請輸入驗證碼!"){
                                      focus=.code
                                  }
                                  if(res=="登陸成功" || res=="請輸入。。。"){
                                      focus=.clear
                                  }
                              }
                          )
                      }
                  }
                  .padding()
              }
          }
          struct ContentView_Previews: PreviewProvider {
              static var previews: some View {
                  ContentView()
              }
          }

          運行得到以下的結(jié)果

          在這里插入圖片描述

          總結(jié)

          1. TextField 的 .focused($focus, .name) 使用
          2. enum 的基本使用
          3. Alert 的基本使用

          門的HTML - tabindex 的作用

          HTML 的 tabindex 屬性開發(fā)過程中一般不會使用到,最近開發(fā)中有個需求兼顧富交互,便總結(jié)了一下。本篇文章同時收錄在我的【前端知識點】中,Github鏈接請點擊閱讀原文直達,歡迎 Star

          兼容性:Safari不支持!

          閱讀本文您將收獲

          • tabindex的作用
          • tabindex的使用
          • 如何利用 tabindex 創(chuàng)造更好的用戶體驗

          前言

          在我們?nèi)粘J褂镁W(wǎng)頁的過程中,可以通過鍵盤控制一些元素的聚焦,從而達到便捷訪問的目的

          element 分為 focusable 和 非focusable ,如果使用了tabindex就可以改變相關(guān)的行為

          在HTML中有6個元素默認支持聚焦:

          • 帶 href 屬性的 <a> 標(biāo)簽
          • 帶 href 屬性的 <link> 標(biāo)簽
          • <button></button> 標(biāo)簽
          • <input /> 標(biāo)簽 (排除帶有 type="hidden" 屬性的)
          • <select></select> 標(biāo)簽
          • <textarea></textarea> 標(biāo)簽

          以上的元素默認都可以使用 Tab 鍵,以及 JS focus() 方法聚焦

          document.querySelector("a").focus();

          使用 tab鍵 進行聚焦元素時,聚焦的順序等于元素在代碼中的出現(xiàn)先后順序,當(dāng)我們進行富交互優(yōu)化時,就需要用到 tabindex 這個屬性來幫助我們進行更好用戶體驗的優(yōu)化了

          tabindex的作用

          ①元素是否能聚焦:通過鍵盤這類輸入設(shè)備,或者通過 JS focus() 方法

          ②元素什么時候能聚焦:在用戶通過鍵盤與頁面交互時

          通俗來說:就是當(dāng)用戶使用鍵盤時,tabindex用來定位html元素,即使用tab鍵時焦點的順序。

          tabindex的范圍

          tabindex理論上可以使用在幾乎所有元素上

          • tabindex 理論上可以用在幾乎所有元素上,不管這個元素默認是否支持聚焦

          tabindex 有三個值:0,-N(通常是-1),N(正值)

          • tabindex=0,該元素可以用tab鍵獲取焦點
            • 且訪問的順序是按照元素在文檔中的順序來focus,即使采用了浮動改變了頁面中顯示的順序,依然是按照html文檔中的順序來定位
          • tabindex<=-1,該元素用tab鍵獲取不到焦點,但是可以通過js獲取
            • 這樣就便于我們通過js設(shè)置上下左右鍵的響應(yīng)事件來focus
            • 取值 -1~-999 之間沒有區(qū)別,但為了可讀性和一致性考慮,推薦使用 -1
          • tabindex>=1,該元素可以用tab鍵獲取焦點,而且優(yōu)先級大于tabindex=0
            • 不過在tabindex>=1時,數(shù)字越小,越先定位到;
            • 如果多個元素擁有相同的 tabindex ,他們的相對順序按照他們在當(dāng)前DOM中的先后順序決定

          tabindex的使用

          tabindex 決定聚焦順序

          • 可聚焦元素中,正整數(shù)數(shù)值越大,順序越往后,正整數(shù)數(shù)值的節(jié)點順序比0值的節(jié)點靠前
          • 代碼:
          // HTML
          <button type="button" tabindex="1">tabindex === 1</button>
          <button type="button" tabindex="999">tabindex === 999</button>
          <button type="button" tabindex="0">tabindex === 0</button>
          • 效果:
          • 可聚焦元素中,相同 tabindex 數(shù)值的節(jié)點,根據(jù) DOM節(jié)點 先后順序決定聚焦順序
          • 代碼:
          // HTML
          <button type="button" tabindex="0">tabindex === 0</button>
          <button type="button" tabindex="1">tabindex === 1</button>
          <button type="button" tabindex="999">tabindex === 999</button>
          <button type="button" tabindex="0">tabindex === 0</button>
          • 效果:

          tabindex 決定是否聚焦

          • 節(jié)點的 tabindex 設(shè)置為 -1 時,當(dāng)前節(jié)點使用 tab鍵 不能聚焦
          • 代碼:
          // HTML
          <button type="button">未設(shè)置tabindex</button>
          <button type="button" tabindex="-1">tabindex === -1</button>
          <button type="button" tabindex="0">tabindex === 0</button>
          <button type="button" tabindex="1">tabindex === 1</button>
          • 效果:

          tabindex 與JS編程聚焦

          • 通過 tabindex 結(jié)合JS可以讓默認不支持聚焦的節(jié)點進行聚焦,tabindex 為不超出范圍的任何整數(shù)值都可以
          • 代碼:
          // HTML
          <button type="button" @click="clickBtn()">點擊讓DIV聚焦</button>
          <div id="FocusDiv" ref="FocusDiv" tabindex="-1">這是一個div</div>
          
          // JS
          clickBtn: function() {
              document.getElementById('FocusDiv').focus();
          }
          • 效果:

          如何利用 tabindex 創(chuàng)造更好的用戶體驗

          針對自定義標(biāo)簽進行富交互優(yōu)化

          • 我們在創(chuàng)建一個自定義的標(biāo)簽時,如果默認行為中不包含聚焦事件,我們可以使用 tabindex 為它增加聚焦功能,從而可以像很多可聚焦節(jié)點一樣進行順次焦點聚焦了

          針對特定節(jié)點禁止聚焦操作

          • 某些浮層及上層節(jié)點,如 toast組件、模態(tài)框、側(cè)邊彈出信息等,我們不希望節(jié)點被用戶聚焦捕獲,可以將節(jié)點的 tabindex 設(shè)置為 -1,就能避免這一問題

          復(fù)雜列表控制聚焦順序

          • 一些復(fù)雜的樹形結(jié)構(gòu)或者列式結(jié)構(gòu),如果需要用戶操作順序按照我們預(yù)想的書序進行聚焦,可以利用tabindex 值的大小來進行處理。

          主站蜘蛛池模板: 91大神在线精品视频一区| 国产品无码一区二区三区在线蜜桃| 日韩高清国产一区在线| 中文字幕人妻第一区| 国产伦理一区二区| 无码日韩AV一区二区三区| 日本内射精品一区二区视频| 动漫精品一区二区三区3d| 乱精品一区字幕二区| 色窝窝无码一区二区三区成人网站 | 国产伦精品一区二区三区精品 | 一级特黄性色生活片一区二区| 亚洲熟女综合一区二区三区| 亚洲AV网一区二区三区| 人妻内射一区二区在线视频| 午夜视频在线观看一区二区| 国产成人精品一区二区三在线观看| 国产激情一区二区三区| 亚洲无线码在线一区观看| 久久久精品人妻一区二区三区 | 久久精品国产免费一区| 亚洲av无码一区二区三区乱子伦| 日韩精品无码一区二区三区| 亚洲中文字幕一区精品自拍| 国产一区二区精品在线观看| 国产亚洲一区二区精品| 精品国产免费观看一区| 性色AV 一区二区三区| 无码中文字幕乱码一区| 国产一区二区三区免费| 亚洲国产欧美国产综合一区| 国产亚洲一区二区三区在线观看| 国产麻豆精品一区二区三区| 国产福利电影一区二区三区久久久久成人精品综合 | 国产成人久久精品区一区二区 | 91视频一区二区| 变态调教一区二区三区| 久久精品成人一区二区三区| 狠狠做深爱婷婷综合一区| 男人的天堂av亚洲一区2区| 99久久精品费精品国产一区二区|