mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-25 20:51:52 +08:00
@@ -212,6 +212,8 @@ yay -S fscan-git
|
|||||||
`fscan.exe -h 192.168.x.x -m ssh -user root -pwd password`
|
`fscan.exe -h 192.168.x.x -m ssh -user root -pwd password`
|
||||||

|

|
||||||
|
|
||||||
|
`fscan.exe -h 192.168.x.x -m ssh -user root -pwda pass1 pass2 pass3` (追加多个密码)
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -p80 -proxy http://127.0.0.1:8080`
|
`fscan.exe -h 192.168.x.x -p80 -proxy http://127.0.0.1:8080`
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -211,6 +211,8 @@ yay -S fscan-git
|
|||||||
`fscan.exe -h 192.168.x.x -m ssh -user root -pwd password`
|
`fscan.exe -h 192.168.x.x -m ssh -user root -pwd password`
|
||||||

|

|
||||||
|
|
||||||
|
`fscan.exe -h 192.168.x.x -m ssh -user root -pwda pass1 pass2 pass3` (add multiple passwords)
|
||||||
|
|
||||||
`fscan.exe -h 192.168.x.x -p80 -proxy http://127.0.0.1:8080`
|
`fscan.exe -h 192.168.x.x -p80 -proxy http://127.0.0.1:8080`
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ fscan -h 192.168.1.0/24 -silent | jq 'select(.type=="VULN")'
|
|||||||
| `-user` | 用户名 |
|
| `-user` | 用户名 |
|
||||||
| `-pwd` | 密码 |
|
| `-pwd` | 密码 |
|
||||||
| `-usera` | 追加用户名 |
|
| `-usera` | 追加用户名 |
|
||||||
| `-pwda` | 追加密码 |
|
| `-pwda` | 追加密码,支持逗号或空格分隔多个值 |
|
||||||
| `-userf` | 用户名字典文件 |
|
| `-userf` | 用户名字典文件 |
|
||||||
| `-pwdf` | 密码字典文件 |
|
| `-pwdf` | 密码字典文件 |
|
||||||
| `-domain` | 域名(SMB/WMI) |
|
| `-domain` | 域名(SMB/WMI) |
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ func parsePasswords(fv *FlagVars) []string {
|
|||||||
|
|
||||||
// 命令行密码
|
// 命令行密码
|
||||||
if fv.Password != "" {
|
if fv.Password != "" {
|
||||||
passwords = append(passwords, strings.Split(fv.Password, ",")...)
|
passwords = append(passwords, splitCredentialValues(fv.Password)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从文件读取
|
// 从文件读取
|
||||||
@@ -138,12 +138,27 @@ func parsePasswords(fv *FlagVars) []string {
|
|||||||
|
|
||||||
// 额外密码
|
// 额外密码
|
||||||
if fv.AddPasswords != "" {
|
if fv.AddPasswords != "" {
|
||||||
passwords = append(passwords, strings.Split(fv.AddPasswords, ",")...)
|
passwords = append(passwords, splitCredentialValues(fv.AddPasswords)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeDuplicate(passwords)
|
return removeDuplicate(passwords)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func splitCredentialValues(input string) []string {
|
||||||
|
fields := strings.FieldsFunc(input, func(r rune) bool {
|
||||||
|
return r == ',' || r == ' ' || r == '\t' || r == '\n' || r == '\r'
|
||||||
|
})
|
||||||
|
|
||||||
|
values := make([]string, 0, len(fields))
|
||||||
|
for _, field := range fields {
|
||||||
|
field = strings.TrimSpace(field)
|
||||||
|
if field != "" {
|
||||||
|
values = append(values, field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
func parseUserPassPairs(fv *FlagVars) ([]config.CredentialPair, error) {
|
func parseUserPassPairs(fv *FlagVars) ([]config.CredentialPair, error) {
|
||||||
var pairs []config.CredentialPair
|
var pairs []config.CredentialPair
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParsePasswordsSplitsCommaAndWhitespace(t *testing.T) {
|
||||||
|
fv := &FlagVars{
|
||||||
|
Password: "root,admin",
|
||||||
|
AddPasswords: "pass1 pass2,pass3\tpass4",
|
||||||
|
}
|
||||||
|
|
||||||
|
got := parsePasswords(fv)
|
||||||
|
want := []string{"root", "admin", "pass1", "pass2", "pass3", "pass4"}
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("parsePasswords() = %#v, want %#v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
+60
-1
@@ -227,7 +227,9 @@ func Flag(Info *HostInfo) error {
|
|||||||
|
|
||||||
// parseCommandLineArgs 解析命令行参数
|
// parseCommandLineArgs 解析命令行参数
|
||||||
func parseCommandLineArgs() error {
|
func parseCommandLineArgs() error {
|
||||||
flag.Parse()
|
if err := flag.CommandLine.Parse(normalizeMultiValueFlagArgs(os.Args[1:], "-pwda")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// 显示Banner
|
// 显示Banner
|
||||||
Banner()
|
Banner()
|
||||||
@@ -236,6 +238,63 @@ func parseCommandLineArgs() error {
|
|||||||
return checkParameterConflicts()
|
return checkParameterConflicts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizeMultiValueFlagArgs(args []string, names ...string) []string {
|
||||||
|
multiValueFlags := make(map[string]struct{}, len(names))
|
||||||
|
for _, name := range names {
|
||||||
|
multiValueFlags[name] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
normalized := make([]string, 0, len(args))
|
||||||
|
for i := 0; i < len(args); i++ {
|
||||||
|
arg := args[i]
|
||||||
|
name, value, ok := splitMultiValueFlag(arg, multiValueFlags)
|
||||||
|
if !ok {
|
||||||
|
normalized = append(normalized, arg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
values := []string{}
|
||||||
|
if value != "" {
|
||||||
|
values = append(values, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
j := i + 1
|
||||||
|
for ; j < len(args); j++ {
|
||||||
|
if strings.HasPrefix(args[j], "-") {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
values = append(values, args[j])
|
||||||
|
}
|
||||||
|
i = j - 1
|
||||||
|
|
||||||
|
if strings.Contains(arg, "=") {
|
||||||
|
normalized = append(normalized, name+"="+strings.Join(values, ","))
|
||||||
|
} else {
|
||||||
|
normalized = append(normalized, name)
|
||||||
|
if len(values) > 0 {
|
||||||
|
normalized = append(normalized, strings.Join(values, ","))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return normalized
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitMultiValueFlag(arg string, names map[string]struct{}) (string, string, bool) {
|
||||||
|
if _, ok := names[arg]; ok {
|
||||||
|
return arg, "", true
|
||||||
|
}
|
||||||
|
|
||||||
|
for name := range names {
|
||||||
|
prefix := name + "="
|
||||||
|
if strings.HasPrefix(arg, prefix) {
|
||||||
|
return name, strings.TrimPrefix(arg, prefix), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
// preProcessLanguage 预处理语言参数,在定义flag之前设置语言
|
// preProcessLanguage 预处理语言参数,在定义flag之前设置语言
|
||||||
func preProcessLanguage() {
|
func preProcessLanguage() {
|
||||||
// 遍历命令行参数查找-lang参数
|
// 遍历命令行参数查找-lang参数
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNormalizeMultiValueFlagArgs(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "space separated pwda values",
|
||||||
|
args: []string{"-h", "192.168.1.1", "-pwda", "pass1", "pass2", "pass3", "-m", "ssh"},
|
||||||
|
want: []string{"-h", "192.168.1.1", "-pwda", "pass1,pass2,pass3", "-m", "ssh"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "equals form with extra values",
|
||||||
|
args: []string{"-pwda=pass1", "pass2", "-h", "192.168.1.1"},
|
||||||
|
want: []string{"-pwda=pass1,pass2", "-h", "192.168.1.1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unrelated args unchanged",
|
||||||
|
args: []string{"-h", "192.168.1.1", "-m", "ssh"},
|
||||||
|
want: []string{"-h", "192.168.1.1", "-m", "ssh"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := normalizeMultiValueFlagArgs(tt.args, "-pwda")
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Fatalf("normalizeMultiValueFlagArgs() = %#v, want %#v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,7 +43,7 @@ flag_password:
|
|||||||
flag_add_users:
|
flag_add_users:
|
||||||
other: "Additional usernames"
|
other: "Additional usernames"
|
||||||
flag_add_passwords:
|
flag_add_passwords:
|
||||||
other: "Additional passwords"
|
other: "Additional passwords, separated by commas or spaces"
|
||||||
flag_users_file:
|
flag_users_file:
|
||||||
other: "Username dictionary file"
|
other: "Username dictionary file"
|
||||||
flag_passwords_file:
|
flag_passwords_file:
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ flag_password:
|
|||||||
flag_add_users:
|
flag_add_users:
|
||||||
other: "额外用户名"
|
other: "额外用户名"
|
||||||
flag_add_passwords:
|
flag_add_passwords:
|
||||||
other: "额外密码"
|
other: "额外密码,支持逗号或空格分隔多个值"
|
||||||
flag_users_file:
|
flag_users_file:
|
||||||
other: "用户名字典文件"
|
other: "用户名字典文件"
|
||||||
flag_passwords_file:
|
flag_passwords_file:
|
||||||
|
|||||||
Reference in New Issue
Block a user