博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UDP反射放大攻击
阅读量:4110 次
发布时间:2019-05-25

本文共 6745 字,大约阅读时间需要 22 分钟。

UDP反射放大攻击

放大攻击原理

很多协议在响应包处理时,要远大于请求包,一个字节的请求十个字的响应,十个字节的请求一百个字的响应,这就是UDP反射放大攻击最根本的原理。

而且,最重要的一点,UDP是不稳定的,不需要请求建立连接的

那么我就有点想法了

  1. 使用SOCKRAW,伪造UDP头和IP头,是否让目标流量返回给目标自己呢?事实上 我可以一点流量都接收不到,而目标在收到请求后需要放大还要将响应返回给自己。
  1. 另外一种用法,我搜集到了很多这种服务器(当做肉鸡),我伪造UDP头和IP头,伪造为我要攻击的目标,那么这些服务器在接收到我发送的数据后,所有的响应信息全部都会返回到目标IP去,这样也可以达到攻击的效果。

正因为UDP协议是可以伪造的,所以企业在溯源时很难找到攻击者是谁。

如今DDoS产业已经泛滥,技术成本极低,黑产链已经相当的完善和成熟,各个人员的分工,资源获取,集中管控,需求中介,简易化操作工具,方便快速的发起攻击,已经成为黑产界最喜爱的方式之一。

发送原始UDP封包 实现

/*使用IP头包含选项创建原始套接字之后,再打开IP_HDRINCL 选项,即可在IP头中封装自己的协议,而不是仅仅使用系统预定义的协议。一般可以使用这种方法来发送UDP和TCP数据IP数据报格式:Version域:这4位指定了数据报的IP版本。对IPV4来说此域值为4.IHL(IP header length 的缩写):因为IP头长度不是固定的,所以需要这4位来确定IP数据报中数据部分的开始位置。大多数IP数据报不包含此选项,所以通常IP数据报有20个字节的头长度。Type of service(服务端类型,TOS):包含在IPV4头中,用来区分不同类型的IP数据报Total length:这是IP数据报的总长度,IP头加数据。这个域是16位(2字节)长,所以IP数据报大小的理论最大值是65535字节。然而数据报的长度很少有超过1500字节的。Identification域:用来表示已发送的IPV4封包。通常,系统每发送一次封包就增加一次这个值。Falgs和Fragment offset域:当IPV4分包被分割为较小的包时使用这2个域。DF代表不要分割(dont fragment),这是一个给路由器的命令,告诉他们不要分割此数据报,因为目标主机没有能力将它们恢复回来(例如:机器在启动时)。MF代表更多的分割(More Fragments)。Time to live(生存时间,TTL)域:包含TTL域是为了确保数据报不会永远呆在网络里打圈。每当数据报被路由器处理时,这个域就会减1,如果减到0,此数据报就会被丢弃。Protocol域:当IP数据报到达目的地时才使用此域,它指定了IP数据报的数据部分将要传递给哪个传输层协议,例如,值6表示数据部分要被传递给TCP,值17表示数据部分要被传递给UDP。Header checksum 域:头校验和帮助路由器检测接收到的IP数据报中的位错误。Source address 和 Destianation address域:指定此数据报的源IP地址和目的IP地址。Options域:选项域是一个长度可变的域,它包含了可选的信息。最大值是40字节。*/#include "pch.h"#include 
#include
#include
#include
#pragma warning(disable:4996)#pragma comment(lib,"ws2_32.lib")typedef struct _IPHeader {
u_char VIHL; //版本和首部长度 各占4bit u_char ToS; //服务类型 u_short TotalLen; //总长度 u_short ID; //标识号 u_short Frag_Flags; //片偏移量 u_char TTL; //生存时间 u_char Protocol; //协议 u_short Checksum; //首部校验和 ULONG SrcIP; ULONG DestIP; //struct in_addr SrcIP; //源IP地址 //struct in_addr DestIP; //目的地址}IPHDR, *PIPHDR;/*UDP头*/typedef struct _udpheader {
USHORT sourcePort; //来源端口 USHORT destinationPort;//目标端口 USHORT len;//封包长度 USHORT checkSum;//校验和}UDP_HDR,*PUDP_HDR;/*因为UDP是不可靠协议,所以计算校验和是可选的。和IP的校验和不同,UDP的校验和除了包含UDP的字节外,还包含IP头中的几个域。计算UDP校验和所需的额外的域成为伪头。UDP校验和基于如下几个域:(针对ipv4)32位的源IP地址32位的目的IP地址8位0域8位协议与16位UDP长度16位源端口号16位目的端口号16位UDP长度16位UDP校验和(0)UDP静荷(payload)*///计算校验和WORD checkSum(WORD* wBuff, int nSize) {
DWORD dwSum = 0;; //将数据以WORD为单位累加到wSum while (nSize > 1) {
dwSum += *wBuff++; nSize -= sizeof(WORD); } //若出现最后还剩一个字节继续与前面结果相加(也就是为奇数的情况)。 if (nSize) {
dwSum += *(BYTE*)wBuff++; } while (dwSum >> 16) {
//如果有高16位,将一直与低16位相加 dwSum = (dwSum >> 16) + (dwSum & 0xFFFF); } //取反 return (WORD)(~dwSum);}//计算UDP校验和void ComputeUdpPseudoHeaderCchecksum(IPHDR * pIphdr, UDP_HDR * pUdphdr, char * payload, int payloadlen) {
char buff[1024] = {
0 }; char *ptr = buff; int checksumlen = 0; ULONG zero = 0; //源IP地址 memcpy_s(ptr, sizeof(pIphdr->SrcIP),&pIphdr->SrcIP, sizeof(pIphdr->SrcIP)); ptr += sizeof(pIphdr->SrcIP); checksumlen += sizeof(pIphdr->SrcIP); //目的IP地址 memcpy_s(ptr, sizeof(pIphdr->DestIP), &pIphdr->DestIP, sizeof(pIphdr->DestIP)); ptr += sizeof(pIphdr->DestIP); checksumlen += sizeof(pIphdr->DestIP); //8位0 memcpy_s(ptr, 1, &zero, 1); ptr += 1; checksumlen += 1; //协议 memcpy_s(ptr, sizeof(pIphdr->Protocol), &pIphdr->Protocol, sizeof(pIphdr->Protocol)); ptr += sizeof(pIphdr->Protocol); checksumlen += sizeof(pIphdr->Protocol); //UDP长度 memcpy_s(ptr, sizeof(pUdphdr->len), &pUdphdr->len, sizeof(pUdphdr->len)); ptr += sizeof(pUdphdr->len); checksumlen += sizeof(pUdphdr->len); //UDP源端口 memcpy_s(ptr, sizeof(pUdphdr->sourcePort), &pUdphdr->sourcePort, sizeof(pUdphdr->sourcePort)); ptr += sizeof(pUdphdr->sourcePort); checksumlen += sizeof(pUdphdr->sourcePort); //UDP目的端口 memcpy_s(ptr, sizeof(pUdphdr->destinationPort), &pUdphdr->destinationPort, sizeof(pUdphdr->destinationPort)); ptr += sizeof(pUdphdr->destinationPort); checksumlen += sizeof(pUdphdr->destinationPort); //又是UDP长度 memcpy_s(ptr, sizeof(pUdphdr->len), &pUdphdr->len, sizeof(pUdphdr->len)); ptr += sizeof(pUdphdr->len); checksumlen += sizeof(pUdphdr->len); //16位的UDP校验和,置为0 memcpy_s(ptr, sizeof(USHORT), &zero, sizeof(USHORT)); ptr += sizeof(USHORT); checksumlen += sizeof(USHORT); //净荷 memcpy_s(ptr, payloadlen, payload, payloadlen); ptr += payloadlen; checksumlen += payloadlen; //补齐到下一个16位边界 for (int i = 0; i < payloadlen%2; i++) {
*ptr = 0; ptr++; checksumlen++; } pUdphdr->checkSum = checkSum((WORD*)buff, checksumlen);}//原始套接字 接收UDP封包unsigned int WINAPI recvThread(PVOID lpParam) {
SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_port = ntohs(4567); sin.sin_addr.S_un.S_addr = inet_addr("192.168.0.5"); if (::bind(s, (SOCKADDR *)&sin, sizeof(sin)) == SOCKET_ERROR) {
printf_s("绑定出错%d\n", GetLastError()); closesocket(s); return 1; } char sz[256] = {
0 }; SOCKADDR_IN addrRemote; int nLen = sizeof(addrRemote); printf_s("准备接收\n"); int nRet = recvfrom(s, sz, 256, 0, (sockaddr*)&addrRemote, &nLen); if (nRet > 0){
printf_s("来自ip:%s:%d,内容:%s \n", inet_ntoa(addrRemote.sin_addr), htons(addrRemote.sin_port), sz); } printf_s("接收线程结束"); return 0;}//原始套接字 发送udp封包int main(){
WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); //先开始接收线程 _beginthreadex(NULL, 0, recvThread, NULL, 0, 0); char Msg[] = "哈哈哈哈"; int nMsgLen = sizeof(Msg); SOCKET sSend = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); if (sSend == INVALID_SOCKET) {
printf_s("请管理员运行\n"); return -1; } BOOL bIncl = TRUE; if (setsockopt(sSend, IPPROTO_IP, IP_HDRINCL, (char*)&bIncl, sizeof(bIncl)) == SOCKET_ERROR) {
printf_s("设置失败 %d\n",WSAGetLastError()); closesocket(sSend); return -1; } char buff[1024] = {
0 }; //ip头 IPHDR* pIphdr = (IPHDR*)buff; pIphdr->VIHL = (4 << 4 | (sizeof(IPHDR) / sizeof(ULONG))); pIphdr->TotalLen = htons(sizeof(IPHDR) + sizeof(UDP_HDR) + nMsgLen); pIphdr->TTL = 128; pIphdr->Protocol = IPPROTO_UDP; pIphdr->SrcIP = inet_addr("192.168.0.5");//做测试 所以都是我 pIphdr->DestIP = inet_addr("192.168.0.5"); pIphdr->Checksum = checkSum((USHORT*)pIphdr, sizeof(IPHDR)); //UDP头 UDP_HDR* pUdphdr = (UDP_HDR*)(buff + sizeof(IPHDR)); pUdphdr->sourcePort = htons(8888); pUdphdr->destinationPort = htons(4567); pUdphdr->len = htons(sizeof(UDP_HDR) + nMsgLen); pUdphdr->checkSum = 0; char* pPayload = buff + sizeof(IPHDR) + sizeof(UDP_HDR); memcpy_s(pPayload, 1024 - sizeof(IPHDR) - sizeof(UDP_HDR), Msg, nMsgLen); ComputeUdpPseudoHeaderCchecksum(pIphdr, pUdphdr, pPayload, nMsgLen); //设置目的地址 要和UDP头中相同 SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_port = htons(4567); sin.sin_addr.S_un.S_addr = inet_addr("192.168.0.5"); int nRet = sendto(sSend, buff, nMsgLen + sizeof(IPHDR) + sizeof(UDP_HDR), 0, (sockaddr*)&sin, sizeof(sin)); if (nRet == SOCKET_ERROR) {
printf_s("发送失败\n"); } printf_s("发送完成\n"); Sleep(10000); closesocket(sSend); WSACleanup();}

转载地址:http://atlsi.baihongyu.com/

你可能感兴趣的文章
(python版)《剑指Offer》JZ01:二维数组中的查找
查看>>
管理用户状态——Cookie与Session
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
PHP 7 的五大新特性
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
【增强学习在无人驾驶中的应用】
查看>>
OpenCV meanshift目标跟踪总结
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
卧槽!Java 虚拟机竟然还有这些性能调优技巧...
查看>>
听说玩这些游戏能提升编程能力?
查看>>
如果你还不了解 RTC,那我强烈建议你看看这个!
查看>>
沙雕程序员在无聊的时候,都搞出了哪些好玩的小玩意...
查看>>
Mysql复制表以及复制数据库
查看>>
深究Java中的RMI底层原理
查看>>
Kafka
查看>>
9.1 为我们的角色划分权限
查看>>
维吉尼亚之加解密及破解
查看>>