Like someone mentioned already, banner grabbing is gonna be fairly effective unless the banner has been disabled and/or modified (or is a honeypot). Your best bet is to enumerate the operating system first, then that will give you some idea of what options they have. After you've narrowed that down, browse around the site and check the HTTP responses with Ethereal or a proxy, look for anything that might indicate what it is running. Read the source to the different pages, see if you can find references to anything that may be specific to a single server type. Try to generate errors (404, 505, 403), larger sites will change these error messages but others won't. Try putting special characters into input fields to generate errors. Try sending different HTTP methods over different potential HTTP ports. The point is, get creative. Different servers will exhibit different behavior in certain areas, try to find that behavior to narrow down the version. There is a tool that does some of this for you, but for the life of me I can't remember what it is called. If I remember I'll post it but your best bet is going to be doing it by hand.