mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Refactor ftp bounce scan into nmap_ftp.{h,cc}
By factoring this code out, we make it easier to convert to NSE. http://seclists.org/nmap-dev/2013/q4/255
This commit is contained in:
133
scan_engine.cc
133
scan_engine.cc
@@ -5857,136 +5857,3 @@ void ultra_scan(std::vector<Target *> &Targets, struct scan_lists *ports,
|
||||
if (o.debugging > 2 && USI.pd != NULL)
|
||||
pcap_print_stats(LOG_PLAIN, USI.pd);
|
||||
}
|
||||
|
||||
/* FTP bounce attack scan. This function is rather lame and should be
|
||||
rewritten. But I don't think it is used much anyway. If I'm going to
|
||||
allow FTP bounce scan, I should really allow SOCKS proxy scan. */
|
||||
void bounce_scan(Target *target, u16 *portarray, int numports,
|
||||
struct ftpinfo *ftp) {
|
||||
o.current_scantype = BOUNCE_SCAN;
|
||||
|
||||
time_t starttime;
|
||||
int res , sd = ftp->sd, i = 0;
|
||||
const char *t = (const char *)target->v4hostip();
|
||||
int retriesleft = FTP_RETRIES;
|
||||
char recvbuf[2048];
|
||||
char targetstr[20];
|
||||
char command[512];
|
||||
char hostname[1200];
|
||||
unsigned short portno, p1, p2;
|
||||
int timedout;
|
||||
|
||||
if (numports == 0)
|
||||
return; /* nothing to scan for */
|
||||
|
||||
Snprintf(targetstr, 20, "%d,%d,%d,%d,", UC(t[0]), UC(t[1]), UC(t[2]), UC(t[3]));
|
||||
|
||||
starttime = time(NULL);
|
||||
if (o.verbose || o.debugging) {
|
||||
struct tm *tm = localtime(&starttime);
|
||||
assert(tm);
|
||||
log_write(LOG_STDOUT, "Initiating TCP FTP bounce scan against %s at %02d:%02d\n", target->NameIP(hostname, sizeof(hostname)), tm->tm_hour, tm->tm_min );
|
||||
}
|
||||
for (i = 0; i < numports; i++) {
|
||||
|
||||
/* Check for timeout */
|
||||
if (target->timedOut(NULL))
|
||||
return;
|
||||
|
||||
portno = htons(portarray[i]);
|
||||
p1 = ((unsigned char *) &portno)[0];
|
||||
p2 = ((unsigned char *) &portno)[1];
|
||||
Snprintf(command, 512, "PORT %s%i,%i\r\n", targetstr, p1, p2);
|
||||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "Attempting command: %s", command);
|
||||
if (send(sd, command, strlen(command), 0) < 0 ) {
|
||||
gh_perror("send in %s", __func__);
|
||||
if (retriesleft) {
|
||||
if (o.verbose || o.debugging)
|
||||
log_write(LOG_STDOUT, "Our FTP proxy server hung up on us! retrying\n");
|
||||
retriesleft--;
|
||||
close(sd);
|
||||
ftp->sd = ftp_anon_connect(ftp);
|
||||
if (ftp->sd < 0)
|
||||
return;
|
||||
sd = ftp->sd;
|
||||
i--;
|
||||
} else {
|
||||
error("Our socket descriptor is dead and we are out of retries. Giving up.");
|
||||
close(sd);
|
||||
ftp->sd = -1;
|
||||
return;
|
||||
}
|
||||
} else { /* Our send is good */
|
||||
res = recvtime(sd, recvbuf, 2048, 15, NULL);
|
||||
if (res <= 0) {
|
||||
perror("recv problem from FTP bounce server");
|
||||
} else { /* our recv is good */
|
||||
recvbuf[res] = '\0';
|
||||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "result of port query on port %i: %s",
|
||||
portarray[i], recvbuf);
|
||||
if (recvbuf[0] == '5') {
|
||||
if (portarray[i] > 1023) {
|
||||
fatal("Your FTP bounce server sucks, it won't let us feed bogus ports!");
|
||||
} else {
|
||||
error("Your FTP bounce server doesn't allow privileged ports, skipping them.");
|
||||
while (i < numports && portarray[i] < 1024) i++;
|
||||
if (!portarray[i]) {
|
||||
fatal("And you didn't want to scan any unpriviliged ports. Giving up.");
|
||||
}
|
||||
}
|
||||
} else { /* Not an error message */
|
||||
if (send(sd, "LIST\r\n", 6, 0) > 0 ) {
|
||||
res = recvtime(sd, recvbuf, 2048, 12, &timedout);
|
||||
if (res < 0) {
|
||||
perror("recv problem from FTP bounce server");
|
||||
} else if (res == 0) {
|
||||
if (timedout)
|
||||
target->ports.setPortState(portarray[i], IPPROTO_TCP, PORT_FILTERED);
|
||||
else target->ports.setPortState(portarray[i], IPPROTO_TCP, PORT_CLOSED);
|
||||
} else {
|
||||
recvbuf[res] = '\0';
|
||||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "result of LIST: %s", recvbuf);
|
||||
if (!strncmp(recvbuf, "500", 3)) {
|
||||
/* fuck, we are not aligned properly */
|
||||
if (o.verbose || o.debugging)
|
||||
error("FTP command misalignment detected ... correcting.");
|
||||
res = recvtime(sd, recvbuf, 2048, 10, NULL);
|
||||
}
|
||||
if (recvbuf[0] == '1' || recvbuf[0] == '2') {
|
||||
target->ports.setPortState(portarray[i], IPPROTO_TCP, PORT_OPEN);
|
||||
if (recvbuf[0] == '1') {
|
||||
res = recvtime(sd, recvbuf, 2048, 5, NULL);
|
||||
if (res < 0)
|
||||
perror("recv problem from FTP bounce server");
|
||||
else {
|
||||
recvbuf[res] = '\0';
|
||||
if (res > 0) {
|
||||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "nxt line: %s", recvbuf);
|
||||
if (recvbuf[0] == '4' && recvbuf[1] == '2' && recvbuf[2] == '6') {
|
||||
target->ports.forgetPort(portarray[i], IPPROTO_TCP);
|
||||
if (o.debugging || o.verbose)
|
||||
log_write(LOG_STDOUT, "Changed my mind about port %i\n", portarray[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* This means the port is closed ... */
|
||||
target->ports.setPortState(portarray[i], IPPROTO_TCP, PORT_CLOSED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (o.debugging || o.verbose)
|
||||
log_write(LOG_STDOUT, "Scanned %d ports in %ld seconds via the Bounce scan.\n",
|
||||
numports, (long) time(NULL) - starttime);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user