Skip to content

Instantly share code, notes, and snippets.

@Estella
Created July 31, 2010 05:41
Show Gist options
  • Save Estella/501800 to your computer and use it in GitHub Desktop.
Save Estella/501800 to your computer and use it in GitHub Desktop.
/**************************************************************************************************/
/* */
/* Estella Mystagic */
/* */
/**************************************************************************************************/
// albino squirrel v2.1 freebsd 8.x (http://www.mystagic.com/albino_squirrel.png)
// syscall hooks on chmod,fchmod,lchmod,fchmodat to prevent modifing sticky,setgid,setuid on
// files/links or directories while in securelevel one or higher.
//
// sysctl mibs:
//
// sysctl kern.albino_squirrel_log, 0 = disable logging, 1 = enable logging (default)
// sysctl kern.albino_squirrel_debug, 0 = disable debug messages (default), 1 = enable debug messages
// sysctl kern.albino_squirrel_restrictdirs, 0 = disable (default), 1 = enable, apply to directories
// sysctl kern.albino_squirrel_luckysevens, 0 = disable (default), 1 = enable, block chmod 777 use
/**************************************************************************************************/
// directories files normal links
//
// DEC OCT DEC OCT DEC OCT DEC OCT
// 16384 = 40000 32768 = 100000 0 = 0 40960 = 120000
// 16895 = 40777 33279 = 100777 511 = 777 41471 = 120777
// 20479 = 47777 36863 = 107777 4095 = 777 45055 = 127777
/**************************************************************************************************/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/syscall.h>
#include <sys/sysproto.h>
#include <sys/sysctl.h>
/**************************************************************************************************/
static int albino_squirrel_log = 1;
SYSCTL_INT(_kern, OID_AUTO, albino_squirrel_log, CTLFLAG_RW, &albino_squirrel_log, 0,
"albino squirrel logging");
static int albino_squirrel_debug = 0;
SYSCTL_INT(_kern, OID_AUTO, albino_squirrel_debug, CTLFLAG_RW, &albino_squirrel_debug, 0,
"albino squirrel debug messages");
static int albino_squirrel_restrictdirs = 0;
SYSCTL_INT(_kern, OID_AUTO, albino_squirrel_restrictdirs, CTLFLAG_RW, &albino_squirrel_restrictdirs, 0,
"albino squirrel directory restrictions");
static int albino_squirrel_luckysevens = 0;
SYSCTL_INT(_kern, OID_AUTO, albino_squirrel_luckysevens, CTLFLAG_RW, &albino_squirrel_luckysevens, 0,
"albino squirrel block chmod 777, lucky sevens");
/**************************************************************************************************/
// 15 AUE_CHMOD STD { int chmod(char *path, int mode); }
/**************************************************************************************************/
static int albino_squirrel_chmod(struct thread *td, void *syscall_args) {
struct chmod_args *uap;
uap = (struct chmod_args *)syscall_args;
char path[255];
size_t done;
int error;
error = copyinstr(uap->path, path, 255, &done);
if (error != 0) { return(error); }
if (albino_squirrel_debug) {
printf("DEBUG chmod syscall -- uid(%d) pid(%d) ppid(%d) object(%s) permissions(%o) - DEC %d\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, path, uap->mode, uap->mode);
}
if (securelevel_ge(td->td_ucred, 1) != 0) {
if (((albino_squirrel_restrictdirs) && (uap->mode > 16895) && (uap->mode <= 20479)) ||
((uap->mode > 41471) && (uap->mode <= 45055)) || ((uap->mode > 33279) && (uap->mode <= 36863)) ||
((uap->mode > 511) && (uap->mode <= 4095))) {
if (albino_squirrel_log) {
printf("BLOCKED CHMOD uid(%d) pid(%d) ppid(%d) object(%s) permissions(%o)\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, path, uap->mode);
}
return (EPERM);
}
if ((albino_squirrel_luckysevens) && ((uap->mode == 4095) || (uap->mode == 41471) ||
(uap->mode == 33279) || (uap->mode == 16895))) { return (EPERM); }
}
return(chmod(td, syscall_args));
}
/**************************************************************************************************/
// 124 AUE_FCHMOD STD { int fchmod(int fd, int mode); }
/**************************************************************************************************/
static int albino_squirrel_fchmod(struct thread *td, void *syscall_args) {
struct fchmod_args *uap;
uap = (struct fchmod_args *)syscall_args;
if (albino_squirrel_debug) {
printf("DEBUG fchmod syscall -- uid(%d) pid(%d) ppid(%d) fd(%d) permissions(%o) - DEC %d\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, uap->fd, uap->mode, uap->mode);
}
if (securelevel_ge(td->td_ucred, 1) != 0) {
if (((albino_squirrel_restrictdirs) && (uap->mode > 16895) && (uap->mode <= 20479)) ||
((uap->mode > 41471) && (uap->mode <= 45055)) || ((uap->mode > 33279) && (uap->mode <= 36863)) ||
((uap->mode > 511) && (uap->mode <= 4095))) {
if (albino_squirrel_log) {
printf("BLOCKED FCHMOD uid(%d) pid(%d) ppid(%d) fd(%d) permissions(%o)\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, uap->fd, uap->mode);
}
return (EPERM);
}
if ((albino_squirrel_luckysevens) && ((uap->mode == 4095) || (uap->mode == 41471) ||
(uap->mode == 33279) || (uap->mode == 16895))) { return (EPERM); }
}
return(fchmod(td, syscall_args));
}
/**************************************************************************************************/
// 274 AUE_LCHMOD STD { int lchmod(char *path, mode_t mode); }
/**************************************************************************************************/
static int albino_squirrel_lchmod(struct thread *td, void *syscall_args) {
struct lchmod_args *uap;
uap = (struct lchmod_args *)syscall_args;
char path[255];
size_t done;
int error;
error = copyinstr(uap->path, path, 255, &done);
if (error != 0) { return(error); }
if (albino_squirrel_debug) {
printf("DEBUG lchmod syscall -- uid(%d) pid(%d) ppid(%d) object(%s) permissions(%o) - DEC %d\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, path, uap->mode, uap->mode);
}
if (securelevel_ge(td->td_ucred, 1) != 0) {
if (((albino_squirrel_restrictdirs) && (uap->mode > 16895) && (uap->mode <= 20479)) ||
((uap->mode > 41471) && (uap->mode <= 45055)) || ((uap->mode > 33279) && (uap->mode <= 36863)) ||
((uap->mode > 511) && (uap->mode <= 4095))) {
if (albino_squirrel_log) {
printf("BLOCKED LCHMOD uid(%d) pid(%d) ppid(%d) object(%s) permissions(%o)\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, path, uap->mode);
}
return (EPERM);
}
if ((albino_squirrel_luckysevens) && ((uap->mode == 4095) || (uap->mode == 41471) ||
(uap->mode == 33279) || (uap->mode == 16895))) { return (EPERM); }
}
return(lchmod(td, syscall_args));
}
/**************************************************************************************************/
// 490 AUE_FCHMODAT STD { int fchmodat(int fd, char *path, mode_t mode, int flag); }
/**************************************************************************************************/
static int albino_squirrel_fchmodat(struct thread *td, void *syscall_args) {
struct fchmodat_args *uap;
uap = (struct fchmodat_args *)syscall_args;
char path[255];
size_t done;
int error;
error = copyinstr(uap->path, path, 255, &done);
if (error != 0) { return(error); }
if (albino_squirrel_debug) {
printf("DEBUG fchmodat syscall -- uid(%d) pid(%d) ppid(%d) fd(%d) object(%s) permissions(%o) - DEC %d\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, uap->fd, path, uap->mode, uap->mode);
}
if (securelevel_ge(td->td_ucred, 1) != 0) {
if (((albino_squirrel_restrictdirs) && (uap->mode > 16895) && (uap->mode <= 20479)) ||
((uap->mode > 41471) && (uap->mode <= 45055)) || ((uap->mode > 33279) && (uap->mode <= 36863)) ||
((uap->mode > 511) && (uap->mode <= 4095))) {
if (albino_squirrel_log) {
printf("BLOCKED FCHMODAT uid(%d) pid(%d) ppid(%d) fd(%d) object(%s) permissions(%o)\n",
td->td_ucred->cr_uid, td->td_proc->p_pid, td->td_proc->p_pptr->p_pid, uap->fd, path, uap->mode);
}
return (EPERM);
}
if ((albino_squirrel_luckysevens) && ((uap->mode == 4095) || (uap->mode == 41471) ||
(uap->mode == 33279) || (uap->mode == 16895))) { return (EPERM); }
}
return(fchmodat(td, syscall_args));
}
/**************************************************************************************************/
static int load(struct module *module, int cmd, void *arg) {
int error = 0;
switch (cmd) {
case MOD_LOAD:
printf("albino_squirrel loaded chmod,fchmod,lchmod,fchmodat restrictions while in high securelevels\n");
sysent[SYS_chmod].sy_call = (sy_call_t *)albino_squirrel_chmod;
sysent[SYS_fchmod].sy_call = (sy_call_t *)albino_squirrel_fchmod;
sysent[SYS_lchmod].sy_call = (sy_call_t *)albino_squirrel_lchmod;
sysent[SYS_fchmodat].sy_call = (sy_call_t *)albino_squirrel_fchmodat;
break;
case MOD_UNLOAD:
printf("albino_squirrel unloaded\n");
sysent[SYS_chmod].sy_call = (sy_call_t *)chmod;
sysent[SYS_fchmod].sy_call = (sy_call_t *)fchmod;
sysent[SYS_lchmod].sy_call = (sy_call_t *)lchmod;
sysent[SYS_fchmodat].sy_call = (sy_call_t *)fchmodat;
break;
default:
error = EOPNOTSUPP;
break;
}
return(error);
}
/**************************************************************************************************/
static moduledata_t albino_squirrel_hook_mod = { "albino_squirrel", load, NULL };
/**************************************************************************************************/
DECLARE_MODULE(albino_squirrel, albino_squirrel_hook_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
/**************************************************************************************************/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment