mirror of
https://git.savannah.gnu.org/git/inetutils.git
synced 2026-01-12 00:19:39 +08:00
rlogind,rshd: Protect against source route spoofing.
An old attack vector was open in the legacy code.
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -23,6 +23,7 @@ Karl Berry
|
||||
Kaveh R. Ghazi
|
||||
Ludovic Courtès
|
||||
Marcus Brinkmann
|
||||
Mats Erik Andersson
|
||||
Matt Roberds
|
||||
Michael Weiser
|
||||
Michal Svoboda
|
||||
|
||||
11
ChangeLog
11
ChangeLog
@@ -1,3 +1,14 @@
|
||||
2011-12-20 Mats Erik Andersson <gnu@gisladisker.se>
|
||||
|
||||
* src/rlogind.c (rlogind_auth) [IP_OPTIONS]: Abort connection as soon
|
||||
either of IPOPT_SSRR or IPOPT_LSRR is found. Other options are recorded,
|
||||
and reported, but immediately erased.
|
||||
* src/rshd.c (doit) [IP_OPTIONS]: Likewise.
|
||||
[HAVE_NETINET_IN_SYSTM_H]: Include <netinet/in_systm.h>.
|
||||
[HAVE_NETINET_IP_H]: Include <netinet/ip.h>.
|
||||
* NEWS: Mention security issue inherent in source routing.
|
||||
* AUTHORS: Mention myself as contributing author.
|
||||
|
||||
2011-12-19 Mats Erik Andersson <gnu@gisladisker.se>
|
||||
|
||||
* src/rcp.c (main) [!KERBEROS]: Exit at non-zero geteuid().
|
||||
|
||||
8
NEWS
8
NEWS
@@ -25,6 +25,14 @@ Handle IPv6 connections. The server can forward messages
|
||||
without using a listening INET socket. It can also bind
|
||||
to a single INET/INET6 address.
|
||||
|
||||
* rlogind, rshd
|
||||
|
||||
This legacy code was vulnerable to an attack based on source routing.
|
||||
Whenever either of IPOPT_SSRR or IPOPT_LSRR is encountered, the newly
|
||||
initiated connection is now server-side aborted. The advisory issued
|
||||
by Secure Networks, Inc., February 1997, was adapted. It was found at
|
||||
http://www.citi.umich.edu/u/provos/papers/secnet-spoof.txt
|
||||
|
||||
* ifconfig
|
||||
|
||||
Now under GNU/Linux "ifconfig -a" shows also interfaces without an address.
|
||||
|
||||
@@ -599,8 +599,33 @@ rlogind_auth (int fd, struct auth_data *ap)
|
||||
&optsize) == 0 && optsize != 0)
|
||||
{
|
||||
lp = lbuf;
|
||||
for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
|
||||
sprintf (lp, " %2.2x", *cp);
|
||||
for (cp = optbuf; optsize > 0; )
|
||||
{
|
||||
sprintf (lp, " %2.2x", *cp);
|
||||
lp += 3;
|
||||
|
||||
/* These two open an attack vector. */
|
||||
if (*cp == IPOPT_SSRR || *cp == IPOPT_LSRR)
|
||||
{
|
||||
syslog (LOG_NOTICE,
|
||||
"Discarding connection from %s with set source routing",
|
||||
inet_ntoa (ap->from.sin_addr));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (*cp == IPOPT_EOL)
|
||||
break;
|
||||
if (*cp == IPOPT_NOP)
|
||||
cp++, optsize--;
|
||||
else
|
||||
{
|
||||
/* Options using a length octet, see RFC 791. */
|
||||
int inc = cp[1];
|
||||
|
||||
optsize -= inc;
|
||||
cp += inc;
|
||||
}
|
||||
}
|
||||
|
||||
syslog (LOG_NOTICE, "Ignoring IP options: %s", lbuf);
|
||||
if (setsockopt (0, ipproto, IP_OPTIONS, (char *) NULL, optsize))
|
||||
{
|
||||
|
||||
50
src/rshd.c
50
src/rshd.c
@@ -48,7 +48,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* remote shell server:
|
||||
* remote shell server exchange protocol:
|
||||
* [port]\0
|
||||
* remuser\0
|
||||
* locuser\0
|
||||
@@ -69,6 +69,12 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_NETINET_IN_SYSTM_H
|
||||
# include <netinet/in_systm.h> /* n_time */
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IP_H
|
||||
# include <netinet/ip.h> /* IPOPT_* */
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
@@ -353,16 +359,46 @@ doit (int sockfd, struct sockaddr_in *fromp)
|
||||
&optsize) && optsize != 0)
|
||||
{
|
||||
lp = lbuf;
|
||||
/* The clent has set IP options. This isn't allowd.
|
||||
* Use syslog() to record the fact.
|
||||
/* The client has set IP options. This isn't allowed.
|
||||
* Use syslog() to record the fact. Only the option
|
||||
* types are printed, not their contents.
|
||||
*/
|
||||
for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
|
||||
sprintf (lp, " %2.2x", *cp);
|
||||
for (cp = optbuf; optsize > 0; )
|
||||
{
|
||||
sprintf (lp, " %2.2x", *cp);
|
||||
lp += 3;
|
||||
|
||||
if (*cp == IPOPT_SSRR || *cp == IPOPT_LSRR)
|
||||
{
|
||||
/* Already the TCP handshake suffices for
|
||||
* a man-in-the-middle attack vector.
|
||||
*/
|
||||
syslog (LOG_NOTICE,
|
||||
"Discarding connection from %s with set source routing",
|
||||
inet_ntoa (fromp->sin_addr));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (*cp == IPOPT_EOL)
|
||||
break;
|
||||
if (*cp == IPOPT_NOP)
|
||||
cp++, optsize--;
|
||||
else
|
||||
{
|
||||
/* Options using a length octet, see RFC 791. */
|
||||
int inc = cp[1];
|
||||
|
||||
optsize -= inc;
|
||||
cp += inc;
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point presumably harmless options are present.
|
||||
* Make a report about them, erase them, and continue. */
|
||||
syslog (LOG_NOTICE,
|
||||
"Connection received from %s using IP options (ignored):%s",
|
||||
"Connection received from %s using IP options (erased):%s",
|
||||
inet_ntoa (fromp->sin_addr), lbuf);
|
||||
|
||||
/* Turn off the options. If this doesn't work, we quit */
|
||||
/* Turn off the options. If this doesn't work, we quit. */
|
||||
if (setsockopt (sockfd, ipproto, IP_OPTIONS,
|
||||
(char *) NULL, optsize) != 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user