├── GoGhost.PNG ├── GoGhostGif.gif ├── GoGhost_linux_amd64 ├── GoGhost_win_amd64.exe ├── NMAP_vs_GoGhost.jpg ├── README.md └── GoGhost.go /GoGhost.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Agent00049/GoGhost/master/GoGhost.PNG -------------------------------------------------------------------------------- /GoGhostGif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Agent00049/GoGhost/master/GoGhostGif.gif -------------------------------------------------------------------------------- /GoGhost_linux_amd64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Agent00049/GoGhost/master/GoGhost_linux_amd64 -------------------------------------------------------------------------------- /GoGhost_win_amd64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Agent00049/GoGhost/master/GoGhost_win_amd64.exe -------------------------------------------------------------------------------- /NMAP_vs_GoGhost.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Agent00049/GoGhost/master/NMAP_vs_GoGhost.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # GoGhost 3 | 4 | GoGhost is a High Performance, lightweight, portable Open Source tool for mass SMBGhost Scan. 5 | 6 | ![GoGhost Running](https://github.com/deepsecurity-pe/GoGhost/blob/master/GoGhost.PNG) 7 | 8 | 9 | ## Installation 10 | 11 | You can download [Windows Binary](https://github.com/deepsecurity-pe/GoGhost/blob/master/GoGhost_win_amd64.exe) or [Linux Binary](https://github.com/deepsecurity-pe/GoGhost/blob/master/GoGhost_linux_amd64). Alternatively, GoGhost uses native Golang libraries so the line above would be fine to compile it: 12 | 13 | ``` 14 | go build GoGhost.go 15 | ``` 16 | 17 | ## Usage Options 18 | 19 | 20 | GoGhost Scanned 25,000 IP addresses in less than 3 seconds, NMAP took more than 600. 21 | 22 | ![NMAP vs GoGhost](https://github.com/deepsecurity-pe/GoGhost/blob/master/NMAP_vs_GoGhost.jpg) 23 | 24 | #### `-iL [FILE]` 25 | By using the -iL option you're able to specify a list file with CIDRs in file. 26 | 27 | #### `-iR [CIDR]` 28 | By using the -iR option you're able to specify an IP Range. 29 | 30 | ## False Positive & False Negative 31 | If the Windows is patched with KB4551762, GoGhost will still flag it as vulnerable. If the list of CIDRs in the file is bigger than 500k IP Addresses it may flag some vulnerable as Timeout. 32 | 33 | ## The Results 34 | Timeout => Closed Port 35 | 36 | Not Vulnerable => Does not has compression 37 | 38 | Vulnerable => LZNT1 compression on SMB. 39 | 40 | ## Disclaimer 41 | This tool was coded to measure the impact of SMBGhost in [Latin America](https://deepsecurity.pe/analisis-de-smbghost-en-latinoamerica/) and Deepsecurity is not responsible for the use of this tool. 42 | -------------------------------------------------------------------------------- /GoGhost.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "fmt" 7 | "log" 8 | "net" 9 | "os" 10 | "strconv" 11 | "strings" 12 | "sync" 13 | "time" 14 | "flag" 15 | ) 16 | 17 | const ( 18 | pkt = 19 | "\x00" + // session 20 | "\x00\x00\xc0"+ // legth 21 | 22 | "\xfeSMB@\x00"+ // protocol 23 | 24 | //[MS-SMB2]: SMB2 NEGOTIATE Request 25 | //https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e14db7ff-763a-4263-8b10-0c3944f52fc5 26 | 27 | "\x00\x00" + 28 | "\x00\x00" + 29 | "\x00\x00" + 30 | "\x00\x00" + 31 | "\x1f\x00" + 32 | "\x00\x00\x00\x00" + 33 | "\x00\x00\x00\x00" + 34 | "\x00\x00\x00\x00" + 35 | "\x00\x00\x00\x00" + 36 | "\x00\x00\x00\x00" + 37 | "\x00\x00\x00\x00" + 38 | "\x00\x00\x00\x00" + 39 | "\x00\x00\x00\x00" + 40 | "\x00\x00\x00\x00" + 41 | "\x00\x00\x00\x00" + 42 | "\x00\x00\x00\x00" + 43 | "\x00\x00\x00\x00" + 44 | 45 | // [MS-SMB2]: SMB2 NEGOTIATE_CONTEXT 46 | // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/15332256-522e-4a53-8cd7-0bd17678a2f7 47 | 48 | "$\x00" + 49 | "\x08\x00" + 50 | "\x01\x00" + 51 | "\x00\x00" + 52 | "\x7f\x00\x00\x00" + 53 | "\x00\x00\x00\x00" + 54 | "\x00\x00\x00\x00" + 55 | "\x00\x00\x00\x00" + 56 | "\x00\x00\x00\x00" + 57 | "x\x00" + 58 | "\x00\x00" + 59 | "\x02\x00" + 60 | "\x00\x00" + 61 | "\x02\x02" + 62 | "\x10\x02" + 63 | "\x22\x02" + 64 | "$\x02" + 65 | "\x00\x03" + 66 | "\x02\x03" + 67 | "\x10\x03" + 68 | "\x11\x03" + 69 | "\x00\x00\x00\x00" + 70 | 71 | 72 | // [MS-SMB2]: SMB2_PREAUTH_INTEGRITY_CAPABILITIES 73 | // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5a07bd66-4734-4af8-abcf-5a44ff7ee0e5 74 | 75 | "\x01\x00" + 76 | "&\x00" + 77 | "\x00\x00\x00\x00" + 78 | "\x01\x00" + 79 | "\x20\x00" + 80 | "\x01\x00" + 81 | "\x00\x00\x00\x00" + 82 | "\x00\x00\x00\x00" + 83 | "\x00\x00\x00\x00" + 84 | "\x00\x00\x00\x00" + 85 | "\x00\x00\x00\x00" + 86 | "\x00\x00\x00\x00" + 87 | "\x00\x00\x00\x00" + 88 | "\x00\x00\x00\x00" + 89 | "\x00\x00" + 90 | 91 | // [MS-SMB2]: SMB2_COMPRESSION_CAPABILITIES 92 | // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/78e0c942-ab41-472b-b117-4a95ebe88271 93 | 94 | "\x03\x00" + 95 | "\x0e\x00" + 96 | "\x00\x00\x00\x00" + 97 | "\x01\x00" + //CompressionAlgorithmCount 98 | "\x00\x00" + 99 | "\x01\x00\x00\x00" + 100 | "\x01\x00" + //LZNT1 101 | "\x00\x00" + 102 | "\x00\x00\x00\x00" 103 | ) 104 | 105 | var wg sync.WaitGroup 106 | 107 | func socketX(ip string, port int) { 108 | defer wg.Done() 109 | addr := strings.Join([]string{ip, strconv.Itoa(port)}, ":") 110 | conn, err := net.DialTimeout("tcp", addr, 2*time.Second) 111 | 112 | if err != nil { 113 | fmt.Println(ip + " Timeout") 114 | } else { 115 | 116 | defer conn.Close() 117 | 118 | conn.Write([]byte(pkt)) 119 | 120 | buff := make([]byte, 1024) 121 | err = conn.SetReadDeadline(time.Now().Add(2 * time.Second)) 122 | n, err := conn.Read(buff) 123 | if err != nil { 124 | fmt.Println(err.Error()) // Profound analysis 125 | } 126 | 127 | if bytes.Contains([]byte(buff[:n]), []byte("Public")) == true { 128 | fmt.Println(ip + " Compression Enabled - Vulnerable") 129 | 130 | } else { 131 | fmt.Println(ip + " Not Vulnerable") 132 | } 133 | } 134 | } 135 | 136 | /////////////////////////////// 137 | // // 138 | // Parse IP // 139 | // // 140 | ////////////////////////////// 141 | func Hosts(cidr string) ([]string, error) { 142 | ip, ipnet, err := net.ParseCIDR(cidr) 143 | if err != nil { 144 | fmt.Println(err.Error()) 145 | } 146 | 147 | var ips []string 148 | for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) { 149 | ips = append(ips, ip.String()) 150 | } 151 | 152 | // remove network address and broadcast address 153 | lenIPs := len(ips) 154 | switch { 155 | case lenIPs < 2: 156 | return ips, nil 157 | 158 | default: 159 | return ips[1 : len(ips)-1], nil 160 | } 161 | } 162 | 163 | 164 | func inc(ip net.IP) { 165 | for j := len(ip) - 1; j >= 0; j-- { 166 | ip[j]++ 167 | if ip[j] > 0 { 168 | break 169 | } 170 | } 171 | } 172 | 173 | 174 | 175 | func main() { 176 | 177 | ilPtr := flag.String("iL", "", "List of IP Addresses on File.") 178 | irPtr := flag.String("iR", "", "IP Range Ex. 192.169.1.0/24") 179 | 180 | flag.Parse() 181 | 182 | 183 | 184 | 185 | 186 | /////////////////////////////// 187 | // // 188 | // List Scan // 189 | // // 190 | /////////////////////////////// 191 | if *ilPtr != "" { 192 | 193 | readFile, err := os.Open(*ilPtr) 194 | 195 | if err != nil { 196 | log.Fatalf("failed to open file: %s", err) 197 | } 198 | 199 | fileScanner := bufio.NewScanner(readFile) 200 | fileScanner.Split(bufio.ScanLines) 201 | var fileTextLines []string 202 | 203 | for fileScanner.Scan() { 204 | fileTextLines = append(fileTextLines, fileScanner.Text()) 205 | } 206 | 207 | readFile.Close() 208 | 209 | 210 | 211 | fmt.Println("==== START TIME ==== ") 212 | fmt.Println(time.Now()) 213 | 214 | for _, eachline := range fileTextLines { 215 | ReadIP, err := Hosts(eachline) 216 | if err != nil { 217 | log.Fatal(err) 218 | } 219 | iplen := len(ReadIP) 220 | wg.Add(iplen) 221 | 222 | for _, eachip := range ReadIP { 223 | go socketX(eachip, 445) 224 | } 225 | 226 | } 227 | wg.Wait() 228 | fmt.Println("==== END TIME ==== ") 229 | fmt.Println(time.Now()) 230 | 231 | 232 | /////////////////////////////// 233 | // // 234 | // IP Scan // 235 | // // 236 | /////////////////////////////// 237 | }else if *irPtr != ""{ 238 | 239 | 240 | ReadIP, err := Hosts(*irPtr) 241 | if err != nil { 242 | log.Fatal(err) 243 | } 244 | 245 | iplen := len(ReadIP) 246 | 247 | wg.Add(iplen) 248 | 249 | fmt.Println("==== START TIME ==== ") 250 | fmt.Println(time.Now()) 251 | for _, eachline := range ReadIP { 252 | go socketX(eachline, 445) 253 | } 254 | wg.Wait() 255 | fmt.Println("==== END TIME ==== ") 256 | fmt.Println(time.Now()) 257 | 258 | 259 | 260 | /////////////////////////////// 261 | // // 262 | // Banner - Help // 263 | // // 264 | /////////////////////////////// 265 | 266 | 267 | 268 | 269 | }else{ 270 | fmt.Println("\033[92m\033[1m") 271 | 272 | fmt.Println(" ________ ________.__ __ "); 273 | fmt.Println(" / _____/ ____ / _____/| |__ ____ _______/ |_ "); 274 | fmt.Println("/ \\ ___ / _ \\/ \\ ___| | \\ / _ \\/ ___/\\ __\\"); 275 | fmt.Println("\\ \\_\\ ( <_> ) \\_\\ \\ Y ( <_> )___ \\ | | "); 276 | fmt.Println(" \\______ /\\____/ \\______ /___| /\\____/____ > |__| "); 277 | fmt.Println(" \\/ \\/ \\/ \\/ "); 278 | fmt.Println(" "); 279 | fmt.Println(" By @DeepSecurity_. "); 280 | 281 | fmt.Println("\033[0m") 282 | 283 | flag.PrintDefaults() 284 | } 285 | } 286 | --------------------------------------------------------------------------------