Utility that attempts to find whether or not users exist on an SMTP server using the EXPN command against a list of user names.
73346010d346ef624f1a57c55f0aaafd2fb9476ea1e7678b6e797981f5d167fb
/* expnbrute.c by CoKi <coki@nosystem.com.ar>
This program tries to find users in a SMTP server
through command EXPN, using a list of user names
Use: ./expnbrute <list> <host>
No System Group - http://www.nosystem.com.ar
coki@nosystem.com.ar
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#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 <coki@nosystem.com.ar>\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 <list> <host>\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;
}