1 
2 /***************************************************************************
3  * ncrack_ftp.cc -- ncrack module for the FTP protocol                     *
4  *                                                                         *
5  ***********************IMPORTANT NMAP LICENSE TERMS************************
6  *                                                                         *
7  * The Nmap Security Scanner is (C) 1996-2019 Insecure.Com LLC ("The Nmap  *
8  * Project"). Nmap is also a registered trademark of the Nmap Project.     *
9  * This program is free software; you may redistribute and/or modify it    *
10  * under the terms of the GNU General Public License as published by the   *
11  * Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE   *
12  * CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN.  This guarantees your   *
13  * right to use, modify, and redistribute this software under certain      *
14  * conditions.  If you wish to embed Nmap technology into proprietary      *
15  * software, we sell alternative licenses (contact sales@nmap.com).        *
16  * Dozens of software vendors already license Nmap technology such as      *
17  * host discovery, port scanning, OS detection, version detection, and     *
18  * the Nmap Scripting Engine.                                              *
19  *                                                                         *
20  * Note that the GPL places important restrictions on "derivative works",  *
21  * yet it does not provide a detailed definition of that term.  To avoid   *
22  * misunderstandings, we interpret that term as broadly as copyright law   *
23  * allows.  For example, we consider an application to constitute a        *
24  * derivative work for the purpose of this license if it does any of the   *
25  * following with any software or content covered by this license          *
26  * ("Covered Software"):                                                   *
27  *                                                                         *
28  * o Integrates source code from Covered Software.                         *
29  *                                                                         *
30  * o Reads or includes copyrighted data files, such as Nmap's nmap-os-db   *
31  * or nmap-service-probes.                                                 *
32  *                                                                         *
33  * o Is designed specifically to execute Covered Software and parse the    *
34  * results (as opposed to typical shell or execution-menu apps, which will *
35  * execute anything you tell them to).                                     *
36  *                                                                         *
37  * o Includes Covered Software in a proprietary executable installer.  The *
38  * installers produced by InstallShield are an example of this.  Including *
39  * Nmap with other software in compressed or archival form does not        *
40  * trigger this provision, provided appropriate open source decompression  *
41  * or de-archiving software is widely available for no charge.  For the    *
42  * purposes of this license, an installer is considered to include Covered *
43  * Software even if it actually retrieves a copy of Covered Software from  *
44  * another source during runtime (such as by downloading it from the       *
45  * Internet).                                                              *
46  *                                                                         *
47  * o Links (statically or dynamically) to a library which does any of the  *
48  * above.                                                                  *
49  *                                                                         *
50  * o Executes a helper program, module, or script to do any of the above.  *
51  *                                                                         *
52  * This list is not exclusive, but is meant to clarify our interpretation  *
53  * of derived works with some common examples.  Other people may interpret *
54  * the plain GPL differently, so we consider this a special exception to   *
55  * the GPL that we apply to Covered Software.  Works which meet any of     *
56  * these conditions must conform to all of the terms of this license,      *
57  * particularly including the GPL Section 3 requirements of providing      *
58  * source code and allowing free redistribution of the work as a whole.    *
59  *                                                                         *
60  * As another special exception to the GPL terms, the Nmap Project grants  *
61  * permission to link the code of this program with any version of the     *
62  * OpenSSL library which is distributed under a license identical to that  *
63  * listed in the included docs/licenses/OpenSSL.txt file, and distribute   *
64  * linked combinations including the two.                                  *
65  *                                                                         *
66  * The Nmap Project has permission to redistribute Npcap, a packet         *
67  * capturing driver and library for the Microsoft Windows platform.        *
68  * Npcap is a separate work with it's own license rather than this Nmap    *
69  * license.  Since the Npcap license does not permit redistribution        *
70  * without special permission, our Nmap Windows binary packages which      *
71  * contain Npcap may not be redistributed without special permission.      *
72  *                                                                         *
73  * Any redistribution of Covered Software, including any derived works,    *
74  * must obey and carry forward all of the terms of this license, including *
75  * obeying all GPL rules and restrictions.  For example, source code of    *
76  * the whole work must be provided and free redistribution must be         *
77  * allowed.  All GPL references to "this License", are to be treated as    *
78  * including the terms and conditions of this license text as well.        *
79  *                                                                         *
80  * Because this license imposes special exceptions to the GPL, Covered     *
81  * Work may not be combined (even as part of a larger work) with plain GPL *
82  * software.  The terms, conditions, and exceptions of this license must   *
83  * be included as well.  This license is incompatible with some other open *
84  * source licenses as well.  In some cases we can relicense portions of    *
85  * Nmap or grant special permissions to use it in other open source        *
86  * software.  Please contact fyodor@nmap.org with any such requests.       *
87  * Similarly, we don't incorporate incompatible open source software into  *
88  * Covered Software without special permission from the copyright holders. *
89  *                                                                         *
90  * If you have any questions about the licensing restrictions on using     *
91  * Nmap in other works, we are happy to help.  As mentioned above, we also *
92  * offer an alternative license to integrate Nmap into proprietary         *
93  * applications and appliances.  These contracts have been sold to dozens  *
94  * of software vendors, and generally include a perpetual license as well  *
95  * as providing support and updates.  They also fund the continued         *
96  * development of Nmap.  Please email sales@nmap.com for further           *
97  * information.                                                            *
98  *                                                                         *
99  * If you have received a written license agreement or contract for        *
100  * Covered Software stating terms other than these, you may choose to use  *
101  * and redistribute Covered Software under those terms instead of these.   *
102  *                                                                         *
103  * Source is provided to this software because we believe users have a     *
104  * right to know exactly what a program is going to do before they run it. *
105  * This also allows you to audit the software for security holes.          *
106  *                                                                         *
107  * Source code also allows you to port Nmap to new platforms, fix bugs,    *
108  * and add new features.  You are highly encouraged to send your changes   *
109  * to the dev@nmap.org mailing list for possible incorporation into the    *
110  * main distribution.  By sending these changes to Fyodor or one of the    *
111  * Insecure.Org development mailing lists, or checking them into the Nmap  *
112  * source code repository, it is understood (unless you specify            *
113  * otherwise) that you are offering the Nmap Project the unlimited,        *
114  * non-exclusive right to reuse, modify, and relicense the code.  Nmap     *
115  * will always be available Open Source, but this is important because     *
116  * the inability to relicense code has caused devastating problems for     *
117  * other Free Software projects (such as KDE and NASM).  We also           *
118  * occasionally relicense the code to third parties as discussed above.    *
119  * If you wish to specify special license conditions of your               *
120  * contributions, just say so when you send them.                          *
121  *                                                                         *
122  * This program is distributed in the hope that it will be useful, but     *
123  * WITHOUT ANY WARRANTY; without even the implied warranty of              *
124  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the Nmap      *
125  * license file for more details (it's in a COPYING file included with     *
126  * Nmap, and also available from https://svn.nmap.org/nmap/COPYING)        *
127  *                                                                         *
128  ***************************************************************************/
129 
130 
131 #include "ncrack.h"
132 #include "nsock.h"
133 #include "NcrackOps.h"
134 #include "Service.h"
135 #include "modules.h"
136 
137 #define FTP_TIMEOUT 20000
138 #define FTP_DIGITS 3
139 
140 
141 extern NcrackOps o;
142 
143 extern void ncrack_read_handler(nsock_pool nsp, nsock_event nse, void *mydata);
144 extern void ncrack_write_handler(nsock_pool nsp, nsock_event nse, void *mydata);
145 extern void ncrack_module_end(nsock_pool nsp, void *mydata);
146 static int ftp_loop_read(nsock_pool nsp, Connection *con, char *ftp_code_ret);
147 
148 enum states { FTP_INIT, FTP_USER, FTP_FINI };
149 
150 
151 static int
ftp_loop_read(nsock_pool nsp,Connection * con,char * ftp_code_ret)152 ftp_loop_read(nsock_pool nsp, Connection *con, char *ftp_code_ret)
153 {
154   int i;
155   int ftp_dig[FTP_DIGITS];
156   char ftp_code[FTP_DIGITS + 2]; /* 3 digits + space + '\0' */
157   char dig[2]; /* temporary digit string */
158   char *p;
159 
160   if (con->inbuf == NULL || con->inbuf->get_len() < FTP_DIGITS + 1) {
161     nsock_read(nsp, con->niod, ncrack_read_handler, FTP_TIMEOUT, con);
162     return -1;
163   }
164 
165   /* Make sure first 3 (FTP_DIGITS) bytes of each line are digits */
166   p = (char *)con->inbuf->get_dataptr();
167   dig[1] = '\0';
168   for (i = 0; i < FTP_DIGITS; i++) {
169     dig[0] = *p++;
170     ftp_dig[i] = (int)Strtoul(dig, 0);
171     if (errno) { /* It wasn't a number! */
172       return -2;  /* Oops, malformed FTP packet */
173     }
174   }
175 
176   /*
177    * http://www.faqs.org/rfcs/rfc959.html
178    * Thus the format for multi-line replies is that the first line
179    * will begin with the exact required reply code, followed
180    * immediately by a Hyphen, "-" (also known as Minus), followed by
181    * text.  The last line will begin with the same code, followed
182    * immediately by Space <SP>, optionally some text, and the Telnet
183    * end-of-line code.
184    *
185    * For example:
186    *   123-First line
187    *   Second line
188    *      234 A line beginning with numbers
189    *   123 The last line
190    */
191 
192   /* Convert digits to string code for parsing */
193   snprintf(ftp_code, FTP_DIGITS + 1, "%d%d%d", ftp_dig[0], ftp_dig[1],
194       ftp_dig[2]);
195   ftp_code[FTP_DIGITS] = ' ';
196   ftp_code[FTP_DIGITS + 1] = '\0';
197 
198   if (*p == '-') {
199     /* FTP message is multiple lines, so first search for the 'ftp code' to
200      * find the last line, according to the scheme proposed by RFC 959 */
201     if (!(p = memsearch((const char *)con->inbuf->get_dataptr(), ftp_code,
202           con->inbuf->get_len()))) {
203       nsock_read(nsp, con->niod, ncrack_read_handler, FTP_TIMEOUT, con);
204       return -1;
205     }
206     /* Now that we found the the last line, find that line's end */
207     if (!memsearch((const char *)p, "\r\n", con->inbuf->get_len())) {
208       nsock_read(nsp, con->niod, ncrack_read_handler, FTP_TIMEOUT, con);
209       return -1;
210     }
211   } else {
212     /* FTP message is one line only */
213     if (!memsearch((const char *)con->inbuf->get_dataptr(), "\r\n",
214           con->inbuf->get_len())) {
215       nsock_read(nsp, con->niod, ncrack_read_handler, FTP_TIMEOUT, con);
216       return -1;
217     }
218   }
219 
220   /* Return the ftp code to caller */
221   memcpy(ftp_code_ret, ftp_code, FTP_DIGITS);
222 
223   return 0;
224 
225 }
226 
227 
228 
229 void
ncrack_ftp(nsock_pool nsp,Connection * con)230 ncrack_ftp(nsock_pool nsp, Connection *con)
231 {
232   nsock_iod nsi = con->niod;
233   Service *serv = con->service;
234   const char *hostinfo = serv->HostInfo();
235   char ftp_code[FTP_DIGITS + 1];
236   memset(ftp_code, 0, sizeof(ftp_code));
237 
238   switch (con->state)
239   {
240     case FTP_INIT:
241 
242       /* Wait to read banner only at the beginning of the connection */
243       if (!con->login_attempts) {
244 
245         if (ftp_loop_read(nsp, con, ftp_code) < 0)
246           break;
247 
248         /* ftp_loop_read already takes care so that the inbuf contains the
249          * 3 first ftp digit code, so you can safely traverse it that much */
250         if (strncmp(ftp_code, "220", FTP_DIGITS)) {
251 
252           if (o.debugging > 6)
253             error("%s Not ftp or service was shutdown\n", hostinfo);
254           return ncrack_module_end(nsp, con);
255         }
256       }
257 
258       con->state = FTP_USER;
259 
260       delete con->inbuf;
261       con->inbuf = NULL;
262 
263       if (con->outbuf)
264         delete con->outbuf;
265       con->outbuf = new Buf();
266       con->outbuf->snprintf(7 + strlen(con->user), "USER %s\r\n", con->user);
267 
268       nsock_write(nsp, nsi, ncrack_write_handler, FTP_TIMEOUT, con,
269           (const char *)con->outbuf->get_dataptr(), con->outbuf->get_len());
270       break;
271 
272     case FTP_USER:
273 
274       if (ftp_loop_read(nsp, con, ftp_code) < 0)
275         break;
276 
277       if (!strncmp(ftp_code, "331", FTP_DIGITS)) {
278         ;
279       } else {
280         return ncrack_module_end(nsp, con);
281       }
282 
283       con->state = FTP_FINI;
284 
285       delete con->inbuf;
286       con->inbuf = NULL;
287 
288       if (con->outbuf)
289         delete con->outbuf;
290       con->outbuf = new Buf();
291       con->outbuf->snprintf(7 + strlen(con->pass), "PASS %s\r\n", con->pass);
292 
293       nsock_write(nsp, nsi, ncrack_write_handler, FTP_TIMEOUT, con,
294         (const char *)con->outbuf->get_dataptr(), con->outbuf->get_len());
295       break;
296 
297     case FTP_FINI:
298 
299       if (ftp_loop_read(nsp, con, ftp_code) < 0)
300         break;
301 
302       if (!strncmp(ftp_code, "230", FTP_DIGITS))
303         con->auth_success = true;
304 
305       con->state = FTP_INIT;
306 
307       delete con->inbuf;
308       con->inbuf = NULL;
309 
310       return ncrack_module_end(nsp, con);
311   }
312   /* make sure that ncrack_module_end() is always called last or returned to
313    * have tail recursion or else stack space overflow might occur */
314 }
315