📄 spp_portscan.c
字号:
FatalError(MODNAME": ERROR: %s (%d) => portscan configuration format: address/mask ports seconds [logfile]\n", file_name, file_line);
}
maxPorts = atoi(toks[1]);
maxTime.tv_sec = atoi(toks[2]);
maxTime.tv_usec = 0;
ParseIP(toks[0], &homeNet, &homeNetMask);
/* Now we use the default log directory if provided from the command line (-l). */
if (numToks == 4)
{
if (pv.log_dir && (*toks[3] != '/'))
{
if (*(pv.log_dir + strlen(pv.log_dir) - 1) != '/')
{
logFileName = malloc(strlen(pv.log_dir) + strlen(toks[3]) + 1 + 1);
strncpy(logFileName, pv.log_dir, strlen(pv.log_dir));
strncat(logFileName, "/", 1);
strncat(logFileName, toks[3], strlen(toks[3]));
}
else
{
logFileName = malloc(strlen(pv.log_dir) + strlen(toks[3]) + 1);
strncpy(logFileName, pv.log_dir, strlen(pv.log_dir));
strncat(logFileName, toks[3], strlen(toks[3]));
}
}
else
{
logFileName = (char *)malloc(strlen(toks[3]) + 1);
strncpy(logFileName, toks[3], strlen(toks[3]));
}
#ifdef DEBUG
printf(MODNAME": logFileName = %s\n", logFileName);
#endif
logFile = fopen(logFileName, "a");
if (!logFile) FatalError(MODNAME": logfile open error (%s)\n", logFileName);
logLevel |= lFILE;
}
/* How about some error detecting? :) */
if (maxPorts == 0 || maxTime.tv_sec == 0)
{
FatalError(MODNAME": ERROR: %s (%d) => portscan configuration format: address/mask ports seconds [logfile]\n", file_name, file_line);
}
/*ZDNOTE Compile time settings. Obviously needs to become runtime settings. */
/* If you do not want every packet with reserved bits set (which shouldn't happen),
just remove the "| sRESERVEDBITS" from the end of this line. If you do that, you
may wish to add a line to detect that in the rules file(s).
*/
/*ZDNOTE If/when I add this to options, this would be "usfFnxXrvidI" scan detection. */
scansToWatch = -1; /* Watch for ALL scans */
/*scansToWatch = sUDP | sSYN | sFIN | sSYNFIN | sNULL | sXMAS | sFULLXMAS | sRESERVEDBITS |
sVECNA | sNOACK | sNMAPID | sSPAU | sINVALIDACK;*/
/* can watch all scans but disable some by doing the following*/
/*scansToWatch = ~(sRESERVEDBITS | sNMAPID );*/
/* ZDNOTE. I'm a fascist and I want people to use my new feature,
so I'm forcing everyone to default to my extended logging. Mwua-ha-ha-ha!!!
*/
logLevel |= lEXTENDED;
/* If you want to log packet contents, uncomment this line. */
/* logLevel |= lPACKET; */
/* If you want to change the number of bytes of packet data stored, change this value.
This is the size of the payload and does not include the packet header.
Set the value to -1 to log the complete packet contents.
*/
packetLogSize = 100;
timeFormat = tLOCAL; /* Alternatively, you can do tGMT (should be runtime setting) */
}
void LogScanInfoToSeparateFile(SourceInfo *currentSource)
{
DestinationInfo *currentDestination;
ConnectionInfo *currentConnection;
char *scanType;
char *reservedBits;
char *month;
struct tm *time;
char sourceAddress[16], destinationAddress[16];
char outBuf[160]; /* Don't need anywhere near this, but better safe than sorry. */
memset(sourceAddress, '\0', 16);
memset(destinationAddress, '\0', 16);
/* Can't have two inet_ntoa() calls in a single printf because it uses a static
buffer. It's also faster to only do it twice instead of twice for each iteration.
*/
strncpy(sourceAddress, inet_ntoa(currentSource->saddr), 15);
for (currentDestination = currentSource->destinationsList; currentDestination;
currentDestination = currentDestination->nextNode)
{
strncpy(destinationAddress, inet_ntoa(currentDestination->daddr), 15);
for (currentConnection = currentDestination->connectionsList; currentConnection;
currentConnection = currentConnection->nextNode)
{
/* Apparently, through some stroke of genius and/or luck, timeval.tv_sec can be
used just like time_t. Sweet. And stuff.
*/
time = (timeFormat == tLOCAL) ? localtime(¤tConnection->timestamp.tv_sec)
: gmtime(¤tConnection->timestamp.tv_sec);
switch (time->tm_mon)
{
case 0:
month = "Jan";
break;
case 1:
month = "Feb";
break;
case 2:
month = "Mar";
break;
case 3:
month = "Apr";
break;
case 4:
month = "May";
break;
case 5:
month = "Jun";
break;
case 6:
month = "Jul";
break;
case 7:
month = "Aug";
break;
case 8:
month = "Sep";
break;
case 9:
month = "Oct";
break;
case 10:
month = "Nov";
break;
case 11:
month = "Dec";
break;
default:
month = "MONTH IS INVALID!!";
break;
}
reservedBits = (currentConnection->scanType & sRESERVEDBITS) ? "RESERVEDBITS" : "";
#ifdef DEBUG
printf("scanType = %x mask = %x result = (%x)\n", currentConnection->scanType, ~sRESERVEDBITS, currentConnection->scanType & ~sRESERVEDBITS);
#endif
switch (currentConnection->scanType & ~sRESERVEDBITS)
{
case sUDP:
scanType = "UDP";
break;
case sSYN:
scanType = "SYN";
break;
case sFIN:
scanType = "FIN";
break;
case sSYNFIN:
scanType = "SYNFIN";
break;
case sNULL:
scanType = "NULL";
break;
case sXMAS:
scanType = "XMAS";
break;
case sFULLXMAS:
scanType = "FULLXMAS";
break;
case sVECNA:
scanType = "VECNA";
break;
case sNOACK:
scanType = "NOACK";
break;
case sNMAPID:
scanType = "NMAPID";
break;
case sSPAU:
scanType = "SPAU";
break;
case sINVALIDACK:
scanType = "INVALIDACK";
break;
default:
/* This used to mean I screwed up, but now since any packet that has reserved bits set is
set as a scan it looks bad if "ERROR" shows up when the packet really has something
bizarre like "2****P**".
*/
#ifdef DEBUG
printf("UNKNOWN: scanType = %x (%x)\n", currentConnection->scanType, currentConnection->scanType & ~sRESERVEDBITS);
#endif
scanType = "UNKNOWN";
break;
}
/* I have control of all data here, so this should be safe */
sprintf(outBuf, "%s %2d %.2d:%.2d:%.2d %s:%d -> %s:%d %s %s %s\n", month, time->tm_mday,
time->tm_hour, time->tm_min, time->tm_sec,
sourceAddress, currentConnection->sport, destinationAddress,
currentConnection->dport, scanType, currentConnection->tcpFlags, reservedBits);
fwrite(outBuf, strlen(outBuf), 1, logFile);
}
}
/* Now that we're done, flush the buffer to disk. */
fflush(logFile);
}
/***** AlertIntermediateInfo() *****
Log number of scan packets and types to standard alert mechanism.
*/
void AlertIntermediateInfo(SourceInfo* currentSource)
{
char logMessage[160];
sprintf(logMessage, MODNAME ": portscan status from %s: %d connections across %d hosts: TCP(%d), UDP(%d)%s",
inet_ntoa(currentSource->saddr), currentSource->numberOfConnections, currentSource->numberOfDestinations,
currentSource->numberOfTCPConnections, currentSource->numberOfUDPConnections,
(currentSource->stealthScanUsed) ? " STEALTH" : "");
(*AlertFunc)(NULL, logMessage);
}
void ExtractHeaderInfo(Packet *p, struct in_addr *saddr, struct in_addr *daddr,
u_short *sport, u_short *dport)
{
/* This function seems kinda silly now that I don't have to do protocol checks
to use the proper protocol headers to get the port, but I think it still
makes it easier and I don't have to worry about something changing later.
*/
*sport = p->sp;
*dport = p->dp;
*saddr = p->iph->ip_src;
*daddr = p->iph->ip_dst;
}
/* Check if packet originated from a machine we have been told to ignore
SYN and UDP "scans" from, presumably because it's a server.
*/
int IsServer(Packet *p)
{
ServerNode *currentServer = serverList;
#ifdef DEBUG
char sourceIP[16], ruleIP[16], ruleNetMask[16];
#endif
while (currentServer)
{
/* Return 1 if the source addr is in the serverlist, 0 if nothing is found.
*/
if (CheckAddrPort(currentServer->address, currentServer->netmask,
0, 0, p, ANY_SRC_PORT, CHECK_SRC))
{
#ifdef DEBUG
memset(sourceIP, '\0', 16);
memset(ruleIP, '\0', 16);
memset(ruleNetMask, '\0', 16);
strncpy(sourceIP, inet_ntoa(p->iph->ip_src), 15);
strncpy(ruleIP, inet_ntoa(*(struct in_addr*)¤tServer->address), 15);
strncpy(ruleNetMask, inet_ntoa(*(struct in_addr*)¤tServer->netmask), 15);
printf(MODNAME": IsServer(): Server %s found in %s/%s!\n", sourceIP, ruleIP, ruleNetMask);
#endif
return(1);
}
currentServer = currentServer->nextNode;
}
return(0);
}
void SetupPortscanIgnoreHosts(void)
{
RegisterPreprocessor("portscan-ignorehosts", PortscanIgnoreHostsInit);
}
void PortscanIgnoreHostsInit(u_char *args)
{
CreateServerList(args);
}
/* Well, it seems we are ignoring more than just servers now. We're also
ignoring SYN and UDP scans from our own networks. I guess this is okay.
Most networks have a soft, chewy center, anyway. Besides, this
makes the coding easier! ;)
*/
void CreateServerList(u_char *servers)
{
char **toks;
int num_toks;
int num_servers = 0;
ServerNode *currentServer;
#ifdef DEBUG
char ruleIP[16], ruleNetMask[16];
#endif
currentServer = NULL;
serverList = NULL;
if (servers == NULL)
{
FatalError(MODNAME": ERROR: %s (%d)=> No arguments to portscan-ignorehosts preprocessor!\n", file_name, file_line);
}
/* tokenize the argument list */
toks = mSplit(servers, " ", 31, &num_toks, '\\');
/* convert the tokens and place them into the server list */
for (num_servers = 0; num_servers < num_toks; num_servers++)
{
if (currentServer != NULL)
{
currentServer->nextNode = (ServerNode*)malloc(sizeof(ServerNode));
currentServer = currentServer->nextNode;
}
else
{
currentServer = (ServerNode*)malloc(sizeof(ServerNode));
serverList = currentServer;
}
#ifdef DEBUG
printf(MODNAME": CreateServerList(): Adding server %s\n", toks[num_servers]);
#endif
ParseIP(toks[num_servers], ¤tServer->address, ¤tServer->netmask);
#ifdef DEBUG
memset(ruleIP, '\0', 16);
memset(ruleNetMask, '\0', 16);
strncpy(ruleIP, inet_ntoa(*(struct in_addr*)¤tServer->address), 15);
strncpy(ruleNetMask, inet_ntoa(*(struct in_addr*)¤tServer->netmask), 15);
printf(MODNAME": CreateServerList(): Added server %s/%s\n", ruleIP, ruleNetMask);
#endif
currentServer->nextNode = NULL;
}
free(toks); /* ZDNOTE Does this really free the memory allocated to each token? */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -