当前位置 博文首页 > R3col:发现Webpack中泄露的api

    R3col:发现Webpack中泄露的api

    作者:R3col 时间:2021-05-07 18:17

    发现Webpack中泄露的api

    目录
    • 发现Webpack中泄露的api
      • 1 - 安装 reverse-sourcemap
      • 2 - 寻找xxx.js.map
      • 3 - 下载xxx.js.map并获取所有webpack打包文件
      • 4 - 使用IDE/其他编辑器寻找接口
        • 4-1 搜索接口
          • 4-1-1 借鉴先验请求的url
          • 4-1-2 直接搜索
            • 4-1-2-1 根据请求方法搜索接口
            • 4-1-2-1 根据猜测命名规则搜索接口
      • 5 - 寻找动态定义的接口

    已在先知社区发表,转载请注明出处

    1 - 安装 reverse-sourcemap

    需要配置好npm环境 (runoob教程)

    使用命令(需要代理) npm install --global reverse-sourcemap 进行安装

    2 - 寻找xxx.js.map

    如果有sourcemap的话,在js最后会有注释:

    //# sourceMappingURL=xxxxxxx.js.map

    比如这里我要下载MarketSearch.js.mapMarketSearch.js是与站点同名的js,应该是主要的js文件)

    • 在开发者工具中搜索.js.map (位置1)
    • 找到MarketSearch.js.map所在的js (位置2)
    • 找到对应的链URL (位置3)
      • 一般来说,静态文件会挂载在当前域名下,但不排除其他站点挂载的情况,所以需要找到对应的URL,比如这里就不同站
      • 这里MarketSearch.jsURL记为http://xxx.xxx/mulu/MarketSearch.js

    3 - 下载xxx.js.map并获取所有webpack打包文件

    使用curl -O http://xxx.xxx/mulu/MarketSearch.js.map

    或者直接访问http://xxx.xxx/mulu/MarketSearch.js.map 下载MarketSearch.js.map

    使用命令reverse-sourcemap --output-dir ./MarketSearch MarketSearch.js.map即可获取所有webpack打包文件

    4 - 使用IDE/其他编辑器寻找接口

    我这里使用的是vs code

    直接使用全局搜索 左边侧边栏的搜索图标,或者ctrl+shift+f

    4-1 搜索接口

    搜索接口有两个方法:

    一个是借鉴先验请求的url,这种情况需要我们可以访问到某些接口,比如非SSO的登录

    另一个是直接搜索,这种情况大多是我们没法访问到当前站点的接口

    4-1-1 借鉴先验请求的url

    比如我们访问的站点xxx.xxx存在登录接口,通过尝试,发现会调用/MarketSearch/api/login接口

    那么我们可以通过不断删减来搜索接口/MarketSearch/api/login,/api/login,/login

    可以看到,当我们删减到/api/login的时候,就可以找到接口对应的代码

    这个接口是可以调用的,但是发现其定义的接口与实际访问的接口不同(第五部分解释,这里使用了动态定义的接口)

    4-1-2 直接搜索

    直接搜索有两种方法,根据请求方法,或者猜测命名规则进行搜索

    4-1-2-1 根据请求方法搜索接口

    接口大多是通过get/post方法进行访问的,所以这是一个很好的关键词

    通过请求方法,可以搜索到动态定义的接口(第五部分),避免找不到接口的问题。

    而且,如果存在请求方法重写的代码,通过请求方法搜索可以发现这些代码的定义。

    post

    get

    4-1-2-1 根据猜测命名规则搜索接口

    一般来说,admin,superadmin,manage之类的关键词比较常见

    此外,还可以根据站点名,可调用api命名规则,js命名规则进行搜索。这个站点没有这样的接口,就不举例了。

    5 - 寻找动态定义的接口

    刚好这个站点存在动态定义的接口(直接明文写在js代码中的静态接口相反):MarketSearch/api/login ,上面我们通过搜索,只发现了/MarketSearch/api/user/login接口,这里介绍一下如何寻找该接口。

    首先搜索login,可以看到在index.ts中对登录进行了定义

    查看index.ts,可以看到这里定义了用到的视图,继续跟踪Login视图,命名为Login_1,路径在./Login

    打开Login.tsx,可以看到根据vse_client_1.defaultMainView.Login视图,创建了对应的元素,vse_client_1定义为vse-client

    打开vse-client目录,寻找defaultMainView视图的定义

    跟踪Login视图,可以看到api_1路径在./api,且Login视图定义了游客登录用户登录两个登录方式,这里跟踪用户登录登录方法

    用户登录使用了LoginModal模态框

    跟踪LoginModal模态框,可以看到登录的行为通过yield api_1.api.login(input)来实现

    api_1 = ./apiinput则是ItemKey生成的表单中用户填写的数据(username & password

    跟踪api_1.api.login

    大致说一下这里的逻辑:

    • key是键值,比如这里调用的是api.login,则key === login

    • 对于每一个vse_share_1.Api定义的接口

    • 如果传入的key与其中一个接口相同,且不为constructor(通过prototype原型读取,所以需要排除构造函数),则向下继续

    • login传入__awaiter_

    • 通过axios_1.default.post(`/${NAMESPACE}/${vse_share_1.ShareConfig.apiPrefix}/${key}`, args)发起请求

      • ${NAMESPACE} === MarketSearch

        • 查看命名空间的定义

        • 跟踪../share

      • ${vse_share_1.ShareConfig.apiPrefix} === api

        • 跟踪vse-share,寻找ShareConfig

      • ${key} === login

      • args === input,即,由ItemKey生成的json{username:"xxx",password:"xxx"}

    这种情况下,通过拼接预定义参数和传入的api名称,动态生成url路径,避免了静态存储api路径,使得寻找api接口需要花费的精力大大提升。(web安全狗流泪)

    bk