thorium-mirror/infra/portable/C/THORIUM-SHELL.sh.x.c
2024-08-20 14:26:49 -05:00

722 lines
20 KiB
C

#if 0
shc Version 4.0.3, Generic Shell Script Compiler
GNU GPL Version 3 Md Jahidul Hamid <jahidulhamid@yahoo.com>
shc -r -v -o ./THORIUM-SHELL -f ./THORIUM-SHELL.sh
#endif
static char data [] =
#define msg2_z 19
#define msg2 ((&data[0]))
"\265\056\004\341\320\071\333\322\273\173\340\045\150\055\363\331"
"\131\122\311\162\102"
#define chk1_z 22
#define chk1 ((&data[23]))
"\165\332\300\237\170\340\352\265\133\014\352\134\211\371\232\001"
"\044\367\324\100\110\034\103\177"
#define rlax_z 1
#define rlax ((&data[45]))
"\031"
#define opts_z 1
#define opts ((&data[46]))
"\341"
#define xecc_z 15
#define xecc ((&data[49]))
"\170\030\231\266\253\203\277\201\350\333\064\025\177\133\042\366"
"\064\213\314\340"
#define text_z 452
#define text ((&data[103]))
"\345\362\247\113\214\263\334\377\365\162\154\367\347\106\214\020"
"\277\116\077\121\246\354\106\036\005\322\352\345\215\075\141\162"
"\057\011\276\274\177\205\315\335\064\272\103\252\006\304\276\135"
"\376\003\100\132\167\115\204\066\125\176\026\117\176\345\102\230"
"\222\311\124\063\010\103\000\022\076\135\013\275\164\020\361\015"
"\200\323\022\207\046\105\342\253\016\163\307\200\323\004\167\170"
"\116\262\227\022\360\065\054\365\300\256\050\244\367\100\335\036"
"\061\222\267\062\034\047\143\345\203\250\331\103\127\044\063\165"
"\047\146\077\155\264\207\060\216\025\064\024\101\366\047\005\305"
"\203\252\105\264\155\124\072\212\142\177\054\377\306\041\214\225"
"\362\213\026\247\145\206\173\370\115\076\004\113\370\225\230\152"
"\271\206\375\305\100\321\164\274\300\212\013\154\373\226\021\367"
"\265\305\325\206\237\205\101\014\021\321\125\053\110\045\206\306"
"\210\314\173\243\347\243\045\346\220\064\212\262\275\230\320\206"
"\104\106\211\345\307\224\106\352\376\302\247\047\301\041\136\002"
"\320\156\246\235\225\244\231\245\115\354\336\341\252\373\105\320"
"\040\147\263\213\262\000\021\014\014\164\304\153\210\352\156\032"
"\147\375\072\365\252\371\214\100\344\313\010\020\142\127\011\156"
"\273\237\232\033\353\077\163\275\214\355\062\234\326\272\062\216"
"\123\146\041\256\230\301\100\221\211\371\214\053\374\361\330\160"
"\102\254\273\060\342\015\115\050\324\113\245\107\232\137\045\246"
"\106\264\371\250\226\301\044\142\102\005\251\172\212\356\322\010"
"\223\221\375\167\313\173\065\051\221\206\257\170\375\251\205\344"
"\327\043\051\226\265\025\332\241\273\213\332\226\116\301\255\276"
"\004\022\045\230\275\351\160\075\161\142\101\263\064\215\002\246"
"\124\207\307\200\047\201\077\222\373\066\322\343\042\073\362\031"
"\103\033\013\343\104\260\135\117\174\302\311\300\242\340\247\367"
"\254\104\047\321\113\375\371\201\112\131\277\102\031\332\310\131"
"\043\264\177\136\137\202\165\343\165\154\207\242\112\361\210\301"
"\151\034\235\326\257\375\200\171\072\310\311\201\037\011\036\016"
"\324\075\146\015\041\014\055\374\275\232\273\262\015\050\252\364"
"\157\066\005\057\205\104\200\054\061\307\112\066\231\065\034\046"
"\162\176\231\241\210\130\136\105\362\031\370\377\102\242\364\261"
"\331\371\340\137\076\141\213\160\050\325\247\302\013\303\351"
#define tst1_z 22
#define tst1 ((&data[611]))
"\037\237\315\314\147\236\203\043\075\111\102\242\262\275\264\037"
"\130\156\251\325\022\255\156\312\333\175"
#define pswd_z 256
#define pswd ((&data[688]))
"\007\316\331\252\302\212\204\274\153\343\372\314\156\153\365\104"
"\022\267\117\326\240\315\030\044\355\342\377\153\362\315\002\372"
"\233\334\244\136\147\050\032\322\014\024\237\172\200\224\276\222"
"\113\016\151\354\061\275\116\330\326\253\337\210\047\173\302\114"
"\027\064\362\167\121\155\370\235\352\262\313\377\150\253\376\373"
"\245\247\147\326\144\265\256\073\140\216\303\210\012\205\324\042"
"\271\307\231\013\064\222\250\037\104\164\036\254\040\034\250\305"
"\303\017\233\050\305\112\143\046\331\047\256\343\254\203\006\146"
"\112\237\161\177\061\032\236\166\216\275\043\256\331\313\163\235"
"\333\017\306\241\131\052\307\062\121\165\026\375\370\034\144\103"
"\273\325\302\355\357\141\144\176\036\207\055\370\122\240\226\056"
"\260\135\317\011\207\226\074\331\014\123\327\005\157\073\110\053"
"\020\013\031\000\155\175\176\214\004\253\204\127\114\033\205\374"
"\171\124\006\000\353\103\332\367\226\261\374\005\354\105\061\374"
"\120\112\375\275\310\173\111\314\047\316\043\163\352\250\160\143"
"\375\167\144\350\272\076\340\121\357\335\127\333\042\210\330\163"
"\323\325\060\233\121\172\147\170\111\213\354\064\063\135\227\061"
"\324\374\032\216\072\372\340\052\327\067\006\372\277\336\155\222"
"\264\236\055\005\031\225\176\142\040\152\226\124\310\056\205\234"
"\053\240\053\145\333\201\020\310\144\020\063\126\336\066\120\171"
"\023\364\330\172\035\362\115\052\007\354\244\207\201\143\032\314"
"\161\203\271\115\004\312\026\150\332\112"
#define tst2_z 19
#define tst2 ((&data[985]))
"\017\062\224\074\067\352\121\266\106\042\363\246\257\277\303\224"
"\044\355\356\256\166\131\004\012"
#define msg1_z 65
#define msg1 ((&data[1008]))
"\135\114\237\142\170\302\266\052\046\356\261\174\346\012\330\061"
"\311\257\052\271\005\161\000\066\141\340\104\032\202\303\363\333"
"\273\207\302\304\172\025\306\302\340\226\314\042\302\066\232\364"
"\372\347\033\056\212\050\057\276\066\017\214\343\275\336\053\007"
"\366\246\077\004\112\360\214\313\124\246\230\306\051\122\023\056"
"\034\052\227"
#define chk2_z 19
#define chk2 ((&data[1091]))
"\260\365\276\077\222\144\077\311\015\324\024\103\044\354\021\261"
"\141\270\153\342\206\145"
#define date_z 1
#define date ((&data[1111]))
"\301"
#define shll_z 10
#define shll ((&data[1113]))
"\352\075\052\144\327\305\121\035\130\344\277\367"
#define inlo_z 3
#define inlo ((&data[1124]))
"\055\367\145"
#define lsto_z 1
#define lsto ((&data[1127]))
"\151"/* End of data[] */;
#define hide_z 4096
#define SETUID 0 /* Define as 1 to call setuid(0) at start of script */
#define DEBUGEXEC 0 /* Define as 1 to debug execvp calls */
#define TRACEABLE 1 /* Define as 1 to enable ptrace the executable */
#define HARDENING 0 /* Define as 1 to disable ptrace/dump the executable */
#define BUSYBOXON 0 /* Define as 1 to enable work with busybox */
#if HARDENING
static const char * shc_x[] = {
"/*",
" * Copyright 2019 - Intika <intika@librefox.org>",
" * Replace ******** with secret read from fd 21",
" * Also change arguments location of sub commands (sh script commands)",
" * gcc -Wall -fpic -shared -o shc_secret.so shc_secret.c -ldl",
" */",
"",
"#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */",
"#define PLACEHOLDER \"********\"",
"#include <dlfcn.h>",
"#include <stdlib.h>",
"#include <string.h>",
"#include <unistd.h>",
"#include <stdio.h>",
"#include <signal.h>",
"",
"static char secret[128000]; //max size",
"typedef int (*pfi)(int, char **, char **);",
"static pfi real_main;",
"",
"// copy argv to new location",
"char **copyargs(int argc, char** argv){",
" char **newargv = malloc((argc+1)*sizeof(*argv));",
" char *from,*to;",
" int i,len;",
"",
" for(i = 0; i<argc; i++){",
" from = argv[i];",
" len = strlen(from)+1;",
" to = malloc(len);",
" memcpy(to,from,len);",
" // zap old argv space",
" memset(from,'\\0',len);",
" newargv[i] = to;",
" argv[i] = 0;",
" }",
" newargv[argc] = 0;",
" return newargv;",
"}",
"",
"static int mymain(int argc, char** argv, char** env) {",
" //fprintf(stderr, \"Inject main argc = %d\\n\", argc);",
" return real_main(argc, copyargs(argc,argv), env);",
"}",
"",
"int __libc_start_main(int (*main) (int, char**, char**),",
" int argc,",
" char **argv,",
" void (*init) (void),",
" void (*fini)(void),",
" void (*rtld_fini)(void),",
" void (*stack_end)){",
" static int (*real___libc_start_main)() = NULL;",
" int n;",
"",
" if (!real___libc_start_main) {",
" real___libc_start_main = dlsym(RTLD_NEXT, \"__libc_start_main\");",
" if (!real___libc_start_main) abort();",
" }",
"",
" n = read(21, secret, sizeof(secret));",
" if (n > 0) {",
" int i;",
"",
" if (secret[n - 1] == '\\n') secret[--n] = '\\0';",
" for (i = 1; i < argc; i++)",
" if (strcmp(argv[i], PLACEHOLDER) == 0)",
" argv[i] = secret;",
" }",
"",
" real_main = main;",
"",
" return real___libc_start_main(mymain, argc, argv, init, fini, rtld_fini, stack_end);",
"}",
"",
0};
#endif /* HARDENING */
/* rtc.c */
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
/* 'Alleged RC4' */
static unsigned char stte[256], indx, jndx, kndx;
/*
* Reset arc4 stte.
*/
void stte_0(void)
{
indx = jndx = kndx = 0;
do {
stte[indx] = indx;
} while (++indx);
}
/*
* Set key. Can be used more than once.
*/
void key(void * str, int len)
{
unsigned char tmp, * ptr = (unsigned char *)str;
while (len > 0) {
do {
tmp = stte[indx];
kndx += tmp;
kndx += ptr[(int)indx % len];
stte[indx] = stte[kndx];
stte[kndx] = tmp;
} while (++indx);
ptr += 256;
len -= 256;
}
}
/*
* Crypt data.
*/
void arc4(void * str, int len)
{
unsigned char tmp, * ptr = (unsigned char *)str;
while (len > 0) {
indx++;
tmp = stte[indx];
jndx += tmp;
stte[indx] = stte[jndx];
stte[jndx] = tmp;
tmp += stte[indx];
*ptr ^= stte[tmp];
ptr++;
len--;
}
}
/* End of ARC4 */
#if HARDENING
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/prctl.h>
#define PR_SET_PTRACER 0x59616d61
/* Seccomp Sandboxing Init */
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/audit.h>
#define ArchField offsetof(struct seccomp_data, arch)
#define Allow(syscall) \
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_##syscall, 0, 1), \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
struct sock_filter filter[] = {
/* validate arch */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ArchField),
BPF_JUMP( BPF_JMP+BPF_JEQ+BPF_K, AUDIT_ARCH_X86_64, 1, 0),
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
/* load syscall */
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct seccomp_data, nr)),
/* list of allowed syscalls */
Allow(exit_group), /* exits a process */
Allow(brk), /* for malloc(), inside libc */
Allow(mmap), /* also for malloc() */
Allow(munmap), /* for free(), inside libc */
/* and if we don't match above, die */
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL),
};
struct sock_fprog filterprog = {
.len = sizeof(filter)/sizeof(filter[0]),
.filter = filter
};
/* Seccomp Sandboxing - Set up the restricted environment */
void seccomp_hardening() {
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("Could not start seccomp:");
exit(1);
}
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &filterprog) == -1) {
perror("Could not start seccomp:");
exit(1);
}
}
/* End Seccomp Sandboxing Init */
void shc_x_file() {
FILE *fp;
int line = 0;
if ((fp = fopen("/tmp/shc_x.c", "w")) == NULL ) {exit(1); exit(1);}
for (line = 0; shc_x[line]; line++) fprintf(fp, "%s\n", shc_x[line]);
fflush(fp);fclose(fp);
}
int make() {
char * cc, * cflags, * ldflags;
char cmd[4096];
cc = getenv("CC");
if (!cc) cc = "cc";
sprintf(cmd, "%s %s -o %s %s", cc, "-Wall -fpic -shared", "/tmp/shc_x.so", "/tmp/shc_x.c -ldl");
if (system(cmd)) {remove("/tmp/shc_x.c"); return -1;}
remove("/tmp/shc_x.c"); return 0;
}
void arc4_hardrun(void * str, int len) {
//Decode locally
char tmp2[len];
char tmp3[len+1024];
memcpy(tmp2, str, len);
unsigned char tmp, * ptr = (unsigned char *)tmp2;
int lentmp = len;
int pid, status;
pid = fork();
shc_x_file();
if (make()) {exit(1);}
setenv("LD_PRELOAD","/tmp/shc_x.so",1);
if(pid==0) {
//Start tracing to protect from dump & trace
if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
kill(getpid(), SIGKILL);
_exit(1);
}
//Decode Bash
while (len > 0) {
indx++;
tmp = stte[indx];
jndx += tmp;
stte[indx] = stte[jndx];
stte[jndx] = tmp;
tmp += stte[indx];
*ptr ^= stte[tmp];
ptr++;
len--;
}
//Do the magic
sprintf(tmp3, "%s %s", "'********' 21<<<", tmp2);
//Exec bash script //fork execl with 'sh -c'
system(tmp2);
//Empty script variable
memcpy(tmp2, str, lentmp);
//Clean temp
remove("/tmp/shc_x.so");
//Sinal to detach ptrace
ptrace(PTRACE_DETACH, 0, 0, 0);
exit(0);
}
else {wait(&status);}
/* Seccomp Sandboxing - Start */
seccomp_hardening();
exit(0);
}
#endif /* HARDENING */
/*
* Key with file invariants.
*/
int key_with_file(char * file)
{
struct stat statf[1];
struct stat control[1];
if (stat(file, statf) < 0)
return -1;
/* Turn on stable fields */
memset(control, 0, sizeof(control));
control->st_ino = statf->st_ino;
control->st_dev = statf->st_dev;
control->st_rdev = statf->st_rdev;
control->st_uid = statf->st_uid;
control->st_gid = statf->st_gid;
control->st_size = statf->st_size;
control->st_mtime = statf->st_mtime;
control->st_ctime = statf->st_ctime;
key(control, sizeof(control));
return 0;
}
#if DEBUGEXEC
void debugexec(char * sh11, int argc, char ** argv)
{
int i;
fprintf(stderr, "shll=%s\n", sh11 ? sh11 : "<null>");
fprintf(stderr, "argc=%d\n", argc);
if (!argv) {
fprintf(stderr, "argv=<null>\n");
} else {
for (i = 0; i <= argc ; i++)
fprintf(stderr, "argv[%d]=%.60s\n", i, argv[i] ? argv[i] : "<null>");
}
}
#endif /* DEBUGEXEC */
void rmarg(char ** argv, char * arg)
{
for (; argv && *argv && *argv != arg; argv++);
for (; argv && *argv; argv++)
*argv = argv[1];
}
void chkenv_end(void);
int chkenv(int argc)
{
char buff[512];
unsigned long mask, m;
int l, a, c;
char * string;
extern char ** environ;
mask = (unsigned long)getpid();
stte_0();
key(&chkenv, (void*)&chkenv_end - (void*)&chkenv);
key(&data, sizeof(data));
key(&mask, sizeof(mask));
arc4(&mask, sizeof(mask));
sprintf(buff, "x%lx", mask);
string = getenv(buff);
#if DEBUGEXEC
fprintf(stderr, "getenv(%s)=%s\n", buff, string ? string : "<null>");
#endif
l = strlen(buff);
if (!string) {
/* 1st */
sprintf(&buff[l], "=%lu %d", mask, argc);
putenv(strdup(buff));
return 0;
}
c = sscanf(string, "%lu %d%c", &m, &a, buff);
if (c == 2 && m == mask) {
/* 3rd */
rmarg(environ, &string[-l - 1]);
return 1 + (argc - a);
}
return -1;
}
void chkenv_end(void){}
#if HARDENING
static void gets_process_name(const pid_t pid, char * name) {
char procfile[BUFSIZ];
sprintf(procfile, "/proc/%d/cmdline", pid);
FILE* f = fopen(procfile, "r");
if (f) {
size_t size;
size = fread(name, sizeof (char), sizeof (procfile), f);
if (size > 0) {
if ('\n' == name[size - 1])
name[size - 1] = '\0';
}
fclose(f);
}
}
void hardening() {
prctl(PR_SET_DUMPABLE, 0);
prctl(PR_SET_PTRACER, -1);
int pid = getppid();
char name[256] = {0};
gets_process_name(pid, name);
if ( (strcmp(name, "bash") != 0)
&& (strcmp(name, "/bin/bash") != 0)
&& (strcmp(name, "sh") != 0)
&& (strcmp(name, "/bin/sh") != 0)
&& (strcmp(name, "sudo") != 0)
&& (strcmp(name, "/bin/sudo") != 0)
&& (strcmp(name, "/usr/bin/sudo") != 0)
&& (strcmp(name, "gksudo") != 0)
&& (strcmp(name, "/bin/gksudo") != 0)
&& (strcmp(name, "/usr/bin/gksudo") != 0)
&& (strcmp(name, "kdesu") != 0)
&& (strcmp(name, "/bin/kdesu") != 0)
&& (strcmp(name, "/usr/bin/kdesu") != 0)
)
{
printf("Operation not permitted\n");
kill(getpid(), SIGKILL);
exit(1);
}
}
#endif /* HARDENING */
#if !TRACEABLE
#define _LINUX_SOURCE_COMPAT
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#if !defined(PT_ATTACHEXC) /* New replacement for PT_ATTACH */
#if !defined(PTRACE_ATTACH) && defined(PT_ATTACH)
#define PT_ATTACHEXC PT_ATTACH
#elif defined(PTRACE_ATTACH)
#define PT_ATTACHEXC PTRACE_ATTACH
#endif
#endif
void untraceable(char * argv0)
{
char proc[80];
int pid, mine;
switch(pid = fork()) {
case 0:
pid = getppid();
/* For problematic SunOS ptrace */
#if defined(__FreeBSD__)
sprintf(proc, "/proc/%d/mem", (int)pid);
#else
sprintf(proc, "/proc/%d/as", (int)pid);
#endif
close(0);
mine = !open(proc, O_RDWR|O_EXCL);
if (!mine && errno != EBUSY)
mine = !ptrace(PT_ATTACHEXC, pid, 0, 0);
if (mine) {
kill(pid, SIGCONT);
} else {
perror(argv0);
kill(pid, SIGKILL);
}
_exit(mine);
case -1:
break;
default:
if (pid == waitpid(pid, 0, 0))
return;
}
perror(argv0);
_exit(1);
}
#endif /* !TRACEABLE */
char * xsh(int argc, char ** argv)
{
char * scrpt;
int ret, i, j;
char ** varg;
char * me = argv[0];
if (me == NULL) { me = getenv("_"); }
if (me == 0) { fprintf(stderr, "E: neither argv[0] nor $_ works."); exit(1); }
ret = chkenv(argc);
stte_0();
key(pswd, pswd_z);
arc4(msg1, msg1_z);
arc4(date, date_z);
if (date[0] && (atoll(date)<time(NULL)))
return msg1;
arc4(shll, shll_z);
arc4(inlo, inlo_z);
arc4(xecc, xecc_z);
arc4(lsto, lsto_z);
arc4(tst1, tst1_z);
key(tst1, tst1_z);
arc4(chk1, chk1_z);
if ((chk1_z != tst1_z) || memcmp(tst1, chk1, tst1_z))
return tst1;
arc4(msg2, msg2_z);
if (ret < 0)
return msg2;
varg = (char **)calloc(argc + 10, sizeof(char *));
if (!varg)
return 0;
if (ret) {
arc4(rlax, rlax_z);
if (!rlax[0] && key_with_file(shll))
return shll;
arc4(opts, opts_z);
#if HARDENING
arc4_hardrun(text, text_z);
exit(0);
/* Seccomp Sandboxing - Start */
seccomp_hardening();
#endif
arc4(text, text_z);
arc4(tst2, tst2_z);
key(tst2, tst2_z);
arc4(chk2, chk2_z);
if ((chk2_z != tst2_z) || memcmp(tst2, chk2, tst2_z))
return tst2;
/* Prepend hide_z spaces to script text to hide it. */
scrpt = malloc(hide_z + text_z);
if (!scrpt)
return 0;
memset(scrpt, (int) ' ', hide_z);
memcpy(&scrpt[hide_z], text, text_z);
} else { /* Reexecute */
if (*xecc) {
scrpt = malloc(512);
if (!scrpt)
return 0;
sprintf(scrpt, xecc, me);
} else {
scrpt = me;
}
}
j = 0;
#if BUSYBOXON
varg[j++] = "busybox";
varg[j++] = "sh";
#else
varg[j++] = argv[0]; /* My own name at execution */
#endif
if (ret && *opts)
varg[j++] = opts; /* Options on 1st line of code */
if (*inlo)
varg[j++] = inlo; /* Option introducing inline code */
varg[j++] = scrpt; /* The script itself */
if (*lsto)
varg[j++] = lsto; /* Option meaning last option */
i = (ret > 1) ? ret : 0; /* Args numbering correction */
while (i < argc)
varg[j++] = argv[i++]; /* Main run-time arguments */
varg[j] = 0; /* NULL terminated array */
#if DEBUGEXEC
debugexec(shll, j, varg);
#endif
execvp(shll, varg);
return shll;
}
int main(int argc, char ** argv)
{
#if SETUID
setuid(0);
#endif
#if DEBUGEXEC
debugexec("main", argc, argv);
#endif
#if HARDENING
hardening();
#endif
#if !TRACEABLE
untraceable(argv[0]);
#endif
argv[1] = xsh(argc, argv);
fprintf(stderr, "%s%s%s: %s\n", argv[0],
errno ? ": " : "",
errno ? strerror(errno) : "",
argv[1] ? argv[1] : "<null>"
);
return 1;
}