Python编写渗透工具学习笔记二 | 0x04编写程序分析流量检测ddos攻击

0x04编写程序分析流量

检测ddos攻击

1使用dpkt发现下载loic的行为

LOIC,即Low Orbit Ion Cannon低轨道离子炮,是用于压力测试的工具,通常被攻击者用来实现DDoS攻击。

我们要编写py脚本来解析http流量,并检查其中有无通过http get获取压缩过的loic二进制可执行文件的情况。为了检查http流量,我们必须先把数据包的以太网部分、ip层以及tcp层部分分解出来,注意http协议是位于tcp协议层之上的。如果http层中使用了get方法,则解析http get所要获取的统一资源标识符(uri)。如果该uri所指向的文件的文件名中包含有 .zip 和loic,则在屏幕上输出一条某个ip正在下载loic的消息。

注意:这个程序在windows下运行可能会报这样的错误(溢出了)

“OverflowError: Python int too large to convert to C long”

所以这里我在kali下执行了

这里的 download.pcap 是下载loic时捕获的压缩包(是http的,不是https的,若为https的则无法直接通过抓包来进行请求头的分析,因为https加密了)

因为后来怕大家不能够理解这个脚本,所以后来我决定写一些基础知识上来

直接上截图(在这个例子当中我已经尽可能详细地说明了~~)

用wireshark打开数据包是这个样子的(以第一个数据包为例分析)

中的arrive time--------》对应的是

可以看出来,wireshark和python的dpkt库对这个时间的解析是存在一定的差异的,不过这个问题不大

----》

其中type:ipv4(0x0800) 对应的是 2048

Ip的对应很容易找

Len=488----->total length:488

Ttl=64----------->time to live=64

DF---------------->对应flags标识中的Don’t fragment

MF----------------->对应flags标识中的More fragments

Offset=0---------------->对应fragment offset:0

分析到这里已经非常清楚了,其实dpkt这个模块在这里就是对数据包进行了解析。

再看一个结构图(用---来表示各层协议的分层情况)

这个也是用dpkt模块解析出来的数据包中各层协议之间一些分布情况

就像一些类中的属性值一样,例如解析出ip包会用ip=eth.data,可以这样去理解,ip包中的数据是eth类的一个属性的值,这个属性的名字是data,然后会得到一个ip类,然后ip类中又存在一个data属性,他的值为tcp包中的数据,所以解析tcp包就使用 tcp=ip.data ,这种说法确实不严谨,但是可以这样去辅助理解一下下~~

现在我们再回来理解一下这个程序

(好吧~说的有点多了~其实说基础知识不是我这次分享的本意~~)

2

解析Hive服务器上的IRC命令

findHivemind()函数--主要用于检测僵尸网络流量中的IRC命令

实现思路分析:

要发起攻击,“匿名者”成员需要登录到指定的irc服务器上发出一条攻击指令,例如

!lazor targetip=66.211.169.66 message=test_test port 80 method=tc wait=false random=true start

通常irc服务器使用的是tcp 6667端口,在编写我们的findHivemind()函数时就可以利用这一点,我们先把数据包中的以太网部分、ip层、tcp层分解出来,在获得tcp层部分的数据后,我们检查它的源端口和目标端口是不是6667,如果我们看到 !lazor 指令的目标端口是6667,则可以确定某个成员提交了一个攻击指令,如果我们看到了 !lazor 指令的源端口为6667,则可以认为这是服务器在向hive中的成员发布攻击的消息。

3

检测DDoS攻击

实现思路:

要识别攻击,需要设置一个不正常的数据包数量的阀值。如果某个用户发送到某个地址的数据包的数量超过了这个阀值,就把它认为是发动了攻击。

整合脚本:

实现能检测到下载行为,监听到hive指令并检查出攻击行为

在这个例子中流量包的总量是29246个,而在实际应用中流量包的总量要比这个还要大得多,我们基本是不可能人工分析出来的,这时候学会编写脚本来分析就显得十分重要了。

4

工具源代码

#!/usr/bin/python  
#coding=utf-8  
import dpkt  
import socket  
import optparse  
#设置阈值为1000 
THRESH = 1000  
#检测下载loic行为
def findDownload(pcap):  
    for (ts, buf) in pcap:  
        try:  
            eth = dpkt.ethernet.Ethernet(buf)  
            ip = eth.data  
            src = socket.inet_ntoa(ip.src)  
            # 获取TCP数据  
            tcp = ip.data  
            # 解析TCP中的上层协议HTTP的请求  
            http = dpkt.http.Request(tcp.data)  
            # 若是GET方法,且请求行中包含“.zip”和“loic”字样则判断为下载LOIC  
            if http.method == 'GET':  
                uri = http.uri.lower()  
                if '.zip' in uri and 'loic' in uri:  
                    print "[!] " + src + " Downloaded LOIC."  
        except:  
            pass  
#监听hive指令
def findHivemind(pcap):  
    for (ts, buf) in pcap:  
        try:  
            eth = dpkt.ethernet.Ethernet(buf)  
            ip = eth.data  
            src = socket.inet_ntoa(ip.src)  
            dst = socket.inet_ntoa(ip.dst)  
            tcp = ip.data  
            dport = tcp.dport  
            sport = tcp.sport  
            # 若目标端口为6667且含有“!lazor”指令,
            #则确定是某个成员提交一个攻击指令  
            if dport == 6667:  
                if '!lazor' in tcp.data.lower():  
                    print '[!] DDoS Hivemind issued by: '+src  
                    print '[+] Target CMD: ' + tcp.data  
            # 若源端口为6667且含有“!lazor”指令,
            #则确定是服务器在向HIVE中的成员发布攻击的消息  
            if sport == 6667:  
                if '!lazor' in tcp.data.lower():  
                    print '[!] DDoS Hivemind issued to: '+src  
                    print '[+] Target CMD: ' + tcp.data  
        except:  
            pass  
#检查出攻击行为
def findAttack(pcap):  
    pktCount = {}  
    for (ts, buf) in pcap:  
        try:  
            eth = dpkt.ethernet.Ethernet(buf)  
            ip = eth.data  
            src = socket.inet_ntoa(ip.src)  
            dst = socket.inet_ntoa(ip.dst)  
            tcp = ip.data  
            dport = tcp.dport  
            # 累计各个src地址对目标地址80端口访问的次数  
            if dport == 80:  
                stream = src + ':' + dst  
                if pktCount.has_key(stream):  
                    pktCount[stream] = pktCount[stream] + 1  
                else:  
                    pktCount[stream] = 1  
        except:  
            pass  
    for stream in pktCount:  
        pktsSent = pktCount[stream]  
        # 若超过设置检测的阈值,则判断为进行DDoS攻击  
        if pktsSent > THRESH:  
            src = stream.split(':')[0]  
            dst = stream.split(':')[1]  
            print '[+] ' + src + ' attacked ' \
             + dst + ' with ' + str(pktsSent) + ' pkts.'  
def main():  
    parser = optparse.OptionParser("[*]Usage python findDDoS.py "\
        +"-p <pcap file> -t <thresh>")  
    parser.add_option('-p', dest='pcapFile', 
                            type='string', 
                            help='specify pcap filename')  
    parser.add_option('-t', dest='thresh', 
                            type='int', 
                            help='specify threshold count ')  
    (options, args) = parser.parse_args()  
    if options.pcapFile == None:  
        print parser.usage  
        exit(0)  
    if options.thresh != None:  
        THRESH = options.thresh  
    pcapFile = options.pcapFile  
    # 若用f = open(pcapFile) 
    #则这里的pcap文件解析只能调用一次,
    #而这里需要多次调用,所以应该使用with open
    with open(pcapFile, 'r') as f:  
        pcap = dpkt.pcap.Reader(f)  
        findDownload(pcap)  
    with open(pcapFile, 'r') as f:  
        pcap = dpkt.pcap.Reader(f)  
        findHivemind(pcap)  
    with open(pcapFile, 'r') as f:  
        pcap = dpkt.pcap.Reader(f)  
        findAttack(pcap)   
if __name__ == '__main__':  
    main()  

原文发布于微信公众号 - 安恒网络空间安全讲武堂(gh_fa1e45032807)

原文发表时间:2017-12-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户画像

3.1.4.2 基本分段存储方式

分页管理方式是从计算机的角度考虑设计的,以提高内存的利用率,提高计算机的性能,提升计算机的性能,且分页通过硬件机制实现 ,对用户完全透明;

1062
来自专栏Linux驱动

第2阶段——编写uboot之硬件初始化和制作链接脚本lds(1)

目标: 第一阶段: 1.关看门狗 2.设置时钟 3.初始化SDRAM (初始化寄存器以及清除bss段) 4.重定位 (将nan...

2265
来自专栏yukong的小专栏

【ssm个人博客项目实战08】博客的分页显示以及模糊查询,删除。前言1、上篇回顾2、具体编码3、测试与小结

在上一节中我们是完成了博客的回台部分,现在我需要在前台拿到回台传来的数据并且给以显示出来。 不知道大家还记得我们在博客类别管理里面,easyui的datagr...

1034
来自专栏漫漫全栈路

ASP.NET MVC学习笔记05模型与访问数据模型

上一篇使用的M模型,并不是真正意义上的Model,现在来添加一些类,并将这些类用来管理数据库中数据(电影)。而这些类,就是ASP.NET MVC中的Model...

2984
来自专栏企鹅号快讯

高并发分布式——主节点选举

1. 概述 本文主要分享 Elastic-Job-Lite 主节点选举。 涉及到主要类的类图如下: ? . 2. 为什么需要选举主节点 首先我们来看一段官方对 ...

2589
来自专栏Coding迪斯尼

java开发系统内核:使用LDT保护进程数据和代码

1073
来自专栏C/C++基础

Linux命令(25)——cp命令

cp命令主要用于复制文件或目录,可以将一个或多个源文件或者目录复制到指定的目的文件或目录,当一次复制多个文件时,目标文件参数必须是一个已经存在的目录,否则将出现...

1392
来自专栏技术碎碎念

OS存储器管理(一)

存储器的层次: 分为寄存器、主存(内存)和 辅存(外存)三个层次。 主存:高速缓冲存储器、主存储器、磁盘缓冲存储器,          主存又称为可执行存储...

3929
来自专栏塔奇克马敲代码

第 8 章 IO库

1975
来自专栏Golang语言社区

实效go编程--4

func handle(queue chan *Request) { for r := range queue { process(r)...

35915

扫码关注云+社区

领取腾讯云代金券