子域名爆破
- os.Open(filename) 打开文件,并使用 bufio.NewScanner(file) 逐行读取子域名。
- 读取到的子域名前缀存入 subdomains 切片中,后续拼接完整域名进行查询。
1 | func loadSubdomains(filename string) ([]string, error) { |
先简单实现一个单线程爆破版本,以 baidu.com 为例
1 | for _, subdomain := range subdomains { |
- 用
net包的LookupHost函数实现DNS解析
1 | func resolveSubdomain(subdomain string) { |

大概功能实现后我们可以继续优化
多线程
• 采用 goroutines 并行查询,提高爆破效率。
• 使用 sync.WaitGroup 确保所有任务执行完成后退出。
• 使用 channel 传递查询结果,防止数据竞争。
1
2
3
4
5
6
7
8
9var wg sync.WaitGroup
maxthreads := 20
sem := make(chan struct{}, maxthreads)
for _, subdomain := range subdomains {
domain := subdomain + ".baidu.com"
wg.Add(1)
go resolveSubdomain(domain, &wg, sem)
}超时控制
DNS 查询可能卡住,可以用 context.WithTimeout() 限制时间:
1
2
3
4
5
6
7
8
9
10
11func resolveSubdomain(subdomain string) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
addrs, err := net.DefaultResolver.LookupHost(ctx, subdomain)
if err != nil {
return
}
for _, addr := range addrs {
fmt.Printf("[+] %s -> %s\n", subdomain, addr)
}
}指定 DNS 服务器
可指定 Google 公共 DNS 解析,提高准确率:
1
2
3
4
5
6
7
8
9ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
resolver := net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{Timeout: 3 * time.Second}
return d.DialContext(ctx, network, "8.8.8.8:53")
},
}
完整代码
1 | package main |
导出文件
输出结果回显在前端直观,但是不好操作数据,所以我们可以添加一个导出功能,我更偏向于导出 csv 文件,设计两个字段,一个域名,一个对应的 ip,这里只保留 ipv4,使用的是 gocsv 库
1 | go get -u github.com/gocarina/gocsv |
1 | type ExportedSubdomain struct { |
进度条实时更新
这就要用到 Events 事件 来侦听了。
后端
1 | runtime.EventsEmit(s.ctx, "subdomain-progress", percentage) |
前端
1 | // 在组件挂载时开始监听事件 |
调用 fofa api
获取用户信息
查一下 fofa 官方文档 https://fofa.info/api/info

1 | type Fofa_Client struct { |
再写一个实现方法
1 | func New_Fofa_Client(email string, key string) *Fofa_Client { |
官网给的响应实例
1 | { |
定义接收类型
1 | type Fofa_API_Info struct { |
实现方法
1 | func (fofa_client *Fofa_Client) API_Info() (*Fofa_API_Info, error) { |
完整代码
1 | package main |
获取主机信息
1 | type Fofa_Info_Search_Host struct { |
端口探测
原理还是基于 TCP 的三次握手

TCP握手有三个过程。首先,客户端发送一个SYN探测包,如果客户端收到连接超时,说明该端口可能在防火墙后面。如果服务端应答syn-ack 包,意味着这个端口是打开的,否则会返回rst包,最后,客户端需要另外发送一个ack包。从这时起,客户端与服务端就已经建立连接。
TCP端口探测的实现,比较简单,原生的net包就有自带的方法,代码如下
1 | package main |
这里使用了net包的DialTimeout方法,该方法第一个参数接收协议名称,这里用的是tcp,第二个参数是ip和端口,需要按照ip:port的格式拼接,第三个参数是超时时间,这里设置了3秒,表示如果超过三秒对端没有回应则不会继续等待。
接下来就是多线程优化了。
1 | package main |
POC 检测
这里打算用 cve-2024-42327,Zabbix SQL注入漏洞来演示。
网站搭建:https://mp.weixin.qq.com/s/ateGftMa4aCheSNYHarH1Q
默认账号密码为:
1 | Admin/zabbix |
抓一个登录包
1 | POST /api_jsonrpc.php HTTP/1.1 |

拿到result的值后,使用第二个数据包,将auth的值改为result的值
1 | POST /api_jsonrpc.php HTTP/1.1 |

可以通过更改userids的值,来遍历其他用户,selectRole参数可控,直接在后面加上sql语句,即可执行

知道漏洞原理就能来编写 go 脚本了
1 | package main |
CDN 解析
这里我们没有那么多服务器,所以还是调一下第三方接口
https://uutool.cn/cdn-check/, 抓包获取他们的服务器。
1 | "https://ips-app-vrdhcyxprn.us-west-1.fcapp.run": "美国-硅⾕", |
该网站 响应IP数量:2 ,说明最多返回两个 ip,这一点接收返回值的时候要考虑进去,因为有这么多服务器,所以我们用多线程。
1 | package main |
EXIF 信息获取
Exif是⼀种图像⽂件格式,实际上Exif格式就是在JPEG格式头部插⼊了数码照⽚的信息,包括拍摄时的光圈、快⻔、⽩平衡、ISO、焦距、⽇期时间等各种和拍摄条件以及相机品牌、型号、⾊彩编码、拍摄时录制的声⾳以及GPS全球定位系统数据、缩略图等。你可以利⽤任何可以查看JPEG⽂件的看图软件浏览Exif格式的照⽚,但并不是所有的图形程序都能处理Exif信息。
EXIF元信息被组织成⼀个图像中的不同图像⽂件⽬录(IFD)。这些IFD的名称与ExifTool系列1组的名称相对应。写⼊EXIF信息时,除⾮指定了另⼀个组,否则将使⽤下⾯列出的默认组。
创建新的IFD时,可以使⽤默认值⾃动添加强制标签(在Writable类型之后⽤冒号表示),如果仅保留默认值的强制标签,则在删除标签时会⾃动删除IFD。
安装 goexif 库
1 | go get -u github.com/rwcarlsen/goexif/exif |
解析 EXIF 格式图片
1 | func main() { |
获取了经纬度我们可以利用高德获取地理位置https://lbs.amap.com/api/webservice/guide/api/georegeo#t5
1 | package main |

EML 信息获取
.eml是⼀种电⼦邮件⽂件格式,它包含完整的电⼦邮件内容,包括发件⼈、收件⼈、主题、正⽂、附件、⽇期等信息。EML是由microsoft公司过邮件客户端导⼊来查看和编辑。
我们可以利用这个来查询钓鱼邮件信息
1 | go get -u github.com/DusanKasan/parsemail |
去github下一个钓鱼邮件做案例
https://github.com/rf-peixoto/phishing_pot
1 | package main |
返回值解析

1 | package main |