Case Study: Raptor Anti-Phish Aug 24th, 2015   [viewed 403 times]

MVProc is the best thing to happen to web servers since CGI. Wow, did I just say that? I'm actually a humble person, not given to over-statement, and I stand by that assessment. In this article, my aim is to show how simple development of an MVProc website is, using Raptor Anti-Phish as an example.

Realtime Anti-Phish Training Online Resource (Raptor)

Raptor is a training tool to help educate the “weakest link” on how they can avoid being a doormat for hackers. By launching harmless phishing campaigns, tracking results, and providing immediate education, Raptor can help you tame your company's mice. Download at Sourceforge.

It's a good example for MVProc because it uses most of MVProc's capabilities, including flexible uri processing, file uploads, controlling outbound headers, User-Defined Functions for functionality exterior to the database, exceptional security, and more.

Where to begin?... Ah, yes! The data model

The "M" in MVC - also in MVProc - the Model is the foundational data structure. Here's a snapshot of Raptor from MySQL Workbench:


As you can see, the heart of the data is the campaign, which has foreign keys to a client and a phish. The emails sent in the campaign, of course, link back to that campaign. The emails table stores md5 hashes of the email addresses for security purposes - in case the server is compromised - but also to focus on aggregate data, while allowing lookup of a specific known address history.

 Fairly standard web stuff so far. But this is MVProc, so we're leaving standard behind, starting now.

UDF Emailer

This is an anti-phishing trainer, so we have to send emails. I can hear the screaming as I type this, but Raptor sends emails with the eSMTP library through a User Defined Function, shown here:

As you can see, it's a very simple and stable function. Obviously it's not the whole file - there are init and deinit functions, but this here is the meat of it. And it's the end of the source file at lines 113-140, so not terribly complex. Now, I will own that I have crashed mysql many times during development of UDFs, but I've never had any issue with stability once they've been thoroughly tested and debugged. In fact, if you do develop UDFs, I recommend using a different machine than your primary development environment. (Also, there are UDFs out there in the wild that give you access to the system() call, and one I developed for running cURL - MySQL UDF cURL on

Ok, so let's now look at the function that actually uses the email UDF:

sendEmails - a MySQL stored function

The function sendEmails resides in the raptorData database, which is only accessible to the webserver through using stored procedures in the raptorAdmin database. (That's why there's no authentication or authorization in the function itself.) It reads its way through an uploaded file of names and email addresses and sends a phishing email (the phish is selected when the campaign is launched) to each address in the list. Notice how few lines of code are required for this.

 So that's a MySQL stored function. Not exactly frightening syntax or content. I have to assert at this point (after having developed 5 or 6 MVProc sites) that debugging stored routines is FAR EASIER than debugging PHP.

I mentioned that sendEmails is called from a Procedure in the raptorAdmin database, which is called by the webserver directly. So let's look at that one.

launchCampaign - a MySQL (MVProc) Stored Procedure

 Simplicity in action. The admin of the Raptor site launches a campaign - here's the relevant part of campaigns.tpl:

Ok, maybe that was rude of me to introduce MVProc templates without any warning, but it shows the content of the form, how the input names line up with the Procedure's parameters, and how files are handled. It also shows two very common control elements in MVProc templating: <# IF #><# ELSE #><# ENDIF #> and <# LOOP #><# ENDLOOP #>.

You should, at this point, have a bit of the flavor of MVProc site development. Much more documentation is available in the README (in the menu above), but I'd like to show you one more thing:

csvData - fine-grained control of data download

Throughout the Raptor Admin site, there are "csv" links which give the admin easy access to the raw data. Let's start with the view:

Here's the procedure that retrieves the data:

Notice the SET @mvp_content_type = 'text/csv'; - That's all it takes to set Content-Type headers. No worries about output starting beforehand. And here's the template:

idCampaign,emailHash,smallHash,dtResponse,ipResponse,campName,idPhish,dtLaunch,idClient,phishName,clientName<# LOOP rawCampaignData #>
<# idCampaign #>,<# emailHash #>,<# smallHash #>,<# dtResponse #>,<# ipResponse #>,<# campName #>,<# idPhish #>,<# dtLaunch #>,<# idClient #>,<# phishName #>,<# clientName #><# ENDLOOP #>

That's two lines with wrap (the actual csv file can't wrap so the template doesn't either). Pretty sweet.

It's the best thing since CGI, right?