-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[New Feature] Gophish with QR code #2897
base: master
Are you sure you want to change the base?
Conversation
Hi @HLOverflow! I did like your pull request allowing native QR code integration instead of classic links for phishing into gophish. However, while testing your code I found that some newer mail clients (new Outlook, gmail) did not show the base64 embedded .png image for some reason. I looked at other images which were showing correctly in the client and found that they were all referenced trough content-id (img src="cid:...."). Using this method instead of inline base64 embedding with gophish worked for me. Below you can find my slightly different implementation. You can then use the variable index 8e9afcb..a059695 100644
--- a/go.mod
+++ b/go.mod
@@ -25,6 +25,7 @@ require (
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/oschwald/maxminddb-golang v1.6.0
github.com/sirupsen/logrus v1.4.2
+ github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/ziutek/mymysql v1.5.4 // indirect
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
diff --git a/go.sum b/go.sum
index a7a6e54..7af7b52 100644
--- a/go.sum
+++ b/go.sum
@@ -74,6 +74,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
diff --git a/models/maillog.go b/models/maillog.go
index 7ab3a2e..593dc06 100644
--- a/models/maillog.go
+++ b/models/maillog.go
@@ -12,11 +12,12 @@ import (
"path/filepath"
"strings"
"time"
-
+ "encoding/base64"
"github.com/gophish/gomail"
"github.com/gophish/gophish/config"
log "github.com/gophish/gophish/logger"
"github.com/gophish/gophish/mailer"
+ qrcode "github.com/skip2/go-qrcode" //library for generating qrcode
)
// MaxSendAttempts set to 8 since we exponentially backoff after each failed send
@@ -164,6 +165,25 @@ func (m *MailLog) GetSmtpFrom() (string, error) {
return f.Address, err
}
+//Generate QR code dataurl
+func generateQRCodeData(websiteURL string) string {
+
+ // imageSize = 256 x 256 pixels
+
+ imageSize := 256
+ qrCodeImageData, taskError := qrcode.Encode(websiteURL, qrcode.High, imageSize)
+
+ if taskError != nil {
+ log.Errorf("Error generating QR code. %s",taskError)
+ }
+
+ // Encode raw QR code data to base 64
+ encodedData := base64.StdEncoding.EncodeToString(qrCodeImageData)
+ log.Infof("QR encodedData = %s", encodedData)
+
+ return encodedData
+ }
+
// Generate fills in the details of a gomail.Message instance with
// the correct headers and body from the campaign and recipient listed in
// the maillog. We accept the gomail.Message as an argument so that the caller
@@ -260,6 +280,15 @@ func (m *MailLog) Generate(msg *gomail.Message) error {
addAttachment(msg, a, ptx)
}
+ // generate QR code png image and embed attachment (reference it with img src="cid:{{.RId}}.png")
+ qrData := generateQRCodeData(ptx.URL)
+ a := Attachment{
+ Content: qrData,
+ Name: (m.RId+".png"),
+ Type: "image/png",
+ }
+ addAttachment(msg, a, ptx)
+
return nil
} |
@Strong-IT-IBK is right: Modern clients, especially web-based ones, do not render inline encoded data for security reasons. Instead, any image must be part of an attachment. Another approach that comes to my mind is to "encode" the qr code with some special characters like U+2588 or "#" to display a qr code as text. e.g. https://github.com/Jojodicus/qr2eascii |
Or use a simple html table as output with some background colors on specific cells: https://metacpan.org/pod/HTML::Barcode::QRCode that would be more stable and flexible on phishing campaigns https://jsfiddle.net/2rc5yven/ import qrcode
# Generate QR Code
url = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(url)
qr.make(fit=True)
# Convert to matrix
img = qr.make_image(fill_color="black", back_color="white")
matrix = qr.get_matrix()
# Convert matrix to HTML table
html_code = '<table style="border-collapse: collapse; border: none;">\n'
for row in matrix:
html_code += '<tr>\n'
for cell in row:
color = 'black' if cell else 'white'
html_code += f' <td style="width: 10px; height: 10px; background-color: {color}; border: none;"></td>\n'
html_code += '</tr>\n'
html_code += '</table>'
# Save HTML code to a file
file_path = 'qr_code_table.html'
with open(file_path, 'w') as file:
file.write(html_code)
file_path |
Hi @jordan-wright
I am sharing the same sentiment on having QR code generated for phishing URL from this issue
I would like to propose my implementation where users can generate QR image with
<img src="{{ .QrURL }}" />
in the email template with this pull request.I have also included a way for users to compile the binary via docker if they do not have Golang in their environment.