main文件中common.Parse(&Info) 如何处理参数
parse中有四个处理参数的函数,分别处理扫描类型、用户名、密码 、输出。
func Parse(Info *HostInfo) {
ParseScantype(Info)
ParseUser(Info)
ParsePass(Info)
ParseInput(Info)
}
ParseScantype(Info)
处理 -m 参数:flag.StringVar(&Info.Scantype, “m”, “all”, “Select scan type ,as: -m ssh”)
- 判断Info.Scantype 是否在PORTList的key中(PORTList定义协议所对应的端口),使用map进行判断,不在则调用showmode(输出PORTList并退出)
- 判断扫描类型是否是all(默认值all)
- 判断-p 参数的info.ports,是否等于默认端口
- 使用switch判断扫描类型
- 判断-p 参数的info.ports,是否等于默认端口
(自己日常使用者从没有用过-m 参数,默认值为all,不进入这里)
func ParseScantype(Info *HostInfo) {
_, ok := PORTList[Info.Scantype]
if !ok {
showmode()
}
if Info.Scantype != "all" {
if Info.Ports == DefaultPorts {
switch Info.Scantype {
case "rdp":
Info.Ports = "3389"
case "wmi":
Info.Ports = "135"
case "web":
Info.Ports = Webport
case "ms17010":
Info.Ports = "445"
case "cve20200796":
Info.Ports = "445"
case "smb2":
Info.Ports = "445"
case "portscan":
Info.Ports = DefaultPorts + "," + Webport
case "main":
Info.Ports = DefaultPorts
default:
port, _ := PORTList[Info.Scantype]
Info.Ports = strconv.Itoa(port)
}
fmt.Println("-m ", Info.Scantype, " start scan the port:", Info.Ports)
}
}
}
ParseUser(Info)
处理爆破时的用户名、用户名文件,-user、-userf
- 判断-user、-userf是否为空,等于空return
- 如果-user参数不为空,使用,分割多个用户名,例如 -user root,admin
- 如果-userf不为空,使用readfile函数打开userfile,
- readfile函数主要bufio处理用户名文件,最终返回下标对应的username(不是很理解,返回的string类型为啥是这样,以及bufio)
0 123
1 456
2 789
3 abc
遍历返回的值拿出username 追加到Info.Usernames 中
- 使用RemoveDuplicate对用户名进行去重
userdict 为常见协议的用户名map,将上面的所有用户名赋值给 Userdict的key。(Userdict应该是在没有设置用户名与用户文件是的默认用户名map,在设置自己的用户名后就覆盖)
var Userdict = map[string][]string{
"ftp": {"ftp", "admin", "www", "web", "root", "db", "wwwroot", "data"},
"mysql": {"root", "mysql"},
"mssql": {"sa", "sql"},
"smb": {"administrator", "admin", "guest"},
"rdp": {"administrator", "admin", "guest"},
"postgresql": {"postgres", "admin"},
"ssh": {"root", "admin"},
"mongodb": {"root", "admin"},
}
func ParseUser(Info *HostInfo) {
if Info.Username == "" && Userfile == "" {
return
}
if Info.Username != "" {
Info.Usernames = strings.Split(Info.Username, ",")
}
if Userfile != "" {
users, err := Readfile(Userfile)
if err == nil {
for _, user := range users {
if user != "" {
Info.Usernames = append(Info.Usernames, user)
}
}
}
}
Info.Usernames = RemoveDuplicate(Info.Usernames)
for name := range Userdict {
Userdict[name] = Info.Usernames
}
}
ParsePass(Info *HostInfo)
密码处理思路跟用户名差不多
- 先判断有无单独 使用-pwd 参数的密码,逗号分隔。
- 判断是否指定了password文件,读取文件追加到Info.Passwords中,然后覆盖默认密码Passwords
判断-uf 指定的url文件,处理后赋值给urls
func ParsePass(Info *HostInfo) {
if Info.Password != "" {
passs := strings.Split(Info.Password, ",")
for _, pass := range passs {
if pass != "" {
Info.Passwords = append(Info.Passwords, pass)
}
}
Passwords = Info.Passwords
}
if Passfile != "" {
passs, err := Readfile(Passfile)
if err == nil {
for _, pass := range passs {
if pass != "" {
Info.Passwords = append(Info.Passwords, pass)
}
}
Passwords = Info.Passwords
}
}
if UrlFile != "" {
urls, err := Readfile(UrlFile)
if err == nil {
TmpUrls := make(map[string]struct{})
for _, url := range urls {
if _, ok := TmpUrls[url]; !ok {
TmpUrls[url] = struct{}{}
if url != "" {
Urls = append(Urls, url)
}
}
}
}
}
}
ParseInput(Info *HostInfo)
处理-o 参数
func ParseInput(Info *HostInfo) {
if Info.Host == "" && HostFile == "" && URL == "" && UrlFile == "" {
fmt.Println("Host is none")
flag.Usage()
os.Exit(0)
}
if TmpOutputfile != "" {
if !strings.Contains(Outputfile, "/") && !strings.Contains(Outputfile, `\`) {
Outputfile = getpath() + TmpOutputfile
} else {
Outputfile = TmpOutputfile
}
}
if TmpSave == true {
IsSave = false
}
if Info.Ports == DefaultPorts {
Info.Ports += "," + Webport
}
if PortAdd != "" {
if strings.HasSuffix(Info.Ports, ",") {
Info.Ports += PortAdd
} else {
Info.Ports += "," + PortAdd
}
}
}