Web

安全开发

自动告警系统

Posted by pic4xiu on May 31, 2023

抓包存mysql中

package main


import (
    "fmt"
    "log"
    "net"
    "strings"


    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/mysql"
)


type DNSPacket struct {
    ID      uint16 `gorm:"primary_key"`
    Queries string
    Answers string
}


func main() {
    // Open the device for capturing
    handle, err := pcap.OpenLive("en0", 65535, true, pcap.BlockForever)
    if err != nil {
        log.Fatal(err)
    }
    defer handle.Close()


    // Set a filter to capture only DNS packets
    filter := "udp and port 53"
    err = handle.SetBPFFilter(filter)
    if err != nil {
        log.Fatal(err)
    }


    // Open a connection to the MySQL database
    db, err := gorm.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/database?charset=utf8&parseTime=True&loc=Local")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()


    // Create the DNSPacket table if it doesn't exist
    db.AutoMigrate(&DNSPacket{})


    // Start capturing packets
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    for packet := range packetSource.Packets() {
        // Parse the DNS packet
        dnsLayer := packet.Layer(layers.LayerTypeDNS)
        if dnsLayer != nil {
            dnsPacket := dnsLayer.(*layers.DNS)
            if dnsPacket.QR == false && dnsPacket.OpCode == layers.DNSOpCodeQuery {
                // Extract the queries from the DNS packet
                queries := make([]string, len(dnsPacket.Questions))


                for i, question := range dnsPacket.Questions {
                    queries[i] = string(question.Name)
                    fmt.Println((question))
                }


                // Check if the DNSPacket already exists in the database
                var count int
                db.Model(&DNSPacket{}).Where("id = ?", dnsPacket.ID).Count(&count)
                if count == 0 {
                    // Recursively resolve the DNS queries
                    answers := make([]string, 0)
                    for _, query := range queries {
                        // fmt.Println(query)
                        ips, err := resolveDNS(query)
                        if err == nil {
                            answers = append(answers, ips...)
                        }
                    }


                    // Create a new DNSPacket object and save it to the database
                    dnsPacket := DNSPacket{
                        ID:      dnsPacket.ID,
                        Queries: strings.Join(queries, ","),
                        Answers: strings.Join(answers, ","),
                    }
                    db.Create(&dnsPacket)
                }
            }
        }
    }
}


func resolveDNS(query string) ([]string, error) {
    // Resolve the DNS query using the system resolver
    ips := make([]string, 0)
    addrs, err := net.LookupHost(query)
    if err != nil {
        return ips, err
    }
    for _, addr := range addrs {
        ips = append(ips, addr)
    }
    return ips, nil
}

过滤器选择udp并且53端口的,然后都存到数据库中

![image.png](https://raw.githubusercontent.com/pic4xiu/pic4xiu.github.io/master/_posts/waf2/em1.png)
```python
#!/usr/bin/env python3

import mysql.connector
# import smtplib
import os
# 恶意域名库文件路径
MALWARE_DOMAINS_FILE = "domains.list"

# MySQL数据库连接信息
MYSQL_HOST = "localhost"
MYSQL_PORT = 3306
MYSQL_USER = "root"
MYSQL_PASSWORD = "123456"
MYSQL_DATABASE = "database"

cnx = mysql.connector.connect(user=MYSQL_USER, password=MYSQL_PASSWORD,
                              host=MYSQL_HOST, port=MYSQL_PORT,
                              database=MYSQL_DATABASE)
cursor = cnx.cursor()

# 检查恶意域名库中的域名是否存在于数据库中
with open(MALWARE_DOMAINS_FILE) as f:
    for domain in f:
        domain = domain.strip()
        query = "SELECT COUNT(*) FROM dns_packets WHERE queries = %s"

        cursor.execute(query, (domain,))
        result = cursor.fetchone()[0]
        print(result)
        if result >= 1:
            # 触发告警
            subject = "Malware Alert"
            body = f"Alert: {domain} found in malware domain list"
            print('echo '+body+'| mail -s "恶意域名!" *****@qq.com')#发送邮件
            os.system('echo '+body+'| mail -s "bad query!" ******@qq.com')#直接用系统命令会简单很多

cursor.close()
cnx.close()

然后如果是开了微信的qq邮箱提醒的话,直接就可以看到,刷新很快啊!

image.png

当然并没有访问恶意域名,只是把bing.com放到数据库里边了,而且在恶意域名库里加了一下而已。

image.png

恶意ip的

package main


import (
    "database/sql"
    "log"


    _ "github.com/go-sql-driver/mysql"
    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
)


func main() {
    // 打开数据库连接
    db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/database")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()


    // 创建TCP数据包表
    _, err = db.Exec("CREATE TABLE IF NOT EXISTS tcp_packets (id INT AUTO_INCREMENT PRIMARY KEY, src_ip VARCHAR(15), dst_ip VARCHAR(15), src_port INT, dst_port INT)")
    if err != nil {
        log.Fatal(err)
    }


    // 打开网络接口
    handle, err := pcap.OpenLive("en0", 65535, true, pcap.BlockForever)
    if err != nil {
        log.Fatal(err)
    }
    defer handle.Close()


    // 设置过滤器,只捕获TCP流量
    filter := "tcp"
    err = handle.SetBPFFilter(filter)
    if err != nil {
        log.Fatal(err)
    }


    // 循环读取TCP数据包
    packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
    for packet := range packetSource.Packets() {
        // 解析TCP数据包
        tcpLayer := packet.Layer(layers.LayerTypeTCP)
        if tcpLayer != nil {
            tcp, _ := tcpLayer.(*layers.TCP)
            srcIP := packet.NetworkLayer().NetworkFlow().Src().String()
            dstIP := packet.NetworkLayer().NetworkFlow().Dst().String()
            srcPort := tcp.SrcPort
            dstPort := tcp.DstPort


            // 将五元组信息存储到数据库中
            _, err = db.Exec("INSERT INTO tcp_packets (src_ip, dst_ip, src_port, dst_port) VALUES (?, ?, ?, ?)", srcIP, dstIP, srcPort, dstPort)
            if err != nil {
                log.Println(err)
            }
        }
    }
}

image.png

自动告警与之类似,不做赘述