批量验证目标URL存活性(使用golang协程高效率验证,10000个目标URL仅需一分钟,附带golang编译用法以及配置国内源)

目录

简介:

使用场景:

代码:

F&Q


简介:

使用场景:

  博主目前从事网络安全工作,有时候会遇到大量url目标需要漏洞测试,比如挖掘src等,这个时候我们就需要对目标进行存活性验证,这样可以减少一些无用的请求,提高我们的工作效率,博主从高效率出发,利用golang的协程高并发编写如下代码。

代码:

废话不多说,代码奉上:

/*
批量验证url存活性;
将需要验证url保存至target.txt中,按照一行一个url格式保存;
需要根据自身目录修改常量path值,例如const path string = "C:\Users\Administrator\Desktop\xx\";
最终输出文件为:urls.txt
 */
package main

import (
	"bufio"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"
)

var wg sync.WaitGroup

const path string = "/xxx/xx/"

func main() {

	// file: 打开URL链接文本{target.txt},file1: 创建保存结果{url.txt}
	file, err := os.Open(path+"target.txt")
	if err != nil {
		log.Fatalf("Error when opening file:\n%s", err)
		return
	}
	defer file.Close()
	file1, err := os.OpenFile(path+"url.txt", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
	if err != nil {
		log.Fatalf("Error when opening file:\n%s", err)
		return
	}
	defer file1.Close()
	// 循环遍历target.txt
	scanners := bufio.NewScanner(file)
	for scanners.Scan() {
		u := scanners.Text()
		// 去除URL中的换行,包含taobao、jd、tb、alibaba等字符的url,可以根据自己需求自行添加规则{res}
		oks := strings.Replace(u, "\n", "", -1)
		res1 := strings.Contains(oks, "taobao")
		res2 := strings.Contains(oks, "jd.")
		res3 := strings.Contains(oks, "tb")
		res4 := strings.Contains(oks, "alibaba")
		res5 := strings.Contains(oks, "tmall")
		res6 := strings.Contains(oks, "1688")
		// 发现存在以上字符跳过开启下一轮循环
		if res1 || res2 || res3 || res4 || res5 || res6 {
			continue
		}
		res7 := strings.Contains(oks, "http://")
		res8 := strings.Contains(oks, "https://")
		// 部分URL缺少协议http://字段,go对没有协议字段的URL会引起恐慌
		if res7 || res8 {
			wg.Add(1)
			go req(oks, file1)
			continue
		}
		// 对缺少协议URL字符串拼接,采取多协程高效率对目标URL验证存活
		okk := "http://" + oks
		okks := "https://" + oks
		wg.Add(1)
		go req(okk, file1)
		wg.Add(1)
		go req(okks, file1)
	}
	wg.Wait()
	quchong()
}

// 目标URL存活验证,传入URL和已经创建好并打开的等待写入的文本文件
func req(ur string, file1 *os.File) {
	defer wg.Done()
	// 有密码认证使用"http://username:password@xxx:8000"
	//proxy := "http://127.0.0.1:8080"
	//proxyAddress, _ := url.Parse(proxy)
	//创建客户端,并添加请求超时时间为10秒
	client := http.Client{
		Timeout: 10 * time.Second,
	}
	// 创建访问http,添加请求头,client.Do执行请求
	req, err := http.NewRequest("GET", ur, nil)
	if err != nil {
		fmt.Print("[err] ",ur," 连接错误: ")
		fmt.Println(err)
		return
	}
	req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36")
	htp, err := client.Do(req)
	if err != nil {
		fmt.Print("[err] ",ur," 连接错误: ")
		fmt.Println(err)
		return
	}
	status := htp.StatusCode
	defer htp.Body.Close()
	fmt.Print("[ok] ",ur, " 状态码:")
	fmt.Println(status)
	// 写入存活状态URL至打开的文本中
	_, err = file1.WriteString(ur+"\n")
	if err != nil {
		fmt.Print("[err] 写入url.txt(一次写入)报错,")
		log.Fatalf("Error when file writestring:\n%s", err)
		return
	}
}

func quchong(){
	// 最后删除中转文件url.txt
	defer remove()
	// 创建切片和集合用于存储遍历url做为判断条件
	a := make([]string, 0, 7)
	b := make(map[string]bool)
	// 打开需要去重文件{url.txt},创建新文件{urls.txt}
	file, err := os.Open(path+"url.txt")
	if err != nil {
		log.Fatalf("Error when opening file:\n%s", err)
		return
	}
	defer file.Close()
	file1, err := os.OpenFile(path+"urls.txt", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
	if err != nil {
		log.Fatalf("Error when opening file:\n%s", err)
		return
	}
	// 将需要去重文件整体赋值为字符串,用于判断url是否重复出现
	defer file1.Close()
	file2, err := os.ReadFile(path+"url.txt")
	if err != nil {
		log.Fatalf("Error when read file:\n%s", err)
		return
	}
	str := string(file2)
	// 循环遍历去除重复url
	scanners := bufio.NewScanner(file)
	for scanners.Scan() {
		ur := scanners.Text()
		res1 := strings.Contains(ur, "http://")
		if res1 {
			url := strings.Replace(ur,"http://","", -1)
			num := strings.Count(str, url)
			if num == 1 {
				_, err = file1.WriteString(ur+"\n")
				if err != nil {
					fmt.Print("[err] 写入urls.txt(二次写入)报错,")
					log.Fatalf("Error when file writestring:\n%s", err)
					return
				}
			} else if num > 1 && ! b[url] {
				a = append(a, url)
				for _, v := range a {
					b[v] = true
				}
				_, _ = file1.WriteString(ur+"\n")
				if err != nil {
					fmt.Print("[err] 写入urls.txt(二次写入)报错,")
					log.Fatalf("Error when file writestring:\n%s", err)
					return
				}
			} else {
				continue
			}
		} else {
			url := strings.Replace(ur,"https://","", -1)
			num := strings.Count(str, url)
			if num == 1 {
				_, err = file1.WriteString(ur+"\n")
				if err != nil {
					fmt.Print("[err] 写入urls.txt(二次写入)报错,")
					log.Fatalf("Error when file writestring:\n%s", err)
					return
				}
			} else if num > 1 && ! b[url] {
				a = append(a, url)
				for _, v := range a {
					b[v] = true
				}
				_, _ = file1.WriteString(ur+"\n")
				if err != nil {
					fmt.Print("[err] 写入urls.txt(二次写入)报错,")
					log.Fatalf("Error when file writestring:\n%s", err)
					return
				}
			} else {
				continue
			}
		}
	}
}

// 创建函数删除中转文件url.txt
func remove() {
	err := os.Remove(path+"url.txt")
	if err != nil {
		fmt.Println("[err] 删除中转文件url.txt失败")
	} else {
		fmt.Println("[ok] 删除中转文件url.txt成功,最终存活URL文件为urls.txt")
	}
}

  使用非常简单,只需要修改代码中 const path string = "/xxx/xx/",将引号中修改为自己代码放置位置的绝对路径,例如:"C:\Users\Administrator\Desktop\xx\",注意最后\一定要有,将代码保存为xxx.go,根据个人喜好将文件放到刚刚指定的目录,,将需要测试存活性的url保存指同级目录,然后命名为target.txt,url没有格式要求随意即可,代码会自动分类处理。

  以上完成后就可以愉快的运行脚本了

go run xxx.go

稍等片刻,存活验证成功的url将会被输出到同级目录为urls.txt。

 

  当然golang也可以将代码打包成二进制文件,windows可以打包成exe,Mac/Linux同样可以打包成对应系统可执行文件,命令:

1.Mac
Mac下编译Linux, Windows平台的64位可执行程序:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build test.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go
2.Linux
Linux下编译Mac, Windows平台的64位可执行程序:
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build test.go
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build test.go
3.Windows
Windows下编译Mac, Linux平台的64位可执行程序:
SET CGO_ENABLED=0
SET GOOS=darwin3
SET GOARCH=amd64
go build main.go
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go
GOOS:目标可执行程序运行操作系统,支持 darwin,freebsd,linux,windows
GOARCH:目标可执行程序操作系统构架,包括 386,amd64,arm

  说到这里不得不说golang配置国内源,这个在下载需要安装第三方库的时候会用上,本文代码用不上,提前配置以后难免会用到:

Mac/Linux
配置国内源
export GOPROXY=https://goproxy.cn

// 编辑配置文件永久配置
vim ~/.bashrc
export GOPROXY=https://goproxy.cn
source ~/.bashrc


windows
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

F&Q

  欢迎使用过程出现的问题评论讨论,目前没有发现bug,如果有童鞋发现可以评论也可以私信。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python和Golang是两种不同的编程语言,它们在不同的领域有着各自的优势和用途。 Python是一种通用的高级编程语言,它具有简单易学、代码可读强的特点,非常适合用于数据分析、人工智能、科学计算等领域。Python拥有丰富的第三方库和生态系统,可以方便地进行各种开发任务。 Golang是一种静态类型的编程语言,它具有高效、并发强的特点,非常适合用于构建高能的网络服务和分布式系统。Golang的语法简洁,编译速度快,可以有效地利用多核处理器的优势。 如果你想结合Python和Golang进行开发,可以考虑以下几种方式: 1. 使用Python调用Golang代码:你可以使用Python的`subprocess`模块或者`ctypes`模块来调用Golang编写的可执行文件或者动态链接库。这样可以充分发挥Golang的高能特点,同时利用Python丰富的库来进行数据处理和分析。 2. 使用Golang调用Python代码:Golang提供了`cgo`模块,可以方便地调用C语言的代码。你可以使用`cgo`模块来调用Python的C API,从而在Golang中调用Python代码。这样可以利用Python强大的库来进行数据处理和分析,同时利用Golang的高能特点来提高程序的执行效率。 3. 使用RPC或消息队列进行通信:你可以使用RPC框架(如gRPC)或消息队列(如RabbitMQ)来实现Python和Golang之间的通信。通过定义好的接口和消息格式,可以方便地在两种语言之间传递数据和调用函数。 总之,Python和Golang可以很好地结合使用,根据具体的求和场景选择合适的方式进行开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值