// medusa config file // // This file introduces a small extension to "net_safe" configuration // file. Study it, when you understood net_safe. // // New 2 bits introduce the write and read worlds for /bin/bash2, // absolutely restricted shell. I used to let it run on my machine in // a non-secure environment to allow some people to use it as terminal. // // Redirects my homedirs /home/www and /root (I have sensitive data there), // redirects /tmp (won't let 'insecure' apps interact with 'secure' ones), // write access only to explicitly defined places. // // Milan Pikula // recursive for set "/" vs=0b0000000000010011; // network sees, local has it recursive for set "/medusa" vs=0b0000000000000001; // only local recursive for set "/home/www" vs=0b0000000000000111; // net can modify and see, local have it recursive for set "/root" vs=0b0000000000000111; // net can modify and see, local have it for set "/home/root" vs=0b0000000000011111; for set "/home/root2" vs=0b0000000000011111; for access "/home/root" { if (vs == 0b0000000000011000) redirect "/home/root2"; } recursive for set "/tmp" vs=0b0000000000000111; for set "/tmp" vs=0b0000000000011111; recursive for set "/tmp2" vs=0b0000000000011000; for access "/tmp" { if (vs == 0b0000000000011000) redirect "/tmp2"; } recursive for set "/var/log" vs=0b0000000000000111; recursive for set "/var/run" vs=0b0000000000000111; recursive for set "/dev/{t,p}ty{,1,2,3,4,5,6,??}" vs=0b0000000000011111; recursive for set "/dev/{zero,null,urandom}" vs=0b0000000000011111; for set "/dev/hd.*" vs=0b0000000000000011; for set "/dev/{mem,kmem}" vs=0b0000000000000011; for set "/proc/kcore" vs=0b0000000000000011; recursive for set "/home/session" vs=0b0000000000011000; on exec { procact = P_PTRACE; if (vs == 0b0000000000011000) { procact |= P_SEXEC | P_SETUID | P_KILL; } } on sexec { if (vs == 0b0000000000011000) { answer = SKIP; euid = target_euid; session; log ":) Someone got EUID " euid " via sexec()"; } } on setuid { if (vs == 0b0000000000011000) { log ":) Someone got UID " uid " via setuid()"; } } on ptrace { if (vs == 0b0000000000011000) { if (uid==target_euid || euid==0) answer = OK; else answer = NO; } else answer = OK; } function session { if (pid==1) /* don't restrict init */ return 1; ecap = CAP_SETUID | CAP_SETGID; pcap = ecap; icap = ecap; vs =0b0000000000011000; vss=0b0000000000011000; vsr=0b0000000000011000; vsw=0b0000000000001000; procact|=P_KILL|P_SEXEC|P_SETUID; fsact = FS_UNLINK; } recursive for unlink "/" { log "lalala"; } /* this will restrict any process that has something to do with network */ function restrict { if (pid==1) /* don't restrict init */ return 1; fsact |= FS_UNLINK; /* watch the unlinks */ vs = 0b110; vss = 0b110; vsr /= 0b001; /* can read only files that have at least one of the first two virtual spaces set. */ vsw /= 0b011; /* can write only files that have the first virtual space set. */ ecap/=CAP_SETPCAP|CAP_LINUX_IMMUTABLE|CAP_NET_RAW |CAP_IPC_OWNER|CAP_SYS_MODULE |CAP_SYS_RAWIO|CAP_SYS_PTRACE|CAP_SYS_BOOT |CAP_SYS_NICE|CAP_SYS_RESOURCE|CAP_SYS_TIME; procact|=P_KILL; // log_proc "restrict"; } on syscall { if (vs == 0b0000000000011000) { if (action == 127) answer = MED_NOT; if (action == 110) answer = MED_NOT; if (action == 101) answer = MED_NOT; trace_on 127 110 101; return 0; } else vs /= 0b0000000000011000; if (action == 102) { /* socketcall */ if ( trace1 == 1 /* SYS_SOCKET */ and lpeek trace2 $x /* verify_area() */ and $x == 2 /* PF_INET */ ) { // it opens an inet socket if (flags ?& 0b10) /* login hack? */ { answer = MED_NOT; log "login hack"; } // otherwise, if it is not trusted process and if // it still is `local', restrict it. /********* else if (flags ?! 0b01 && vs ?& 0b01) { log "Process " pid " is restricted now."; restrict; } *********/ } } else /* we are not interested in other system calls */ trace_off action; } // trusted programs - they keep their mode (restricted/full) when // they call socket(): for exec "/sbin/{route,ifconfig,ipchains}" flags|=0b01; for exec "/bin/login" { // login hack: mark /bin/login as flags |= 0b10; // the program, which cannot open // the socket procact|=P_EXEC; // and turn on the exec watching to // turn this flag off for logins // successor. } for exec "/usr/sbin/syslogd" { // seems like we trust this (to keep this config small) // reason: both local and network processes wants to use this. vs=0b111; } for exec "/bin/bash2" { session; } for exec "/bin/ping" { ecap |= CAP_NET_RAW; icap |= CAP_NET_RAW; pcap |= CAP_NET_RAW; } on exec { // turn off the login hack for logins successor (whoever it is) if( action==0 /* pred execom */ and flags ?& 0b10 ) { flags/=0b10; // turn it off procact /= P_EXEC; // and we don't care about EXEC anymore } } on fork { // we must check, if the `local' process is not trying to make // the inet socket. if (vs ?& 0b001) { trace_on 102; vs/=0b110; // to fix the default 0b111 value } } on kill { // `network' user cannot kill constable or init process if (vs ?! 0b001) if (target_pid==constable_pid or target_pid==1) answer=MED_NOT; } /* network users have different passwords */ for access "/etc/shadow" if(vs ?! 0b001) redirect "/etc/shadow.net"; for access "/etc/passwd" if(vs ?! 0b001) redirect "/etc/passwd.net"; /************************************************************************/ // the portal to another dimension - just a pure 'ps' process. for exec "/bin/pshacker" if (vs ?! 0b110) { vs = 0b111; // local users see the network processes via vss = 0b11111; // pshacker } else redirect "/usr/games/trek"; // but network users can // only play startrek.