1 #include "hydra-mod.h"
2 
3 extern char *HYDRA_EXIT;
4 char *buf;
5 
start_ftp(int32_t s,char * ip,int32_t port,unsigned char options,char * miscptr,FILE * fp)6 int32_t start_ftp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
7   char *empty = "\"\"";
8   char *login, *pass, buffer[510];
9 
10   if (strlen(login = hydra_get_next_login()) == 0)
11     login = empty;
12   if (strlen(pass = hydra_get_next_password()) == 0)
13     pass = empty;
14 
15   sprintf(buffer, "USER %.250s\r\n", login);
16 
17   if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
18     return 1;
19   }
20   buf = hydra_receive_line(s);
21   if (buf == NULL)
22     return 1;
23   /* special hack to identify 530 user unknown msg. suggested by
24    * Jean-Baptiste.BEAUFRETON@turbomeca.fr */
25   if (buf[0] == '5' && buf[1] == '3' && buf[2] == '0') {
26     if (verbose)
27       printf("[INFO] user %s does not exist, skipping\n", login);
28     hydra_completed_pair_skip();
29     if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
30       return 4;
31     free(buf);
32     return 1;
33   }
34   // for servers supporting anon access without password
35   if (buf[0] == '2') {
36     hydra_report_found_host(port, ip, "ftp", fp);
37     hydra_completed_pair_found();
38     if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
39       return 4;
40     free(buf);
41     return 1;
42   }
43   if (buf[0] != '3') {
44     if (buf) {
45       if (verbose || debug)
46         hydra_report(stderr, "[ERROR] Not an FTP protocol or service shutdown: %s\n", buf);
47       free(buf);
48     }
49     return 3;
50   }
51   free(buf);
52 
53   sprintf(buffer, "PASS %.250s\r\n", pass);
54 
55   if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
56     return 1;
57   }
58   buf = hydra_receive_line(s);
59   if (buf == NULL)
60     return 1;
61   if (buf[0] == '2') {
62     hydra_report_found_host(port, ip, "ftp", fp);
63     hydra_completed_pair_found();
64     if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
65       return 4;
66     free(buf);
67     return 1;
68   }
69 
70   free(buf);
71   hydra_completed_pair();
72   if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
73     return 4;
74 
75   return 2;
76 }
77 
service_ftp_core(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname,int32_t tls)78 void service_ftp_core(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname, int32_t tls) {
79   int32_t run = 1, next_run = 1, sock = -1;
80   int32_t myport = PORT_FTP, mysslport = PORT_FTP_SSL;
81 
82   hydra_register_socket(sp);
83   if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
84     hydra_child_exit(0);
85   while (1) {
86     switch (run) {
87     case 1: /* connect and service init function */
88       if (sock >= 0)
89         sock = hydra_disconnect(sock);
90       //      usleepn(300);
91       if ((options & OPTION_SSL) == 0) {
92         if (port != 0)
93           myport = port;
94         sock = hydra_connect_tcp(ip, myport);
95         port = myport;
96       } else {
97         if (port != 0)
98           mysslport = port;
99         sock = hydra_connect_ssl(ip, mysslport, hostname);
100         port = mysslport;
101       }
102       if (sock < 0) {
103         if (verbose || debug)
104           hydra_report(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int32_t)getpid());
105         hydra_child_exit(1);
106       }
107       usleepn(250);
108       buf = hydra_receive_line(sock);
109       if (buf == NULL || buf[0] != '2') { /* check the first line */
110         if (verbose || debug)
111           hydra_report(stderr, "[ERROR] Not an FTP protocol or service shutdown: %s\n", buf);
112         hydra_child_exit(2);
113         if (buf != NULL)
114           free(buf);
115         hydra_child_exit(2);
116       }
117 
118       while (buf != NULL && strncmp(buf, "220 ", 4) != 0 && strstr(buf, "\n220 ") == NULL) {
119         free(buf);
120         buf = hydra_receive_line(sock);
121       }
122       free(buf);
123 
124       // this mode is manually chosen, so if it fails we giving up
125       if (tls) {
126         if (hydra_send(sock, "AUTH TLS\r\n", strlen("AUTH TLS\r\n"), 0) < 0) {
127           hydra_child_exit(2);
128         }
129         buf = hydra_receive_line(sock);
130         if (buf == NULL) {
131           if (verbose || debug)
132             hydra_report(stderr, "[ERROR] Not an FTP protocol or service shutdown: %s\n", buf);
133           hydra_child_exit(2);
134         }
135         if (buf[0] == '2') {
136           if ((hydra_connect_to_ssl(sock, hostname) == -1) && verbose) {
137             hydra_report(stderr, "[ERROR] Can't use TLS\n");
138             hydra_child_exit(2);
139           } else {
140             if (verbose)
141               hydra_report(stderr, "[VERBOSE] TLS connection done\n");
142           }
143         } else {
144           hydra_report(stderr, "[ERROR] TLS negotiation failed %s\n", buf);
145           hydra_child_exit(2);
146         }
147         free(buf);
148       }
149 
150       next_run = 2;
151       break;
152     case 2: /* run the cracking function */
153       next_run = start_ftp(sock, ip, port, options, miscptr, fp);
154       break;
155     case 3: /* error exit */
156       if (sock >= 0)
157         sock = hydra_disconnect(sock);
158       hydra_child_exit(2);
159       break;
160     case 4: /* clean exit */
161       if (sock >= 0)
162         sock = hydra_disconnect(sock);
163       hydra_child_exit(0);
164       break;
165     default:
166       hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n");
167       hydra_child_exit(2);
168     }
169     run = next_run;
170   }
171 }
172 
service_ftp(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname)173 void service_ftp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { service_ftp_core(ip, sp, options, miscptr, fp, port, hostname, 0); }
174 
service_ftps(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname)175 void service_ftps(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) { service_ftp_core(ip, sp, options, miscptr, fp, port, hostname, 1); }
176 
service_ftp_init(char * ip,int32_t sp,unsigned char options,char * miscptr,FILE * fp,int32_t port,char * hostname)177 int32_t service_ftp_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE *fp, int32_t port, char *hostname) {
178   // called before the childrens are forked off, so this is the function
179   // which should be filled if initial connections and service setup has to be
180   // performed once only.
181   //
182   // fill if needed.
183   //
184   // return codes:
185   //   0 all OK
186   //   -1  error, hydra will exit, so print a good error message here
187 
188   return 0;
189 }
190