tibbar
Feb 12 2004, 02:37 AM
good point. this should compile to a .dll, as it is a portscanner plugin.
here's portscan.c:
_____________________________________________________________
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include "PortScan.h"
char c_Error_In_Args []= "Error in arguments.";
char c_Error_No_Free_PS []= "No free portscans.";
char c_Error_PS_NFound []= "Scan No. %d not active.";
char c_Ouput_Info []= "#%-2d:%s";
char c_Error_WSA_STARTUP []= "Error with WSAStartup() - exiting thread.";
char c_StartingScan []= "Starting scan.";
char c_Found_Open []= "%15s:%-5d is open.";
char c_CurrentlyScanning []= "Currently scanning %s:%d, %d seconds elapsed.";
char c_Error_Resuming []= "Error resuming new thread %d.";
char c_Error_CNT []= "Error Creating new thread.";
char c_No_Active_Portscans []= "No active scans.";
char c_Tot_Portscans []= "Total %d portscan(s) listed.";
char c_Paused_C []= " PAUSED";
char c_Stopping []= " STOPPING";
char c_Paused []= "Paused.";
char c_Unpaused []= "Unpaused.";
char c_Scan_List []= "Scanning %s:%s.";
char c_Halted_At []= "Halted at %s:%d, %d seconds elapsed.";
char c_Stop_Msg []= "Stop msg sent.";
char c_Fin []= "Finnished scanning, %d open ports found, %d seconds elapsed.";
unsigned short p_wait = 3500;
/* define this for VERY verbose debug msgs from the scanning thread - this helped me solve the last bug which plauged me for over 2 hours! */
//#define _PORTSCAN_DEBUG_VERBOSE_
/* define this for debug msgs from plugin */
//#define _PORTSCAN_DEBUG_
/* define this for debug message boxes from plugin */
//#define _PORTSCAN_DEBUG_LOCAL_
/* This is where we keep track of our scans */
struct PortScan g_Scans[MAX_SIMULTANIOUS_PORTSCANS];
/* Called by the portscan thread only to get the next port in a port list */
unsigned short GetPort (char *cPortList,unsigned short iCount) {
char buffer[512],*split;
USHORT n=0,len = strlen(cPortList),count = 0;
do {
memset(buffer,0,sizeof(buffer));
while ( (cPortList[count] != ',' ) && ( count <= len ) ) {
buffer[n++] = cPortList[count++];
}
count++;
n=0;
split = strchr(buffer,'-');
if (split) {
int f,s,l;
*split = 0;
f= atoi(buffer);
s= atoi(split + 1);
if (f>s) {
l = f-s + 1;
if (l > iCount) {
return atoi(buffer) - iCount;
} else {
iCount -= l;
}
} else if (s>f) {
l = s-f + 1;
if (l > iCount) {
return atoi(buffer) + iCount;
} else {
iCount -= l;
}
} else {
if (!iCount)
return atoi(buffer);
iCount--;
}
*split = '-';
} else {
if (!iCount)
return atoi(buffer);
iCount--;
}
} while (count <= len);
return 0;
}
/* This thread does the actual scanning */
DWORD WINAPI PortScanThread(LPVOID Args) {
SOCKADDR_IN IA_Host;
SOCKET s[MAX_SIMULTANIOUS_PORTSCAN_SOCKETS];
char *split = 0,buf[256];
struct PortScan *scan = (struct PortScan*)Args;
int sc,
res;
LONG lStartHost,
lEndHost,
scan_time;
BOOL bCountingUp = TRUE;
USHORT p=0,
pcount=0,
o_count=0,
max =MAX_SIMULTANIOUS_PORTSCAN_SOCKETS;
DWORD wait,
dwLen;
fd_set rfds;
TIMEVAL tm;
WSADATA WSock_dat;
LINGER s_linger;
WORD WSock_ver=MAKEWORD(1,1);
scan->inUse = TRUE;
if (WSAStartup(WSock_ver,&WSock_dat)) {
SendMsg(c_Error_WSA_STARTUP,scan->sId,scan->reply_to.where ,scan->reply_to.nick,scan->reply_to.pointer);
Delete(scan);
return -1;
}
tm.tv_sec=0;
tm.tv_usec=0;
split = strchr(scan->ips,'-');
if (split) {
*split = 0;
}
/* lip = ntohl(inet_addr("126.255.224.1")); */
lStartHost = ntohl(inet_addr(scan->ips));
if (split){
lEndHost = ntohl(inet_addr(split + 1));
} else {
lEndHost = lStartHost;
}
if (lStartHost > lEndHost)
bCountingUp = FALSE;
if (split) {
*split = '-';
}
IA_Host.sin_family = AF_INET;
IA_Host.sin_addr.S_un.S_addr = htonl(lStartHost);
SendMsg(c_StartingScan,scan->sId,scan->reply_to.where,scan->reply_to.nick,scan->reply_to.pointer);
scan_time = GetTickCount();
sc=0;
while (sc < max){
s[sc++] = INVALID_SOCKET;
}
while (scan->Stop == FALSE) {
wait = GetTickCount();
sc = 0;
while (sc < max) {
while ( (p = GetPort(scan->ports,pcount++)) && sc < max) {
IA_Host.sin_port = htons(p);
s[sc] = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
dwLen = TRUE; /* Must be non zero to set non blocking! */
res = ioctlsocket(s[sc],FIONBIO,&dwLen);
res = connect(s[sc],(const SOCKADDR*)&IA_Host,sizeof(IA_Host));
if (res == SOCKET_ERROR && WSAGetLastError() == WSAENOBUFS ) {
max = sc-1;
// scan_wait = max/MAX_SIMULTANIOUS_PORTSCAN_SOCKETS * PORTSCAN_WAIT;
pcount -=2; /* two instead of one, because were not breaking, and the while loop increments pcount before it breaks! */
}
sc++;
}
if (sc >= max){
break;
}
if (lStartHost == lEndHost){
break;
}
pcount=0;
if(bCountingUp)
lStartHost++;
else
lStartHost--;
IA_Host.sin_addr .S_un .S_addr = htonl(lStartHost);
}
if (GetTickCount() - wait < scan->portscan_delay )
Sleep(scan->portscan_delay - GetTickCount() + wait);
sc = 0;
while (sc < max) {
if (s[sc] == INVALID_SOCKET){
sc++;
continue;
}
FD_ZERO(&rfds);
FD_SET(s[sc],&rfds);
if((res=select(0,NULL,&rfds,NULL,&tm))>0) {
char buffer[1024];
IN_ADDR found;
SOCKADDR sname;
USHORT fp;
int coolio = sizeof(sname);
getpeername (s[sc],&sname,&coolio);
memcpy(&found.S_un.S_addr,&sname.sa_data[2],4);
memcpy(&fp,&sname.sa_data,2);
sprintf(buffer,c_Found_Open,inet_ntoa(found),ntohs(fp));
o_count++;
SendMsg(buffer,scan->sId,scan->reply_to .where,scan->reply_to.nick,scan->reply_to.pointer);
}
/* make sure were doing a hard close with no waiting - fairly important! */
s_linger.l_onoff =1;
s_linger.l_linger =0;
setsockopt(s[sc],SOL_SOCKET,SO_LINGER,(char*)&s_linger,sizeof(s_linger));
res = closesocket(s[sc]);
s[sc] = INVALID_SOCKET;
sc++;
}
if (lStartHost == lEndHost && !p)
break;
while (scan->Pause) {
Sleep(50);
}
if (scan->Info) {
char buffer[1024];
IN_ADDR found;
found.S_un .S_addr = htonl(lStartHost);
sprintf(buffer,c_CurrentlyScanning,inet_ntoa(found),p,(GetTickCount() - scan_time) / 1000);
SendMsg(buffer,scan->sId,scan->reply_to.where,scan->reply_to.nick,scan->reply_to.pointer);
scan->Info = FALSE;
}
}
if (scan->Stop) {
IN_ADDR found;
found.S_un .S_addr = htonl(lStartHost);
sprintf(buf,c_Halted_At,inet_ntoa(found),p, (GetTickCount() - scan_time) / 1000 );
SendMsg(buf,scan->sId,scan->reply_to.where,scan->reply_to.nick,scan->reply_to.pointer);
}else{
sprintf(buf,c_Fin,o_count,(GetTickCount() - scan_time) / 1000);
SendMsg(buf,scan->sId,scan->reply_to.where,scan->reply_to.nick,scan->reply_to.pointer);
}
sc = 0;
while (sc < max) {
closesocket(s[sc++]);
}
Delete(scan);
return 0;
}
/* Client Interface to find the correct portscan and stop it */
BOOL StopPortScan(unsigned short portscan, char *buffer) {
struct PortScan *scan = GetPortScan(portscan);
if (scan == 0) {
sprintf(buffer,c_Error_PS_NFound,portscan);
return FALSE;
}
scan->Stop = TRUE;
scan->Pause = FALSE;
strcpy(buffer,c_Stop_Msg);
return TRUE;
}
/* Makes sure the list we are getting works so there is no trouble later */
BOOL ParsePortList(char *cPortList) {
USHORT len = strlen(cPortList);
UINT count=len,n=0;
char buffer[8],*t,*v,*u;
/* Check that the only characters were allowing are: 0 1 2 3 4 5 6 7 8 9 , - */
while (count-- > 0){
if (! isdigit(cPortList[count]) ) {
if (cPortList[count] == ',' || cPortList[count] == '-') {
continue;
}
else return FALSE;
continue;
}
}
//Now check if any ports are below 0 or above 65535
count=0;
do {
memset(buffer,0,sizeof(buffer));
while (cPortList[count] != ',' && cPortList[count] != '-' && n < sizeof(buffer) && cPortList[count]) {
buffer[n++] = cPortList[count++];
}
n=0;
if (atoi(buffer) > 0xffff || atoi(buffer) < 1) return FALSE;
} while (count++ < len);
count =0;
// Check there is no 114-116-118 type thing (not sure how bullet proof this is)
// Really checks that there is not more than one '-' before each ','
while ( (t = strchr(cPortList + count,'-')) ) {
v = strchr(t,',');
u = strchr(t+1,'-');
if (v && u && v > u)
return FALSE;
else if (!v && u)
return FALSE;
count = t - cPortList + 1 ;
}
return TRUE;
}
/* Makes sure the IPs we are getting are valid */
BOOL ParseIP(char *cIp) {
char *split = strchr(cIp,'-');
/* The minimum Ip length is "1.2.3.4" == 7 */
if (strlen(cIp) < 7)
return FALSE;
if (split) {
*split = 0;
if (inet_addr(cIp) == INADDR_NONE || inet_addr(split + 1) == INADDR_NONE) {
*split = '-';
return FALSE;
}
*split = '-';
} else {
if (inet_addr(cIp) == INADDR_NONE) {
return FALSE;
}
}
return TRUE;
}
/*
Called when we dont need the portscan anymore.. only
to be called by the portscan thread, or if it hasnt
been created yet by StartPortScan()
*/
void Delete(struct PortScan *scan) {
scan->Info = scan->inUse = scan->Pause = scan->Stop = FALSE;
scan->reply_to.pointer = NULL;
scan->portscan_delay = PORTSCAN_WAIT;
memset(scan->reply_to.nick,0,sizeof(scan->reply_to.nick));
memset(scan->reply_to.where,0,sizeof(scan->reply_to.where));
memset(scan->ips,0,sizeof(scan->ips));
memset(scan->ports,0,sizeof(scan->ports));
}
/* Called on pluin startup to set initial variables APPLICATION INTERFACE */
void InitScanList() {
USHORT i=MAX_SIMULTANIOUS_PORTSCANS;
for (;i>0;) {
g_Scans[i].sId = i;
Delete(&g_Scans[i--]);
}
}
/* Gets the next free portscan */
struct PortScan *GetFreeScan(void) {
USHORT i=MAX_SIMULTANIOUS_PORTSCANS;
for (;i>0;i--) {
if (g_Scans[i].inUse == FALSE)
return &g_Scans[i];
}
return NULL;
}
struct PortScan *GetPortScan(unsigned short id) {
USHORT i=MAX_SIMULTANIOUS_PORTSCANS;
for (;i>0;i--) {
if (g_Scans[i].sId == id && g_Scans[i].inUse == TRUE)
return &g_Scans[i];
}
return NULL;
}
/* Sets the PAUSE BOOL CLIENT INTERFACE */
BOOL PausePortScan(unsigned short dId,char *buffer) {
struct PortScan* scan = GetPortScan(dId);
if (scan == 0) {
sprintf(buffer,c_Error_PS_NFound,dId);
return FALSE;
}
if (scan->Pause == TRUE) {
scan->Pause = FALSE;
strcpy(buffer,c_Unpaused);
return TRUE;
} else {
scan->Pause = TRUE;
strcpy(buffer,c_Paused);
return TRUE;
}
}
/* Lists active portscans */
void ListPortScans(char *where,char *who,void *pointer,char *buffer) {
USHORT i=MAX_SIMULTANIOUS_PORTSCANS;
USHORT count =0;
for (;i>0;i--) {
if (g_Scans[i].inUse == TRUE) {
sprintf(buffer,c_Scan_List,g_Scans[i].ips ,g_Scans[i].ports);
if (g_Scans[i].Pause) strcat(buffer,c_Paused_C);
if (g_Scans[i].Stop) strcat(buffer,c_Stopping);
SendMsg(buffer,g_Scans[i].sId,where,who,pointer);
count++;
}
}
if (!count) {
strcpy(buffer,c_No_Active_Portscans);
return;
}
sprintf(buffer,c_Tot_Portscans,count);
return;
}
/* Stops all portscans */
void StopAllPortscans() {
USHORT i=MAX_SIMULTANIOUS_PORTSCANS;
for (;i>0;i--) {
if (g_Scans[i].inUse) {
g_Scans[i].Pause = FALSE;
g_Scans[i].Stop = TRUE;
}
}
}
/* Sets the INFO BOOL so the portscan thread sends the info */
BOOL PortScanInfo (unsigned short dId,char *buffer){
struct PortScan* scan = GetPortScan(dId);
if (scan == 0 ) {
sprintf(buffer,c_Error_PS_NFound,dId);
return FALSE;
}
scan->Info = TRUE;
*buffer = 0;
return TRUE;
}
BOOL StartPortScan(char *ip,char *ports,char *who,char *where,void *pointer,char *buffer) {
struct PortScan *scan =GetFreeScan();
DWORD tId;
HANDLE hThread;
if (!scan) {
strcpy(buffer,c_Error_No_Free_PS);
return FALSE;
}
if ( ! ParsePortList(ports) ||
! ParseIP(ip) ) {
strcpy(buffer,c_Error_In_Args);
return FALSE;
}
scan->portscan_delay = p_wait;
strncpy(scan->ports,ports,sizeof(scan->ports) -1);
strncpy(scan->ips,ip,sizeof(scan->ips) -1);
strncpy(scan->reply_to.nick,who,sizeof(scan->reply_to.nick) -1);
strncpy(scan->reply_to.where,where,sizeof(scan->reply_to.where) - 1);
scan->reply_to.pointer= pointer;
hThread = CreateThread(NULL,0,PortScanThread,(LPVOID)scan,CREATE_SUSPENDED,&tId);
if (hThread ==NULL) {
strcpy(buffer,c_Error_CNT);
Delete(scan);
} else {
if (ResumeThread(hThread) == 0xFFFFFFFF) {
sprintf(buffer,c_Error_Resuming,GetLastError());
Delete(scan);
return FALSE;
}
}
*buffer=0;
return TRUE;
}
_____________________________________________________________
and now portscan.h
#ifndef _PORT_SCAN_HEADER_
#define _PORT_SCAN_HEADER_
#define MAX_SIMULTANIOUS_PORTSCAN_SOCKETS 256
extern unsigned short p_wait;
#define PORTSCAN_WAIT p_wait
#define MAX_SIMULTANIOUS_PORTSCANS 4
struct PortScan {
char ips[256];
char ports[512];
unsigned short portscan_delay;
BOOL Pause,
Stop,
Info,
inUse;
unsigned short sId;
struct {
void *pointer;
char nick[256];
char where[256];
}reply_to;
};
extern char c_Error_In_Args [];
BOOL StopPortScan(unsigned short portscan, char *buffer);
void InitScanList();
BOOL PausePortScan(unsigned short dId,char *buffer);
void ListPortScans(char *where,char *who,void *pointer,char *buffer);
void StopAllPortscans();
BOOL PortScanInfo (unsigned short dId,char *buffer);
BOOL StartPortScan(char *ip,char *ports,char *who,char *where,void *pointer,char *buffer);
void SendMsg(char *msg,unsigned short sId,char *where,char* to,void *pointer);
void Delete(struct PortScan *scan);
struct PortScan *GetPortScan(unsigned short id);
#endif //_PORT_SCAN_HEADER_
__________________________________________________________________
it is written in vc++6.