mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-05-25 17:17:53 +02:00
add deny page visit event
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
This commit is contained in:
@@ -1577,6 +1577,57 @@ func (s *Server) renderDenyPage(
|
||||
|
||||
c.Data(http.StatusOK, "text/html; charset=utf-8", buf.Bytes())
|
||||
c.Abort()
|
||||
|
||||
// log deny page visited event
|
||||
denyPageVisitEventID := uuid.New()
|
||||
eventID := cache.EventIDByName[data.EVENT_CAMPAIGN_RECIPIENT_DENY_PAGE_VISITED]
|
||||
clientIP := vo.NewOptionalString64Must(utils.ExtractClientIP(c.Request))
|
||||
userAgent := vo.NewOptionalString255Must(utils.Substring(c.Request.UserAgent(), 0, MAX_USER_AGENT_SAVED))
|
||||
|
||||
var denyPageVisitEvent *model.CampaignEvent
|
||||
if !campaign.IsAnonymous.MustGet() {
|
||||
denyPageVisitEvent = &model.CampaignEvent{
|
||||
ID: &denyPageVisitEventID,
|
||||
CampaignID: &campaignID,
|
||||
RecipientID: &recipientID,
|
||||
IP: clientIP,
|
||||
UserAgent: userAgent,
|
||||
EventID: eventID,
|
||||
Data: vo.NewEmptyOptionalString1MB(),
|
||||
}
|
||||
} else {
|
||||
denyPageVisitEvent = &model.CampaignEvent{
|
||||
ID: &denyPageVisitEventID,
|
||||
CampaignID: &campaignID,
|
||||
RecipientID: nil,
|
||||
IP: vo.NewEmptyOptionalString64(),
|
||||
UserAgent: vo.NewEmptyOptionalString255(),
|
||||
EventID: eventID,
|
||||
Data: vo.NewEmptyOptionalString1MB(),
|
||||
}
|
||||
}
|
||||
|
||||
err = s.repositories.Campaign.SaveEvent(c, denyPageVisitEvent)
|
||||
if err != nil {
|
||||
s.logger.Errorw("failed to save deny page visit event",
|
||||
"error", err,
|
||||
"campaignID", campaignID.String(),
|
||||
)
|
||||
}
|
||||
|
||||
// check and update if most notable event for recipient
|
||||
currentNotableEventID, _ := campaignRecipient.NotableEventID.Get()
|
||||
if cache.IsMoreNotableCampaignRecipientEventID(¤tNotableEventID, eventID) {
|
||||
campaignRecipient.NotableEventID.Set(*eventID)
|
||||
err := s.repositories.CampaignRecipient.UpdateByID(c, &campaignRecipientID, campaignRecipient)
|
||||
if err != nil {
|
||||
s.logger.Errorw("failed to update campaign recipient notable event",
|
||||
"error", err,
|
||||
"campaignRecipientID", campaignRecipientID.String(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// safely log with nil checks
|
||||
pageName := "unknown"
|
||||
if pageNameVal, err := page.Name.Get(); err == nil {
|
||||
|
||||
Vendored
+1
@@ -43,6 +43,7 @@ var CampaignEventPriority = map[string]int{
|
||||
data.EVENT_CAMPAIGN_RECIPIENT_AFTER_PAGE_VISITED: 60,
|
||||
data.EVENT_CAMPAIGN_RECIPIENT_BEFORE_PAGE_VISITED: 40,
|
||||
data.EVENT_CAMPAIGN_RECIPIENT_PAGE_VISITED: 50,
|
||||
data.EVENT_CAMPAIGN_RECIPIENT_DENY_PAGE_VISITED: 38,
|
||||
data.EVENT_CAMPAIGN_RECIPIENT_EVASION_PAGE_VISITED: 35,
|
||||
data.EVENT_CAMPAIGN_RECIPIENT_MESSAGE_READ: 30,
|
||||
data.EVENT_CAMPAIGN_RECIPIENT_MESSAGE_FAILED: 20,
|
||||
|
||||
@@ -14,6 +14,7 @@ const (
|
||||
EVENT_CAMPAIGN_RECIPIENT_BEFORE_PAGE_VISITED = "campaign_recipient_before_page_visited"
|
||||
EVENT_CAMPAIGN_RECIPIENT_PAGE_VISITED = "campaign_recipient_page_visited"
|
||||
EVENT_CAMPAIGN_RECIPIENT_AFTER_PAGE_VISITED = "campaign_recipient_after_page_visited"
|
||||
EVENT_CAMPAIGN_RECIPIENT_DENY_PAGE_VISITED = "campaign_recipient_deny_page_visited"
|
||||
EVENT_CAMPAIGN_RECIPIENT_SUBMITTED_DATA = "campaign_recipient_submitted_data"
|
||||
EVENT_CAMPAIGN_RECIPIENT_REPORTED = "campaign_recipient_reported"
|
||||
EVENT_CAMPAIGN_RECIPIENT_CANCELLED = "campaign_recipient_cancelled"
|
||||
@@ -34,6 +35,7 @@ var Events = []string{
|
||||
EVENT_CAMPAIGN_RECIPIENT_BEFORE_PAGE_VISITED,
|
||||
EVENT_CAMPAIGN_RECIPIENT_PAGE_VISITED,
|
||||
EVENT_CAMPAIGN_RECIPIENT_AFTER_PAGE_VISITED,
|
||||
EVENT_CAMPAIGN_RECIPIENT_DENY_PAGE_VISITED,
|
||||
EVENT_CAMPAIGN_RECIPIENT_SUBMITTED_DATA,
|
||||
EVENT_CAMPAIGN_RECIPIENT_REPORTED,
|
||||
EVENT_CAMPAIGN_RECIPIENT_CANCELLED,
|
||||
|
||||
@@ -3457,6 +3457,9 @@ func (m *ProxyHandler) serveDenyPageResponseDirect(req *http.Request, reqCtx *Re
|
||||
resp.Header.Set("Content-Length", fmt.Sprintf("%d", len(htmlContent)))
|
||||
resp.Header.Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
|
||||
// log deny page visit event
|
||||
m.registerDenyPageVisitEventDirect(req, reqCtx)
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
@@ -3670,6 +3673,63 @@ func (m *ProxyHandler) renderEvasionPageTemplate(req *http.Request, reqCtx *Requ
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
func (m *ProxyHandler) registerDenyPageVisitEventDirect(req *http.Request, reqCtx *RequestContext) {
|
||||
// use cached recipient data
|
||||
if reqCtx.CampaignRecipient == nil || reqCtx.RecipientID == nil || reqCtx.CampaignID == nil || reqCtx.Campaign == nil {
|
||||
return
|
||||
}
|
||||
|
||||
recipientID := reqCtx.RecipientID
|
||||
campaignID := reqCtx.CampaignID
|
||||
campaign := reqCtx.Campaign
|
||||
|
||||
eventID := cache.EventIDByName[data.EVENT_CAMPAIGN_RECIPIENT_DENY_PAGE_VISITED]
|
||||
newEventID := uuid.New()
|
||||
clientIP := vo.NewOptionalString64Must(utils.ExtractClientIP(req))
|
||||
userAgent := vo.NewOptionalString255Must(utils.Substring(req.UserAgent(), 0, 1000)) // MAX_USER_AGENT_SAVED equivalent
|
||||
|
||||
var event *model.CampaignEvent
|
||||
if !campaign.IsAnonymous.MustGet() {
|
||||
event = &model.CampaignEvent{
|
||||
ID: &newEventID,
|
||||
CampaignID: campaignID,
|
||||
RecipientID: recipientID,
|
||||
IP: clientIP,
|
||||
UserAgent: userAgent,
|
||||
EventID: eventID,
|
||||
Data: vo.NewEmptyOptionalString1MB(),
|
||||
}
|
||||
} else {
|
||||
ua := vo.NewEmptyOptionalString255()
|
||||
event = &model.CampaignEvent{
|
||||
ID: &newEventID,
|
||||
CampaignID: campaignID,
|
||||
RecipientID: nil,
|
||||
IP: vo.NewEmptyOptionalString64(),
|
||||
UserAgent: ua,
|
||||
EventID: eventID,
|
||||
Data: vo.NewEmptyOptionalString1MB(),
|
||||
}
|
||||
}
|
||||
|
||||
err := m.CampaignRepository.SaveEvent(req.Context(), event)
|
||||
if err != nil {
|
||||
m.logger.Errorw("failed to save deny page visit event", "error", err)
|
||||
}
|
||||
|
||||
// check and update if most notable event for recipient
|
||||
cRecipient := reqCtx.CampaignRecipient
|
||||
currentNotableEventID, _ := cRecipient.NotableEventID.Get()
|
||||
if cache.IsMoreNotableCampaignRecipientEventID(¤tNotableEventID, eventID) {
|
||||
cRecipient.NotableEventID.Set(*eventID)
|
||||
campaignRecipientID := reqCtx.CampaignRecipientID
|
||||
err := m.CampaignRecipientRepository.UpdateByID(req.Context(), campaignRecipientID, cRecipient)
|
||||
if err != nil {
|
||||
m.logger.Errorw("failed to update campaign recipient notable event for deny page", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ProxyHandler) registerEvasionPageVisitEventDirect(req *http.Request, reqCtx *RequestContext) {
|
||||
// use cached recipient data
|
||||
if reqCtx.CampaignRecipient == nil || reqCtx.RecipientID == nil || reqCtx.CampaignID == nil || reqCtx.Campaign == nil {
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
campaign_recipient_before_page_visited: true,
|
||||
campaign_recipient_page_visited: true,
|
||||
campaign_recipient_after_page_visited: true,
|
||||
campaign_recipient_deny_page_visited: true,
|
||||
campaign_recipient_submitted_data: true,
|
||||
campaign_recipient_reported: true
|
||||
};
|
||||
@@ -741,9 +742,11 @@
|
||||
campaign_recipient_message_sent: '#94cae6',
|
||||
campaign_recipient_message_failed: '#f2bb58',
|
||||
campaign_recipient_message_read: '#4cb5b5',
|
||||
campaign_recipient_evasion_page_visited: '#c8a2f0',
|
||||
campaign_recipient_before_page_visited: '#eea5fa',
|
||||
campaign_recipient_page_visited: '#f96dcf',
|
||||
campaign_recipient_after_page_visited: '#f6287b',
|
||||
campaign_recipient_deny_page_visited: '#ff6b35',
|
||||
campaign_recipient_submitted_data: '#f42e41',
|
||||
campaign_recipient_reported: '#2c3e50'
|
||||
};
|
||||
@@ -770,12 +773,16 @@
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L4.072 16.5c-.77.833.192 2.5 1.732 2.5z"/></svg>',
|
||||
campaign_recipient_message_read:
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>',
|
||||
campaign_recipient_evasion_page_visited:
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>',
|
||||
campaign_recipient_before_page_visited:
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>',
|
||||
campaign_recipient_page_visited:
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/></svg>',
|
||||
campaign_recipient_after_page_visited:
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>',
|
||||
campaign_recipient_deny_page_visited:
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/></svg>',
|
||||
campaign_recipient_submitted_data:
|
||||
'<svg fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>',
|
||||
campaign_recipient_reported:
|
||||
@@ -798,9 +805,11 @@
|
||||
campaign_recipient_message_sent: 'Email successfully delivered',
|
||||
campaign_recipient_message_failed: 'Email delivery failed',
|
||||
campaign_recipient_message_read: 'Recipient opened the email',
|
||||
campaign_recipient_evasion_page_visited: 'Recipient encountered evasion page',
|
||||
campaign_recipient_before_page_visited: 'Recipient browsing before target page',
|
||||
campaign_recipient_page_visited: 'Recipient visited the target page',
|
||||
campaign_recipient_after_page_visited: 'Recipient continued browsing after target',
|
||||
campaign_recipient_deny_page_visited: 'Recipient was denied access',
|
||||
campaign_recipient_submitted_data: 'Recipient submitted form data',
|
||||
campaign_recipient_reported: 'Email was reported as spam'
|
||||
};
|
||||
@@ -1001,6 +1010,15 @@
|
||||
/>
|
||||
<span class="text-gray-600 dark:text-gray-300">After Page Visited</span>
|
||||
</label>
|
||||
<label class="flex items-center text-xs">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={eventFilters.campaign_recipient_deny_page_visited}
|
||||
on:change={() => filterUpdateCounter++}
|
||||
class="mr-2 rounded border-slate-300 dark:border-gray-700/60"
|
||||
/>
|
||||
<span class="text-gray-600 dark:text-gray-300">Deny Page Visited</span>
|
||||
</label>
|
||||
<label class="flex items-center text-xs">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
||||
@@ -15,6 +15,11 @@ const eventNameMap = {
|
||||
priority: 45,
|
||||
color: 'bg-evasion-page-visited'
|
||||
},
|
||||
campaign_recipient_deny_page_visited: {
|
||||
name: 'Deny Page Visited',
|
||||
priority: 47,
|
||||
color: 'bg-deny-page-visited'
|
||||
},
|
||||
campaign_recipient_before_page_visited: {
|
||||
name: 'Before Page Visited',
|
||||
priority: 50,
|
||||
|
||||
@@ -1121,12 +1121,12 @@
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.5"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
|
||||
d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"
|
||||
/>
|
||||
</svg>
|
||||
</StatsCard>
|
||||
|
||||
@@ -36,9 +36,11 @@ export default {
|
||||
cancelled: '#161692',
|
||||
'message-sent': '#94cae6',
|
||||
'message-read': '#4cb5b5',
|
||||
'evasion-page-visited': '#c8a2f0',
|
||||
'before-page-visited': '#eea5fa',
|
||||
'page-visited': '#f96dcf',
|
||||
'after-page-visited': '#f6287b',
|
||||
'deny-page-visited': '#ff6b35',
|
||||
'submitted-data': '#f42e41',
|
||||
reported: '#2c3e50',
|
||||
'completed-campaign': '#48bb78',
|
||||
|
||||
Reference in New Issue
Block a user