逆矿机下载器
Table of Contents
逆矿机下载器 #
有一台vps被弱口令干了
翻来翻去
找到个二进制文件如下
per #
搜main函数关键字可以判断是用shc加密shell脚本生成的二进制文件
/* shc.c */
/**
* This software contains an ad hoc version of the 'Alleged RC4' algorithm,
* which was anonymously posted on sci.crypt news by cypherpunks on Sep 1994.
*
* My implementation is a complete rewrite of the one found in
* an unknown-copyright (283 characters) version picked up from:
* From: allen@gateway.grumman.com (John L. Allen)
* Newsgroups: comp.lang.c
* Subject: Shrink this C code for fame and fun
* Date: 21 May 1996 10:49:37 -0400
* And it is licensed also under GPL.
*
*That's where I got it, now I am going to do some work on it
*It will reside here: http://github.com/neurobin/shc
*/
static const char my_name[] = "shc";
static const char version[] = "Version 4.0.3";
static const char subject[] = "Generic Shell Script Compiler";
static const char cpright[] = "GNU GPL Version 3";
static const struct { const char * f, * s, * e; }
provider = { "Md Jahidul", "Hamid", "<jahidulhamid@yahoo.com>" };
尝试生成一个echo “helloworld”,看看shc生成的文件是什么构造
shc #
shc -f test.sh 会输出一个test.sh.c和编译好的test.sh.x
test.sh.c:
↓ 这玩意 gcc 编译运行相当于echo helloworld
#if 0
shc Version 4.0.1, Generic Shell Script Compiler
GNU GPL Version 3 Md Jahidul Hamid <jahidulhamid@yahoo.com>
shc -f ./test.sh
#endif
static char data [] =
#define tst1_z 22
#define tst1 ((&data[2]))
"\154\144\213\051\037\376\300\113\326\246\272\226\124\136\064\132"
"\167\355\357\342\113\213\337\355\116\320\024"
#define tst2_z 19
#define tst2 ((&data[29]))
"\105\211\257\152\253\044\251\020\372\310\155\003\136\175\017\023"
"\024\034\362\130\360\073"
#define shll_z 8
#define shll ((&data[49]))
"\020\256\013\240\147\066\316\105\031"
#define pswd_z 256
#define pswd ((&data[76]))
"\315\060\165\351\160\174\263\200\375\307\371\153\154\145\317\272"
"\065\343\152\224\170\100\127\076\174\353\127\131\367\211\066\325"
"\243\312\134\355\061\145\104\323\226\345\147\053\032\155\245\171"
"\206\020\015\376\121\145\075\315\121\225\046\111\037\135\036\302"
"\050\173\260\132\340\364\055\167\332\224\243\364\001\111\156\207"
"\131\174\206\252\341\304\170\063\131\236\174\170\374\233\073\045"
"\026\353\177\367\337\254\157\272\101\022\257\102\133\035\312\264"
"\231\121\137\173\025\327\256\157\166\053\350\163\306\043\230\335"
"\016\027\325\356\303\104\251\004\126\130\107\261\166\022\146\020"
"\143\306\213\171\235\072\351\024\145\321\207\054\365\037\012\004"
"\066\337\362\372\043\234\377\172\364\107\054\153\131\222\173\275"
"\130\006\066\366\101\040\012\247\361\222\324\346\261\336\352\350"
"\276\335\343\342\171\342\134\156\052\210\332\204\033\125\101\164"
"\134\170\153\235\230\165\104\212\007\031\160\271\367\133\241\266"
"\071\204\230\263\147\364\042\222\175\374\026\230\121\130\015\255"
"\320\170\113\151\356\220\363\366\251\144\257\240\277\121\126\370"
"\326\357\254\076\344\316\320\141\312\347\372\033\077\007\311\017"
"\200\024\251\305\111\357\116\204\044\204\376\076\207\110\270\125"
"\171\056\076\351\252\361\151\247\271\142\023\046\307\343\341\375"
"\307"
#define chk1_z 22
#define chk1 ((&data[367]))
"\173\022\225\237\043\031\266\276\070\126\037\076\032\305\230\135"
"\303\051\303\012\252\341\075\014\001\201"
#define msg2_z 19
#define msg2 ((&data[391]))
"\036\333\204\140\063\362\171\125\145\015\020\342\074\045\366\005"
"\236\211\212\073\116\226\163\124\304"
#define rlax_z 1
#define rlax ((&data[414]))
"\351"
#define opts_z 1
#define opts ((&data[415]))
"\004"
#define xecc_z 15
#define xecc ((&data[416]))
"\373\253\201\273\354\314\236\344\141\302\366\034\112\226\131"
#define text_z 32
#define text ((&data[438]))
"\145\317\325\360\223\345\153\344\166\302\365\050\351\012\045\311"
"\111\245\360\065\065\174\107\317\307\006\353\102\053\350\025\025"
"\015\140\276\012\353\162\146"
#define chk2_z 19
#define chk2 ((&data[472]))
"\074\016\302\053\162\232\331\112\224\273\101\241\253\134\117\245"
"\035\136\334\277\201"
#define msg1_z 65
#define msg1 ((&data[497]))
"\200\315\077\104\177\175\147\002\375\172\341\073\155\300\014\222"
"\242\357\341\005\175\363\143\002\100\354\153\257\255\111\035\342"
"\026\115\106\120\374\173\222\267\374\102\245\214\236\132\274\200"
"\232\174\063\344\125\336\117\104\072\171\125\026\144\201\106\175"
"\323\246\312\141\367\016\114\264\043\044\313\200\056\366\004\000"
"\005\151\317\332\132\143"
#define date_z 1
#define date ((&data[577]))
"\006"
#define inlo_z 3
#define inlo ((&data[578]))
"\152\262\244"
#define lsto_z 1
#define lsto ((&data[581]))
"\054"/* 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 HARDENINGSP 0 /* Define as 1 to disable bash child process */
#define BUSYBOXON 0 /* Define as 1 to enable work with busybox */
/* 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 processs */
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 arc4_hardrun(void * str, int len) {
//Decode locally
char tmp2[len];
memcpy(tmp2, str, len);
unsigned char tmp, * ptr = (unsigned char *)tmp2;
int lentmp = len;
#if HARDENINGSP
//Start tracing to protect from dump & trace
if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
printf("Operation not permitted\n");
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--;
}
//Exec bash script
system(tmp2);
//Empty script variable
memcpy(tmp2, str, lentmp);
//Sinal to detach ptrace
ptrace(PTRACE_DETACH, 0, 0, 0);
exit(0);
/* Seccomp Sandboxing - Start */
seccomp_hardening();
exit(0);
#endif /* HARDENINGSP Exit here anyway*/
int pid, status;
pid = fork();
if(pid==0) {
//Start tracing to protect from dump & trace
if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
printf("Operation not permitted\n");
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--;
}
//Exec bash script
system(tmp2);
//Empty script variable
memcpy(tmp2, str, lentmp);
//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();
printf("mask[pid] = %d",mask);
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
printf("%d\n",j);
printf("%s\n",varg[0]);
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;
}
summary #
程序把shell命令用rc4加密在了硬编码里面,那么最啥波一的办法就是逆向算法然后手动写解密脚本
我们选择断网调试,但程序会exce调用子进程,在子进程里面解密,
但我又不想attach上去,那么想想办法能不能直接在父进程解密
嘻嘻😋😋😋😋
在518行有一个ret值会判段pid
如果当前为父进程(pid=0)则596行execvp(shll, varg);
varg装载默认变量执行 sh <程序名>.elf
, 相当于自己再调用自己
如果为子进程则varg装载shell命令
执行 echo helloworld
额,好像有些网页没行号,摆了
那么回到样本,只要更改ret的值然后调到execvp 然后print mem就能得到shell脚本了
patch && dump mem #
修改ret值
源码有个位置在移动shell命令
#define hide_z 4096
...
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);
...
text为shell命令,被copy到&scrpt+4096的位置,并没有在varg直接调用
用的是
bash exec "#!/bin/bash\n xxxxxxxxxxxxxxxxxxxxxx"
这种形式调用
祖传字符串脚本
base =0x000000000602B83
end = 0x00000000006074F0
ans=[]
for i in range(base,end):
tmp = idc.get_wide_byte(i)
ans.append(tmp)
if(tmp == 0):
print(bytes(ans))
ans=[]
shlll = b''
with open("dl.sh.tmp", "w") as f:
print(shlll.decode(),file=f)
暂且写个脚本存一下
脚本里面有一个位置从172.104.170.240下载了一个矿机文件 上网搜一下ip是一个矿池
啊哈哈哈哈哈味道对了
非常好云主机
样本行为和5月的不太一样,没有那么多yayaya,查杀方法也有些不一样,应该是在shell命令上做了改变
https://www.freebuf.com/articles/network/366444.html
但矿池应该是同一拨人弄的
黑客真可恶啊!😋😋😋😋😋