/* expnbrute.c by CoKi This program tries to find users in a SMTP server through command EXPN, using a list of user names Use: ./expnbrute No System Group - http://www.nosystem.com.ar coki@nosystem.com.ar */ #include #include #include #include #include #include #include #include #include #include #include #define DATAMAX 300 #define ERROR -1 #define TIMEOUT 3 #define PORT 25 void use(char *program); int connect_timeout(int sfd, struct sockaddr *serv_addr, socklen_t addrlen, int timeout); int main(int argc, char *argv[]) { FILE *list; int sockfd, cant=0, cant_u=0; char buf[DATAMAX], sendstr[DATAMAX]; char user[30]; struct hostent *he; struct sockaddr_in dest_dir; struct timeval timeout; fd_set readfds; if(argc != 3) use(argv[0]); printf("\n expnbrute by CoKi \n\n"); printf(" [1] verifying list:\t"); fflush(stdout); if((list=fopen(argv[1], "r")) == NULL) { printf("Failed\n\n"); exit(1); } while(!feof(list)) if('\n' == fgetc(list)) cant++; rewind(list); printf("OK (%d users)\n", cant); printf(" [2] host:\t\t"); fflush(stdout); if((he=gethostbyname(argv[2])) == NULL) { herror("Error"); printf("\n"); exit(1); } printf("OK\n"); printf(" [3] connecting:\t"); fflush(stdout); if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == ERROR) { perror("Error"); printf("\n"); exit(1); } dest_dir.sin_family = AF_INET; dest_dir.sin_port = htons(PORT); dest_dir.sin_addr = *((struct in_addr *)he->h_addr); bzero(&(dest_dir.sin_zero), 8); if(connect_timeout(sockfd, (struct sockaddr *)&dest_dir, sizeof(struct sockaddr), TIMEOUT) == ERROR) { printf("Closed\n\n"); exit(1); } printf("OK\n"); printf(" [4] verifying expn:\t"); fflush(stdout); timeout.tv_sec = TIMEOUT; timeout.tv_usec = 0; FD_ZERO(&readfds); FD_SET(sockfd, &readfds); select(sockfd+1, &readfds, NULL, NULL, &timeout); if(!FD_ISSET(sockfd, &readfds)) { printf("timeout\n\n"); exit(1); } recv(sockfd, buf, sizeof(buf), 0); bzero(buf, sizeof(buf)); sprintf(sendstr, "EXPN root\n"); send(sockfd, sendstr, strlen(sendstr), 0); recv(sockfd, buf, sizeof(buf), 0); if(strstr(buf, "250")) printf("OK\n"); else { printf("OFF\n\n"); exit(1); } printf(" [5] searching for system accounts...\n"); fflush(stdout); while(!feof(list)) { if(fgets(user, sizeof(user), list) == NULL) break; user[strlen(user)-1] = '\0'; printf(" %s\t=> ", user); fflush(stdout); bzero(buf, sizeof(buf)); sprintf(sendstr, "EXPN %s\n", user); send(sockfd, sendstr, strlen(sendstr), 0); recv(sockfd, buf, sizeof(buf), 0); if(strstr(buf, "250")) { printf("OK\n"); cant_u++; } else printf("NO\n"); } if(cant_u == 0) printf("\t\t None\n"); printf("\n"); close(sockfd); fclose(list); } void use(char *program) { printf("Use: %s \n", program); exit(1); } int connect_timeout(int sfd, struct sockaddr *serv_addr, socklen_t addrlen, int timeout) { int res, slen, flags; struct timeval tv; struct sockaddr_in addr; fd_set rdf, wrf; fcntl(sfd, F_SETFL, O_NONBLOCK); res = connect(sfd, serv_addr, addrlen); if (res >= 0) return res; FD_ZERO(&rdf); FD_ZERO(&wrf); FD_SET(sfd, &rdf); FD_SET(sfd, &wrf); bzero(&tv, sizeof(tv)); tv.tv_sec = timeout; if (select(sfd + 1, &rdf, &wrf, 0, &tv) <= 0) return -1; if (FD_ISSET(sfd, &wrf) || FD_ISSET(sfd, &rdf)) { slen = sizeof(addr); if (getpeername(sfd, (struct sockaddr*)&addr, &slen) == -1) return -1; flags = fcntl(sfd, F_GETFL, NULL); fcntl(sfd, F_SETFL, flags & ~O_NONBLOCK); return 0; } return -1; }