PenetrationTestingScripts/antSword/source/core/base.js

296 lines
9.1 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.

/**
* 中国蚁剑::核心模块::基础函数库
* 开写2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
const iconv = require('iconv-lite');
class Base {
/**
* 初始化
* @param {Object} opts 配置对象
* @return {Object} this
*/
constructor(opts) {
// 默认配置
opts['encode'] = opts['encode'] || 'utf8';
opts['encoder'] = opts['encoder'] || 'default';
this.__opts__ = opts;
this['__encoder__'] = {
/**
* 默认编码器
* @param {String} pwd 连接密码
* @param {Object} data 请求数据
* @return {Object} 生成数据
*/
default(pwd, data) {
data[pwd] = data['_'];
delete data['_'];
return data;
},
/**
* 随机编码器
* @param {String} pwd 连接密码
* @param {Object} data 请求数据
* @return {Object} 生成数据
*/
random(pwd, data) {
let _encoders = [];
for (let _ in this) {
if (_ === 'random') { continue }
_encoders.push(_);
}
let _index = parseInt(Math.random() * _encoders.length);
return this[
_encoders[_index]
](pwd, data);
}
}
// 解析自定义编码器
this.user_encoders.map((_)=>{
this.parseEncoder(`${_}`);
});
}
/**
* 返回参数列表
* @return {array} [arg1, arg2, arg3..]
*/
argv() {
// 生成一个随机的变量名
let random = () => `0x${(Math.random() + Math.random()).toString(16).substr(2)}`;
// 返回六个随机变量名数组
return [
random(), random(), random(),
random(), random(), random()
];
}
/**
* 字符串格式化处理
* 使用方法const format = new format()
* @param {String} encode [字符串编码默认utf8]
* @return {Object} [返回字符串处理函数对象]
*/
format(encode) {
return {
/**
* base64编码
* @param {String} str 字符串
* @return {String} 编码后的字符串
*/
base64(str) {
return new Buffer(
iconv.encode(new Buffer(str), encode)
).toString('base64');
},
/**
* 字符串转16进制不进行编码转换
* @param {String} str 转换的字符串
* @return {Buffer} 转换完成的buffer
*/
buffer(str) {
return new Buffer(str).toString('hex').toUpperCase();
},
/**
* 字符串转16进制进行编码转换
* @param {String} str 转换的字符串
* @return {Buffer} 转换完成的buffer
*/
hex(str) {
return new Buffer(
iconv.encode(new Buffer(str), encode)
).toString('hex').toUpperCase();
}
}
}
/**
* 解析脚本模板
* @param {String} tpl 模板文件
* @return {Object} 解析完毕的模板对象(参数`_`为主代码入口
*/
parseTemplate(tpl) {
// 把模板路径的`/`转换为`_`
let templateName = (tpl.split('template/')[1]).replace(/\//g, '_');
this[templateName] = {};
// 加载模板
let _argv = this.argv();
let templateObj = require(`${tpl}`)(
_argv[0], _argv[1], _argv[2],
_argv[3], _argv[4], _argv[5]
);
// let formatter = new this.format(this.__opts__['encode']);
let formatter = Base.prototype.format(this.__opts__['encode']);
// 解析模板
for (let funcName in templateObj) {
this[templateName][funcName] = (
(args) => {
if (typeof(args) === 'object') {
// 如果脚本函数需要参数,则进行解析
return (argv) => {
let data = {};
// 克隆源数据到返回数据中
for (let _ in args) {
data[_] = args[_];
}
// 循环替换脚本中的标签
for (let arg in args) {
(args[arg].match(/#{([\w\:]+)}/g) || []).map(
// example: #{hex::str} = hex(str), #{arg1} = arg1
(tag) => {
let tagStr = tag.substr(2, tag.length - 3);
let tagArr = tagStr.split('::');
let func, retStr;
if (
(tagArr.length > 0) &&
(func = formatter[tagArr[0]])
) {
// 如果包含有分割标签且该格式化函数存在,则调用该函数进行处理
retStr = func( argv[tagArr[1] || ''] );
} else {
// 否则替换直接返回字符串
retStr = argv[tagStr] || '';
}
// 组合最终生成模板代码
data[arg] = args[arg].replace(tag, retStr);
}
)
}
// 发送HTTP请求
return data;
}
} else {
// 否则直接返回
return () => ({ _: args });
}
}
)(templateObj[funcName]);
}
}
/**
* 解析编码器
* ? 编码器其实模板返回的脚本对象进行编码处理,主要就是把脚本模板中的`_`主变量改为用户传递的密码
* @param {String} enc 编码器文件
* @return {Object} 编码器处理函数对象
*/
parseEncoder(enc) {
// 加载编码器
// QAQ我也不知道为什么如果直接require变量名babel编译就会warningso我只好加个`咯~
this['__encoder__'][enc.split('encoder/')[1]] = require(`${enc}`);
}
/**
* 编码处理并返回操作
* @param {String} tag_s 前截断符
* @param {String} tag_e 后截断符
* @param {Object} data 源POST数据
* @return {Object} 最终生成数据// 将返回三个参数对象tag_s,tag_e,data
*/
encodeComplete(tag_s, tag_e, data) {
// 编码器处理
let finalData = this.__encoder__[this.__opts__['encoder']](
this.__opts__['pwd'],
data
);
return {
'tag_s': tag_s,
'tag_e': tag_e,
'data': finalData
};
}
/**
* HTTP请求函数
* ? 用法core.request(core.base.info()).then((ret) => {}).catch((e) => {})..
* @param {Object} code 请求源数据
* @param {Function} chunkCallBack 二进制流回调函数,可选
* @return {Promise} Promise操作对象
*/
request(code, chunkCallBack) {
const opt = this.complete(code);
return new Promise((res, rej) => {
// 随机ID(用于监听数据来源)
const hash = (String(+new Date) + String(Math.random())).substr(10, 10).replace('.', '_');
// 监听数据返回
antSword['ipcRenderer']
// 请求完毕返回数据{text,buff}
.once(`request-${hash}`, (event, ret) => {
return res({
'text': ret['text'],
'buff': ret['buff']
});
})
// HTTP请求返回字节流
.on(`request-chunk-${hash}`, (event, ret) => {
return chunkCallBack ? chunkCallBack(ret) : null;
})
// 数据请求错误
.once(`request-error-${hash}`, (event, ret) => {
return rej(ret);
})
// 发送请求数据
.send('request', {
url: this.__opts__['url'],
hash: hash,
data: opt['data'],
tag_s: opt['tag_s'],
tag_e: opt['tag_e'],
encode: this.__opts__['encode'],
ignoreHTTPS: (this.__opts__['otherConf'] || {})['ignore-https'] === 1,
timeout: parseInt((this.__opts__['otherConf'] || {})['request-timeout']),
headers: (this.__opts__['httpConf'] || {})['headers'] || {},
body: (this.__opts__['httpConf'] || {})['body'] || {}
});
})
}
/**
* 文件下载专用函数因有些文件过大导致Electron出错
* @param {String} savePath 保存文件路径
* @param {Object} postCode 提交数据
* @param {Function} progressCallback 进度回调
* @return {Promise} Promise操作对象
*/
download(savePath, postCode, progressCallback) {
const opt = this.complete(postCode);
return new Promise((ret, rej) => {
// 随机ID(用于监听数据来源)
const hash = (String(+new Date) + String(Math.random())).substr(10, 10).replace('.', '_');
// 监听数据返回
antSword['ipcRenderer']
// 请求完毕返回数据(size)
.once(`download-${hash}`, (event, size) => {
return ret(size);
})
// HTTP请求返回字节流大小
.on(`download-progress-${hash}`, (event, size) => {
return progressCallback ? progressCallback(size) : null;
})
// 数据请求错误
.once(`download-error-${hash}`, (event, ret) => {
throw new Error(ret);
})
// 发送请求数据
.send('download', {
url: this.__opts__['url'],
hash: hash,
path: savePath,
data: opt['data'],
tag_s: opt['tag_s'],
tag_e: opt['tag_e'],
encode: this.__opts__['encode']
});
})
}
}
// export default Base;
module.exports = Base;