本文讲述了作者在目标站点的JS脚本中发现了NPM_TOKEN和私有仓库链接,然后利用该NPM_TOKEN,结合.npmrc格式请求,访问到了目标站点相关的NPM项目私有仓库。漏洞获得了厂商$8000的奖励。

发现过程

最近,我选择了一个处理效率和支付奖励相对较高的漏洞测试项目,寄希望于能从其中发现一些高危漏洞。我先是在目标站点中尝试了模板注入(template injection),之后又测了一遍IDOR,都一无所获。于是,我就下载目标站点中的JS文件看看能否发现一些信息泄露问题。
首先,我用BURP Suite pro来把目标站点的JS文件提取下载为一个文件,这样的方式不算太直观友好,然后我又用以下脚本来把它们分隔成单独文件:
cat urls.txt | xargs -I{} wget "{}"
# Assuming urls are clean i.e. they don't have any extra parameters in the end
# if the url is like this : https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-cacheable-response.prod.js?v=123122
# Then you need to cut the part after '?' like the following
cat urls.txt | cut -d"?" -f1 | xargs -I{} wget "{}"
Tomnomnom的代码模式转化工具gf在此就派上用场了,使用gf加文件路径的方式,我从上述JS脚本中发现了一个泄露IP地址:http://172.x.x.x,在其上下文信息中我又找到了一个NPM_TOKEN值,但这个NPM_TOKEN怎么来利用呢?我有点不懂。平时很少用到NMP,只知道它是Node package manager。
经过一番研究,我对NPM_TOKEN值有了以下了解:
1、在一些持续集成的开发系统(Continuous Integration systems)中,如Jenkins pipelines或Travis CI等,会在自动化模式的Web应用开发部署中用到NPM_TOKEN值,用NPM_TOKEN可以访问到项目的一些NPM私有仓库(Npm private repository);
2、不同类型的NPM_TOKEN具备不同的权限,如有仅限读+发布的Read and publish only、只读的Readonly以及指定特定IP范围的CIDR白名单化等等;
3、用以下.npmrc格式来使用NPM_TOKEN:
registry=https://registry_link_here
//registry_link_here/:_authToken=auth_token_here
于是,我就尝试用以下 .npmrc格式来测试:
registry=https://registry.npmjs.org
//registry.npmjs.org/:_authToken=auth_token_here
测试第一天-在该利用方式中,如果NPM_TOKEN有效的话,执行npm whoami命令,会收到响应。但很可惜,没有任何响应。另外,有一些文章说 .npmrc格式中的NPM_TOKEN是加密串。
测试第二天-工作到家将近晚上8点了,我又继续测试这个NPM_TOKEN。我想到在年初我读了一些跨站WebSocket劫持(CSWH)的文章,Cross Site Websocket Hijacking,所以我结合其进行了一些分析。CSWH利用的条件是,websocket只使用cookie进行通信交流,这有点像跨站请求伪造(CSRF)攻击。在BURP练习中对CSWH也有所涉及:
接着,我想看看能不能在前述获得的JS脚本中发现一些websocket信息,但一无所获。之后,我从中发现了客户端请求时,服务端产生分配的一个nonce值,经测试发现可以用它实现CSRF攻击,就这样在寻找CSWH漏洞的过程中发现了CSRF漏洞。于是我进行了上报,在另外的博文中我会作讲解。
测试第三天-经过两小时的分析,我发现其中一个JS脚本文件有点意思,可以用以下三步操作使其代码规则化。Firefox下的代码规则化:
Chrome下的代码规则化:
该文件将近有17k数量的行数,大多是webpack类代码,经过仔细分析,在其中又发现了一个NPM_TOKEN值:
并且,在其附近还存在一个私有注册链接(private registry link):
我就想,那这个注册链接会不会是其私有仓库的链接呢,于是,我就加入了发现的NPM_TOKEN值,用下.npmrc方法进行了请求:
registry=https://private_registry_link_here
//private_registry_link_here/:_authToken=auth_token_here
执行npm whoami命令,竟然有了成功响应:srv-npm-registry-ci。
然后,我想列出它的所有NPM包信息,不行。于是,我在其JS文件中的打包信息中发现了一些私有仓库的线索,如以下这个:
因此,我用下述命令对其私有仓库进行了请求:
npm view private_repo
npm get private_repo
响应如下:
使用这种方法,我可以下载一些目标项目的私有仓库,从中发现了一些配置类JS脚本和大量的源代码。开发者在项目中明显未做权限设置。没有做深入测试,我就把漏洞上报了。漏洞在当天就被分类处理了,7天之后,我收到了$8000的奖励。

总结

1、可以从一些JS脚本文件中发现隐藏信息;
2、要学会使用浏览器的开发者工具,它们的功能超乎想像;
3、保持测试工具更新;
4、坚持不懈是关键。
参考来源:
 

本文作者:clouds, 转自FreeBuf