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 + 1A 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:
#!/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 codeCode: mailFlood.py