PenetrationTestingScripts/antSword/source/modules/settings/encoders.js

374 lines
11 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* 中国蚁剑::编码器管理
* 创建2017-05-30
* 更新2018-08-19
* 作者Virink <virink@outlook.com>
* 作者Medici.Yan <Medici.Yan@gmail.com>
*/
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: `<i class="fa fa-file-code-o"></i> ${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(`
&nbsp;,
${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: `<i class="fa fa-file-code-o"></i> ${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: `<i class="fa fa-trash"></i> ${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: [
`<i class="fa fa-file-code-o"></i>`,
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;