Example #1
0
/* Handle generic error strings */
func handleErrorString(a attempt, rc chan attempt, nA *lockedint.TInt,
	ts *tslist.List) bool {
	s := a.Err.Error()
	switch {
	case strings.HasPrefix(s, "ssh: handshake failed: ssh: unable "+
		"to authenticate") && strings.HasSuffix(s, "no supported "+
		"methods remain"):
		/* Auth failed, Decrement the number of attempts in the wild */
		nA.Dec()
	case strings.HasSuffix(s, "ssh: handshake failed: ssh: no common "+
		"algorithms"):
		removeHost(ts, a, "no common algorithms", nA)
	case strings.HasSuffix(s, "ssh: handshake failed: ssh: invalid "+
		"packet length, packet too large"):
		removeHost(ts, a, "packet to large", nA)
	case strings.HasSuffix(s, "ssh: handshake failed: EOF"):
		/* Sometimes EOFs aren't the host's fault. */
		if *gc.Rteoff {
			log.Printf("[%v] Retrying %v@%v - %v in 1 second "+
				"due to EOF", a.Tasknum, a.User, a.Host,
				a.Pass)
			/* This causes all new attempts to halt for a second */
			time.Sleep(time.Second)
		} else {
			removeHost(ts, a, "unexpected EOF", nA)
		}
	case strings.HasPrefix(s, "ssh: handshake failed: read tcp") &&
		strings.HasSuffix(s, "connection reset by peer"):
		removeHost(ts, a, "connection reset by target", nA)
	default:
		return false
	}
	return true

}
Example #2
0
/* Remove a host from the template list, give the reason as r and decrement
nA.  If r is the empty string, no message will be printed. */
func removeHost(ts *tslist.List, a attempt, r string, nA *lockedint.TInt) {
	/* Tell the user what's going on */
	if r != "" {
		log.Printf("[%v] Removing %v from attack queue: %v", a.Tasknum,
			a.Host, r)
	}
	/* Mark a bunch of hosts for removal */
	for e := ts.Head(); e != nil; e = e.Next() {
		if c, ok := e.Value().(*template); !ok {
			printTemplateNotOk(e)
			os.Exit(-10)
		} else if ok && c.Host == a.Host {
			e.RemoveMark()
		}
	}
	/* Remove the marked hosts */
	ts.RemoveMarked()
	/* Decrement the number of attempts in the wild */
	nA.Dec()
}
Example #3
0
/* sshTask represents one parallelizable brute-forcer. attempts come in on
attemptc, and if a match is found, the userame, password, and host are sent
back on successc.  Tasknum is a unique identifier for this task. If triesf is
true, every attempt will to be printed. wait specifies how long each attempt
will wait, with an upper bound specified opaquely by the ssh library.  If errdb
is true, ssh errors will be printed.  The task will pause for pause after each
attempt. */
func sshTask(a attempt, nRunning *lockedint.TInt, failc, successc chan attempt,
	tasknum int, triesf bool, wait, pause time.Duration) {
	/* Attempt to connect to server and authenticate. */
	if triesf {
		log.Printf("[%v] Attempting %v@%v - %v", tasknum, a.User,
			a.Host, textIfBlank(a.Pass))
	}
	/* Channels internal to this sshtask */
	sc := make(chan attempt)
	fc := make(chan attempt)
	/* Closure (yuck) goroutine to actually run the task */
	go func() {
		_, err := ssh.Dial("tcp", a.Host, a.Config)
		/* Send the attempt on the appropriate channel. */
		if err != nil {
			a.Err = err
			a.Tasknum = tasknum
			fc <- a
		} else {
			sc <- a
		}
	}()
	select {
	case a := <-fc:
		failc <- a
	case a := <-sc:
		successc <- a
	case <-time.After(wait):
		a.Err = &TimeoutError{}
		a.Tasknum = tasknum
		failc <- a
	}
	/* Decrement the counter of alive sshtasks */
	nRunning.Dec()
	/* Pause for rate-limiting. */
	if pause > 0 {
		time.Sleep(pause)
	}
}