Spread the love

The preamble to this post is that you can do this in a few lines with CURL, telnet, wget etc. I’m also sure someone has already written one of these but coming from a Java background, it was useful for me (and may be to others) to write a simple application that uses sockets in C.

very Simple HTTP Server Detector 1.0

(I was laughing when I wrote that title)

nobody@nobody:~/$ ./detect
Usage: ./detect < domainname >

Output looks like this

nobody@nobody:~/$ ./detect www.microsoft.com
Server: Microsoft-IIS/7.5

nobody@nobody:~/$ ./detect www.thexploit.com
Server: Apache

nobody@nobody:~/$ ./detect www.google.com
Server: gws

nobody@nobody:~/$ ./detect www.facebook.com
Server: unknown

nobody@nobody:~/$ ./detect www.reddit.com
Server: AkamaiGHost

nobody@nobody:~/$ ./detect www.twitter.com
Server: hi <=== LOL!!

If you’re new to C, see if you can come up with an implementation on your own and then check out the reference below (heavily commented for understanding):

/*
 * Simple HTTP Server Detector
 *
 * Copyleft 2010.
 * All rights have been wronged.
 *
 *  Created on: Oct 5, 2010
 *      Author: xploit
 */
#include <stdio.h> /* Printf, perror, etc */
#include <stdlib.h> /* exit */
#include <sys/socket.h> /* sockets */
#include <netinet/in.h>
#include <netdb.h> /* Host lookup */
#include <string.h> /* bzero */

/* HTTP port */
#define WEB_PORT 80
/* Receive buffer size */
#define RECV_BUF 1024
/* Server buffer size */
#define SRVR_BUF 256

void fatal(char *error);

int main(int argc, char **argv) {

	int socket_fd, i;
	struct sockaddr_in remote_addr;
	struct hostent *remote_host;
	char recv_buf[RECV_BUF], srvr[SRVR_BUF];

	if (argc < 2) {
		printf("Usage: %s <domainname>n", argv[0]);
		exit(1);
	}

	/* Create a socket */
	if ((socket_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
		fatal("Failed to create socketn");
	}

	/* Resolve the domain name */
	if ((remote_host = gethostbyname(argv[1])) == NULL) {
		fatal("Failed to resolve domain namen");
	}

	/* Set address and port of remote host */
	memcpy(&(remote_addr.sin_addr), remote_host->h_addr_list[0],
			remote_host->h_length);
	remote_addr.sin_family = AF_INET;
	remote_addr.sin_port = htons(WEB_PORT);

	/* Zero out the rest of the struct */
	memset(&(remote_addr.sin_zero), 0, 8);

	/* Connect to the domain */
	if ((connect(socket_fd, (struct sockaddr *) &remote_addr,
			sizeof(struct sockaddr))) == -1) {
		fatal("Unable to connect to domainn");
	}

	/* Send a HTTP head req */
	if ((send(socket_fd, "HEAD / HTTP/1.0rnrn", 19, 0)) == -1) {
		fatal("Error sending HEAD requestn");
	}

	/* Receive the response */
	if ((recv(socket_fd, &recv_buf, 1024, 0)) == -1) {
		fatal("Error reading HEAD responsen");
	}

	/* Find the server substring */
	char *srvr_ptr = strstr(recv_buf, "Server:");

	/* Fail if it wasn't found */
	if (srvr_ptr == NULL) {
		fatal("Server: unknownn");
	}

	/* Read server line*/
	i = 0;
	while (srvr_ptr[i] != 'n' && i < SRVR_BUF) {
		srvr[i] = srvr_ptr[i];
		i++;
	}
	/* Terminate String */
	srvr[i] = '\0';

	/* Clear string */
	srvr_ptr = NULL;

	/* Print the results */
	printf("%sn", srvr);

	/* Stop both reception and transmission */
	shutdown(socket_fd, 2);

	return 0;
}

// Prints an error and exits
void fatal(char *error) {
	printf(error);
	exit(1);
}