1. 程式人生 > 其它 >spring-data-redis 動態切換資料來源

spring-data-redis 動態切換資料來源

SQL注入

SQL注入是因為後臺SQL語句拼接了使用者的輸入,而且Web應用程式對使用者輸入資料的合法性沒有判斷和過濾,前端傳入後端的引數是攻擊者可控的,攻擊者可以通過構造不同的SQL語句來實現對資料庫的任意操作。比如查詢、刪除,增加,修改資料等等,如果資料庫的使用者許可權足夠大,還可以對作業系統執行操作。

SQL注入可以分為平臺層注入和程式碼層注入。前者由不安全的資料庫配置或資料庫平臺的漏洞所致;後者主要是由於程式設計師對輸入未進行細緻地過濾。SQL注入是針對資料庫、後臺、系統層面的攻擊!

mysql中註釋符:# 、/**/ 、 --

一、分類

  1. 依據注入點型別分類

    • 數字型別的注入

    • 字串型別的注入

    • 搜尋型注入

  2. 依據提交方式分類

    • GET注入

    • POST注入

    • COOKIE注入

    • HTTP注入(XFF注入、UA注入、REFERER注入)

      XFF:X-Forwarded-ForXFF)是用來識別通過HTTP代理負載均衡方式連線到Web伺服器的客戶端最原始的IP地址的HTTP請求頭欄位。

      UA:使用者代理(User Agent,簡稱 UA),是一個特殊字串頭,使得伺服器能夠識別客戶使用的作業系統及版本、CPU 型別、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器外掛等。

      REFERER:HTTP Referer是header的一部分,當瀏覽器向web伺服器傳送請求的時候,一般會帶上Referer,告訴伺服器該網頁是從哪個頁面連結過來的,伺服器因此可以獲得一些資訊用於處理。

  3. 依據獲取資訊的方式分類

    • 基於布林的盲注

    • 基於時間的盲注

    • 基於報錯的注入

    • 聯合查詢注入

    • 堆查詢注入(可同時執行多條語句)

二、判斷是否存在SQL注入

  1. 工具掃描:網站漏掃工具、AWVS、AppScan、OWASP-ZAP、Nessus等

  2. 手動測試:

    • 單雙引號、括號;進行組合測試,看是否報錯

    • 對於數字型:?id=3-1 ?id=2#

      如果顯示的是?id=2時的正常頁面,可判斷注入點是數字型注入;如果返回不正常,則可判斷非數字型注入

    • 對於字元型:?id=2a ?id=2'#

      Mysql 中,等號兩邊如果型別不一致,會發生強制型別轉換。當數字與字串進行比較時, 首先先將字串轉換成數字,然後再進行比較。

    • 對於布林盲注:

      盲注:就是在伺服器沒有錯誤回顯時完成的注入攻擊。伺服器沒有錯誤回顯,對於攻擊者來說缺少了非常重要的資訊,所以攻擊者必須找到一個方法來驗證注入的SQL語句是否得到了執行。

      ?id=1' and '1 ?id=1' and 'a

      這裡沒有使用註釋符號進行後面的單引號閉合,使用的是手工單引號閉合

      或者, ?id=1' and 1=1# ?id=1' and 1=2#

      兩者的頁面截然不同,一個正常回顯,一個沒有回顯的話,就可判斷是布林盲注。

    • 對於時間盲注:

      ?id=1' and sleep(3)#

      在MySQL中,有一個Benchmark() 函式,它是用於測試效能的。 Benchmark(count,expr) ,這個函式執行的結果,是將表示式 expr 執行 count 次 。

      因此,利用benchmark函式,可以讓同一個函式執行若干次,使得結果返回的時間比平時要 長,通過時間長短的變化,可以判斷注入語句是否執行成功。這是一種邊通道攻擊,這個技巧在 盲注中被稱為Timing Attack,也就是時間盲注。

  3. 常見SQL注入功能點

    只要是存在資料庫互動的地方都有可能出現 SQL 注入。

    常出現在 登入頁面、訂單頁面、文章或新聞展示頁面、修改密碼頁面(二次注入)、涉及獲 取 HTTP 頭(XFF等)的功能點等。

三、MySQL注入

  1. 必備

    1. 元資料庫 information_schema

      元資料庫 information_schema 中:

      存放資料庫資訊的表:schemata
      schemata 表中
      欄位 schema_name 存放所有資料庫名;

      存放表資訊的表:tables
      tables 表中
      欄位 table_name 存放所有表名
      欄位 table_schema 存放所有表所在的資料庫名;

      存放所有欄位資訊的表:columns
      columns 表中
      欄位 column_name 存放所有欄位名,
      欄位 table_name 存放所有欄位所在的表名,
      欄位 table_schema 存放所有欄位所在的資料庫名;
    2. 語句分類

      1.DQL(資料查詢語言):查詢語句,所有的 select 語句
      2.DML(資料操作語言):insert , delete , update , 對錶中的 資料 進行 增刪改
      3.DDL(資料定義語言):create , drop , alter 對錶 結構 增刪改
      4.TCL(事務控制語言):commit 提交資料,rollback 回滾資料 Transaction
      5.DCL(資料控制語言):grant 授權,revoke 撤銷許可權等
    3. 基本語句

      # 查庫:
      show databases;
      select schema_name from information_schema.schemata;
      # 建庫:
      create database + 庫名;
      # 刪庫:
      drop database + 庫名;
      # 進入資料庫:
      use + 庫名;
      # 查表:
      show tables;
      select table_name from information_schema.tables where table_schema='security'
      select table_name from information_schema.tables where table_schema=database
      # 查列:
      select * from users;
      select column_name from information_schema.columns where table_name='users'
      # 查欄位:
      select username,password from security.users;
    4. 基本函式

      #資料庫安裝、路徑,使用者 資訊
      version(); Mysql 資料庫版本
      database(); 當前 資料庫名
      user(); 資料庫的使用者名稱
      current_user(); 當前使用者名稱
      session_user(); 連線到資料庫的使用者名稱
      system_user(); 系統使用者名稱
      @@datadir(); 資料庫檔案的存放路徑
      @@version_compile_os; 作業系統版本
      @@basedir; 資料庫的安裝目錄
      #字串長度、擷取
      length(); 返回字串的長度
      substring(a,b,c); 擷取字串
      substr(a,b,c);
      mid(a,b,c);
      三個引數:a.擷取的字串 b.擷取的起始位置 c.長度
      left(a,b); 從左側擷取a的前b位,正確返回1,錯誤返回0
      #字串配對連線
      concat(a,0x5e,b); 字串配對連線
      concat_ws('~',A,B); 含有分隔符的連線字串
      group_concat(); 將字串連線為一個組,可將不同列分到同一行中
      #字串特殊處理
      ord(); 返回ASCII碼
      ascii('a'); 將字母 a 轉換為ascii值
      rand(); 返回0~1之間的隨機浮點數
      round(); 返回最近的整數值
      md5(); 返回MD5值
      hex(); 將字串轉換為十六進位制
      unhex(); hex()的反向操作
      floor(x); 返回不大於x的最大整數
      load_file(); 讀取檔案,返回檔案內容作為一個字串
      sleep(a); 沉睡a秒
      if(true,t,f); 判斷語句為true ,執行第一個,否則第二個
      find_in_set(); 返回字串在字串列表中的位置
      benchmark(); 指定語句執行的次數
      name_const(); 返回表作為結果
    5. 匯入資料

      當希望匯入一個 較大 的檔案或者是想要批量的執行sql語句時,可以使用 mysql 中的 source 使用方法:source + 檔案路徑(直接拖拽)

  2. 語句

    # insert
    insert into 表名(欄位名1,欄位名2,欄位名3......) values(值1,值2,值3......)
    # delete
    delete from 表名 where 條件;//可回滾
    對於大表:
    truncate table 表名;//不可回滾,將會永久丟失
    # update
    update 表名 set 欄位名1=值1,欄位名2=值2,......where 條件;
    # select
    select 欄位1,欄位2,...... from + 表名 where + 條件;
    # between and
    select * from users where id between 2 and 8;
    select * from users where id >=2 and id <=8;
    # in not in
    select password from users where id not in(5,8);
    指查找出 id不等於5 id不等於8 的使用者的密碼
    注:不是 5~8,in之後不是一個區間
    # like
    1.% 代表任意多個字元
    2._ 代表任意一個字元
    select username from users where username like '%b%';
    指查找出使用者名稱中帶有字母b的使用者名稱
    select username from users where username like '_a%';
    指查找出使用者名稱中帶第二個字母為a的使用者名稱
    select username from users where username like '%b';
    指查找出使用者名稱中帶最後一個字母為b的使用者名稱
    select username from users where username like '%\_%';
    指查找出使用者名稱中帶有下劃線_的使用者名稱
    注:特殊字元需要轉義
    # order by
    select username from users order by 欄位名;
    注:預設為升序排列
    指定升序:asc
    select username from users order by 欄位名 asc;
    指定降序:desc
    select username from users order by 欄位名 desc;
    雙重需求:
    select username from users order by 欄位名1 desc,欄位名2 asc;
    # 分組函式
    select sum(grade) from users;
    select avg(grade) from users;
    select max(grade) from users;
    select min(grade) from users;
    # 空處理函式
    select sum(ifnull(salary,0)*12), from crew;
    求一年的薪水之和,當薪水為NULL時,被當作0來處理
    # group by 與 having
    group by:按照某個欄位或某些欄位進行分組
    having:對分組之後的資料進行再次過濾,即having 必須跟在 group by 後面使用
    select max(grade) from students group by classes;
    先根據班級分組,再查出各個班級的成績最高學生的成績
    1.分組函式一般與 group by 聯合使用,並且任何一個分組函式(count,sum,avg,max,min)都是堆一組資料進行操作的
    2.當一條sql語句沒有 group by 時,整張表會自成一組
    3.當sql語句中使用group by時,select之後只能跟參與分組的欄位或者分組函式
    # distinct 去重
    distinct 關鍵字 去除重複記錄
    select distinct job from company;
    查詢該公司中的工作崗位
    # 語句執行順序
    select 5號:挑選出滿足條件的資料
    from 1號:定表
    where 2號:過濾原始資料
    group by 3號:進行分組
    having 4號:對資料進行再次過濾
    order by 6號:進行排序
    1.字串資料 sum,avg 0,max,min 按字母大小取
    2.分組函式會自動忽略 NULL
    3.數學運算 中如果有NULL參與,結果為定為NULL
    4.分組函式不能直接出現在 where 後面,原因是 group by 是在where語句執行結束之後執行的
    5.分組函式可組合使用
    # inner join
    select a.ename,b.dname from emp a join dept b on a.deptno=b.deptno;
    # left/right join
    select dname,ename from dept a left join emp b on a.deptno=b.deptno;

    or 語句:當前面語句不符合情況或者出現錯誤時執行or後面的內容