By: Harmeet Singh Bhatia (SN: 101234046)
Project details
The idea for my project was using modern tools like LLMs to create a sample phishing email generator. And for a 2nd part, an NLP-based phishing detection tool. Then generate the emails using part 1 and test them against the detection tool to test how many things the detector can detect even when the emails are generated by an LLM tool.
Project update
Some progress has been made for part 1 of phishing email generation. Although I have been trying to train a model that generates better emails than the current solution, I have decided to share the stuff that works for sure and generates phishing emails quickly.
Instructions
1. Install Go lang
2. Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
3. Set up Ollama
ollama serve
ollama pull llama3
NOTE: Although not ideal,
llama3is used here as it was the only model available at the time of writing that could reliably generate phishing emails besidesgemma3.llama3was chosen due to its slightly better messages however it will probably be replaced once I discover a better system or train a model myself.
4. Write the program
touch phisher.go
phisher.go:
package main
import (
"bytes"
"encoding/json"
"fmt"
"math/rand"
"net/http"
"os"
"slices"
"strings"
)
const ollamaURL = "http://localhost:11434/api/generate"
var phishingTactics = []string{
"urgency/fear (e.g. account suspension)",
"impersonation/authority (e.g. pretending to be a bank)",
"emotional appeal (e.g. charity or friend in need)",
"tech support scam (e.g. pretending to be Microsoft)",
"business compromise (e.g. paycheck redirection)",
}
type OllamaRequest struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
Stream bool `json:"stream"`
}
type OllamaResponse struct {
Response string `json:"response"`
}
func generatePhishingPrompt() string {
selectedTactics := []string{}
target := 1 + rand.Intn(1)
for len(selectedTactics) < target {
tactic := phishingTactics[rand.Intn(len(phishingTactics))]
if slices.Contains(selectedTactics, tactic) {
continue
}
selectedTactics = append(selectedTactics, tactic)
}
// Prompt format
prompt := "Generate a realistic phishing email that uses the following tactics"
prompt = fmt.Sprintf("%s: fake links, %s. ", prompt, strings.Join(selectedTactics, ", "))
// Additional instructions
// 1. No placeholders
prompt += "Replace any placeholders such as [Name] with a realistic name and [Account Number] with a realistic (random) account number. "
// 2. No warning messages
prompt += "Remove any warning or instruction text as the output will be used to test a phishing detection tool as is. "
// 3. Only body text
prompt += "Only generate the body text of the email. Do not include the subject line or any other metadata. "
// 4. Link decoration
prompt += "Do not stylize or decorate links. "
// 5. No placeholders (again, needs to be repeated for it to work)
prompt += "Make sure there are NO placeholders or square brackets ([]) in the text."
return prompt
}
func generatePhishingEmail(prompt string) (string, error) {
requestBody, _ := json.Marshal(OllamaRequest{
Model: "llama3",
Prompt: prompt,
Stream: false,
})
req, err := http.NewRequest(
"POST",
ollamaURL,
bytes.NewBuffer(requestBody),
)
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
var ollamaResponse OllamaResponse
err = json.NewDecoder(resp.Body).Decode(&ollamaResponse)
if err != nil {
return "", err
}
return ollamaResponse.Response, nil
}
func main() {
prompt := generatePhishingPrompt()
fmt.Println("Generated prompt: ", prompt)
success := false
email := ""
err := error(nil)
for !success {
email, err = generatePhishingEmail(prompt)
if err != nil {
fmt.Println("Error generating phishing email: ", err)
return
}
// Llama3 fix
split_email := strings.Split(email, "\n\n")
email = strings.Join(split_email[1:], "\n\n")
if strings.Contains(email, "[") {
fmt.Println("Email contains placeholders, retrying...")
} else {
success = true
}
}
f, err := os.Create("phishing_email.txt")
if err != nil {
fmt.Println("Error creating file: ", err)
return
}
l, err := f.WriteString(email)
if err != nil {
fmt.Println("Error writing to file: ", err)
f.Close()
return
}
fmt.Println("Generated phishing email, written", l, "bytes to file.")
err = f.Close()
if err != nil {
fmt.Println("Error closing file: ", err)
}
}
5. Run the program to generate the phishing_email.txt
go run phisher.go