Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vulnerability Report: cmswing 1.3.8 code execution #49

Open
jiguangsdf opened this issue Oct 10, 2019 · 1 comment
Open

Vulnerability Report: cmswing 1.3.8 code execution #49

jiguangsdf opened this issue Oct 10, 2019 · 1 comment

Comments

@jiguangsdf
Copy link

jiguangsdf commented Oct 10, 2019

Find a code execution vulnerability in cmswing project version 1.3.8,Details can be found in the analysis below.

The vulnerability lies in the log function in the cmswing/src/mode/action.js

async log(action, model, record_id, user_id, ip, url) {
    // action=action||null,model=model||null,record_id=record_id||null,user_id=user_id||null;
    // 参数检查
    if (think.isEmpty(action) || think.isEmpty(model) || think.isEmpty(record_id)) {
      return '参数不能为空';
    }

    if (think.isEmpty(user_id)) {
      const user = await think.session('userInfo');
      const id = user.id;
      user_id = id;
    }

    // 查询行为,判断是否执行

    const action_info = await this.where({name: action}).find();
    if (action_info.status != 1) {
      return '该行为被禁用';
    }

    // 插入行为日志

    const data = {
      action_id: action_info.id,
      user_id: user_id,
      action_ip: _ip2int(ip),
      model: model,
      record_id: record_id,
      create_time: new Date().valueOf()
    };
    data.remark = '';
    // 解析日志规则,生成日志备注;
    if (!think.isEmpty(action_info.log)) {
      const match = action_info.log.match(/\[(\S+?)\]/g);
      if (!think.isEmpty(match)) {
        const log = {
          user: user_id,
          record: record_id,
          model: model,
          time: new Date().valueOf(),
          data: {
            user: user_id,
            record: record_id,
            model: model,
            time: new Date().valueOf()
          }
        };

        const replace = [];
        for (let val of match) {
          val = val.replace(/(^\[)|(\]$)/g, '');
          const param = val.split('|');
          console.log(1111111,param);
          if (!think.isEmpty(param[1])) {
            if (param[0] == 'user') {
              replace.push(await call_user_func(param[1], log[param[0]]));
            } else {
              replace.push(call_user_func(param[1], log[param[0]]));
            }
          } else {
            replace.push(log[param[0]]);
          }
        }

        data.remark = str_replace(match, replace, action_info.log);
        // console.log(data.remark)
      } else {
        data.remark = action_info.log;
      }
    } else {
      // 未定义日志规则,记录操作URL
      data.remark = '操作url:' + url;
    }
    if (!think.isNumber(record_id)) {
      data.record_id = 0;
    }
    await this.model('action_log').add(data);

    if (!think.isEmpty(action_info.rule)) {
      const rules = await this.parse_action(action, user_id);
      // console.log(rules);
      const res = await this.execute_action(rules, action_info.id, user_id);
    }
  }
  
  ......
  
  global.call_user_func = function(cb, params) {
  const func = eval(cb);
  if (!think.isArray(params)) {
    params = [params];
  }
  return func.apply(cb, params);
};


The variable log is the user behavior log data transmitted by the front end. The function log implements the processing of the variable log. If the param[0]=='user', the call_user_func function is called. The variable is not checked. Malicious parameters will lead to the eval method of the call_user_fun function to implement code execution.

Local Test

Enter the background of the system, select user behavior,add our payload to the rules of conduct

8.png

Add an article to trigger the user behavior just now.

7.png

Execution Log, the code was successfully executed and the IP-related information was printed out

9.png

@xsser
Copy link

xsser commented Nov 7, 2019

6666

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants