-
Notifications
You must be signed in to change notification settings - Fork 1
/
kspids-0.0.2-kernel-2.6.24.7.patch
321 lines (309 loc) · 9.26 KB
/
kspids-0.0.2-kernel-2.6.24.7.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
--- linux-2.6.24.7_orig/fs/exec.c 2008-05-07 01:22:34.000000000 +0200
+++ linux-2.6.24.7_new/fs/exec.c 2008-05-09 16:01:25.000000000 +0200
@@ -1352,6 +1352,10 @@ int do_execve(char * filename,
retval = search_binary_handler(bprm,regs);
if (retval >= 0) {
/* execve success */
+
+ /* register exec in spids */
+ security_kspids_register(KSPIDS_EXECVE, current->user->uid, filename);
+
free_arg_pages(bprm);
security_bprm_free(bprm);
acct_update_integrals(current);
--- linux-2.6.24.7_orig/include/linux/security.h 2008-05-07 01:22:34.000000000 +0200
+++ linux-2.6.24.7_new/include/linux/security.h 2008-05-09 16:02:43.000000000 +0200
@@ -110,6 +110,9 @@ struct request_sock;
#define LSM_UNSAFE_PTRACE 2
#define LSM_UNSAFE_PTRACE_CAP 4
+/* kernel service profile IDS */
+#define KSPIDS_EXECVE 1
+
#ifdef CONFIG_SECURITY
/**
@@ -1429,6 +1432,10 @@ struct security_operations {
int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall);
#endif /* CONFIG_SECURITY_NETWORK_XFRM */
+#ifdef CONFIG_SECURITY_KSPIDS
+ void (*kspids_register)(int cmd, uid_t uid, char *filename);
+#endif /* CONFIG_SECURITY_KSPIDS */
+
/* key management security hooks */
#ifdef CONFIG_KEYS
int (*key_alloc)(struct key *key, struct task_struct *tsk, unsigned long flags);
@@ -2559,6 +2566,15 @@ static inline void security_skb_classify
#endif /* CONFIG_SECURITY_NETWORK_XFRM */
+#ifdef CONFIG_SECURITY_KSPIDS
+void security_kspids_register(int cmd, uid_t uid, char *filename);
+#else /* CONFIG_SECURITY_KSPIDS */
+static inline void security_kspids_register(int cmd, uid_t uid, char *filename)
+{
+}
+#endif /* CONFIG_SECURITY_KSPIDS */
+
+
#ifdef CONFIG_KEYS
#ifdef CONFIG_SECURITY
--- linux-2.6.24.7_orig/security/security.c 2008-05-07 01:22:34.000000000 +0200
+++ linux-2.6.24.7_new/security/security.c 2008-05-09 16:03:48.000000000 +0200
@@ -1061,6 +1061,13 @@ EXPORT_SYMBOL(security_skb_classify_flow
#endif /* CONFIG_SECURITY_NETWORK_XFRM */
+#ifdef CONFIG_SECURITY_KSPIDS
+void security_kspids_register(int cmd, uid_t uid, char *filename)
+{
+ security_ops->kspids_register(cmd, uid, filename);
+}
+#endif /* CONFIG_SECURITY_KSPIDS */
+
#ifdef CONFIG_KEYS
int security_key_alloc(struct key *key, struct task_struct *tsk, unsigned long flags)
--- linux-2.6.24.7_orig/security/Makefile 2008-05-07 01:22:34.000000000 +0200
+++ linux-2.6.24.7_new/security/Makefile 2008-05-09 16:03:34.000000000 +0200
@@ -16,3 +16,4 @@ obj-$(CONFIG_SECURITY) += security.o d
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
+obj-$(CONFIG_SECURITY_KSPIDS) += kspids.o
--- linux-2.6.24.7_orig/security/Kconfig 2008-05-07 01:22:34.000000000 +0200
+++ linux-2.6.24.7_new/security/Kconfig 2008-05-09 16:03:11.000000000 +0200
@@ -103,6 +103,13 @@ config SECURITY_ROOTPLUG
If you are unsure how to answer this question, answer N.
+config SECURITY_KSPIDS
+ bool "Kernel Service Profile IDS"
+ depends on SECURITY
+ help
+ KSPIDS monitors the behavior of users of services. It can be
+ configured by the super user.
+
source security/selinux/Kconfig
endmenu
--- /dev/null 2008-04-23 18:27:10.000000000 +0200
+++ linux-2.6.24.7_new/security/kspids.c 2008-05-09 16:06:34.000000000 +0200
@@ -0,0 +1,227 @@
+/*
+ * Kernel Service Profile Intrusion Detection System
+ *
+ * Written by Steffen Wendzel
+ *
+ * Copyright (C) 2008 Steffen Wendzel <steffen (at) wendzel (dot) de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 3 of the
+ * License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/security.h>
+
+#define KSPIDS_UID_MIN 1
+#define KSPIDS_UID_MAX 999
+
+#define KSPIDS_ATKLVL_DEF 20 /* def. atk-level for new usr */
+#define KSPIDS_ATKLVL_MAX 99 /* "max." atk-level (=max. risk) */
+#define KSPIDS_ATKLVL_HIGH 80
+#define KSPIDS_ATKLVL_MEDIUM 60
+#define KSPIDS_ATKLVL_LOW 40
+#define KSPIDS_ATKLVL_DEFDEC 10 /* val. to dec. the atk-level if nothing happens */
+
+#define KSPIDS_COUNTER_MAX 0x7f
+#define KSPIDS_ATKLVL_INC_NEWPROG 80 /* value to inc. on new prog */
+#define KSPIDS_ATKLVL_CNTHIGH 99
+#define KSPIDS_ATKLVL_INC_CNTHIGH 0 /* don't increment on usual prog */
+#define KSPIDS_ATKLVL_CNTMEDIUM 20
+#define KSPIDS_ATKLVL_INC_CNTMEDIUM 15 /* medium-used prog */
+#define KSPIDS_ATKLVL_CNTLOW 3
+#define KSPIDS_ATKLVL_INC_CNTLOW 30 /* unfrequently used prog */
+#define KSPIDS_ATKLVL_INC_CNTLIKENEW 35 /* > 1 && < KSPIDS_ATKLVL_CNTLOW */
+
+struct kspids_filelist {
+ char *filename;
+ /* counter: 0 ... KSPIDS_COUNTER_MAX (=max val.) */
+ int counter;
+ struct list_head list;
+};
+
+struct kspids_uidlist {
+ uid_t uid;
+ s16 atklvl;
+ struct kspids_filelist *fl;
+ struct list_head list;
+};
+
+static struct kspids_uidlist *ul = NULL;
+
+static void kspids_alert_memalloc(void);
+
+static void kspids_alert_memalloc()
+{
+ printk(KERN_DEBUG "kspids:kmalloc() returned NULL\n");
+}
+
+static void kspids_alert_idslvl(struct kspids_uidlist *ulp)
+{
+ static char low[] = "low",
+ medium[] = "medium",
+ high[] = "HIGH";
+ char *p;
+
+ if (ulp->atklvl > KSPIDS_ATKLVL_HIGH)
+ p = high;
+ else if (ulp->atklvl > KSPIDS_ATKLVL_MEDIUM)
+ p = medium;
+ else
+ p = low;
+
+ printk("kspids attacker level alert for user %u (level is %s)\n",
+ ulp->uid, p);
+}
+
+static void kspids_ids_atklvl(struct kspids_uidlist *ulp)
+{
+ /* check the value and print out warning log message, if needed */
+
+ if (ulp->atklvl > KSPIDS_ATKLVL_LOW)
+ kspids_alert_idslvl(ulp);
+
+ /* default-decrease attacker level now */
+ ulp->atklvl -= KSPIDS_ATKLVL_DEFDEC;
+ /* if -lt 0, set back to zero */
+ if (ulp->atklvl < (s16) 0)
+ ulp->atklvl = 0;
+ /* if -gt MAX, set back to MAX */
+ if (ulp->atklvl > KSPIDS_ATKLVL_MAX)
+ ulp->atklvl = KSPIDS_ATKLVL_MAX;
+}
+
+static void kspids_register_filename(struct kspids_uidlist *ulp, char *filename)
+{
+ struct kspids_filelist *new = NULL;
+
+ if (!ulp->fl) {
+ ulp->fl = (struct kspids_filelist *)
+ kmalloc(sizeof(struct kspids_filelist), GFP_KERNEL);
+ if (!ulp->fl) {
+ kspids_alert_memalloc();
+ return;
+ }
+ INIT_LIST_HEAD(&ulp->fl->list);
+ new = ulp->fl;
+ } else {
+ /* try to find the filename and add it, in the case we could
+ * not find it.
+ */
+ struct list_head *p, *n;
+ struct kspids_filelist *ufp;
+ u8 found = 0;
+
+ list_for_each_safe(p, n, &ulp->fl->list) {
+ ufp = list_entry(p, struct kspids_filelist, list);
+ if (strcmp(ufp->filename, filename) == 0) {
+ found = 1;
+ if (ufp->counter < KSPIDS_COUNTER_MAX) {
+ ufp->counter++;
+ if (ufp->counter > KSPIDS_ATKLVL_CNTHIGH)
+ ulp->atklvl += KSPIDS_ATKLVL_INC_CNTHIGH;
+ else if (ufp->counter > KSPIDS_ATKLVL_CNTMEDIUM)
+ ulp->atklvl += KSPIDS_ATKLVL_INC_CNTMEDIUM;
+ else if (ufp->counter > KSPIDS_ATKLVL_CNTLOW)
+ ulp->atklvl += KSPIDS_ATKLVL_INC_CNTLOW;
+ else /* still very unfrequently used tool! */
+ ulp->atklvl += KSPIDS_ATKLVL_INC_CNTLIKENEW;
+ }
+ }
+ }
+ if (!found) {
+ new = (struct kspids_filelist *)
+ kmalloc(sizeof(struct kspids_filelist), GFP_KERNEL);
+ if (!new) {
+ kspids_alert_memalloc();
+ return;
+ }
+ list_add(&new->list, &ulp->fl->list);
+ }
+ }
+ if (new) {
+ /* this should not lead to an integer overflow because of MAX_PATHLEN */
+ u16 len;
+ len = strlen(filename) * sizeof(char);
+ new->filename = (char *) kmalloc(len + 1, GFP_KERNEL);
+ if (!new->filename) {
+ kspids_alert_memalloc();
+ return;
+ }
+ new->filename[len] = '\0';
+ strncpy(new->filename, filename, len);
+ new->counter = 1;
+ /* increase attacker level here */
+ ulp->atklvl += KSPIDS_ATKLVL_INC_NEWPROG;
+ printk("kspids: registered UID=%u, binary=%s\n", ulp->uid, filename);
+ }
+ return;
+}
+
+void security_kspids_register(int cmd, uid_t uid, char *filename)
+{
+ struct kspids_uidlist *new = NULL;
+
+ /* only monitor UIDs within a given range */
+ if (uid < KSPIDS_UID_MIN || uid > KSPIDS_UID_MAX)
+ return;
+
+ if (!ul) {
+ /* create a new ul list head for this user */
+ ul = (struct kspids_uidlist *)
+ kmalloc(sizeof(struct kspids_uidlist), GFP_KERNEL);
+ if (!ul) {
+ kspids_alert_memalloc();
+ return;
+ }
+ INIT_LIST_HEAD(&ul->list);
+ new = ul;
+ } else {
+ /* try to find the user and add him, if not found, at
+ * the end of the list.
+ */
+ struct list_head *p, *n;
+ struct kspids_uidlist *ulp;
+ u8 found = 0;
+
+ list_for_each_safe(p, n, &ul->list) {
+ ulp = list_entry(p, struct kspids_uidlist, list);
+ if (ulp->uid == uid) {
+ found = 1;
+ switch (cmd) {
+ case KSPIDS_EXECVE:
+ kspids_register_filename(ulp, filename);
+ break;
+ }
+ kspids_ids_atklvl(ulp);
+ }
+ }
+ if (!found) {
+ /* create new element */
+ new = (struct kspids_uidlist *)
+ kmalloc(sizeof(struct kspids_uidlist), GFP_KERNEL);
+ if (!new) {
+ kspids_alert_memalloc();
+ return;
+ }
+ list_add(&new->list, &ul->list);
+ }
+
+ }
+ /* if there is a new element, fill it with data */
+ if (new) {
+ new->uid = uid;
+ new->fl = NULL;
+ new->atklvl = KSPIDS_ATKLVL_DEF;
+ switch (cmd) {
+ case KSPIDS_EXECVE:
+ kspids_register_filename(new, filename);
+ break;
+ }
+ kspids_ids_atklvl(new);
+ }
+ return;
+}
+