/** * 中国蚁剑::编码器管理 * 创建:2017-05-30 * 更新:2018-08-19 * 作者:Virink * 作者:Medici.Yan */ const LANG = antSword['language']['settings']['encoders']; const LANG_T = antSword['language']['toastr']; const fs = require('fs'); const path = require('path'); const WIN = require("../../ui/window"); class Encoders { constructor(sidebar) { var that = this; this.encoders = antSword["encoders"]; sidebar.addItem({ id: 'encoders', text: ` ${LANG['title']}` }); that.cell = sidebar.cells('encoders'); const toolbar = that.cell.attachToolbar(); toolbar.loadStruct([ { type: 'buttonSelect', text: LANG['toolbar']['new'], icon: 'plus-circle', id: 'new', openAll: true, options: [ { id: 'new_asp', icon: 'file-code-o', type: 'button', text: "ASP" }, { id: 'new_aspx', icon: 'file-code-o', type: 'button', text: "ASPX"}, { id: 'new_php', icon: 'file-code-o', type: 'button', text: "PHP"}, { type: 'separator' }, { id: 'new_custom', icon: 'file-code-o', type: 'button', text: "Custom"} ]}, { type: 'separator' }, { type: 'button', text: LANG['toolbar']['edit'], icon: 'fa fa-edit', id: 'edit' }, { type: 'button', text: LANG['toolbar']['delete'], icon: 'fa fa-trash-o', id: 'delete' }, ]); toolbar.attachEvent("onClick", (id)=>{ switch(id) { case "new_asp": that.createEncoder("asp"); break; case "new_aspx": that.createEncoder("aspx"); break; case "new_php": that.createEncoder("php"); break; case "new_custom": that.createEncoder("custom"); break; case "edit": that.editEncoder(); break; case "delete": that.deleteEncoder(); break; } }); let grid = that.cell.attachGrid(); grid.setHeader(`  , ${LANG['grid']['ename']}, ${LANG['grid']['etype']} `); grid.setColTypes("ro,edtxt,coro"); grid.setColSorting('str,str,str'); grid.setInitWidths("40,*,150"); grid.setColAlign("center,left,center"); grid.enableMultiselect(true); var combobox = grid.getCombo(2); combobox.put("asp","ASP"); combobox.put("aspx","ASPX"); combobox.put("php","PHP"); combobox.put("custom","CUSTOM"); grid.attachEvent("onEditCell", function(stage,rId,cInd,nValue,oValue){ // 2 编辑完成 if(stage === 2) { nValue = nValue.toLocaleLowerCase(); oValue = oValue.toLocaleLowerCase(); if(nValue === oValue){return;} var oename = grid.getRowAttribute(rId, "ename"); var oepath = grid.getRowAttribute(rId, "epath"); var oetype = grid.getRowAttribute(rId, "etype"); oepath = oepath+".js"; switch(cInd){ case 1: // name if(!nValue.match(/^[a-zA-Z0-9_]+$/)){ toastr.error(LANG["message"]["ename_invalid"],LANG_T['error']); return } if(that._checkname(nValue, oetype)){ toastr.error(LANG['message']['ename_duplicate'], LANG_T['error']); return; } fs.renameSync(oepath, path.join(process.env.AS_WORKDIR, `antData/encoders/${oetype}/encoder/${nValue}.js`)); toastr.success(LANG['message']["rename_success"],LANG_T["success"]); break case 2: // type if(nValue != "asp" && nValue != "aspx" && nValue != "php" && nValue != "custom") { toastr.error(LANG['message']["etype_error"], LANG_T['error']); return } if(that._checkname(oename, nValue)){ toastr.error(LANG['message']['ename_duplicate'], LANG_T['error']); return; } fs.renameSync(oepath, path.join(process.env.AS_WORKDIR, `antData/encoders/${nValue}/encoder/${oename}.js`)); toastr.success(LANG['message']["retype_success"],LANG_T["success"]); break } that.syncencoders(); } }); grid.init(); that.grid = grid; that.parseData(); } // 创建新的编码器 createEncoder(t) { let self = this; layer.prompt({ value: `myencoder`, title: ` ${LANG["prompt"]["create_encoder"]}` },(value, i, e) => { value = value.toLocaleLowerCase(); if(!value.match(/^[a-zA-Z0-9_]+$/)){ toastr.error(LANG["message"]["ename_invalid"],LANG_T['error']); return } if(self._checkname(value, t)){ toastr.error(LANG["message"]["ename_duplicate"] ,LANG_T['error']); layer.close(i); return } let savePath= path.join(process.env.AS_WORKDIR,`antData/encoders/${t}/encoder/${value}.js`); fs.writeFileSync(savePath, self.default_template); var ids = self.grid.getAllRowIds(); let _id = 1; if(ids.length > 0){ _id = parseInt(ids[ids.length-1]); } _id ++; self.grid.addRow(_id, `${_id},${antSword.noxss(value)},${t}`); toastr.success(LANG["message"]["create_success"], LANG_T["success"]); self.cell.progressOff(); layer.close(i); self.syncencoders(); }); } // 编辑选中的编码器代码 editEncoder() { let self = this; // 获取选中ID列表 let ids = self.grid.getSelectedId(); if(!ids){ toastr.warning(LANG["message"]["edit_not_select"], LANG_T["warning"]); return } let _ids = ids.split(","); if (_ids.length !== 1) { toastr.warning(LANG["message"]["edit_only_single"], LANG_T["warning"]); return } let _id = _ids[0]; const ename = self.grid.getRowAttribute(_id, 'ename'); const epath = self.grid.getRowAttribute(_id, 'epath'); let buff = fs.readFileSync(epath+".js"); let opt = { title: `${LANG["edit_win_title"]}: ${ename}`, width: 800, height: 600, }; let _win = new WIN(opt); _win.win.centerOnScreen(); _win.win.button('minmax').show(); _win.win.button('minmax').enable(); // _win.win.maximize(); let toolbar = _win.win.attachToolbar(); toolbar.loadStruct([ { id: 'save', type: 'button', icon: 'save', text: LANG["toolbar"]['save'] }, { type: 'separator' }, ]); toolbar.attachEvent('onClick', (id) => { if (id === 'save') { // 保存代码 let saveData = editor.session.getValue(); if(!saveData){ toastr.warning(LANG["message"]["edit_null_value"],LANG_T["warning"]); return } fs.writeFileSync(epath+".js", saveData); toastr.success(LANG["message"]["edit_save_success"], LANG_T["success"]); } }); // 创建编辑器 let editor = ace.edit(_win.win.cell.lastChild); editor.$blockScrolling = Infinity; editor.setTheme('ace/theme/tomorrow'); editor.session.setMode(`ace/mode/javascript`); editor.session.setUseWrapMode(true); editor.session.setWrapLimitRange(null, null); editor.setOptions({ fontSize: '14px', enableBasicAutocompletion: true, enableSnippets: true, enableLiveAutocompletion: true }); // 编辑器快捷键 editor.commands.addCommand({ name: 'save', bindKey: { win: 'Ctrl-S', mac: 'Command-S' }, exec: () => { toolbar.callEvent('onClick', ['save']); } }); editor.session.setValue(buff.toString()); // 定时刷新 const inter = setInterval(editor.resize.bind(editor), 200); _win.win.attachEvent('onClose', () => { self.syncencoders(); clearInterval(inter); return true; }); } deleteEncoder() { let self = this; // 获取选中ID列表 let ids = self.grid.getSelectedId(); if(!ids){ toastr.warning(LANG["message"]["delete_not_select"], LANG_T["warning"]); return } let _ids = ids.split(","); layer.confirm(`${LANG['confirm']['delete'](_ids.length==1?self.grid.getRowAttribute(_ids[0],"ename"): _ids.length)}`, { icon: 2, shift: 6, title: ` ${LANG["delete_title"]}`, },(_)=>{ layer.close(_); _ids.map((_id)=>{ var ename = self.grid.getRowAttribute(_id, 'ename'); var epath = self.grid.getRowAttribute(_id, 'epath'); fs.unlink(epath+".js"); }); toastr.success(LANG["message"]["delete_success"], LANG_T["success"]); self.syncencoders(); }); } get default_template() { return `/** * php::base64编码器 * Create at: ${new Date().format("yyyy/MM/dd hh:mm:ss")} */ \'use strict\'; /* * @param {String} pwd 连接密码 * @param {Array} data 编码器处理前的 payload 数组 * @return {Array} data 编码器处理后的 payload 数组 */ module.exports = (pwd, data) => { // ########## 请在下方编写你自己的代码 ################### // 以下代码为 PHP Base64 样例 // 生成一个随机变量名 let randomID = \`_0x\${Math.random().toString(16).substr(2)}\`; // 原有的 payload 在 data['_']中 // 取出来之后,转为 base64 编码并放入 randomID key 下 data[randomID] = new Buffer(data['_']).toString('base64'); // shell 在接收到 payload 后,先处理 pwd 参数下的内容, data[pwd] = \`eval(base64_decode($_POST[\${randomID}]));\`; // ########## 请在上方编写你自己的代码 ################### // 删除 _ 原有的payload delete data['_']; // 返回编码器处理后的 payload 数组 return data; }`; } // 检查 name 是否重复 _checkname(name,t) { let tstr = ',' + antSword['encoders'][t].join(',')+','; return tstr.indexOf(","+name+",")!=-1; } // 解析数据 parseData() { let data = []; let self = this; let _id = 1; Object.keys(self.encoders).map((t) => { self.encoders[t].map( _ => { data.push({ id: _id, ename: _, epath: path.join(process.env.AS_WORKDIR, `antData/encoders/${t}/encoder/${_}`), etype: t, data: [ ``, antSword.noxss(_), t ] }); _id++; }); }); self.grid.clearAll(); self.grid.parse({ 'rows': data }, 'json'); } // 同步到全局编码器 syncencoders() { antSword['encoders'] = (function(){ var encoders = {asp:[],aspx:[],php:[],custom:[]}; var encoders_path = {asp:[],aspx:[],php:[],custom:[]}; let userencoder_path = path.join(process.env.AS_WORKDIR,'antData/encoders'); // 初始化 !fs.existsSync(userencoder_path) ? fs.mkdirSync(userencoder_path) : null; ['asp','aspx','php','custom'].map((t)=>{ !fs.existsSync(path.join(userencoder_path, `${t}`))? fs.mkdirSync(path.join(userencoder_path, `${t}`)):null; let t_path = path.join(userencoder_path, `${t}/encoder/`); !fs.existsSync(t_path) ? fs.mkdirSync(t_path) : null; let es = fs.readdirSync(t_path); if(es){ es.map((_)=>{ if(!_.endsWith(".js")){ return } encoders[t].push(_.slice(0,-3)); encoders_path[t].push(path.join(t_path, _.slice(0,-3))); }); } antSword["core"][t].prototype.user_encoders = encoders_path[t]; }); return encoders; })(); this.encoders=antSword["encoders"]; this.parseData(); } } module.exports = Encoders;