Skip to content

Commit

Permalink
Fix issue when the connection was remotely closed
Browse files Browse the repository at this point in the history
  • Loading branch information
nodauf committed Feb 16, 2022
1 parent 4df1aea commit f228c00
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 22 deletions.
36 changes: 36 additions & 0 deletions src/modules/smtp/private.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package smtp

import (
"GoMapEnum/src/utils"

smtp "github.com/nodauf/net-smtp"
)

func (options *Options) prepareOneConnection(client *smtp.Client) error {

mailFrom := utils.RandomString(6) + "@" + options.Domain
err := client.Mail(mailFrom)
if err != nil {
//options.Log.Error("Mail From command failed with email: " + mailFrom + " and error " + err.Error())
return err
}
options.Log.Debug("One connection has been successfully prepared")

return nil
}

func (options *Options) createNewConnection() *smtp.Client {
client, err := smtp.Dial(options.Target + ":25")
if err != nil {
options.Log.Error("Failed to establish a connection " + err.Error())
return nil
}

hello := utils.RandomString(6)
err = client.Hello(hello)
if err != nil {
options.Log.Error("helo command failed with helo " + hello + " and error " + err.Error())
return nil
}
return client
}
5 changes: 3 additions & 2 deletions src/modules/smtp/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ type Options struct {
Mode string
utils.BaseOptions

all bool
connectionsPool chan *smtp.Client
all bool
connectionsPool chan *smtp.Client
expnNotRecognized bool
}

func (options *Options) GetBaseOptions() *utils.BaseOptions {
Expand Down
57 changes: 37 additions & 20 deletions src/modules/smtp/userEnum.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package smtp

import (
"GoMapEnum/src/utils"
"fmt"
"net"
"reflect"
"strconv"
Expand Down Expand Up @@ -32,27 +30,27 @@ func PrepareSMTPConnections(optionsInterface *interface{}) {
}
options.Log.Debug("Preparing a pool of " + strconv.Itoa(nbConnectionsRequired) + " connections")
for i := 1; i <= nbConnectionsRequired; i++ {
client, err := smtp.Dial(options.Target + ":25")
if err != nil {
options.Log.Error("Failed to establish a connection " + err.Error())
continue
}
err = client.Hello(utils.RandomString(6))
if err != nil {
fmt.Println("hello" + err.Error())
}
err = client.Mail(utils.RandomString(6) + "@" + options.Domain)
if err != nil {
fmt.Println("mail" + err.Error())
client := options.createNewConnection()
if client != nil {
options.connectionsPool <- client
}
options.connectionsPool <- client
}
}

func UserEnum(optionsInterface *interface{}, username string) bool {
options := (*optionsInterface).(*Options)
valid := false
smtpConnection := <-options.connectionsPool
smtpConnection.Reset()
err := options.prepareOneConnection(smtpConnection)
if err != nil && strings.Contains(err.Error(), "connection reset by peer") {
options.Log.Debug("Connection reset. Generating new one")
smtpConnection = options.createNewConnection()
err = options.prepareOneConnection(smtpConnection)
}
if err != nil {
options.Log.Fatal("Failed to prepare a connection. " + err.Error())
}
switch strings.ToLower(options.Mode) {
case "rcpt":
err := smtpConnection.Rcpt(username)
Expand All @@ -61,6 +59,11 @@ func UserEnum(optionsInterface *interface{}, username string) bool {
valid = true
} else {
options.Log.Debug(username + " => " + err.Error())
if strings.Contains(err.Error(), "connection reset by peer") {
smtpConnection.Close()
options.createNewConnection()
return UserEnum(optionsInterface, username)
}
options.Log.Fail(username)
}
case "vrfy":
Expand All @@ -70,6 +73,11 @@ func UserEnum(optionsInterface *interface{}, username string) bool {
valid = true
} else {
options.Log.Debug(username + " => " + err.Error())
if strings.Contains(err.Error(), "connection reset by peer") {
smtpConnection.Close()
options.createNewConnection()
return UserEnum(optionsInterface, username)
}
options.Log.Fail(username)
}
case "expn":
Expand All @@ -80,12 +88,20 @@ func UserEnum(optionsInterface *interface{}, username string) bool {
} else {
code := strings.Split(err.Error(), " ")[0]
options.Log.Debug(username + " => " + err.Error())
if strings.Contains(err.Error(), "connection reset by peer") {
smtpConnection.Close()
options.createNewConnection()
return UserEnum(optionsInterface, username)
}
options.Log.Fail(username)
// If the command is not implemented no need to pursue
if code == "502" && !options.all {
CloseSMTPConnections(optionsInterface)
options.Log.Fatal("The command EXPN is not implemented. No need to pursue using this method.")
}
if code == "502" && options.all {
options.expnNotRecognized = true
}
}
case "", "all":

Expand All @@ -111,15 +127,16 @@ func UserEnum(optionsInterface *interface{}, username string) bool {
return true
}
// EXPN
options.Log.Debug("Enumerate with EXPN")
optionsCopy.Mode = "expn"
newOptionsInterface = reflect.ValueOf(&optionsCopy).Interface()
valid = UserEnum(&newOptionsInterface, username)
if !options.expnNotRecognized {
options.Log.Debug("Enumerate with EXPN")
optionsCopy.Mode = "expn"
newOptionsInterface = reflect.ValueOf(&optionsCopy).Interface()
valid = UserEnum(&newOptionsInterface, username)
}
return valid
default:
options.Log.Fatal("Unrecognised mode: " + options.Mode + ". Only RCPT, VRFY and EXPN are supported.")
}

options.connectionsPool <- smtpConnection
return valid
}
Expand Down

0 comments on commit f228c00

Please sign in to comment.