Evolution of a Hack

by Uriah C.

Some years ago, I was learning the basics of an SMTP server.

I learned how the protocol allowed me to connect and I could interact with it.  Well, the first thing I did was to send myself an email.  I just happened to send that email saying that it was from: santa@northpoll.com

My first spoofed email was created, and sent.

Over time, I wanted to be able to do this more often.

I installed Sendmail on my Linux box, and started to Telnet to my local server.  It worked great.  I knew how to make the email say it was from anyone.  I put my outgoing server settings on my mail clients to my local server so I didn't have to login to send mail.

Then I had an idea for a prank!

What would someone do if they got 20 emails from themselves?  So I fired up my text editor and wrote down my first mailFlood.py program.  It was run in the console and asked for input and did the job.

The pseudocode went like this:

mailFlood-1:

write "How many emails:"
num = read input

write "What is the address:"
addy = read input

subj = "PWND"
body = "Stop emailing yourself!"

date = system.get_date

msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n%s\n" %(addy, addy, subj, date, body)

n = 0
while n < num:
    connect to smtp (localhost, 25)
    sendmail(addy, addy, msg)
    disconnect from smtp
    n = n + 1 

A very simple way of doing it.

Once I coded it up in Python, I got it working with no problem.

Later, I thought I would like to change the message a bit.  I want to have a personal message, other "From" email address, and so on.  I revised my code a bit.

The pseudocode was like this:

mailFlood-2:

define numb():
     write "How many emails:"
     numb = read input
     return numb

define fromAddy():
     write "From address:"
     fromAddy = read input
     return fromAddy

define toAddy():
     write "To address:"
     toAddy = read input
     return toAddy

define subj():
      write "Subject:"
      subj = read input
      return subj

define msgBody():
      write "Type your msg:"
      msgBody = read input
      return msgBody

define main():
     num = numb()
     fromAdd = fromAddy()
     toAdd = toAddy()
     sub = subj()
     msgBod = msgBody()
     date = system.get_date

     msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n%s\n" %(fromAdd, toAdd, sub, date, msgBod)

     n = 0
     while n < num:
         connect to smtp (localhost, 25)
         sendmail(fromAdd, toAdd, msg)
         disconnect from smtp
         n = n + 1

main()

It was a bit longer now, and I could have saved code by not defining all the inputs on their own.

I did have a reason for doing this.  I was thinking about errors, and what if someone put a string when it asked for the number of emails.  I could later put in a check for an integer, without changing the main function.

Python had upgraded a lot since I last translated that pseudocode.

Also, Python 3 is not backward compatible with 2.x.  I decided that it was time to revamp the code one more time.  Since my program uses interactive prompts instead of command line arguments, I decided that I should give it a GUI.

The nice thing about the last pseudocode is that it is read to be converted to an event driven GUI.  I had not planned it that way, but it was just there when I dug it up to recode.

So here is a pseudocode of the GUI program:

mailFlood-3:

define window():
     window = GUI()
     numblbl = Label("Number of Emails")
     numtxt = Entry()

     fromlbl = Label("From:")
     fromtxt = Entry()

     tolbl = Label("To:")
     totxt = Entry()
    
     sublbl = Label("Subject:")
     subtxt = Entry()

     bodylbl = Label("Body:")
     bodytxt = Entry()

     sendbutton = Button("Send", cmd=onClicked)

     window.mainloop()

define onClicked():
     num = int(numtxt.get())
     fromadd = string(fromtxt.get())
     toadd = string(totxt.get())
     subj = string(subtxt.get())
     body = string(bodytxt.get())
     date = system.get_date

     msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n%s\n" %(fromadd, toadd, subj, date, body)

     n = 0

     while n < num:
         connect to smtp (localhost, 25)
         sendmail(fromadd, toadd, msg)
         disconnect from smtp
         n = n + 1

window()

Now that I had the basic idea of what I wanted, I could then refine it a bit.

The basic program logic is the same: put user input into a format the SMTP server can use, start a counter, connect and send message, add one to the counter, repeat.

The bulk of the code is formatting the GUI, while I could almost cut-and-paste the main logic from version to version.  I ended up coding it in Python 3, and using Tkinter for the GUI.

I spent a good amount of code framing up the window so it would have a nice UI to look at.

When I hacked this joke up back in 2010, I had no idea that I would still be working on it in 2014.

One can write a joke program like this one, a script that pulls log files, or a quick and simple server that lets you connect to a computer remotely for some reason.  You may need to update the code, add a feature, or fix a bug.

The point is, you don't know how a simple thing will grow more complex, and actually be a project in development.

I started with Telnet, went to a CLI based program, then to a CLI based program with more options, and finally to a full GUI program.

It is obvious that there was some evolution there.  That evolution was not just the code.  It was an evolution in me.

As I evolved as a hacker, my coding evolved.  Let us hack away.  Solve problems, and learn about systems.

See what breaks, and then try to fix it.

And never forget the reason we hack... it's fun!!!

And, in case you wanted to see it, here is the actual Python 3 code I have:

mailFlood.py:

#!/usr/bin/python3

# start of code
# import smtp functions, date functions, and Tkinter
from smtplib import SMTP
import datetime
from tkinter import *

class mf22:

   def __init__(self):

       # make the GUI
       self.window1 = Tk()

       # frames to section the GUI and improve layout
       self.frameTop = Frame((self.window1))
       self.frameTop.pack(side=TOP)
       self.frameBot = Frame((self.window1))
       self.frameBot.pack(side=BOTTOM)
       self.frame1 = Frame((self.frameTop))
       self.frame1.pack(side=LEFT)
       self.frame2 = Frame((self.frameTop))
       self.frame2.pack(side=RIGHT)
       self.frame3 = Frame((self.frameBot))
       self.frame3.pack()
	
       # Put in the labels and texfields and the button
       self.numLbl = Label((self.frame1), text="Number of Emails:")
       self.numLbl.pack()
       self.numTxt = Entry((self.frame2), text="")
       self.numTxt.pack()

       self.fromLbl = Label((self.frame1), text="From:")
       self.fromLbl.pack()
       self.fromTxt = Entry((self.frame2), text="")
       self.fromTxt.pack()

       self.toLbl = Label((self.frame1), text="To:")
       self.toLbl.pack()
       self.toTxt = Entry((self.frame2), text="")
       self.toTxt.pack()

       self.subLbl = Label((self.frame3), text="Subject:")
       self.subLbl.pack()
       self.subTxt = Entry((self.frame3), text="")
       self.subTxt.pack()

       self.msgLbl = Label((self.frame3), text="Message:")
       self.msgLbl.pack()
       self.msgTxt = Entry((self.frame3), text="")
       self.msgTxt.pack()

       self.sendButton = Button((self.frame3), text="Send",
           command=(self.onClicked)) # button activates the event onClicked
       self.sendButton.pack()

       self.doneLabel = Label(self.frame3,
           text="All fields will clear when done")
       self.doneLabel.pack()

       # start the main loop
       self.window1.mainloop()

   def onClicked(self):
	
       # pull data from the entries
       self.num = int(self.numTxt.get())
       self.fromAdd = str(self.fromTxt.get())
       self.toAdd = str(self.toTxt.get())
       self.subj = str(self.subTxt.get())
       self.body = str(self.msgTxt.get())

       # get the time and date
       self.date = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")

       # format the message
       self.msg = "From: %s\nTo: %s\nSubject: %s\nDate: %s\n\n%s" %((self.fromAdd), (self.toAdd), (self.subj), (self.date), (self.body))

       # start the counter and be ready to connect to the mail server
       smtp = SMTP()
       n = 0
       l = self.num

       while n < l:
       	smtp.connect('127.0.0.1', 25)
        smtp.helo('localhost')
        smtp.sendmail((self.fromAdd), (self.toAdd), (self.msg))
        smtp.quit()
        n = n + 1

       # clear all fields once done
       self.numTxt.delete(0, END)
       self.fromTxt.delete(0, END)
       self.toTxt.delete(0, END)
       self.subTxt.delete(0, END)
       self.msgTxt.delete(0, END)

# run the class
if __name__ == "__main__":
   main = mf22()
# end of code

Code: mailFlood.py

Return to $2600 Index