Skip to content

Commit

Permalink
添加ip地理位置识别及运营商,优化查询条件
Browse files Browse the repository at this point in the history
  • Loading branch information
kN6jq committed Jan 26, 2024
1 parent 852ec2d commit b9806a2
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 16 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

> 举例如下,日后有空还会新增其他搜索引擎,方便后续加入我的信息收集系统

# qqwry使用说明

将qqwry.dat文件放在可执行文件同目录

## fofa


Expand Down
4 changes: 2 additions & 2 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module:
fofa:
url: https://fofa.info/api/v1/search/all
email: xxx
token: 111111111111111111111111111
email:
token:
all: true # 是否获取全部
size: 1000 # 如果不是全部,那么最大获取多少
batchSize: 10 # 一次查询多少
Expand Down
14 changes: 10 additions & 4 deletions module/fofa.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,16 @@ func RunFofa(data string, filename string) {
if fofadataTotal > 0 {
pageSize := 100 // 每页处理 100 条数据
// 这里修改为通过开关设置获取全部还是指定数量
if utils.Config.Module.Fofa.All == true {
if utils.Config.Module.Fofa.All == true && fofadataTotal > config.Module.Fofa.Size {
fofadataTotal = fofadataTotal
} else if utils.Config.Module.Fofa.All == false {
} else if utils.Config.Module.Fofa.All == true && fofadataTotal < config.Module.Fofa.Size {
fofadataTotal = fofadataTotal
} else if utils.Config.Module.Fofa.All == false && fofadataTotal > config.Module.Fofa.Size {
fofadataTotal = config.Module.Fofa.Size
} else if utils.Config.Module.Fofa.All == false && fofadataTotal < config.Module.Fofa.Size {
fofadataTotal = fofadataTotal
}

// 计算总页数
totalPages := (fofadataTotal + pageSize - 1) / pageSize

Expand Down Expand Up @@ -81,9 +86,10 @@ func RunFofa(data string, filename string) {
webTitle := utils.ToString(result[2])
ip := utils.ToString(result[3])
port := utils.ToString(result[4])
row := []string{domain, url, webTitle, ip, port}
area, country, _ := utils.QueryIp(ip)
row := []string{domain, url, webTitle, ip, port, country, area}
rows = append(rows, row)
fmt.Printf("%-20s %-50s %-50s %-30s %-30s\n", domain, url, webTitle, ip, port)
fmt.Printf("%-20s %-50s %-50s %-30s %-30s %-30s %-30s\n", domain, url, webTitle, ip, port, country, area)
}
}
if len(rows) > 0 {
Expand Down
15 changes: 10 additions & 5 deletions module/hunter.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,14 @@ func RunHunter(data string, filename string) {
pageSize := 100 // 每页处理 10 条数据

// 获取全部还是指定数量
if utils.Config.Module.Hunter.All == true {
if utils.Config.Module.Hunter.All == true && hunterdataTotal > config.Module.Hunter.Size {
hunterdataTotal = hunterdataTotal
} else if utils.Config.Module.Hunter.All == true && hunterdataTotal < config.Module.Hunter.Size {
hunterdataTotal = hunterdataTotal
} else if utils.Config.Module.Hunter.All == false && hunterdataTotal > config.Module.Hunter.Size {
hunterdataTotal = config.Module.Hunter.Size
} else if utils.Config.Module.Hunter.All == false && hunterdataTotal < config.Module.Hunter.Size {
hunterdataTotal = hunterdataTotal
} else if utils.Config.Module.Hunter.All == false {
hunterdataTotal = utils.Config.Module.Hunter.Size
}
// 计算总页数
totalPages := (hunterdataTotal + pageSize - 1) / pageSize
Expand All @@ -118,8 +122,9 @@ func RunHunter(data string, filename string) {
statusCode := hunterDataResults.Data.Arr[i].StatusCode
ip := utils.ToString(hunterDataResults.Data.Arr[i].IP)
port := hunterDataResults.Data.Arr[i].Port
fmt.Printf("%-20s %-30s %-40s %-20d %-20s %-20d\n", domain, url, webTitle, statusCode, ip, port)
row := []string{domain, url, webTitle, strconv.Itoa(statusCode), ip, strconv.Itoa(port)}
area, country, _ := utils.QueryIp(ip)
fmt.Printf("%-20s %-30s %-40s %-20d %-20s %-20d %-30s %-40s\n", domain, url, webTitle, statusCode, ip, port, country, area)
row := []string{domain, url, webTitle, strconv.Itoa(statusCode), ip, strconv.Itoa(port), country, area}
rows = append(rows, row)
}

Expand Down
5 changes: 3 additions & 2 deletions module/shodan.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ func RunShodan(data string, filename string) {
subdomain = shodanResults.Data[i].Subdomain + "." + data
}
ip := shodanResults.Data[i].Value
rows = append(rows, []string{data, subdomain, ip})
fmt.Printf("%-20s %-20s %-20s \n", data, subdomain, ip)
area, country, _ := utils.QueryIp(ip)
rows = append(rows, []string{data, subdomain, ip, area, country})
fmt.Printf("%-20s %-20s %-20s %-20s %-20s\n", data, subdomain, ip, area, country)
}
if len(rows) > 0 {
// 保存数据到 Excel 文件
Expand Down
Binary file added qqwry.dat
Binary file not shown.
31 changes: 31 additions & 0 deletions utils/goqqery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package utils

import (
"github.com/kN6jq/gatherSearch/utils/goqqwry"
"log"
"strings"
)

func init() {
goqqwry.IPData.FilePath = "./qqwry.dat"
}

func QueryIp(ip string) (area string, country string, iscloud bool) {
res := goqqwry.IPData.InitIPData()
if v, ok := res.(error); ok {
log.Panic(v)
}
qqWry := goqqwry.NewQQwry()

if ip == "" {
log.Fatalln("请输入ip地址")
}

rs := map[string]goqqwry.ResultQQwry{}
rs[ip] = qqWry.Find(ip)
if strings.Contains(rs[ip].Area, "云") || strings.Contains(rs[ip].Area, "数据中心") || strings.Contains(rs[ip].Area, "cloud") {
return rs[ip].Area, rs[ip].Country, true
} else {
return rs[ip].Area, rs[ip].Country, false
}
}
32 changes: 32 additions & 0 deletions utils/goqqwry/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package goqqwry

import "os"

const (
// IndexLen 索引长度
IndexLen = 7
// RedirectMode1 国家的类型, 指向另一个指向
RedirectMode1 = 0x01
// RedirectMode2 国家的类型, 指向一个指向
RedirectMode2 = 0x02
)

// ResultQQwry 归属地信息
type ResultQQwry struct {
IP string `json:"ip"`
Country string `json:"country"`
Area string `json:"area"`
}

type FileData struct {
Data []byte
FilePath string
Path *os.File
IPNum int64
}

// QQwry 纯真ip库
type QQwry struct {
Data *FileData
Offset int64
}
219 changes: 219 additions & 0 deletions utils/goqqwry/qqwry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package goqqwry

import (
"encoding/binary"
"errors"
"io/ioutil"
"log"
"net"
"os"
"strings"

"golang.org/x/text/encoding/simplifiedchinese"
)

var IPData FileData

// InitIPData 初始化ip库数据到内存中
func (f *FileData) InitIPData() (rs interface{}) {

// 判断文件是否存在
_, err := os.Stat(f.FilePath)
if err != nil && os.IsNotExist(err) {
rs = errors.New("文件不存在")
return
}

// 打开文件句柄
f.Path, err = os.OpenFile(f.FilePath, os.O_RDONLY, 0400)
if err != nil {
rs = err
return
}
defer f.Path.Close()

tmpData, err := ioutil.ReadAll(f.Path)
if err != nil {
log.Println(err)
rs = err
return
}

f.Data = tmpData

buf := f.Data[0:8]
start := binary.LittleEndian.Uint32(buf[:4])
end := binary.LittleEndian.Uint32(buf[4:])

f.IPNum = int64((end-start)/IndexLen + 1)

return true
}

// NewQQwry 新建 qqwry 类型
func NewQQwry() QQwry {
return QQwry{
Data: &IPData,
}
}

// ReadData 从文件中读取数据
func (q *QQwry) ReadData(num int, offset ...int64) (rs []byte) {
if len(offset) > 0 {
q.SetOffset(offset[0])
}
nums := int64(num)
end := q.Offset + nums
dataNum := int64(len(q.Data.Data))
if q.Offset > dataNum {
return nil
}

if end > dataNum {
end = dataNum
}
rs = q.Data.Data[q.Offset:end]
q.Offset = end
return
}

// SetOffset 设置偏移量
func (q *QQwry) SetOffset(offset int64) {
q.Offset = offset
}

// Find ip地址查询对应归属地信息
func (q *QQwry) Find(ip string) (res ResultQQwry) {

res = ResultQQwry{}

res.IP = ip
if strings.Count(ip, ".") != 3 {
return res
}
offset := q.searchIndex(binary.BigEndian.Uint32(net.ParseIP(ip).To4()))
if offset <= 0 {
return
}

var country []byte
var area []byte

mode := q.readMode(offset + 4)
if mode == RedirectMode1 {
countryOffset := q.readUInt24()
mode = q.readMode(countryOffset)
if mode == RedirectMode2 {
c := q.readUInt24()
country = q.readString(c)
countryOffset += 4
} else {
country = q.readString(countryOffset)
countryOffset += uint32(len(country) + 1)
}
area = q.readArea(countryOffset)
} else if mode == RedirectMode2 {
countryOffset := q.readUInt24()
country = q.readString(countryOffset)
area = q.readArea(offset + 8)
} else {
country = q.readString(offset + 4)
area = q.readArea(offset + uint32(5+len(country)))
}

enc := simplifiedchinese.GBK.NewDecoder()
res.Country, _ = enc.String(string(country))
res.Area, _ = enc.String(string(area))

return
}

// readMode 获取偏移值类型
func (q *QQwry) readMode(offset uint32) byte {
mode := q.ReadData(1, int64(offset))
return mode[0]
}

// readArea 读取区域
func (q *QQwry) readArea(offset uint32) []byte {
mode := q.readMode(offset)
if mode == RedirectMode1 || mode == RedirectMode2 {
areaOffset := q.readUInt24()
if areaOffset == 0 {
return []byte("")
}
return q.readString(areaOffset)
}
return q.readString(offset)
}

// readString 获取字符串
func (q *QQwry) readString(offset uint32) []byte {
q.SetOffset(int64(offset))
data := make([]byte, 0, 30)
buf := make([]byte, 1)
for {
buf = q.ReadData(1)
if buf[0] == 0 {
break
}
data = append(data, buf[0])
}
return data
}

// searchIndex 查找索引位置
func (q *QQwry) searchIndex(ip uint32) uint32 {
header := q.ReadData(8, 0)

start := binary.LittleEndian.Uint32(header[:4])
end := binary.LittleEndian.Uint32(header[4:])

buf := make([]byte, IndexLen)
mid := uint32(0)
_ip := uint32(0)

for {
mid = q.getMiddleOffset(start, end)
buf = q.ReadData(IndexLen, int64(mid))
_ip = binary.LittleEndian.Uint32(buf[:4])

if end-start == IndexLen {
offset := byteToUInt32(buf[4:])
buf = q.ReadData(IndexLen)
if ip < binary.LittleEndian.Uint32(buf[:4]) {
return offset
}
return 0
}

// 找到的比较大,向前移
if _ip > ip {
end = mid
} else if _ip < ip { // 找到的比较小,向后移
start = mid
} else if _ip == ip {
return byteToUInt32(buf[4:])
}
}
}

// readUInt24
func (q *QQwry) readUInt24() uint32 {
buf := q.ReadData(3)
return byteToUInt32(buf)
}

// getMiddleOffset
func (q *QQwry) getMiddleOffset(start uint32, end uint32) uint32 {
records := ((end - start) / IndexLen) >> 1
return start + records*IndexLen
}

// byteToUInt32 将 byte 转换为uint32
func byteToUInt32(data []byte) uint32 {
i := uint32(data[0]) & 0xff
i |= (uint32(data[1]) << 8) & 0xff00
i |= (uint32(data[2]) << 16) & 0xff0000
return i
}
Loading

0 comments on commit b9806a2

Please sign in to comment.