summaryrefslogtreecommitdiff
path: root/src/usr.bin/nc/data
diff options
context:
space:
mode:
authorderaadt <>1996-09-05 08:55:43 +0000
committerderaadt <>1996-09-05 08:55:43 +0000
commitc7823c0917675fd1ab482937ee1bd01d837b081c (patch)
treede25439975bbe0baac0f70799dad301539b7be3b /src/usr.bin/nc/data
parentc215a9e8412ead0190b788622f09bcdbb08794fa (diff)
downloadopenbsd-c7823c0917675fd1ab482937ee1bd01d837b081c.tar.gz
openbsd-c7823c0917675fd1ab482937ee1bd01d837b081c.tar.bz2
openbsd-c7823c0917675fd1ab482937ee1bd01d837b081c.zip
nc is *hobbit*'s netcat; let the sysadm have the same tools the crackers
have, so that he may learn what the network is about and protect it better.
Diffstat (limited to 'src/usr.bin/nc/data')
-rw-r--r--src/usr.bin/nc/data/Makefile10
-rw-r--r--src/usr.bin/nc/data/README9
-rw-r--r--src/usr.bin/nc/data/data.c274
-rw-r--r--src/usr.bin/nc/data/dns-any.d36
-rw-r--r--src/usr.bin/nc/data/nfs-0.d59
-rw-r--r--src/usr.bin/nc/data/pm.d8
-rw-r--r--src/usr.bin/nc/data/pmap-dump.d60
-rw-r--r--src/usr.bin/nc/data/pmap-mnt.d78
-rw-r--r--src/usr.bin/nc/data/rip.d52
-rw-r--r--src/usr.bin/nc/data/rservice.c68
-rw-r--r--src/usr.bin/nc/data/showmount.d63
-rw-r--r--src/usr.bin/nc/data/xor.c92
12 files changed, 809 insertions, 0 deletions
diff --git a/src/usr.bin/nc/data/Makefile b/src/usr.bin/nc/data/Makefile
new file mode 100644
index 0000000000..65cf185358
--- /dev/null
+++ b/src/usr.bin/nc/data/Makefile
@@ -0,0 +1,10 @@
1all: data rservice xor
2
3data: data.c
4 cc -s -O -o data data.c
5rservice: rservice.c
6 cc -s -O -o rservice rservice.c
7xor: xor.c
8 cc -s -O -o xor xor.c
9clean:
10 rm -f *.o data rservice xor
diff --git a/src/usr.bin/nc/data/README b/src/usr.bin/nc/data/README
new file mode 100644
index 0000000000..7e4b9fbf63
--- /dev/null
+++ b/src/usr.bin/nc/data/README
@@ -0,0 +1,9 @@
1For now, read the header comments inside each of these for documentation.
2The programs are simple enough that they don't really need a Makefile any more
3complex than the one given; ymmv. Data and xor may also be useful on DOS,
4which is why there are hooks for it in the code.
5
6data.c a primitive atob / btoa byte generator
7*.d example input to "data -g"
8rservice.c a utility for scripting up rsh/rexec attacks
9xor.c generic xor handler
diff --git a/src/usr.bin/nc/data/data.c b/src/usr.bin/nc/data/data.c
new file mode 100644
index 0000000000..56c167fd96
--- /dev/null
+++ b/src/usr.bin/nc/data/data.c
@@ -0,0 +1,274 @@
1/* primitive arbitrary-data frontend for netcat. 0.9 960226
2 only handles one value per ascii line, but at least parses 0xNN too
3 an input line containing "%r" during "-g" generates a random byte
4
5 todo:
6 make work on msloss jus' for kicks [workin' on it...]
7
8 syntax: data -X [limit]
9 where X is one of
10 d: dump raw bytes to ascii format
11 g: generate raw bytes from ascii input
12 c: generate ??? of value -- NOTYET
13 r: generate all random bytes
14 and limit is how many bytes to generate or dump [unspecified = infinite]
15
16 *Hobbit*, started 951004 or so and randomly screwed around with since */
17
18#include <stdio.h>
19
20#ifdef MSDOS /* for MSC only at the moment... */
21#include <fcntl.h>
22#else /* MSDOS */
23#include <sys/file.h>
24#define HAVE_RANDOM /* XXX: might have to change */
25#endif /* MSDOS */
26
27static char buf_in [128];
28static char buf_raw [8192];
29static char surveysez[] = "survey sez... XXX\n";
30
31/* fgetss :
32 wrapper for fgets, that yanks trailing newlines. Doing the work ourselves
33 instead of calling strchr/strlen/whatever */
34char * fgetss (buf, len, from)
35 char * buf;
36 size_t len;
37 FILE * from;
38{
39 register int x;
40 register char * p, * q;
41 p = fgets (buf, len, from); /* returns ptr to buf */
42 if (! p)
43 return (NULL);
44 q = p;
45 for (x = 0; x < len; x++) {
46 *p = (*p & 0x7f); /* rip parity, just in case */
47 switch (*p) {
48 case '\n':
49 case '\r':
50 case '\0':
51 *p = '\0';
52 return (q);
53 } /* switch */
54 p++;
55 } /* for */
56} /* fgetss */
57
58/* randint:
59 swiped from rndb.c. Generates an INT, you have to mask down to char. */
60int randint()
61{
62 register int q;
63 register int x;
64
65#ifndef HAVE_RANDOM
66 q = rand();
67#else
68 q = random();
69#endif
70 x = ((q >> 8) & 0xff); /* perturb low byte using some higher bits */
71 x = q ^ x;
72 return (x);
73}
74
75main (argc, argv)
76 int argc;
77 char ** argv;
78{
79 register unsigned char * p;
80 register char * q;
81 register int x;
82 int bc = 0;
83 int limit = 0; /* num to gen, or 0 = infinite */
84 register int xlimit; /* running limit */
85 FILE * txt; /* line-by-line ascii file */
86 int raw; /* raw bytes fd */
87 int dumping = 0; /* cmd flags ... */
88 int genning = 0;
89 int randing = 0;
90
91 memset (buf_in, 0, sizeof (buf_in));
92 memset (buf_raw, 0, sizeof (buf_raw));
93
94 xlimit = 1; /* doubles as "exit flag" */
95 bc = 1; /* preload, assuming "dump" */
96 x = getpid() + 687319;
97/* if your library doesnt have srandom/random, use srand/rand. [from rnd.c] */
98#ifndef HAVE_RANDOM
99 srand (time(0) + x);
100#else
101 srandom (time(0) + x);
102#endif
103
104#ifdef O_BINARY
105/* DOS stupidity */
106/* Aha: *here's* where that setmode() lib call conflict in ?BSD came from */
107 x = setmode (0, O_BINARY); /* make stdin raw */
108 if (x < 0) {
109 fprintf (stderr, "stdin binary setmode oops: %d\n", x);
110 exit (1);
111 }
112 x = setmode (1, O_BINARY); /* make stdout raw */
113 if (x < 0) {
114 fprintf (stderr, "stdout binary setmode oops: %d\n", x);
115 exit (1);
116 }
117#endif /* O_BINARY */
118
119 if (argv[1]) {
120 p = argv[1]; /* shit-simple single arg parser... */
121 if (*p == '-') /* dash is optional, we'll deal */
122 p++;
123 if (*p == 'd')
124 dumping++;
125 if (*p == 'g')
126 genning++;
127 if (*p == 'r')
128 randing++;
129 } /* if argv 1 */
130
131/* optional second argument: limit # of bytes shoveled either way */
132 if (argv[2]) {
133 x = atoi (argv[2]);
134 if (x)
135 limit = x;
136 else
137 goto wrong;
138 xlimit = limit;
139 }
140
141/* Since this prog would likely best be written in assmbler, I'm gonna
142 write it *like* assembler. So there. */
143
144 if (randing)
145 goto do_rand;
146
147nextbuf: /* loop sleaze */
148
149 if (dumping) { /* switch off to wherever */
150 if (genning)
151 goto wrong;
152 goto do_dump;
153 }
154 if (genning)
155 goto do_gen;
156wrong:
157 fprintf (stderr, surveysez); /* if both or neither */
158 exit (1);
159
160do_gen:
161/* here if genning -- original functionality */
162 q = buf_raw;
163 bc = 0;
164/* suck up lines until eof or buf_raw is full */
165 while (1) {
166 p = fgetss (buf_in, 120, stdin);
167 if (! p)
168 break; /* EOF */
169/* super-primitive version first: one thingie per line */
170 if (*p == '#') /* comment */
171 continue;
172 if (*p == '\0') /* blank line */
173 continue;
174 if (*p == '%') { /* escape char? */
175 p++;
176 if (*p == 'r') { /* random byte */
177 x = randint();
178 goto stuff;
179 } /* %r */
180 } /* if "%" escape */
181 if (*p == '0')
182 if (*(p+1) == 'x') /* 0x?? */
183 goto hex;
184 x = atoi (p); /* reg'lar decimal number */
185 goto stuff;
186
187hex:
188/* A 65 a 97 */
189/* xxx: use a conversion table for this or something. Since we ripped the
190 parity bit, we only need a preset array of 128 with downconversion factors
191 loaded in *once*. maybe look at scanf... */
192 p++; p++; /* point at hex-chars */
193 x = 0;
194 if ((*p > 96) && (*p < 123)) /* a-z */
195 *p = (*p - 32); /* this is massively clumsy */
196 if ((*p > 64) && (*p < 71)) /* A-F */
197 x = (*p - 55);
198 if ((*p > 47) && (*p < 58)) /* digits */
199 x = (*p - 48);
200 p++;
201 if (*p) /* another digit? */
202 x = (x << 4); /* shift to hi half */
203 if ((*p > 96) && (*p < 123)) /* a-z */
204 *p = (*p - 32);
205 if ((*p > 64) && (*p < 71)) /* A-F */
206 x = (x | (*p - 55)); /* lo half */
207 if ((*p > 47) && (*p < 58)) /* digits */
208 x = (x | (*p - 48));
209
210/* fall thru */
211stuff: /* cvt to byte and add to buffer */
212 *q = (x & 0xff);
213 q++;
214 bc++;
215 if (limit) {
216 xlimit--;
217 if (xlimit == 0) /* max num reached */
218 break;
219 } /* limit */
220 if (bc >= sizeof (buf_raw)) /* buffer full */
221 break;
222 } /* while 1 */
223
224/* now in theory we have our buffer formed; shovel it out */
225 x = write (1, buf_raw, bc);
226 if (x <= 0) {
227 fprintf (stderr, "write oops: %d\n", x);
228 exit (1);
229 }
230 if (xlimit && p)
231 goto nextbuf; /* go get some more */
232 exit (0);
233
234do_dump:
235/* here if dumping raw stuff into an ascii file */
236/* gad, this is *so* much simpler! can we say "don't rewrite printf"? */
237 x = read (0, buf_raw, 8192);
238 if (x <= 0)
239 exit (0);
240 q = buf_raw;
241 for ( ; x > 0; x--) {
242 p = q;
243 printf ("%-3.3d # 0x%-2.2x # ", *p, *p);
244 if ((*p > 31) && (*p < 127))
245 printf ("%c %d\n", *p, bc);
246 else
247 printf (". %d\n", bc);
248 q++;
249 bc++;
250 if (limit) {
251 xlimit--;
252 if (xlimit == 0) {
253 fflush (stdout);
254 exit (0);
255 }
256 } /* limit */
257 } /* for */
258 goto nextbuf;
259
260do_rand:
261/* here if generating all-random bytes. Stays in this loop */
262 p = buf_raw;
263 while (1) {
264 *p = (randint() & 0xff);
265 write (1, p, 1); /* makes very slow! */
266 if (limit) {
267 xlimit--;
268 if (xlimit == 0)
269 break;
270 }
271 } /* while */
272 exit (0);
273
274} /* main */
diff --git a/src/usr.bin/nc/data/dns-any.d b/src/usr.bin/nc/data/dns-any.d
new file mode 100644
index 0000000000..77b014cf70
--- /dev/null
+++ b/src/usr.bin/nc/data/dns-any.d
@@ -0,0 +1,36 @@
1# dns "any for ." query, to udp 53
2# if tcp: precede with 2 bytes of len:
3# 0
4# 17
5# you should get at least *one* record back out
6
7# HEADER:
80 # query id = 2
92
10
111 # flags/opcodes = query, dorecurse
120
13
140 # qdcount, i.e. nqueries: 1
151
16
170 # ancount: answers, 0
180
19
200 # nscount: 0
210
22
230 # addl records: 0
240
25
26# end of fixed header
27
280 # name-len: 0 for ".", lenbyte plus name-bytes otherwise
29
300 # type: any, 255
310xff
32
330 # class: IN
341
35
36# i think that's it..
diff --git a/src/usr.bin/nc/data/nfs-0.d b/src/usr.bin/nc/data/nfs-0.d
new file mode 100644
index 0000000000..0360938227
--- /dev/null
+++ b/src/usr.bin/nc/data/nfs-0.d
@@ -0,0 +1,59 @@
1# UDP NFS null-proc call; finds active NFS listeners on port 2049.
2# If you get *something* back, there's an NFS server there.
3
4000 # XID: 4 trash bytes
5001
6002
7003
8
9000 # CALL: 0
10000
11000
12000
13
14000 # RPC version: 2
15000
16000
17002
18
19000 # nfs: 100003
20001
210x86
220xa3
23
24000 # version: 1
25000
26000
27001
28
29000 # procedure number: 0
30000
31000
32000
33
34000 # port: junk
35000
36000
37000
38
39000 # auth trash
40000
41000
42000
43
44000 # auth trash
45000
46000
47000
48
49000 # auth trash
50000
51000
52000
53
54000 # extra auth trash? probably not needed
55000
56000
57000
58
59# that's it!
diff --git a/src/usr.bin/nc/data/pm.d b/src/usr.bin/nc/data/pm.d
new file mode 100644
index 0000000000..fe327693a9
--- /dev/null
+++ b/src/usr.bin/nc/data/pm.d
@@ -0,0 +1,8 @@
1# obligatory duplicate of dr delete's Livingston portmaster crash, aka
2# telnet break. Fire into its telnet listener. An *old* bug by now, but
3# consider the small window one might obtain from a slightly out-of-rev PM
4# used as a firewall, that starts routing IP traffic BEFORE its filter sets
5# are fully loaded...
6
7255 # 0xff # . 1
8243 # 0xf3 # . 2
diff --git a/src/usr.bin/nc/data/pmap-dump.d b/src/usr.bin/nc/data/pmap-dump.d
new file mode 100644
index 0000000000..bc6b63277d
--- /dev/null
+++ b/src/usr.bin/nc/data/pmap-dump.d
@@ -0,0 +1,60 @@
1# portmap dump request: like "rpcinfo -p" but via UDP instead
2# send to UDP 111 and hope it's not a logging portmapper!
3# split into longwords, since rpc apparently only deals with them
4
5001 # 0x01 # . # XID: 4 trash bytes
6002 # 0x02 # .
7003 # 0x03 # .
8004 # 0x04 # .
9
10000 # 0x00 # . # MSG: int 0=call, 1=reply
11000 # 0x00 # .
12000 # 0x00 # .
13000 # 0x00 # .
14
15000 # 0x00 # . # pmap call body: rpc version=2
16000 # 0x00 # .
17000 # 0x00 # .
18002 # 0x02 # .
19
20000 # 0x00 # . # pmap call body: prog=PMAP, 100000
21001 # 0x01 # .
22134 # 0x86 # .
23160 # 0xa0 # .
24
25000 # 0x00 # . # pmap call body: progversion=2
26000 # 0x00 # .
27000 # 0x00 # .
28002 # 0x02 # .
29
30000 # 0x00 # . # pmap call body: proc=DUMP, 4
31000 # 0x00 # .
32000 # 0x00 # .
33004 # 0x04 # .
34
35# with AUTH_NONE, there are 4 zero integers [16 bytes] here
36
37000 # 0x00 # . # auth junk: cb_cred: auth_unix = 1; NONE = 0
38000 # 0x00 # .
39000 # 0x00 # .
40000 # 0x00 # .
41
42000 # 0x00 # . # auth junk
43000 # 0x00 # .
44000 # 0x00 # .
45000 # 0x00 # .
46
47000 # 0x00 # . # auth junk
48000 # 0x00 # .
49000 # 0x00 # .
50000 # 0x00 # .
51
52000 # 0x00 # . # auth junk
53000 # 0x00 # .
54000 # 0x00 # .
55000 # 0x00 # .
56
57# The reply you get back contains your XID, int 1 if "accepted", and
58# a whole mess of gobbledygook containing program numbers, versions,
59# and ports that rpcinfo knows how to decode. For the moment, you get
60# to wade through it yourself...
diff --git a/src/usr.bin/nc/data/pmap-mnt.d b/src/usr.bin/nc/data/pmap-mnt.d
new file mode 100644
index 0000000000..00588ba41f
--- /dev/null
+++ b/src/usr.bin/nc/data/pmap-mnt.d
@@ -0,0 +1,78 @@
1# portmap request for mountd [or whatever; see where prog=MOUNT]
2# send to UDP 111 and hope it's not a logging portmapper!
3# split into longwords, since rpc apparently only deals with them
4
5001 # 0x01 # . # XID: 4 trash bytes
6002 # 0x02 # .
7003 # 0x03 # .
8004 # 0x04 # .
9
10000 # 0x00 # . # MSG: int 0=call, 1=reply
11000 # 0x00 # .
12000 # 0x00 # .
13000 # 0x00 # .
14
15000 # 0x00 # . # pmap call body: rpc version=2
16000 # 0x00 # .
17000 # 0x00 # .
18002 # 0x02 # .
19
20000 # 0x00 # . # pmap call body: prog=PMAP, 100000
21001 # 0x01 # .
22134 # 0x86 # .
23160 # 0xa0 # .
24
25000 # 0x00 # . # pmap call body: progversion=2
26000 # 0x00 # .
27000 # 0x00 # .
28002 # 0x02 # .
29
30000 # 0x00 # . # pmap call body: proc=GETPORT, 3
31000 # 0x00 # .
32000 # 0x00 # .
33003 # 0x03 # .
34
35# with AUTH_NONE, there are 4 zero integers [16 bytes] here
36
37000 # 0x00 # . # auth junk: cb_cred: auth_unix = 1; NONE = 0
38000 # 0x00 # .
39000 # 0x00 # .
40000 # 0x00 # .
41
42000 # 0x00 # . # auth junk
43000 # 0x00 # .
44000 # 0x00 # .
45000 # 0x00 # .
46
47000 # 0x00 # . # auth junk
48000 # 0x00 # .
49000 # 0x00 # .
50000 # 0x00 # .
51
52000 # 0x00 # . # auth junk
53000 # 0x00 # .
54000 # 0x00 # .
55000 # 0x00 # .
56
57000 # 0x00 # . # prog=MOUNT, 100005
58001 # 0x01 # .
59134 # 0x86 # .
60165 # 0xa5 # .
61
62000 # 0x00 # . # progversion=1
63000 # 0x00 # .
64000 # 0x00 # .
65001 # 0x01 # .
66
67000 # 0x00 # . # protocol=udp, 17
68000 # 0x00 # .
69000 # 0x00 # .
70017 # 0x11 # .
71
72000 # 0x00 # . # proc num = junk
73000 # 0x00 # .
74000 # 0x00 # .
75000 # 0x00 # .
76
77# The reply you get back contains your XID, int 1 if "accepted", and
78# mountd's port number at the end or 0 if not registered.
diff --git a/src/usr.bin/nc/data/rip.d b/src/usr.bin/nc/data/rip.d
new file mode 100644
index 0000000000..da505e2143
--- /dev/null
+++ b/src/usr.bin/nc/data/rip.d
@@ -0,0 +1,52 @@
1# struct netinfo {
2# struct sockaddr rip_dst; /* destination net/host */
3# int rip_metric; /* cost of route */
4# };
5# struct rip {
6# u_char rip_cmd; /* request/response */
7# u_char rip_vers; /* protocol version # */
8# u_char rip_res1[2]; /* pad to 32-bit boundary */
9# union {
10# struct netinfo ru_nets[1]; /* variable length... */
11# char ru_tracefile[1]; /* ditto ... */
12# } ripun;
13#define rip_nets ripun.ru_nets
14#define rip_tracefile ripun.ru_tracefile
15#define RIPCMD_REQUEST 1 /* want info */
16#define RIPCMD_RESPONSE 2 /* responding to request */
17#define RIPCMD_TRACEON 3 /* turn tracing on */
18#define RIPCMD_TRACEOFF 4 /* turn it off */
19#define HOPCNT_INFINITY 16 /* per Xerox NS */
20#define MAXPACKETSIZE 512 /* max broadcast size */
21
22### RIP packet redux
23### UDP send FROM clued-rtr/520 to target/520
242 # RIPCMD_RESPONSE
251 # version
260 # padding
270
28
29# sockaddr-plus-metric structs begin, as many as necessary...
300 # len
312 # AF_INET
320 # port
330
34# addr bytes:
35X
36Y
37Z
38Q
390 # filler, out to 16 bytes [sizeof (sockaddr)] ...
400
410
420
430
440
450
460
470 # metric: net-order integer
480
490
501
51
52## that's it
diff --git a/src/usr.bin/nc/data/rservice.c b/src/usr.bin/nc/data/rservice.c
new file mode 100644
index 0000000000..1085d9cb78
--- /dev/null
+++ b/src/usr.bin/nc/data/rservice.c
@@ -0,0 +1,68 @@
1/* generate ^@string1^@string2^@cmd^@ input to netcat, for scripting up
2 rsh/rexec attacks. Needs to be a prog because shells strip out nulls.
3
4 args:
5 locuser remuser [cmd]
6 remuser passwd [cmd]
7
8 cmd defaults to "pwd".
9
10 ... whatever. _H*/
11
12#include <stdio.h>
13
14/* change if you like; "id" is a good one for figuring out if you won too */
15static char cmd[] = "pwd";
16
17static char buf [256];
18
19main(argc, argv)
20 int argc;
21 char * argv[];
22{
23 register int x;
24 register int y;
25 char * p;
26 char * q;
27
28 p = buf;
29 memset (buf, 0, 256);
30
31 p++; /* first null */
32 y = 1;
33
34 if (! argv[1])
35 goto wrong;
36 x = strlen (argv[1]);
37 memcpy (p, argv[1], x); /* first arg plus another null */
38 x++;
39 p += x;
40 y += x;
41
42 if (! argv[2])
43 goto wrong;
44 x = strlen (argv[2]);
45 memcpy (p, argv[2], x); /* second arg plus null */
46 x++;
47 p += x;
48 y += x;
49
50 q = cmd;
51 if (argv[3])
52 q = argv[3];
53 x = strlen (q); /* not checked -- bfd */
54 memcpy (p, q, x); /* the command, plus final null */
55 x++;
56 p += x;
57 y += x;
58
59 memcpy (p, "\n", 1); /* and a newline, so it goes */
60 y++;
61
62 write (1, buf, y); /* zot! */
63 exit (0);
64
65wrong:
66 fprintf (stderr, "wrong! needs 2 or more args.\n");
67 exit (1);
68}
diff --git a/src/usr.bin/nc/data/showmount.d b/src/usr.bin/nc/data/showmount.d
new file mode 100644
index 0000000000..499794bc8a
--- /dev/null
+++ b/src/usr.bin/nc/data/showmount.d
@@ -0,0 +1,63 @@
1# UDP mountd call. Use as input to find mount daemons and avoid portmap.
2# Useful proc numbers are 2, 5, and 6.
3# UDP-scan around between 600-800 to find most mount daemons.
4# Using this with "2", plugged into "nc -u -v -w 2 victim X-Y" will
5# directly scan *and* dump the current exports when mountd is hit.
6# combine stdout *and* stderr thru "strings" or something to clean it up
7
8000 # XID: 4 trash bytes
9001
10002
11003
12
13000 # CALL: 0
14000
15000
16000
17
18000 # RPC version: 2
19000
20000
21002
22
23000 # mount: 100005
24001
250x86
260xa5
27
28000 # mount version: 1
29000
30000
31001
32
33000 # procedure number -- put what you need here:
34000 # 2 = dump [showmount -e]
35000 # 5 = exportlist [showmount -a]
36xxx # "sed s/xxx/$1/ | data -g | nc ..." or some such...
37
38000 # port: junk
39000
40000
41000
42
43000 # auth trash
44000
45000
46000
47
48000 # auth trash
49000
50000
51000
52
53000 # auth trash
54000
55000
56000
57
58000 # extra auth trash? probably not needed
59000
60000
61000
62
63# that's it!
diff --git a/src/usr.bin/nc/data/xor.c b/src/usr.bin/nc/data/xor.c
new file mode 100644
index 0000000000..9feead0cba
--- /dev/null
+++ b/src/usr.bin/nc/data/xor.c
@@ -0,0 +1,92 @@
1/* Generic xor handler.
2
3 With no args, xors stdin against 0xFF to stdout. A single argument is a
4 file to read xor-bytes out of. Any zero in the xor-bytes array is treated
5 as the end; if you need to xor against a string that *includes* zeros,
6 you're on your own.
7
8 The indirect file can be generated easily with data.c.
9
10 Written because there are so many lame schemes for "masking" plaintext
11 passwords and the like floating around, and it's handy to just run an
12 obscure binary-format configuration file through this and look for strings.
13
14 *Hobbit*, 960208 */
15
16#include <stdio.h>
17#include <fcntl.h>
18
19char buf[8192];
20char bytes[256];
21char * py;
22
23/* do the xor, in place. Uses global ptr "py" to maintain "bytes" state */
24xorb (buf, len)
25 char * buf;
26 int len;
27{
28 register int x;
29 register char * pb;
30
31 pb = buf;
32 x = len;
33 while (x > 0) {
34 *pb = (*pb ^ *py);
35 pb++;
36 py++;
37 if (! *py)
38 py = bytes;
39 x--;
40 }
41} /* xorb */
42
43/* blah */
44main (argc, argv)
45 int argc;
46 char ** argv;
47{
48 register int x = 0;
49 register int y;
50
51/* manually preload; xor-with-0xFF is all too common */
52 memset (bytes, 0, sizeof (bytes));
53 bytes[0] = 0xff;
54
55/* if file named in any arg, reload from that */
56#ifdef O_BINARY /* DOS shit... */
57 x = setmode (0, O_BINARY); /* make stdin raw */
58 if (x < 0) {
59 fprintf (stderr, "stdin binary setmode oops: %d\n", x);
60 exit (1);
61 }
62 x = setmode (1, O_BINARY); /* make stdout raw */
63 if (x < 0) {
64 fprintf (stderr, "stdout binary setmode oops: %d\n", x);
65 exit (1);
66 }
67#endif /* O_BINARY */
68
69 if (argv[1])
70#ifdef O_BINARY
71 x = open (argv[1], O_RDONLY | O_BINARY);
72#else
73 x = open (argv[1], O_RDONLY);
74#endif
75 if (x > 0) {
76 read (x, bytes, 250); /* nothin' fancy here */
77 close (x);
78 }
79 py = bytes;
80 x = 1;
81 while (x > 0) {
82 x = read (0, buf, sizeof (buf));
83 if (x <= 0)
84 break;
85 xorb (buf, x);
86 y = write (1, buf, x);
87 if (y <= 0)
88 exit (1);
89 }
90 exit (0);
91}
92