Linux IDS攻略(4)

发表于:2007-06-23来源:作者:点击数: 标签:
Linux IDS攻略 lids解决办法: 对于2.4用户: http://www.lids.org/download/lids-1.1.1pre2-2.4.16.tar.gz http://www.lids.org/download/lids-1.1.1pre2-2.4.16.tar.gz.asc (或者lids-1.1.1pre2以后的版本) 对于2.2用户: http://www.lids.org/download/

   
  Linux IDS攻略
    lids解决办法:

对于2.4用户:
http://www.lids.org/download/lids-1.1.1pre2-2.4.16.tar.gz
http://www.lids.org/download/lids-1.1.1pre2-2.4.16.tar.gz.asc
(或者lids-1.1.1pre2以后的版本)

对于2.2用户:
http://www.lids.org/download/LIDS-security-patch-0.10.1-2.2.20.diff.gz
http://www.lids.org/download/LIDS-security-patch-0.10.1-2.2.20.diff.gz.asc
(或者lids-0.11.0以后的版本)

附capscan 源程序:
--------------[ stealth ]------
#cap.h
------------------------------
#ifndef __cap_h__
#define __cap_h__

#include

typedef struct __user_cap_header_struct cap_user_header;
typedef struct __user_cap_data_struct cap_user_data;

int capget(cap_user_header_t,cap_user_data_t);
int capset(cap_user_header_t,cap_user_data_t);
int print_cap(cap_user_data_t, cap_user_data_t);

int brute_caps();

#endif
----------------------
# cap.c
----------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "cap.h"

extern int wait(int *);

int try_chown()
{
char p[] = "/tmp/fooXXXXXX";
int r, fd = mkstemp(p);
if (fd < 0)
return 0;
close(fd);

/* try a give-away */
if (chown(p, getuid()+1, getgid()+1) < 0)
r = 0;
else
r = 1;

unlink(p);
return r;
}

int try_setuid()
{
int euid = geteuid();

if (seteuid(euid + 1) < 0)
return 0;

seteuid(euid);
return 1;
}

int try_setgid()
{
int egid = getegid();

if (setegid(egid + 1) < 0)
return 0;

setegid(egid);
return 1;
}

int try_kill()
{
/* XXX: suffices? */
if (kill(1, SIGCONT) < 0)
return 0;
return 1;
}

int try_bind()
{
struct sockaddr_in sin;
int r, fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
return 0;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(666);

if (bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
r = 0;
else
r = 1;

close(fd);
return r;
}

int try_net_raw()
{
int fd = socket(PF_INET, SOCK_RAW, 0);

if (fd >= 0) {
close(fd);
return 1;
}
return 0;
}

int try_nice()
{
return (nice(-1) == 0);
}

extern caddr_t create_module(const char *, size_t);

int try_module()
{
errno = 0;
create_module("adore", 1234);
delete_module("adore");
return (errno == 0);
}

int try_chroot()
{
int r;
if (fork() == 0) {
if (chroot("/tmp") < 0)
exit(0);
else
exit(1);
}
wait(&r);
return r != 0;
}

int try_rawio()
{
int fd = open("/dev/kmem", O_RDONLY);
if (fd < 0)
return 0;
close(fd);
return 1;
}

int try_admin()
{
char h[1024];
memset(h, 0, sizeof(h));
gethostname(h, sizeof(h));
if (sethostname("hola!", 5) < 0)
return 0;
sethostname(h, strlen(h));
return 1;
}

int try_net_admin()
{
int sock;
struct ifreq ifr;

strcpy(ifr.ifr_name, "lo");

if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
return 0;

if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0)
return 0;

ifr.ifr_flags &= ~IFF_UP;
if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0)
return 0;

ifr.ifr_flags  = IFF_UP;
ioctl(sock, SIOCSIFFLAGS, &ifr);
close(sock);
return 1;
}

int try_ptrace()
{
int child, r = 0;

if ((child = fork()) == 0) {
sleep(10);
exit(0);
}
if (ptrace(PTRACE_ATTACH, child, 0, 0) < 0)
r = 0;
else
r = 1;
kill(child, SIGKILL);
wait(NULL);
return r;
}

int try_mknod()
{
unlink("/tmp/fd0");
if (mknod("/tmp/fd0", 0600 S_IFCHR, 2<<8) < 0)
return 0;
unlink("/tmp/fd0");
return 1;
}

struct {
int value;
char *name;
int (*try)();
} caps[] = {
{0, "CAP_CHOWN", try_chown},
{1, "CAP_DAC_OVERRIDE", NULL},
{2, "CAP_DAC_READ_SEARCH", NULL},
{3, "CAP_FOWNER", NULL},
{4, "CAP_FSETID", NULL},
{5, "CAP_KILL", try_kill},
{6, "CAP_SETGID", try_setgid},
{7, "CAP_SETUID", try_setuid},
{8, "CAP_SETPCAP", NULL},
{9, "CAP_LINUX_IMMUTABLE", NULL},
{10, "CAP_NET_BIND_SERVICE", try_bind},
{11, "CAP_NET_BROADCAST", NULL},
{12, "CAP_NET_ADMIN", try_net_admin},
{13, "CAP_NET_RAW", try_net_raw},
{14, "CAP_IPC_LOCK", NULL},
{15, "CAP_IPC_OWNER", NULL},
{16, "CAP_SYS_MODULE", try_module},
{17, "CAP_SYS_RAWIO", try_rawio},
{18, "CAP_SYS_CHROOT", try_chroot},
{19, "CAP_SYS_PTRACE", try_ptrace},
{20, "CAP_SYS_PACCT", NULL},
{21, "CAP_SYS_ADMIN", try_admin},
{22, "CAP_SYS_BOOT", NULL},//haha :>
{23, "CAP_SYS_NICE", try_nice},
{24, "CAP_SYS_RESOURCE", NULL},
{25, "CAP_SYS_TIME", NULL},
{26, "CAP_SYS_TTY_CONFIG", NULL},
{27, "CAP_MKNOD", try_mknod},
{28, "CAP_LEASE", NULL},
{-1, (void*)0}
};

/* if (capable(d.cap_effective, CAP_SYS_MODULE)
* ...
*/
int capable(int cap, int flag)
{
return (cap & (1<}

int print_cap(cap_user_data_t new, cap_user_data_t old)
{
int i = 0;
FILE *f;

if (!new    !old)
return -1;

f = fopen("/dev/tty", "w+");
if (!f)
return -1;

fprintf(f, "nE %x nI %x nP %x\n"
"oE %x oI %x oP %x\n\n",
new->effective, new->inheritable, new->permitted,
old->effective, old->inheritable, old->permitted);

/* Print New's advanced (effective) caps over old ones */
/* HACK! This is left here due to a private version of capcan */
for (i = 0; caps[i].value != -1; ++i) {
if (capable(new->effective, caps[i].value) &&
!capable(old->effective, caps[i].value))
fprintf(f, "e %d %s\n", caps[i].value, caps[i].name);
}

printf("\n");

/* Print New's advanced (inhertiable) caps over old ones */
for (i = 0; caps[i].value != -1; ++i) {
if (capable(new->inheritable, caps[i].value) &&
!capable(old->inheritable, caps[i].value))
fprintf(f, "i %d %s\n", caps[i].value, caps[i].name);
}

/* No news */
if (new->effective == new->permitted)
return 0;

printf("\n");

/* Print New's advanced permitted caps */
for (i = 0; caps[i].value != -1; ++i) {
if (capable(new->permitted, caps[i].value) &&
!capable(old->permitted, caps[i].value))
fprintf(f, "p %d %s\n", caps[i].value, caps[i].name);
}

fclose(f);
return 0;
}

int brute_caps()
{
int i = 0;

for (; caps[i].value != -1; ++i) {
if (caps[i].try) {
if (caps[i].try()) {
printf("b %d %s\n", caps[i].value,
caps[i].name);
}
}
}
return 0;
}
-----------------------
#capscan.c
-----------------------
#include
#include
#include
#include
#include
#include
#include
#include
#include "cap.h"

extern pid_t wait(int *);

void die(const char *s)
{
perror(s);
exit(errno);
}

int main(int argc, char **argv)
{
cap_user_header h;
cap_user_data d, we;

h.version = _LINUX_CAPABILITY_VERSION;
h.pid = 0;

if (argc < 2) {
fprintf(stderr, "Usage: %s [-w] [-b]\n", *argv);
exit(1);
}

/* Just print the caps we have yet */
if (argv[1][1] == 'w') {
if (capget(&h, &we) < 0)
die("capget");

memset(&d, 0, sizeof(d));
print_cap(&we, &d);

} else if (argv[1][1] == 'b') {
brute_caps();
}
return 0;
}
-------------------

后语:
就我个人认为,LIDS是个好软件,适合安装在linux服务器上,保护进程和重要文件,防止root权限滥用。建议使用最新的稳定版本而且注意升级,如果用老版本的话就一定要合理认真的配置,否则还不如不装。

参考文献:
http://www.lids.org的相关文档和FAQ
Linux下的入侵监测系统LIDS
用LIDS建立安全的系统

原文转自:http://www.ltesting.net