From 1bb8a43b03b52d51de9fb5d520065f71889030b9 Mon Sep 17 00:00:00 2001 From: Mehul Ahuja Date: Fri, 31 Mar 2017 00:58:29 +0530 Subject: [PATCH 1/6] SMTP responses fixed --- app/server.go | 24 ------------------------ smtp.go | 21 +++++++++++---------- telnet.go | 10 ++-------- 3 files changed, 13 insertions(+), 42 deletions(-) diff --git a/app/server.go b/app/server.go index 2f6929f..96d934d 100644 --- a/app/server.go +++ b/app/server.go @@ -7,7 +7,6 @@ import ( "os" "os/signal" "sync" - "syscall" log "github.com/Sirupsen/logrus" "github.com/mushorg/glutton" @@ -49,29 +48,6 @@ func main() { // Setting up the logger logger := log.New() - -<<<<<<< HEAD - // get the uid of the user - uid := syscall.Getuid() - if uid == 0 { - // process is running as root - logger.Info("[glutton ] The server is running as root. Dropping privilages to nobody...") - // drop the group privilages to nobody user - if err := syscall.Setgid(65534); err != nil { - logger.Fatal("Could not set group privilages. ", err) - } else { - logger.Info("[glutton ] Group privilages dropped.") - } - // drop the user privilages - if err := syscall.Setuid(65534); err != nil { - logger.Fatal("Could not set user privilages. ", err) - } else { - logger.Info("[glutton ] User privilages dropped.") - } - } - -======= ->>>>>>> upstream/master // Write log to file and stdout f, err := os.OpenFile(*logPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) onErrorExit(err) diff --git a/smtp.go b/smtp.go index 936adeb..664b6e4 100644 --- a/smtp.go +++ b/smtp.go @@ -5,6 +5,7 @@ import ( "math/rand" "net" "regexp" + "strings" "time" ) @@ -22,7 +23,7 @@ func (c *Client) w(s string) { func (c *Client) r(g *Glutton) string { reply, err := c.bufin.ReadString('\n') if err != nil { - g.logger.Errorf("[smpt ] %v", err) + g.logger.Errorf("[smtp ] %v", err) } return reply } @@ -33,14 +34,14 @@ func random(min, max int) int { } func validateMail(query string) bool { - email := regexp.MustCompile("^MAIL FROM:<.+@.+>$\\r\\n") // naive regex + email := regexp.MustCompile("^MAIL FROM:<.+@.+>$") // naive regex if email.MatchString(query) { return true } return false } func validateRCPT(query string) bool { - rcpt := regexp.MustCompile("^RCPT TO:<.+@.+>$\\r\\n") + rcpt := regexp.MustCompile("^RCPT TO:<.+@.+>$") if rcpt.MatchString(query) { return true } @@ -55,29 +56,29 @@ func (g *Glutton) HandleSMTP(conn net.Conn) { bufin: bufio.NewReader(conn), bufout: bufio.NewWriter(conn), } - rand := random(500, 3000) // random time between 0.5 and 3 seconds - duration := time.Duration(rand) * time.Millisecond client.w("220 Welcome!") for { query := client.r(g) + query = strings.Trim(query, "\r\n") g.logger.Infof("[smtp ] Payload : %q", query) s := strings.Split(query, " ") if s[0] == "HELO" && len(s) == 2 { - client.w("250 Hello " + s[1] + "! Pleased to meet you.") - } else if s[0] == "MAIL" && validateMail() { + client.w("250 Hello! Pleased to meet you.") + } else if s[0] == "MAIL" && validateMail(query) { client.w("250 OK") - } else if s[0] == "RCPT" && validateRCPT() { + } else if s[0] == "RCPT" && validateRCPT(query) { client.w("250 OK") } else if s[0] == "DATA" && len(s) == 1 { client.w("354 End data with .") + for strings.Compare(client.r(g), ".\r\n") != 0 { + } + client.w("250 OK") } else if s[0] == "QUIT" && len(s) == 1 { client.w("Bye") break } else { client.w("Recheck the command you entered.") } - // wait for random time - time.Sleep(duration) } } diff --git a/telnet.go b/telnet.go index ff43b13..643a14b 100644 --- a/telnet.go +++ b/telnet.go @@ -21,10 +21,8 @@ import ( // Mirai botnet - https://github.com/CymmetriaResearch/MTPot/blob/master/mirai_conf.json // Hajime botnet - https://security.rapiditynetworks.com/publications/2016-10-16/hajime.pdf var miraiCom = map[string][]string{ -<<<<<<< HEAD - "ps": []string{"1 pts/21 00:00:00 init"}, - "cat /proc/mounts": []string{"tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3231524k,mode=755 0 0"}, -======= + "ps": []string{"1 pts/21 00:00:00 init"}, + "cat /proc/mounts": []string{"tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3231524k,mode=755 0 0"}, "ps": []string{"1 pts/21 00:00:00 init"}, "cat /proc/mounts": []string{"rootfs / rootfs rw 0 0\r\n/dev/root / ext2 rw,relatime,errors=continue 0 0\r\nproc /proc proc rw,relatime 0 0\r\nsysfs /sys sysfs rw,relatime 0 0\r\nudev /dev tmpfs rw,relatime 0 0\r\ndevpts /dev/pts devpts rw,relatime,mode=600,ptmxmode=000 0 0\r\n/dev/mtdblock1 /home/hik jffs2 rw,relatime 0 0\r\ntmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3231524k,mode=755 0 0\r\n"}, "(cat .s || cp /bin/echo .s)": []string{"cat: .s: No such file or directory"}, @@ -32,7 +30,6 @@ var miraiCom = map[string][]string{ "wget": []string{"wget: missing URL"}, "(dd bs=52 count=1 if=.s || cat .s)": []string{"\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00\x01\x00\x00\x00\xbc\x14\x01\x00\x34\x00\x00\x00"}, "sh": []string{"$"}, ->>>>>>> upstream/master "echo -e \\x6b\\x61\\x6d\\x69/dev > /dev/.nippon": []string{""}, "cat /dev/.nippon": []string{"kami/dev"}, "rm /dev/.nippon": []string{""}, @@ -50,11 +47,8 @@ var miraiCom = map[string][]string{ "/bin/busybox rm /run/.nippon": []string{""}, "/bin/busybox cat /bin/sh": []string{""}, "/bin/busybox cat /bin/echo": []string{"/bin/busybox cat /bin/echo\r\n\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00\x01\x00\x00\x00\x6c\xb9\x00\x00\x34\x00\x00\x00"}, -<<<<<<< HEAD "rm /dev/.human": []string{"rm: can't remote '/.t': No such file or directory\r\nrm: can't remote '/.sh': No such file or directory\r\nrm: can't remote '/.human': No such file or directory\r\ncd /dev"}, -======= "rm /dev/.human": []string{"rm: can't remove '/.t': No such file or directory\r\nrm: can't remove '/.sh': No such file or directory\r\nrm: can't remove '/.human': No such file or directory\r\ncd /dev"}, ->>>>>>> upstream/master } func writeMsg(conn net.Conn, msg string, g *Glutton) error { From 3bfb62c4e74d8b1f8f302b909a32af44dffa1e7d Mon Sep 17 00:00:00 2001 From: Mehul Ahuja Date: Fri, 31 Mar 2017 01:02:37 +0530 Subject: [PATCH 2/6] removed rand function --- smtp.go | 5 ----- telnet.go | 3 --- 2 files changed, 8 deletions(-) diff --git a/smtp.go b/smtp.go index 664b6e4..a7d33a5 100644 --- a/smtp.go +++ b/smtp.go @@ -28,11 +28,6 @@ func (c *Client) r(g *Glutton) string { return reply } -func random(min, max int) int { - rand.Seed(time.Now().Unix()) - return rand.Intn(max-min) + min -} - func validateMail(query string) bool { email := regexp.MustCompile("^MAIL FROM:<.+@.+>$") // naive regex if email.MatchString(query) { diff --git a/telnet.go b/telnet.go index 643a14b..dff5a58 100644 --- a/telnet.go +++ b/telnet.go @@ -21,8 +21,6 @@ import ( // Mirai botnet - https://github.com/CymmetriaResearch/MTPot/blob/master/mirai_conf.json // Hajime botnet - https://security.rapiditynetworks.com/publications/2016-10-16/hajime.pdf var miraiCom = map[string][]string{ - "ps": []string{"1 pts/21 00:00:00 init"}, - "cat /proc/mounts": []string{"tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3231524k,mode=755 0 0"}, "ps": []string{"1 pts/21 00:00:00 init"}, "cat /proc/mounts": []string{"rootfs / rootfs rw 0 0\r\n/dev/root / ext2 rw,relatime,errors=continue 0 0\r\nproc /proc proc rw,relatime 0 0\r\nsysfs /sys sysfs rw,relatime 0 0\r\nudev /dev tmpfs rw,relatime 0 0\r\ndevpts /dev/pts devpts rw,relatime,mode=600,ptmxmode=000 0 0\r\n/dev/mtdblock1 /home/hik jffs2 rw,relatime 0 0\r\ntmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3231524k,mode=755 0 0\r\n"}, "(cat .s || cp /bin/echo .s)": []string{"cat: .s: No such file or directory"}, @@ -47,7 +45,6 @@ var miraiCom = map[string][]string{ "/bin/busybox rm /run/.nippon": []string{""}, "/bin/busybox cat /bin/sh": []string{""}, "/bin/busybox cat /bin/echo": []string{"/bin/busybox cat /bin/echo\r\n\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00\x01\x00\x00\x00\x6c\xb9\x00\x00\x34\x00\x00\x00"}, - "rm /dev/.human": []string{"rm: can't remote '/.t': No such file or directory\r\nrm: can't remote '/.sh': No such file or directory\r\nrm: can't remote '/.human': No such file or directory\r\ncd /dev"}, "rm /dev/.human": []string{"rm: can't remove '/.t': No such file or directory\r\nrm: can't remove '/.sh': No such file or directory\r\nrm: can't remove '/.human': No such file or directory\r\ncd /dev"}, } From da3dbdbe313e4e8a3bb7eae406ddd223c2d54765 Mon Sep 17 00:00:00 2001 From: Mehul Ahuja Date: Fri, 31 Mar 2017 01:20:46 +0530 Subject: [PATCH 3/6] refactor --- smtp.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/smtp.go b/smtp.go index a7d33a5..77ae205 100644 --- a/smtp.go +++ b/smtp.go @@ -23,11 +23,16 @@ func (c *Client) w(s string) { func (c *Client) r(g *Glutton) string { reply, err := c.bufin.ReadString('\n') if err != nil { - g.logger.Errorf("[smtp ] %v", err) + g.logger.Errorf("[smpt ] %v", err) } return reply } +func random(min, max int) int { + rand.Seed(time.Now().Unix()) + return rand.Intn(max-min) + min +} + func validateMail(query string) bool { email := regexp.MustCompile("^MAIL FROM:<.+@.+>$") // naive regex if email.MatchString(query) { @@ -54,22 +59,20 @@ func (g *Glutton) HandleSMTP(conn net.Conn) { client.w("220 Welcome!") for { - query := client.r(g) - query = strings.Trim(query, "\r\n") + query := strings.Trim(client.r(g), "\r\n") g.logger.Infof("[smtp ] Payload : %q", query) - s := strings.Split(query, " ") - if s[0] == "HELO" && len(s) == 2 { + if strings.HasPrefix(query, "HELO ") { client.w("250 Hello! Pleased to meet you.") - } else if s[0] == "MAIL" && validateMail(query) { + } else if validateMail(query) { client.w("250 OK") - } else if s[0] == "RCPT" && validateRCPT(query) { + } else if validateRCPT(query) { client.w("250 OK") - } else if s[0] == "DATA" && len(s) == 1 { + } else if strings.Compare(query, "DATA") == 0 { client.w("354 End data with .") for strings.Compare(client.r(g), ".\r\n") != 0 { } client.w("250 OK") - } else if s[0] == "QUIT" && len(s) == 1 { + } else if strings.Compare(query, "QUIT") == 0 { client.w("Bye") break } else { From f2bfed79a9e397102df574c0361100f4d751b45e Mon Sep 17 00:00:00 2001 From: Mehul Ahuja Date: Fri, 31 Mar 2017 01:40:55 +0530 Subject: [PATCH 4/6] refactor --- smtp.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/smtp.go b/smtp.go index 77ae205..e4e04f6 100644 --- a/smtp.go +++ b/smtp.go @@ -28,11 +28,6 @@ func (c *Client) r(g *Glutton) string { return reply } -func random(min, max int) int { - rand.Seed(time.Now().Unix()) - return rand.Intn(max-min) + min -} - func validateMail(query string) bool { email := regexp.MustCompile("^MAIL FROM:<.+@.+>$") // naive regex if email.MatchString(query) { From 4cfcc1d885534c51d6fe1f6cbf16d3a68527b271 Mon Sep 17 00:00:00 2001 From: Mehul Ahuja Date: Fri, 31 Mar 2017 02:01:59 +0530 Subject: [PATCH 5/6] random removed --- smtp.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/smtp.go b/smtp.go index e4e04f6..55e8ce8 100644 --- a/smtp.go +++ b/smtp.go @@ -2,11 +2,9 @@ package glutton import ( "bufio" - "math/rand" "net" "regexp" "strings" - "time" ) // Client is a connection container From f25198eeee13975c72b4718f58cde9c781560bcc Mon Sep 17 00:00:00 2001 From: Mehul Ahuja Date: Fri, 31 Mar 2017 04:07:35 +0530 Subject: [PATCH 6/6] supports random wait time for response --- smtp.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/smtp.go b/smtp.go index 55e8ce8..b9e7d46 100644 --- a/smtp.go +++ b/smtp.go @@ -2,9 +2,11 @@ package glutton import ( "bufio" + "math/rand" "net" "regexp" "strings" + "time" ) // Client is a connection container @@ -26,6 +28,14 @@ func (c *Client) r(g *Glutton) string { return reply } +func rwait() { + // makes the process sleep for random time + rand.Seed(time.Now().Unix()) + // between 0.5 - 1.5 seconds + rtime := rand.Intn(1500) + 500 + duration := time.Duration(rtime) * time.Millisecond + time.Sleep(duration) +} func validateMail(query string) bool { email := regexp.MustCompile("^MAIL FROM:<.+@.+>$") // naive regex if email.MatchString(query) { @@ -49,21 +59,25 @@ func (g *Glutton) HandleSMTP(conn net.Conn) { bufin: bufio.NewReader(conn), bufout: bufio.NewWriter(conn), } - + rwait() client.w("220 Welcome!") for { query := strings.Trim(client.r(g), "\r\n") g.logger.Infof("[smtp ] Payload : %q", query) if strings.HasPrefix(query, "HELO ") { + rwait() client.w("250 Hello! Pleased to meet you.") } else if validateMail(query) { + rwait() client.w("250 OK") } else if validateRCPT(query) { + rwait() client.w("250 OK") } else if strings.Compare(query, "DATA") == 0 { client.w("354 End data with .") for strings.Compare(client.r(g), ".\r\n") != 0 { } + rwait() client.w("250 OK") } else if strings.Compare(query, "QUIT") == 0 { client.w("Bye")