restructure internal shellcode structure
This commit is contained in:
parent
588aae09e9
commit
6828dd7bae
9 changed files with 116 additions and 74 deletions
|
|
@ -4,16 +4,11 @@
|
|||
#include "struc.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
typedef struct debashify_params {
|
||||
bool need_random_string=false;
|
||||
bool need_random_tmpfile=false;
|
||||
bool need_array_create=false;
|
||||
bool need_array_set=false;
|
||||
bool need_array_get=false;
|
||||
bool need_map_create=false;
|
||||
bool need_map_set=false;
|
||||
bool need_map_get=false;
|
||||
std::set<std::string> required_fcts;
|
||||
void require_fct(std::string const& in) { required_fcts.insert(in); }
|
||||
// map of detected arrays
|
||||
// bool value: is associative
|
||||
std::map<std::string,bool> arrays;
|
||||
|
|
@ -21,7 +16,7 @@ typedef struct debashify_params {
|
|||
|
||||
bool r_debashify(_obj* o, debashify_params* params);
|
||||
|
||||
void debashify(_obj* o, debashify_params* params);
|
||||
void debashify(shmain* sh);
|
||||
std::set<std::string> debashify(_obj* o, debashify_params* params);
|
||||
std::set<std::string> debashify(shmain* sh);
|
||||
|
||||
#endif //DEBASHIFY_HPP
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "struc.hpp"
|
||||
|
||||
// constants
|
||||
#define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG", "LC_.*", "LANG", "TERM", "RANDOM"
|
||||
#define RESERVED_VARIABLES "HOME", "PATH", "SHELL", "PWD", "OPTIND", "OPTARG", "LC_.*", "LANG", "TERM", "RANDOM", "TMPDIR"
|
||||
|
||||
// types
|
||||
typedef std::map<std::string,uint32_t> countmap_t;
|
||||
|
|
@ -73,7 +73,7 @@ bool r_delete_var(_obj* in, set_t* vars);
|
|||
|
||||
/** Processing **/
|
||||
|
||||
void insert_lxsh_commands(shmain* sh);
|
||||
std::set<std::string> find_lxsh_commands(shmain* sh);
|
||||
void add_unset_variables(shmain* sh, std::regex const& exclude);
|
||||
|
||||
#endif //PROCESSING_HPP
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
#ifndef SHELLCODE_HPP
|
||||
#define SHELLCODE_HPP
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "struc.hpp"
|
||||
|
||||
struct lxsh_fct {
|
||||
std::string arguments;
|
||||
std::string description;
|
||||
const char* code;
|
||||
std::vector<std::string> depends_on=std::vector<std::string>();
|
||||
};
|
||||
|
||||
extern const std::map<const std::string, const struct lxsh_fct> lxsh_shellcode_fcts;
|
||||
extern const std::map<const std::string, const struct lxsh_fct> lxsh_extend_fcts;
|
||||
extern const std::map<const std::string, const struct lxsh_fct> lxsh_array_fcts;
|
||||
extern const std::map<const std::string, const struct lxsh_fct> lxsh_allfcts;
|
||||
|
||||
void add_lxsh_fcts(shmain* sh, std::set<std::string> fcts);
|
||||
|
||||
#endif //SHELLCODE_HPP
|
||||
|
|
|
|||
|
|
@ -341,12 +341,12 @@ subshell_arithmetic* do_debashify_arithmetic(arithmetic* in, debashify_params* p
|
|||
if(params->arrays[varname])
|
||||
{
|
||||
c = make_cmd_varindex("_lxsh_map_get", varname, index);
|
||||
params->need_map_get=true;
|
||||
params->require_fct("_lxsh_map_get");
|
||||
}
|
||||
else
|
||||
{
|
||||
c = make_cmd_varindex("_lxsh_array_get", varname, index);
|
||||
params->need_array_get=true;
|
||||
params->require_fct("_lxsh_array_get");
|
||||
}
|
||||
|
||||
ret = new subshell_arithmetic(new subshell(c));
|
||||
|
|
@ -430,12 +430,12 @@ bool debashify_array_get(arg* in, debashify_params* params)
|
|||
if(params->arrays[varname])
|
||||
{
|
||||
c = make_cmd_varindex("_lxsh_map_get", varname, index);
|
||||
params->need_map_get=true;
|
||||
params->require_fct("_lxsh_map_get");
|
||||
}
|
||||
else
|
||||
{
|
||||
c = make_cmd_varindex("_lxsh_array_get", varname, index);
|
||||
params->need_array_get=true;
|
||||
params->require_fct("_lxsh_array_get");
|
||||
}
|
||||
|
||||
subshell_subarg* sb = new subshell_subarg(new subshell(c));
|
||||
|
|
@ -469,12 +469,12 @@ bool debashify_array_set(cmd* in, debashify_params* params)
|
|||
if(params->arrays[varname])
|
||||
{
|
||||
c->args->insert(0, new arg("_lxsh_map_create") );
|
||||
params->need_map_create=true;
|
||||
params->require_fct("_lxsh_map_create");
|
||||
}
|
||||
else
|
||||
{
|
||||
c->args->insert(0, new arg("_lxsh_array_create") );
|
||||
params->need_array_create=true;
|
||||
params->require_fct("_lxsh_array_create");
|
||||
}
|
||||
subshell_subarg* sb = new subshell_subarg(new subshell(c));
|
||||
// insert new value
|
||||
|
|
@ -486,7 +486,6 @@ bool debashify_array_set(cmd* in, debashify_params* params)
|
|||
else if(it->first != nullptr && it->first->index != nullptr)
|
||||
{
|
||||
// array value set: VAR[]=
|
||||
params->need_array_set=true;
|
||||
force_quotes(it->second);
|
||||
force_quotes(it->first->index);
|
||||
string_subarg* tt=dynamic_cast<string_subarg*>(it->second->sa[0]);
|
||||
|
|
@ -507,12 +506,12 @@ bool debashify_array_set(cmd* in, debashify_params* params)
|
|||
if(params->arrays[varname])
|
||||
{
|
||||
c = make_cmd_varindex("_lxsh_map_get", varname, copy(index));
|
||||
params->need_map_get=true;
|
||||
params->require_fct("_lxsh_map_get");
|
||||
}
|
||||
else
|
||||
{
|
||||
c = make_cmd_varindex("_lxsh_array_get", varname, copy(index));
|
||||
params->need_array_get=true;
|
||||
params->require_fct("_lxsh_array_get");
|
||||
}
|
||||
subshell_subarg* sb = new subshell_subarg(new subshell(c));
|
||||
sb->quoted=true;
|
||||
|
|
@ -528,12 +527,12 @@ bool debashify_array_set(cmd* in, debashify_params* params)
|
|||
if(params->arrays[varname])
|
||||
{
|
||||
c->args->add(new arg("_lxsh_map_set") );
|
||||
params->need_map_set=true;
|
||||
params->require_fct("_lxsh_map_set");
|
||||
}
|
||||
else
|
||||
{
|
||||
c->args->add(new arg("_lxsh_array_set") );
|
||||
params->need_array_set=true;
|
||||
params->require_fct("_lxsh_array_set");
|
||||
}
|
||||
// _lxsh_array_set "$VAR"
|
||||
c->args->add( make_arg("\"$"+varname+"\"") );
|
||||
|
|
@ -552,7 +551,6 @@ bool debashify_array_set(cmd* in, debashify_params* params)
|
|||
{
|
||||
// array add: VAR+=()
|
||||
// can be done by creating a new array with old array + new
|
||||
params->need_array_create=true;
|
||||
|
||||
std::string varname = it->first->varname;
|
||||
|
||||
|
|
@ -571,7 +569,7 @@ bool debashify_array_set(cmd* in, debashify_params* params)
|
|||
else
|
||||
{
|
||||
c->args->insert(0, new arg("_lxsh_array_create") );
|
||||
params->need_array_create=true;
|
||||
params->require_fct("_lxsh_array_create");
|
||||
}
|
||||
// second arg is varname
|
||||
c->args->insert(1, make_arg("\"$"+varname+"\"") );
|
||||
|
|
@ -703,7 +701,7 @@ bool debashify_procsub(list* lst, debashify_params* params)
|
|||
// perform the replace
|
||||
if(affected_args.size()>0)
|
||||
{
|
||||
params->need_random_tmpfile = true;
|
||||
params->require_fct("_lxsh_random_tmpfile");
|
||||
has_replaced=true;
|
||||
list* lst_insert = new list;
|
||||
std::string mkfifocmd="mkfifo";
|
||||
|
|
@ -755,6 +753,8 @@ bool debashify_var(variable* in, debashify_params* params)
|
|||
{
|
||||
if(in->is_manip && in->precedence && in->manip->string() == "!")
|
||||
throw std::runtime_error("Cannot debashify ${!VAR}");
|
||||
if(in->varname == "RANDOM")
|
||||
throw std::runtime_error("Cannot debashify $RANDOM");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -827,31 +827,18 @@ bool r_debashify(_obj* o, debashify_params* params)
|
|||
return true;
|
||||
}
|
||||
|
||||
void debashify(_obj* o, debashify_params* params)
|
||||
// return value: dependencies
|
||||
std::set<std::string> debashify(_obj* o, debashify_params* params)
|
||||
{
|
||||
recurse(r_debashify, o, params);
|
||||
return params->required_fcts;
|
||||
}
|
||||
|
||||
//
|
||||
void debashify(shmain* sh)
|
||||
// return value: dependencies
|
||||
std::set<std::string> debashify(shmain* sh)
|
||||
{
|
||||
debashify_params params;
|
||||
sh->shebang = "#!/bin/sh";
|
||||
recurse(r_debashify, sh, ¶ms);
|
||||
if(params.need_random_string || params.need_random_tmpfile)
|
||||
sh->lst->insert(0, new condlist(make_block(RANDOM_TMPFILE_SH)));
|
||||
if(params.need_random_tmpfile)
|
||||
sh->lst->insert(0, new condlist(make_block(RANDOM_STRING_SH)));
|
||||
if(params.need_array_create)
|
||||
sh->lst->insert(0, new condlist(make_block(ARRAY_CREATE_SH)));
|
||||
if(params.need_array_set)
|
||||
sh->lst->insert(0, new condlist(make_block(ARRAY_SET_SH)));
|
||||
if(params.need_array_get)
|
||||
sh->lst->insert(0, new condlist(make_block(ARRAY_GET_SH)));
|
||||
if(params.need_map_create)
|
||||
sh->lst->insert(0, new condlist(make_block(MAP_CREATE_SH)));
|
||||
if(params.need_map_set)
|
||||
sh->lst->insert(0, new condlist(make_block(MAP_SET_SH)));
|
||||
if(params.need_map_get)
|
||||
sh->lst->insert(0, new condlist(make_block(MAP_GET_SH)));
|
||||
return params.required_fcts;
|
||||
}
|
||||
|
|
|
|||
13
src/exec.cpp
13
src/exec.cpp
|
|
@ -13,6 +13,7 @@
|
|||
#include "debashify.hpp"
|
||||
#include "resolve.hpp"
|
||||
#include "recursive.hpp"
|
||||
#include "shellcode.hpp"
|
||||
|
||||
#define PIPE_READ 0
|
||||
#define PIPE_WRITE 1
|
||||
|
|
@ -262,15 +263,11 @@ int exec_process(std::string const& runtime, std::vector<std::string> const& arg
|
|||
ffd = fopen(fifopath.c_str(), "w");
|
||||
if(options["debashify"])
|
||||
{
|
||||
fprintf(ffd, "%s\n", ARRAY_CREATE_SH);
|
||||
fprintf(ffd, "%s\n", ARRAY_GET_SH);
|
||||
fprintf(ffd, "%s\n", ARRAY_SET_SH);
|
||||
fprintf(ffd, "%s\n", MAP_CREATE_SH);
|
||||
fprintf(ffd, "%s\n", MAP_GET_SH);
|
||||
fprintf(ffd, "%s\n", MAP_SET_SH);
|
||||
fprintf(ffd, "%s\n", RANDOM_STRING_SH);
|
||||
fprintf(ffd, "%s\n", RANDOM_TMPFILE_SH);
|
||||
for(auto it: lxsh_array_fcts)
|
||||
fprintf(ffd, "%s\n", it.second.code);
|
||||
}
|
||||
for(auto it: lxsh_extend_fcts)
|
||||
fprintf(ffd, "%s\n", it.second.code);
|
||||
parse_exec(ffd, filecontents, file);
|
||||
}
|
||||
catch(std::runtime_error& e)
|
||||
|
|
|
|||
24
src/main.cpp
24
src/main.cpp
|
|
@ -17,6 +17,7 @@
|
|||
#include "processing.hpp"
|
||||
#include "debashify.hpp"
|
||||
#include "exec.hpp"
|
||||
#include "shellcode.hpp"
|
||||
|
||||
#include "version.h"
|
||||
#include "g_version.h"
|
||||
|
|
@ -115,9 +116,9 @@ int main(int argc, char* argv[])
|
|||
bool first_run = true;
|
||||
|
||||
// do parsing
|
||||
bool shebang_is_bin=false;
|
||||
for(uint32_t i=0 ; i<args.size() ; i++)
|
||||
{
|
||||
bool shebang_is_bin=false;
|
||||
std::string file = args[i];
|
||||
std::string filecontents=import_file(file);
|
||||
std::string shebang=filecontents.substr(0,filecontents.find('\n'));
|
||||
|
|
@ -173,12 +174,12 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
tsh = parse_text(filecontents, file);
|
||||
if(shebang_is_bin) // resolve lxsh shebang to sh
|
||||
tsh->shebang="#!/bin/sh";
|
||||
tsh->shebang="#!/bin/sh";
|
||||
|
||||
/* mid processing */
|
||||
// resolve/include
|
||||
if(g_include || g_resolve)
|
||||
resolve(tsh);
|
||||
resolve(tsh);
|
||||
|
||||
// concatenate to main
|
||||
sh->concat(tsh);
|
||||
|
|
@ -187,6 +188,10 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
} // end of argument parse
|
||||
|
||||
// pre-listing modifiers
|
||||
if(options["remove-unused"])
|
||||
delete_unused( sh, re_var_exclude, re_fct_exclude );
|
||||
|
||||
// list outputs
|
||||
if(options["list-var"])
|
||||
list_vars(sh, re_var_exclude);
|
||||
|
|
@ -205,17 +210,20 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
else
|
||||
{
|
||||
// modifiers
|
||||
insert_lxsh_commands(sh);
|
||||
// post-listing modifiers
|
||||
// implement commands
|
||||
std::set<std::string> req_fcts;
|
||||
if(shebang_is_bin)
|
||||
req_fcts = find_lxsh_commands(sh);
|
||||
if(options["debashify"])
|
||||
debashify(sh);
|
||||
concat_sets(req_fcts, debashify(sh) );
|
||||
|
||||
add_lxsh_fcts(sh, req_fcts);
|
||||
|
||||
// processing before output
|
||||
// minify
|
||||
if(options['m'])
|
||||
opt_minify=true;
|
||||
if(options["remove-unused"])
|
||||
delete_unused( sh, re_var_exclude, re_fct_exclude );
|
||||
if(options["minify-quotes"])
|
||||
minify_quotes(sh);
|
||||
if(options["minify-var"])
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ ztd::option_set gen_options()
|
|||
ztd::option('J', "json", false, "Output the json structure"),
|
||||
ztd::option("\r [Processing]"),
|
||||
ztd::option('m', "minify", false, "Minify code without changing functionality"),
|
||||
ztd::option('M', "minify-full", false, "Enable all minifying features: -m --minify-quotes --minify-var --minify-fct --remove-unused"),
|
||||
ztd::option("minify-quotes", false, "Remove unnecessary quotes"),
|
||||
ztd::option('C', "no-cd", false, "Don't cd when doing %include and %resolve"),
|
||||
ztd::option('I', "no-include", false, "Don't resolve %include commands"),
|
||||
|
|
@ -62,6 +63,14 @@ void get_opts()
|
|||
re_var_exclude=var_exclude_regex("", !options["no-exclude-reserved"]);
|
||||
if(options["exclude-fct"])
|
||||
re_fct_exclude=fct_exclude_regex(options["exclude-fct"]);
|
||||
if(options['M'])
|
||||
{
|
||||
options['m'].activated=true;
|
||||
options["minify-var"].activated=true;
|
||||
options["minify-fct"].activated=true;
|
||||
options["minify-quotes"].activated=true;
|
||||
options["remove-unused"].activated=true;
|
||||
}
|
||||
}
|
||||
|
||||
ztd::option_set create_include_opts()
|
||||
|
|
@ -126,7 +135,7 @@ void print_resolve_help()
|
|||
|
||||
void print_lxsh_cmd_help()
|
||||
{
|
||||
for(auto it: lxsh_shellcode_fcts)
|
||||
for(auto it: lxsh_extend_fcts)
|
||||
{
|
||||
printf("%s %s\n%s\n\n", it.first.c_str(), it.second.arguments.c_str(), it.second.description.c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -401,20 +401,18 @@ bool r_delete_var(_obj* in, set_t* vars)
|
|||
return true;
|
||||
}
|
||||
|
||||
void insert_lxsh_commands(shmain* sh)
|
||||
std::set<std::string> find_lxsh_commands(shmain* sh)
|
||||
{
|
||||
std::set<std::string> ret;
|
||||
cmdmap_get(sh, regex_null);
|
||||
bool req_rescan=false;
|
||||
for(auto it: lxsh_shellcode_fcts)
|
||||
for(auto it: lxsh_extend_fcts)
|
||||
{
|
||||
if(m_cmds.find(it.first) != m_cmds.end())
|
||||
{
|
||||
sh->lst->insert(0, make_condlist(it.second.code));
|
||||
req_rescan=true;
|
||||
ret.insert(it.first);
|
||||
}
|
||||
}
|
||||
if(req_rescan)
|
||||
require_rescan_all();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** JSON **/
|
||||
|
|
|
|||
|
|
@ -1,8 +1,47 @@
|
|||
#include "shellcode.hpp"
|
||||
|
||||
#include "g_shellcode.h"
|
||||
#include "processing.hpp"
|
||||
#include "struc_helper.hpp"
|
||||
|
||||
const std::map<const std::string, const struct lxsh_fct> lxsh_shellcode_fcts = {
|
||||
{ "_lxsh_random_string", { "N", "Generate a random alphanumeric string of length N. Default 20", RANDOM_STRING_SH} },
|
||||
{ "_lxsh_random_tmpfile", { "N", "Get a random TMP filepath, with N random chars. Default 20", RANDOM_TMPFILE_SH} }
|
||||
const std::map<const std::string, const struct lxsh_fct> lxsh_extend_fcts = {
|
||||
{ "_lxsh_random_string", { "[N]", "Generate a random alphanumeric string of length N. Default 20", RANDOM_STRING_SH} },
|
||||
{ "_lxsh_random_tmpfile", { "[N]", "Get a random TMP filepath, with N random chars. Default 20", RANDOM_TMPFILE_SH, {"_lxsh_random_string"} } }
|
||||
};
|
||||
|
||||
const std::map<const std::string, const struct lxsh_fct> lxsh_array_fcts = {
|
||||
{ "_lxsh_array_create", { "<VAL...>", "Create an array out of input arguments", ARRAY_CREATE_SH} },
|
||||
{ "_lxsh_array_get", { "<ARRAY> <I>", "Get value from array", ARRAY_GET_SH} },
|
||||
{ "_lxsh_array_set", { "<ARRAY> <I> <VAL>", "Set value of array", ARRAY_SET_SH} },
|
||||
{ "_lxsh_map_create", { "<VAL...>", "Create a map (associative array) out of input arguments", MAP_CREATE_SH} },
|
||||
{ "_lxsh_map_get", { "<MAP> <KEY>", "Get value from map", MAP_GET_SH} },
|
||||
{ "_lxsh_map_set", { "<MAP> <KEY> <VAL>", "Set value of map", MAP_SET_SH} }
|
||||
};
|
||||
|
||||
std::map<const std::string, const struct lxsh_fct> create_allfcts()
|
||||
{
|
||||
auto r = lxsh_array_fcts;
|
||||
for(auto it: lxsh_extend_fcts)
|
||||
r.insert(it);
|
||||
return r;
|
||||
}
|
||||
|
||||
const std::map<const std::string, const struct lxsh_fct> lxsh_allfcts = create_allfcts();
|
||||
|
||||
void add_lxsh_fcts(shmain* sh, std::set<std::string> fcts)
|
||||
{
|
||||
// resolve dependencies
|
||||
for(auto fctname: fcts)
|
||||
{
|
||||
auto ti=lxsh_allfcts.find(fctname);
|
||||
if(ti != lxsh_allfcts.end())
|
||||
for(auto dep: ti->second.depends_on)
|
||||
fcts.insert(dep);
|
||||
}
|
||||
// insert functions
|
||||
for(auto it: fcts)
|
||||
{
|
||||
sh->lst->insert(0, make_condlist(lxsh_allfcts.find(it)->second.code) );
|
||||
}
|
||||
require_rescan_all();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue