source: trunk/src/samhain_setpwd.c@ 14

Last change on this file since 14 was 1, checked in by katerina, 19 years ago

Initial import

File size: 8.4 KB
Line 
1#include "config_xor.h"
2
3#ifdef HAVE_BROKEN_INCLUDES
4#define _ANSI_C_SOURCE
5#define _POSIX_SOURCE
6#endif
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <ctype.h>
12
13#include <unistd.h>
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <fcntl.h>
17#include <time.h>
18
19
20#ifdef SH_STEALTH
21char * globber(const char * string);
22#define _(string) globber(string)
23#define N_(string) string
24#else
25#define _(string) string
26#define N_(string) string
27#endif
28
29#ifdef SH_STEALTH
30#ifndef SH_MAX_GLOBS
31#define SH_MAX_GLOBS 32
32#endif
33char * globber(const char * str)
34{
35 register int i, j;
36 static int count = -1;
37 static char glob[SH_MAX_GLOBS][128];
38
39 ++count; if (count > (SH_MAX_GLOBS-1) ) count = 0;
40 j = strlen(str);
41 if (j > 127) j = 127;
42
43 for (i = 0; i < j; ++i)
44 {
45 if (str[i] != '\n' && str[i] != '\t')
46 glob[count][i] = str[i] ^ XOR_CODE;
47 else
48 glob[count][i] = str[i];
49 }
50 glob[count][j] = '\0';
51 return glob[count];
52}
53#endif
54
55/* This is a very inefficient algorithm, but there is really no
56 * need for anything more elaborated here. Can handle NULL's in haystack
57 * (not in needle), which strstr() apparently cannot.
58 */
59char * my_strstr (char * haystack, char * needle, int haystack_size)
60{
61 register int i = 0, j = 0;
62 register int siz;
63 register char * ptr = haystack;
64 register int len;
65
66 siz = strlen(needle);
67 len = haystack_size - siz;
68
69 while (j < len)
70 {
71 i = 0;
72 while (i < siz)
73 {
74 if (needle[i] != ptr[i]) break;
75 if (i == (siz-1))
76 return ptr;
77 ++i;
78 }
79 ++ptr; ++j;
80 }
81 return NULL;
82}
83
84/* fread() does not return the number of chars read, thus we need to
85 * read only a small number of bytes, in order not to expand the binary
86 * too much with the last fwrite(). Too lazy to fix this now.
87 */
88#define GRAB_SIZE 1024
89
90int readhexchar ( char c )
91{
92 if ( c >= '0' && c <= '9' )
93 return c - '0';
94 else if ( c >= 'a' && c <= 'f' )
95 return c - 'a' + 10;
96 else if ( c >= 'A' && c <= 'F' )
97 return c - 'A' + 10;
98 else return -1;
99}
100
101int main (int argc, char * argv[])
102{
103 /* the default password
104 */
105 unsigned char TcpFlag[9] = { 0xF7,0xC3,0x12,0xAA,0xAA,0x12,0xC3,0xF7 };
106 unsigned char BadFlag[9] = { 0xFF,0xC3,0x12,0xAA,0xAA,0x12,0xC3,0xFF };
107
108 char * found_it;
109 int i;
110 int suc = 0;
111 int badcnt = 0;
112
113 char * newn;
114 int oldf;
115 int newf;
116
117 unsigned long bytecount;
118
119 char in[9];
120 int j, k;
121 char ccd;
122 char * str;
123
124 char * buf = (char *) malloc(GRAB_SIZE);
125 size_t dat;
126 char * newpwd = (char *) malloc(5 * 8 + 2);
127 char * oldpwd = (char *) malloc(5 * 8 + 2);
128
129 memset (newpwd, '\0', 5 * 8 + 2);
130 memset (oldpwd, '\0', 5 * 8 + 2);
131
132
133 if (argc < 4)
134 {
135 fprintf (stderr, _("\nUsage: samhain_setpwd <filename> <suffix> "\
136 "<new_password>\n\n"));
137 fprintf (stderr, _(" This program is a utility that will:\n"));
138 fprintf (stderr, _(" - search in the binary executable <filename> "\
139 "for samhain's\n"));
140 fprintf (stderr, _(" compiled-in default password,\n"));
141 fprintf (stderr, _(" - change it to <new_password>,\n"));
142 fprintf (stderr, _(" - and output the modified binary to "\
143 "<filename>.<suffix>\n\n"));
144 fprintf (stderr, _(" To allow for non-printable chars, "\
145 "<new_password> must be\n"));
146 fprintf (stderr, _(" a 16-digit hexadecimal "\
147 "number (only 0-9,A-F allowed in input),\n"));
148 fprintf (stderr, _(" thus corresponding"\
149 " to an 8-byte password.\n\n"));
150 fprintf (stderr, _(" Example: 'samhain_setpwd samhain new "\
151 "4142434445464748'\n"));
152 fprintf (stderr, _(" takes the file 'samhain', sets the password to "\
153 "'ABCDEFGH'\n"));
154 fprintf (stderr, _(" ('A' = 41 hex, 'B' = 42 hex, ...) "\
155 "and outputs the result\n"));
156 fprintf (stderr, _(" to 'samhain.new'.\n"));
157 return EXIT_FAILURE;
158 }
159
160 if (strlen(argv[3]) != 16)
161 {
162 fprintf (stdout, _("ERROR <new_password> %s has not exactly 16 chars\n"),
163 argv[0]);
164 fflush(stdout);
165 return EXIT_FAILURE;
166 }
167
168
169 str = &argv[3][0];
170 i = 0;
171 while (i < 16)
172 {
173 k = i/2; j = 0;
174 if (2*k == i) in[k] = 0;
175 while (j < 16)
176 {
177 if (-1 != readhexchar(str[i]))
178 {
179 in[k] += readhexchar(str[i]) * (i == 2*k ? 16 : 1);
180 break;
181 }
182 ++j;
183 if (j == 16)
184 {
185 fprintf(stdout, _("ERROR Invalid char %c\n"), str[i]);
186 fflush(stdout);
187 return EXIT_FAILURE;
188 }
189 }
190 ++i;
191 }
192 in[8] = '\0';
193
194 /* ---- initialize -----
195 */
196 (void) umask (0);
197
198 srand(time(NULL) ^ getpid());
199
200 bytecount = 0;
201
202
203 /* ---- open files -----
204 */
205
206 oldf = open(argv[1], O_RDONLY);
207
208 newn = (char *) malloc (strlen(argv[1])+strlen(argv[2])+2);
209 strcpy(newn, argv[1]);
210 strcat(newn, ".");
211 strcat(newn, argv[2]);
212 newf = open(newn, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
213
214 if (oldf < 0)
215 {
216 fprintf(stdout, _("ERROR Cannot open input file %s.\n"), argv[1]);
217 fflush(stdout);
218 return EXIT_FAILURE;
219 }
220 if (newf < 0)
221 {
222 fprintf(stdout, _("ERROR Cannot open output file %s.\n"), newn);
223 fflush(stdout);
224 return EXIT_FAILURE;
225 }
226
227 /* ---- scan file -----
228 */
229
230
231 while (1)
232 {
233 dat = read (oldf, buf, GRAB_SIZE);
234 if (dat == 0)
235 break;
236
237 bytecount += dat;
238
239 while ( (found_it = my_strstr(buf, (char *) TcpFlag, GRAB_SIZE)) != NULL)
240 {
241 suc = 1;
242 fprintf (stdout, _("INFO old password found\n"));
243 fflush(stdout);
244 for (i = 0; i < 8; ++i)
245 {
246 sprintf(&oldpwd[i*2], _("%02x"),
247 (unsigned char) *found_it);
248 sprintf(&newpwd[i*2], _("%02x"),
249 (unsigned char) in[i]);
250 *found_it = in[i];
251 ++found_it;
252 }
253 fprintf (stdout, _("INFO replaced: %s by: %s\n"),
254 oldpwd, newpwd);
255 fflush(stdout);
256 }
257
258 while ( (found_it = my_strstr(buf, (char *) BadFlag, GRAB_SIZE)) != NULL)
259 {
260 badcnt++;
261 /* fprintf (stderr, _("INFO old filler found\n")); */
262 for (i = 0; i < 8; ++i)
263 {
264 sprintf(&oldpwd[i*2], _("%02x"),
265 (unsigned char) *found_it);
266
267 ccd = (unsigned char) (256.0 * rand()/(RAND_MAX+1.0));
268 sprintf(&newpwd[i*2], _("%02x"),
269 (unsigned char) ccd);
270 *found_it = ccd;
271
272 ++found_it;
273 }
274 /* fprintf (stderr, _("INFO replaced: %s by: %s\n"),
275 oldpwd, newpwd);
276 */
277 }
278
279
280 write (newf, buf, dat);
281 }
282
283 if (suc == 1 && badcnt == 7)
284 {
285 fprintf (stdout, _("INFO finished\n"));
286 close (newf);
287 close (oldf);
288 fflush(stdout);
289 return (0);
290 }
291
292 lseek (oldf, 0, SEEK_SET);
293 lseek (newf, 0, SEEK_SET);
294
295 fprintf (stdout, _("INFO Not found in first pass.\n"));
296 fprintf (stdout, _("INFO Second pass ..\n"));
297
298 /* offset the start point
299 */
300
301 dat = read (oldf, buf, (GRAB_SIZE / 2));
302 write (newf, buf, dat);
303
304 bytecount = 0;
305 suc = 0;
306 badcnt = 0;
307
308 while (1)
309 {
310 dat = read (oldf, buf, GRAB_SIZE);
311 if (dat == 0)
312 break;
313
314 bytecount += dat;
315
316 while ( (found_it = my_strstr(buf, (char *) TcpFlag, GRAB_SIZE)) != NULL)
317 {
318 suc = 1;
319 fprintf (stdout, _("INFO old password found\n"));
320 for (i = 0; i < 8; ++i)
321 {
322 sprintf(&oldpwd[i*2], _("%02x"),
323 (unsigned char) *found_it);
324 sprintf(&newpwd[i*2], _("%02x"),
325 (unsigned char) in[i]);
326 *found_it = in[i];
327 ++found_it;
328 }
329 fprintf (stdout, _("INFO Replaced: %s by: %s\n"),
330 oldpwd, newpwd);
331 }
332
333 while ( (found_it = my_strstr(buf, (char *) BadFlag, GRAB_SIZE)) != NULL)
334 {
335 badcnt++;
336 /* fprintf (stderr, _("INFO old filler found\n")); */
337 for (i = 0; i < 8; ++i)
338 {
339 sprintf(&oldpwd[i*2], _("%02x"),
340 (unsigned char) *found_it);
341
342 ccd = (unsigned char) (256.0 * rand()/(RAND_MAX+1.0));
343 sprintf(&newpwd[i*2], _("%02x"),
344 (unsigned char) ccd);
345 *found_it = ccd;
346
347 ++found_it;
348 }
349 /* fprintf (stderr, _("INFO Replaced: %s by: %s\n"),
350 oldpwd, newpwd);*/
351 }
352
353 write (newf, buf, dat);
354 }
355
356 close (newf);
357 close (oldf);
358
359 if (suc == 1 && badcnt == 7)
360 {
361 fprintf (stdout, _("INFO finished\n"));
362 fflush(stdout);
363 return 0;
364 }
365
366 if (suc == 0 || badcnt < 7)
367 {
368 fprintf (stdout, _("ERROR incomplete replacement\n"));
369 }
370 else
371 {
372 fprintf (stdout, _("ERROR bad replacement\n"));
373 }
374 fflush(stdout);
375 return EXIT_FAILURE;
376}
Note: See TracBrowser for help on using the repository browser.