Skip to content

Instantly share code, notes, and snippets.

@hc0d3r
Created July 13, 2019 16:48
Show Gist options
  • Save hc0d3r/318b0aa0ae4697372688b624cecbd610 to your computer and use it in GitHub Desktop.
Save hc0d3r/318b0aa0ae4697372688b624cecbd610 to your computer and use it in GitHub Desktop.
#include <spyderhook.h>
#include <ignotum.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define die(msg) do { \
perror(msg); \
exit(1); \
} while(0)
// for human-beings
enum {
pipe_read,
pipe_write
};
int syscall_enter(pidinfo_t *info, unsigned long nr, void *data);
int syscall_result(pidinfo_t *info, unsigned long nr, void *data);
void *read_until_zero(pid_t pid, off_t raddr, size_t *len);
void hexdump(const char *data, size_t n);
void print_execve(pid_t pid);
int wantcontinue(void);
/* lê a memoria ate encontrar um null-byte
* ou ate não ter mais dados que possam ser lidos */
void *read_until_zero(pid_t pid, off_t raddr, size_t *len){
char *buf = NULL, *aux;
size_t n = 128, prev = 0, total, i, nread;
while(1){
buf = realloc(buf, n);
if(buf == NULL)
die("realloc()");
aux = buf+prev;
total = n-prev;
nread = (size_t)ignotum_mem_read(pid, aux, total, raddr+prev);
for(i=0; i<nread; i++){
if(aux[i] == 0){
i++;
goto end;
}
}
if(nread != total)
break;
prev = n;
n *= 2;
}
end:
*len = prev+i;
return buf;
}
/* don't judge me for be lazy */
void hexdump(const char *data, size_t n){
pid_t pid;
int pfd[2];
pipe(pfd);
pid = fork();
if(pid == 0){
close(pfd[pipe_write]);
dup2(pfd[pipe_read], 0);
execlp("hexdump", "hexdump", "-C", NULL);
_exit(0);
}
write(pfd[pipe_write], data, n);
close(pfd[pipe_write]);
close(pfd[pipe_read]);
waitpid(pid, NULL, 0);
}
void print_execve(pid_t pid){
long exe, args, addr;
size_t len;
int i = 0;
char *string;
/* pega os endereços de memória */
exe = sh_getreg(pid, SH_FIRST_ARG);
/* read_until_zero usa a libignotum */
string = read_until_zero(pid, exe, &len);
printf("\n[*] cmd = %s\n", string);
free(string);
if(wantcontinue()){
return;
}
args = sh_getreg(pid, SH_SECOND_ARG);
while(1){
addr = 0;
/* addr = *remote_argv */
ignotum_mem_read(pid, &addr, sizeof(long), args);
if(addr == 0)
break;
printf("ARG[%d]:\n", i++);
/* printf("%s\n", addr); */
string = read_until_zero(pid, addr, &len);
hexdump(string, len);
free(string);
/* remote_argv++ */
args += sizeof(long);
}
}
int wantcontinue(void){
char opt;
printf(">> printar os parametros (s/n) ? ");
opt = getchar();
while(getchar() != '\n');
return (opt != 's' && opt != 'S');
}
int syscall_enter(pidinfo_t *info, unsigned long nr, void *data){
/* faz a lib 'pular' a syscall */
if(nr == SYS_prctl){
return SH_SKIP_SYSCALL;
}
/* printa os parametros da syscall execve */
if(nr == SYS_execve){
print_execve(info->pid);
}
return SH_CONTINUE;
}
int syscall_result(pidinfo_t *info, unsigned long nr, void *data){
if(nr == SYS_ptrace){
/* altera o resultado da syscall ptrace
* que no SHC é usada para detectar se
* o processo está sendo debugado */
sh_setreg(info->pid, SH_SYSCALL_RESULT, 0);
}
return SH_CONTINUE;
}
int main(int argc,char **argv, char **envp){
spyderhook_t *sh;
int err;
setvbuf(stdout, NULL, _IONBF, 0);
if(argc != 2){
printf("unshc [prog]\n");
return 0;
}
/* re-executa o programa se o primeiro argumento
* for diferente de /bin/bash */
if(strcmp(argv[0], "/bin/bash")){
char *exe = argv[0];
argv[0] = "/bin/bash";
execve(exe, argv, envp);
/* encerra o programa, se execve falhar */
return 1;
}
sh = sh_init();
if(sh == NULL){
die("sh_init()");
return 1;
}
sh_setopt(sh, SHOPT_FILENAME, argv[1]);
sh_setopt(sh, SHOPT_ARGV, argv+1);
sh_setopt(sh, SHOPT_ENVP, envp);
sh_setopt(sh, SHOPT_ENTER_CALLBACK, syscall_enter);
sh_setopt(sh, SHOPT_RESULT_CALLBACK, syscall_result);
sh_setopt(sh, SHOPT_FOLLOW_ALL, 1);
if((err = sh_mainloop(sh)) != SH_SUCCESS){
printf("error => %s\n", sh_strerror(err));
}
sh_free(sh);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment