1
0

final work on Port Scan

This commit is contained in:
Andrew Woodlee 2022-12-03 19:12:00 -06:00
parent df06753e1a
commit d61e25e18f
3 changed files with 10349 additions and 196 deletions

View File

@ -17,6 +17,7 @@ struct scanTypes
u_int halfOpen; u_int halfOpen;
u_int udp; u_int udp;
u_int attemptedScans; u_int attemptedScans;
u_int totalPacketsPerAttack;
u_int xmas; u_int xmas;
} scansInFile; } scansInFile;
@ -46,21 +47,24 @@ struct tcpDictionary
{ {
struct tcpFlagsSet tcpFlags; struct tcpFlagsSet tcpFlags;
int packetNumInGroup; int packetNumInGroup;
uint timesSeen;
struct scanTypesBools scanTypes; struct scanTypesBools scanTypes;
uint16_t srcPort; uint16_t srcPort;
uint16_t port; uint16_t port;
uint16_t dstPort; uint16_t dstPort;
uint16_t srcIP; char *srcIP;
uint16_t dstIP; char *dstIP;
} currentTCPPacket; } currentTCPPacket;
struct udpPacket struct udpPacket
{ {
uint16_t timesSeen;
uint16_t srcPort; uint16_t srcPort;
uint16_t port; uint16_t port;
uint16_t dstPort; uint16_t dstPort;
uint16_t srcIP; char *srcIP;
uint16_t dstIP; char *dstIP;
} currentUDPPacket; };
// Provided structures // Provided structures
struct pcap_pkthdr *pcapHeaderStruct; struct pcap_pkthdr *pcapHeaderStruct;
@ -80,17 +84,13 @@ void addToTable(int key, void *data);
void printScans(); void printScans();
// Global variables and constants // Global variables and constants
int *seqNums; uint *portNums;
int connectScans = 0; int connectScans = 0;
const int TCP_DICTIONARY_SIZE = 100000; const int TCP_DICTIONARY_SIZE = 100000;
const char *ErrorMSG = "Must provide input file.\n"; const char *ErrorMSG = "Must provide input file.\n";
uint8_t *shost;
uint8_t *dhost;
ENTRY *search; ENTRY *search;
ENTRY entry; ENTRY entry;
@ -98,7 +98,6 @@ int main(int argc, char **argv)
{ {
if (hcreate(TCP_DICTIONARY_SIZE) == 0) if (hcreate(TCP_DICTIONARY_SIZE) == 0)
{ {
printf("error");
hcreate(50000); hcreate(50000);
}; };
if (argc < 3) if (argc < 3)
@ -107,7 +106,7 @@ int main(int argc, char **argv)
return 0; return 0;
} }
seqNums = malloc(TCP_DICTIONARY_SIZE * TCP_DICTIONARY_SIZE * sizeof(int)); portNums = malloc(TCP_DICTIONARY_SIZE * TCP_DICTIONARY_SIZE * sizeof(uint));
char errbuf[PCAP_ERRBUF_SIZE]; char errbuf[PCAP_ERRBUF_SIZE];
char *pcapFileName = argv[2]; char *pcapFileName = argv[2];
@ -124,12 +123,13 @@ int main(int argc, char **argv)
void printScans() void printScans()
{ {
printf("Null: %d\n", scansInFile.null); printf("Null: %u\n", scansInFile.null);
printf("Xmas: %d\n", scansInFile.xmas); printf("Xmas: %u\n", scansInFile.xmas);
printf("UDP: %d\n", scansInFile.udp); printf("UDP: %u\n", scansInFile.udp);
printf("Half-open: %d\n", scansInFile.halfOpen); printf("Half-open: %u\n", scansInFile.halfOpen);
printf("Connect: %d\n", scansInFile.connect); printf("Connect: %u\n", scansInFile.connect);
printf("Attempted scans: %d\n", scansInFile.attemptedScans); printf("Attempted scans: %u\n", scansInFile.attemptedScans);
printf("Total packets per attack: %u\n", scansInFile.totalPacketsPerAttack);
} }
void myHandler( void myHandler(
@ -167,33 +167,70 @@ void myHandler(
u_char protocol = *(ip_header + 9); u_char protocol = *(ip_header + 9);
struct udpPacket currentUDPPacket;
/*
UDP scan is not successful if ICMP is returned
*/
if (protocol == IPPROTO_ICMP) if (protocol == IPPROTO_ICMP)
{ {
search = seachTable(currentUDPPacket.port); search = seachTable(currentUDPPacket.port);
struct udpPacket *prevUDPPacket; struct udpPacket *prevUDPPacket;
if (search != NULL) prevUDPPacket = search->data; if (search != NULL)
scansInFile.udp--; prevUDPPacket = search->data;
icmp_header = packet + ethHeaderLength + ipHeaderLength; icmp_header = packet + ethHeaderLength + ipHeaderLength;
icmpHeaderStruct = (struct icmphdr *)icmp_header; icmpHeaderStruct = (struct icmphdr *)icmp_header;
if (icmpHeaderStruct->type == ICMP_DEST_UNREACH) if (icmpHeaderStruct->type == ICMP_DEST_UNREACH)
{ {
scansInFile.udp--;
scansInFile.attemptedScans++; scansInFile.attemptedScans++;
} }
} }
// UDP scan is successful if no response from server or response.
if (protocol == IPPROTO_UDP) if (protocol == IPPROTO_UDP)
{ {
struct udpPacket *prevUDPPacket;
udp_header = packet + ethHeaderLength + ipHeaderLength; udp_header = packet + ethHeaderLength + ipHeaderLength;
udpHeaderStruct = (struct udphdr *)udp_header; udpHeaderStruct = (struct udphdr *)udp_header;
currentUDPPacket.port = ntohs(udpHeaderStruct->source); currentUDPPacket.port = ntohs(udpHeaderStruct->source);
addToTable(currentUDPPacket.port, &currentUDPPacket);
if (udpHeaderStruct->uh_dport == 53) search = seachTable(currentUDPPacket.port);
if (search != NULL)
prevUDPPacket = search->data;
currentUDPPacket.dstPort = ntohs(udpHeaderStruct->dest);
currentUDPPacket.srcPort = ntohs(udpHeaderStruct->source);
if (currentUDPPacket.dstPort == 53 || currentUDPPacket.srcPort == 53)
{ {
return; return;
} }
// response from server
if (search != NULL && currentUDPPacket.dstPort == prevUDPPacket->port)
{
scansInFile.totalPacketsPerAttack++;
scansInFile.attemptedScans++;
scansInFile.udp++;
}
currentUDPPacket.timesSeen++;
if (search != NULL && prevUDPPacket->timesSeen > 1)
{
scansInFile.udp--;
addToTable(currentUDPPacket.port, &currentUDPPacket);
return;
}
addToTable(currentUDPPacket.port, &currentUDPPacket);
scansInFile.udp++; scansInFile.udp++;
return; return;
} }
@ -210,7 +247,6 @@ void myHandler(
tcpHeaderLength = tcpHeaderLength * 4; tcpHeaderLength = tcpHeaderLength * 4;
tcpHeaderStruct = (struct tcphdr *)tcp_header; tcpHeaderStruct = (struct tcphdr *)tcp_header;
const bool ACKflag = (tcpHeaderStruct->ack == 1); const bool ACKflag = (tcpHeaderStruct->ack == 1);
const bool RSTflag = (tcpHeaderStruct->rst == 1); const bool RSTflag = (tcpHeaderStruct->rst == 1);
const bool SYNflag = (tcpHeaderStruct->syn == 1); const bool SYNflag = (tcpHeaderStruct->syn == 1);
@ -231,59 +267,29 @@ void myHandler(
TCP SYN flag is set when connection is made and when server sends back SYN/ACK TCP SYN flag is set when connection is made and when server sends back SYN/ACK
ACK flag set when server sends back SYN/ACK, and when client sends response to SYN/ACK ACK flag set when server sends back SYN/ACK, and when client sends response to SYN/ACK
TCP Half-open:
SYN, SYN/ACK, RST
Connect scan:
Open state:
SYN is first
SYN, ACK is second
RST is last
*/ */
search = seachTable(currentTCPPacket.port); const uint16_t dstPort = ntohs(tcpHeaderStruct->dest);
// printf("Packet Num: %d\n", currentTCPPacket.packetNumInGroup);
/*
returns a value when
*/
// first packet
const uint16_t srcPort = ntohs(tcpHeaderStruct->th_sport);
const uint16_t dstPort = ntohs(tcpHeaderStruct->th_dport);
// struct in_addr_t srcIP = ipHeaderStruct->ip_src.s_addr;
struct tcpDictionary *prevPacket;
if (search!=NULL) prevPacket = search->data;
if (search == NULL || srcPort == prevPacket->port
|| dstPort == prevPacket->port)
{
search = seachTable(currentTCPPacket.srcPort);
const uint16_t srcPort = ntohs(tcpHeaderStruct->source);
char *srcIP = inet_ntoa(ipHeaderStruct->ip_dst);
currentTCPPacket.packetNumInGroup = 0; currentTCPPacket.packetNumInGroup = 0;
if (ACKflag || RSTflag)
{ portNums[currentTCPPacket.port]++;
return;
}
// start of packet for Half-open and Connect // start of packet for Half-open and Connect
if (SYNflag && !ACKflag && !RSTflag && !FINflag && !PSHflag && !URGflag) if (SYNflag && !ACKflag && !RSTflag && !FINflag && !PSHflag && !URGflag)
{ {
currentTCPPacket.port = dstPort; currentTCPPacket.port = dstPort;
currentTCPPacket.srcPort = srcPort;
currentTCPPacket.dstPort = dstPort;
currentTCPPacket.packetNumInGroup = 1; currentTCPPacket.packetNumInGroup = 1;
// hdestroy(); portNums[dstPort] = 1;
// hcreate(TCP_DICTIONARY_SIZE);
addToTable(currentTCPPacket.dstPort, &currentTCPPacket); addToTable(currentTCPPacket.dstPort, &currentTCPPacket);
return; return;
} }
// else one of the other scans else if (FINflag)
else
{
if (FINflag)
{ {
// Xmas pattern // Xmas pattern
if (PSHflag && URGflag) if (PSHflag && URGflag)
@ -300,128 +306,203 @@ void myHandler(
!RSTflag && !FINflag && !RSTflag && !FINflag &&
!PSHflag && !URGflag) !PSHflag && !URGflag)
{ {
scansInFile.null++;
scansInFile.totalPacketsPerAttack++;
currentTCPPacket.port = dstPort; currentTCPPacket.port = dstPort;
currentTCPPacket.packetNumInGroup = 1; currentTCPPacket.packetNumInGroup = 1;
addToTable(currentTCPPacket.port, &currentTCPPacket); addToTable(currentTCPPacket.port, &currentTCPPacket);
return; return;
} }
}
} struct tcpDictionary *prevPacket;
else
// SYN, ACK
if (ACKflag && SYNflag)
{
for (uint i = 0; i < TCP_DICTIONARY_SIZE; i++)
{
search = seachTable(i);
if (currentTCPPacket.dstPort == 1029 && search != NULL)
{
printf("\nSYN ACK flag");
printf("\n\nDST port: %d\n", currentTCPPacket.dstPort);
printf("\nSRC port: %d\n", currentTCPPacket.srcPort);
}
if (search != NULL && i == currentTCPPacket.dstPort)
{ {
// printf("found\n");
// found packet
prevPacket = search->data; prevPacket = search->data;
currentTCPPacket.packetNumInGroup++; scansInFile.totalPacketsPerAttack++;
const uint16_t dstPort = ntohs(tcpHeaderStruct->dest);
const uint16_t srcPort = ntohs(tcpHeaderStruct->source);
char *srcIP = inet_ntoa(ipHeaderStruct->ip_dst);
// does last packet match X-Mas pattern? // does last packet match X-Mas pattern?
if (prevPacket->tcpFlags.PSH && if (prevPacket->tcpFlags.PSH &&
prevPacket->tcpFlags.FIN && prevPacket->tcpFlags.FIN &&
prevPacket->tcpFlags.URG) prevPacket->tcpFlags.URG)
{ {
// printf("Run\n");
if (FINflag) if (FINflag)
{ {
// Xmas pattern // Xmas pattern
if (PSHflag && URGflag) if (PSHflag && URGflag)
{ {
// scansInFile.xmas++; scansInFile.xmas++;
currentTCPPacket.port = dstPort; currentTCPPacket.port = dstPort;
currentTCPPacket.packetNumInGroup = 1; currentTCPPacket.packetNumInGroup = 1;
addToTable(currentTCPPacket.port, &currentTCPPacket); addToTable(currentTCPPacket.port, &currentTCPPacket);
return; return;
} }
} }
scansInFile.xmas++;
if (ACKflag && RSTflag)
{
scansInFile.xmas--; scansInFile.xmas--;
scansInFile.attemptedScans++; scansInFile.attemptedScans++;
// printf("XMas\n");
currentTCPPacket.packetNumInGroup = 0; currentTCPPacket.packetNumInGroup = 0;
return; return;
} }
return; else if (prevPacket->tcpFlags.SYN)
}
// ACK and SYN current
else if (SYNflag && ACKflag &&
!RSTflag && !FINflag &&
!PSHflag && !URGflag)
{ {
// printf("SYN, ACK Port %u\n", currentTCPPacket.dstPort);
currentTCPPacket.packetNumInGroup++; currentTCPPacket.packetNumInGroup++;
if (prevPacket->tcpFlags.SYN && prevPacket->tcpFlags.ACK) scansInFile.totalPacketsPerAttack++;
currentTCPPacket.port = dstPort;
addToTable(currentTCPPacket.port, &currentTCPPacket);
}
}
}
return;
}
// RST, ACK
else if (ACKflag && RSTflag)
{ {
for (uint i = 0; i < TCP_DICTIONARY_SIZE; i++)
{
search = seachTable(i);
if (search != NULL && i == currentTCPPacket.dstPort)
{
prevPacket = search->data;
// printf("\nRST ACK\n");
// printf("\nDST port: %d\n", currentTCPPacket.dstPort);
// printf("\nSRC port: %d\n", currentTCPPacket.srcPort);
const uint16_t dstPort = ntohs(tcpHeaderStruct->dest);
const uint16_t srcPort = ntohs(tcpHeaderStruct->source);
char *srcIP = inet_ntoa(ipHeaderStruct->ip_dst);
// does last packet match X-Mas pattern?
if (prevPacket->tcpFlags.PSH &&
prevPacket->tcpFlags.FIN &&
prevPacket->tcpFlags.URG)
{
if (FINflag)
{
// Xmas pattern
if (PSHflag && URGflag)
{
portNums[dstPort] = dstPort;
scansInFile.xmas++;
currentTCPPacket.port = dstPort;
currentTCPPacket.packetNumInGroup = 1;
addToTable(currentTCPPacket.port, &currentTCPPacket); addToTable(currentTCPPacket.port, &currentTCPPacket);
return; return;
} }
addToTable(currentTCPPacket.port, &currentTCPPacket);
return;
} }
// ACK and SYN prev scansInFile.xmas--;
// Connect and half-open scansInFile.attemptedScans++;
else if (prevPacket->tcpFlags.ACK && prevPacket->tcpFlags.SYN && scansInFile.totalPacketsPerAttack++;
!prevPacket->tcpFlags.FIN && !prevPacket->tcpFlags.PSH &&
!prevPacket->tcpFlags.RST && !prevPacket->tcpFlags.URG)
{
if (RSTflag){
scansInFile.halfOpen++;
addToTable(currentTCPPacket.port, &currentTCPPacket);
currentTCPPacket.packetNumInGroup = 0; currentTCPPacket.packetNumInGroup = 0;
return; return;
} }
else if (ACKflag) // connect scan complete
else if (prevPacket->tcpFlags.ACK && prevPacket->dstPort == i)
{ {
currentTCPPacket.packetNumInGroup++; portNums[dstPort] = dstPort;
addToTable(currentTCPPacket.port, &currentTCPPacket);
return;
}
}
// ACK prev
// Connect successful?
else if (prevPacket->tcpFlags.ACK && !prevPacket->tcpFlags.SYN &&
!prevPacket->tcpFlags.FIN && !prevPacket->tcpFlags.PSH &&
!prevPacket->tcpFlags.RST && !prevPacket->tcpFlags.URG)
{
// yes
if (RSTflag){
scansInFile.connect++; scansInFile.connect++;
currentTCPPacket.packetNumInGroup = 0; scansInFile.totalPacketsPerAttack++;
return; return;
} }
// no if (!prevPacket->tcpFlags.SYN && !prevPacket->tcpFlags.ACK &&
else if (ACKflag) !prevPacket->tcpFlags.RST && !prevPacket->tcpFlags.FIN &&
!prevPacket->tcpFlags.PSH && !prevPacket->tcpFlags.URG)
{ {
currentTCPPacket.packetNumInGroup++; scansInFile.totalPacketsPerAttack++;
addToTable(currentTCPPacket.port, &currentTCPPacket); scansInFile.null--;
}
}
}
return; return;
} }
// ACK flag
} else if (ACKflag && !SYNflag &&
// ACK prev, SYN current !PSHflag && !FINflag &&
else if (SYNflag && !ACKflag && !RSTflag && !FINflag && !PSHflag && !URGflag && prevPacket->tcpFlags.ACK) !RSTflag && !URGflag)
{
for (uint i = 0; i < TCP_DICTIONARY_SIZE; i++)
{
search = seachTable(i);
if (currentTCPPacket.dstPort == 1029 && search != NULL)
{ {
currentTCPPacket.packetNumInGroup++;
addToTable(currentTCPPacket.port, &currentTCPPacket);
return;
}
// Filtered for printf("\nACK flag");
else if (!SYNflag && !ACKflag && printf("\n\nDST port: %d\n", currentTCPPacket.dstPort);
!RSTflag && !FINflag && printf("\nSRC port: %d\n", currentTCPPacket.srcPort);
!PSHflag && !URGflag && }
if (search != NULL && i == currentTCPPacket.dstPort)
{
printf("\nFound port: %d\n", currentTCPPacket.srcPort);
portNums[dstPort]++;
prevPacket = search->data;
const uint16_t dstPort = ntohs(tcpHeaderStruct->dest);
const uint16_t srcPort = ntohs(tcpHeaderStruct->source);
char *srcIP = inet_ntoa(ipHeaderStruct->ip_dst);
if (prevPacket->tcpFlags.ACK &&
prevPacket->tcpFlags.SYN) prevPacket->tcpFlags.SYN)
{ {
scansInFile.attemptedScans++; scansInFile.totalPacketsPerAttack++;
} addToTable(currentTCPPacket.dstPort, &currentTCPPacket);
// scans for
else if (prevPacket->tcpFlags.SYN &&
!SYNflag && !ACKflag &&
RSTflag && !FINflag &&
!PSHflag && !URGflag)
{
return; return;
} }
// addToTable(currentTCPPacket.dstPort, &currentTCPPacket);
}
return;
}
}
else if (RSTflag)
{
for (uint i = 0; i < TCP_DICTIONARY_SIZE; i++)
{
search = seachTable(i);
// printf("\nDST port: %d\n", currentTCPPacket.dstPort);
// printf("\nSRC port: %d\n", currentTCPPacket.srcPort);
if (search != NULL)
{
// printf("\nFound port: %d\n", currentTCPPacket.port);
portNums[dstPort]++;
prevPacket = search->data;
const uint16_t dstPort = ntohs(tcpHeaderStruct->dest);
const uint16_t srcPort = ntohs(tcpHeaderStruct->source);
char *srcIP = inet_ntoa(ipHeaderStruct->ip_dst);
if (prevPacket->tcpFlags.SYN && prevPacket->tcpFlags.ACK)
{
portNums[dstPort] = dstPort;
scansInFile.halfOpen++;
scansInFile.totalPacketsPerAttack++;
return;
}
}
}
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
#!/bin/bash
echo "udp_scan.pcap: "
./anw0044.exe -i udp_scan.pcap
echo "halfopen.pcap: "
./anw0044.exe -i halfopen.pcap
echo "null_scan.pcap: "
./anw0044.exe -i null_scan.pcap
echo "noscan.pcap: "
./anw0044.exe -i noscan.pcap
echo "connect_scan.pcap: "
./anw0044.exe -i connect_scan.pcap