1
0
mirror of https://github.com/sairson/Yasso.git synced 2026-02-12 14:55:32 +08:00

Yasso更新大改动,更新扫描方式,去除不常用功能,增加指纹和协议识别,修补bug等

This commit is contained in:
sairson
2022-05-29 09:11:07 +08:00
parent a6cd80f8e8
commit cb72f18edd
129 changed files with 16619 additions and 6278 deletions

301
core/parse/parse_ip.go Normal file
View File

@@ -0,0 +1,301 @@
package parse
import (
"Yasso/core/logger"
"bufio"
"errors"
"fmt"
"github.com/projectdiscovery/cdncheck"
"net"
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"sync"
)
// ReadFile 从文件中读取数据
func ReadFile(filename string) ([]string, error) {
file, err := os.Open(filename)
if err != nil {
logger.Fatal("open file has an error", err.Error())
return nil, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
var re []string
for scanner.Scan() {
text := strings.TrimSpace(scanner.Text())
if text != "" {
re = append(re, text)
}
}
re = Duplicate(re) // 去重
return re, nil
}
// ConvertDomainToIpAddress 将域名转换成ip地址
func ConvertDomainToIpAddress(domains []string, thread int) ([]string, error) {
checkChan := make(chan string, 100)
var wg sync.WaitGroup
var re []string
for i := 0; i < thread; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for host := range checkChan {
if strings.Count(host, ".") == 3 && len(strings.Split(host, ":")) == 2 {
// 这种是带有端口的ip地址
re = append(re, host)
continue
}
ip, err := net.LookupHost(host)
if err != nil {
continue
}
if ip != nil {
// 证明存在cdn直接丢掉即可(不跑带有cdn的域名)
if len(ip) >= 2 {
logger.Info(fmt.Sprintf("%s has cdn %v", host, ip[:]))
continue
} else {
for _, i := range ip {
re = append(re, i)
}
}
}
}
}()
}
for _, domain := range domains {
if strings.Contains(domain, "http://") {
domain = strings.TrimPrefix(domain, "http://")
}
if strings.Contains(domain, "https://") {
domain = strings.TrimPrefix(domain, "https://")
}
checkChan <- domain
}
close(checkChan)
wg.Wait()
re = Duplicate(re) // 去重
return re, nil
}
// cdnFilter cdn过滤器
func cdnFilter(ip string, client *cdncheck.Client) string {
if found, _, err := client.Check(net.ParseIP(ip)); found && err == nil {
return ip
}
return ""
}
// Duplicate 去重
func Duplicate(slc []string) []string {
var re []string
temp := map[string]byte{}
for _, v := range slc {
l := len(temp)
temp[v] = 0
if len(temp) != l {
re = append(re, v)
}
}
return re
}
// RegIpv4Address 匹配ipv4
func RegIpv4Address(context string) string {
matched, err := regexp.MatchString("((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}", context)
if err != nil {
return ""
}
if matched {
return context
}
return ""
}
func HandleIps(ip string) ([]string, error) {
var Unprocessed []string
var err error
var basic []string
if strings.Contains(ip, ".txt") {
if strings.ToLower(path.Ext(filepath.Base(ip))) == ".txt" {
// 文件后缀为.txt的话,我们按照文件解析并获取数据结果
Unprocessed, err = ReadFile(ip)
if err != nil {
return []string{}, err
}
}
/*
这里获取到的数据格式可能为
192.168.248.1/24
192.168.248.1-155
www.baidu.com
192.168.248.1:3389
https://www.baidu.com
*/
// 第一波解析开始解析ip地址格式
for _, i := range Unprocessed {
switch {
case RegIpv4Address(i) != "" && (strings.Count(i, "/24") == 1 || strings.Count(i, "/16") == 1):
temp, err := ConvertIpFormatA(i)
if err != nil {
logger.Fatal("parse ip address has an error", err.Error())
return []string{}, err
}
basic = append(basic, temp...)
case RegIpv4Address(i) != "" && strings.Count(i, "-") == 1 && !strings.Contains(i, "/"):
fmt.Println(i)
temp, err := ConvertIpFormatB(i)
if err != nil {
logger.Fatal("parse ip address has an error", err.Error())
return []string{}, err
}
basic = append(basic, temp...)
case strings.Contains(i, "https://") || strings.Contains(i, "http://"):
if strings.Contains(i, "https://") {
basic = append(basic, strings.ReplaceAll(i, "https://", ""))
}
if strings.Contains(i, "http://") {
basic = append(basic, strings.ReplaceAll(i, "https", ""))
}
default:
basic = append(basic, i)
}
}
// 第一波解析完成,开始第二波解析,解析域名
basic = Duplicate(basic) // 第一次去重
basic, err = ConvertDomainToIpAddress(basic, 100)
if err != nil {
logger.Fatal("parse domain has an error", err.Error())
return nil, err
}
basic = Duplicate(basic) // 第二次去重
} else {
basic, err = ConvertIpFormatAll(ip)
if err != nil {
logger.Fatal("parse ip address has an error", err.Error())
return []string{}, err
}
}
// 二次筛选
var newBasic []string
for _, ip := range basic {
if strings.Contains(ip, "/") {
newBasic = append(newBasic, strings.Split(ip, "/")[0])
} else {
newBasic = append(newBasic, ip)
}
}
// 对获取到的ip地址进行排序进行后续操作
sort.Strings(newBasic)
return newBasic, err
}
// ConvertIpFormatA 不解析192.168.248.1/8格式目前
func ConvertIpFormatA(ip string) ([]string, error) {
var ip4 = net.ParseIP(strings.Split(ip, "/")[0])
if ip4 == nil {
return []string{}, errors.New("not an ipv4 address")
}
var mark = strings.Split(ip, "/")[1]
var temp []string
var err error
switch mark {
case "24":
var ip3 = strings.Join(strings.Split(ip[:], ".")[0:3], ".")
for i := 0; i <= 255; i++ {
temp = append(temp, ip3+"."+strconv.Itoa(i))
}
err = nil
case "16":
var ip2 = strings.Join(strings.Split(ip[:], ".")[0:2], ".")
for i := 0; i <= 255; i++ {
for j := 0; j <= 255; j++ {
temp = append(temp, ip2+"."+strconv.Itoa(i)+"."+strconv.Itoa(j))
}
}
err = nil
default:
temp = []string{}
err = errors.New("not currently supported")
}
return temp, err
}
func ConvertIpFormatB(ip string) ([]string, error) {
var ip4 = strings.Split(ip, "-")
var ipA = net.ParseIP(ip4[0])
if ip4 == nil {
return []string{}, errors.New("not an ipv4 address")
}
var temp []string
if len(ip4[1]) < 4 {
iprange, err := strconv.Atoi(ip4[1])
if ipA == nil || iprange > 255 || err != nil {
return []string{}, errors.New("input format is not ccorrect")
}
var splitip = strings.Split(ip4[0], ".")
ip1, err1 := strconv.Atoi(splitip[3])
ip2, err2 := strconv.Atoi(ip4[1])
prefixip := strings.Join(splitip[0:3], ".")
if ip1 > ip2 || err1 != nil || err2 != nil {
return []string{}, errors.New("input format is not ccorrect")
}
for i := ip1; i <= ip2; i++ {
temp = append(temp, prefixip+"."+strconv.Itoa(i))
}
} else {
var splitip1 = strings.Split(ip4[0], ".")
var splitip2 = strings.Split(ip4[1], ".")
if len(splitip1) != 4 || len(splitip2) != 4 {
return []string{}, errors.New("input format is not ccorrect")
}
start, end := [4]int{}, [4]int{}
for i := 0; i < 4; i++ {
ip1, err1 := strconv.Atoi(splitip1[i])
ip2, err2 := strconv.Atoi(splitip2[i])
if ip1 > ip2 || err1 != nil || err2 != nil {
return []string{}, errors.New("input format is not ccorrect")
}
start[i], end[i] = ip1, ip2
}
startNum := start[0]<<24 | start[1]<<16 | start[2]<<8 | start[3]
endNum := end[0]<<24 | end[1]<<16 | end[2]<<8 | end[3]
for num := startNum; num <= endNum; num++ {
ip := strconv.Itoa((num>>24)&0xff) + "." + strconv.Itoa((num>>16)&0xff) + "." + strconv.Itoa((num>>8)&0xff) + "." + strconv.Itoa((num)&0xff)
temp = append(temp, ip)
}
}
return temp, nil
}
func ConvertIpFormatAll(ip string) ([]string, error) {
reg := regexp.MustCompile(`[a-zA-Z]+`)
switch {
case strings.Count(ip, "/") == 1:
return ConvertIpFormatA(ip)
case strings.Count(ip, "-") == 1:
return ConvertIpFormatB(ip)
case reg.MatchString(ip):
_, err := net.LookupHost(ip)
if err != nil {
return []string{}, err
}
return []string{ip}, nil
default:
var isip = net.ParseIP(ip)
if isip == nil {
return []string{}, errors.New("input format is not ccorrect")
}
return []string{ip}, nil
}
}

50
core/parse/parse_port.go Normal file
View File

@@ -0,0 +1,50 @@
package parse
import (
"strconv"
"strings"
)
// HandlePorts 解析端口格式
func HandlePorts(ports string) ([]int, error) {
var scanPorts []int
slices := strings.Split(ports, ",")
for _, port := range slices {
port = strings.Trim(port, " ")
upper := port
if strings.Contains(port, "-") {
ranges := strings.Split(port, "-")
if len(ranges) < 2 {
continue
}
startPort, _ := strconv.Atoi(ranges[0])
endPort, _ := strconv.Atoi(ranges[1])
if startPort < endPort {
port = ranges[0]
upper = ranges[1]
} else {
port = ranges[1]
upper = ranges[0]
}
}
start, _ := strconv.Atoi(port)
end, _ := strconv.Atoi(upper)
for i := start; i <= end; i++ {
scanPorts = append(scanPorts, i)
}
}
scanPorts = RemoveDuplicate(scanPorts)
return scanPorts, nil
}
func RemoveDuplicate(old []int) []int {
result := make([]int, 0, len(old))
temp := map[int]struct{}{}
for _, item := range old {
if _, ok := temp[item]; !ok {
temp[item] = struct{}{}
result = append(result, item)
}
}
return result
}