Skip to content

Commit

Permalink
Add WireGuard Canarytoken
Browse files Browse the repository at this point in the history
Brings support for the WireGuard Canarytoken to the open sourced canarytokens.org. With this change, deployments will need to add a private key seed and public IP to the the config files documented in the Canarytokens Docker repository.
  • Loading branch information
azh-r authored Oct 27, 2021
1 parent ea1ea01 commit 6aa9c0f
Show file tree
Hide file tree
Showing 17 changed files with 379 additions and 4 deletions.
12 changes: 11 additions & 1 deletion canarydrop.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from tokens import Canarytoken
from users import User, AnonymousUser
from exception import NoUser, NoCanarytokenPresent, UnknownAttribute
import wireguard as wg

class Canarydrop(object):
allowed_attrs = ['alert_email_enabled', 'alert_email_recipient',\
Expand All @@ -30,7 +31,8 @@ class Canarydrop(object):
'generated_email', 'generated_hostname','timestamp', 'user',
'imgur_token' ,'imgur', 'auth', 'browser_scanner_enabled', 'web_image_path',\
'web_image_enabled', 'type', 'clonedsite', 'aws_secret_access_key',\
'aws_access_key_id', 'redirect_url', 'region', 'output', 'slack_api_key']
'aws_access_key_id', 'redirect_url', 'region', 'output', 'slack_api_key',
'wg_key']

def __init__(self, generate=False, **kwargs):
self._drop = {}
Expand Down Expand Up @@ -223,6 +225,14 @@ def get_qrcode_data_uri_png(self,):
qrcode = pyqrcode.create(self.get_url()).png_as_base64_str(scale=5)
return "data:image/png;base64,{qrcode}".format(qrcode=qrcode)

def get_wg_conf(self):
return wg.clientConfig(self._drop['wg_key'])

def get_wg_qrcode(self):
wg_conf = self.get_wg_conf()
qrcode = pyqrcode.create(wg_conf).png_as_base64_str(scale=2)
return "data:image/png;base64,{}".format(qrcode)

@property
def canarytoken(self):
"""Return the Canarydrop's Canarytoken object."""
Expand Down
18 changes: 18 additions & 0 deletions channel_input_wireguard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from twisted.application import internet
from constants import INPUT_CHANNEL_WIREGUARD
from channel import InputChannel
import wireguard as wg
from canarydrop import Canarydrop
import queries
class ChannelWireGuard(InputChannel):
CHANNEL = INPUT_CHANNEL_WIREGUARD

def __init__(self, switchboard, port=wg.DEFAULT_PORT):
InputChannel.__init__(self, switchboard, name=self.CHANNEL, unique_channel=True)
self.service = internet.UDPServer(port, wg.WireGuardProtocol(channel=self))

def dispatch(self, **kwargs):
canarytoken = kwargs.pop('canarytoken')
# TODO: If canarydrop no longer exists, delete key -> canarytoken mapping in WireGuard keymap
kwargs['canarydrop'] = Canarydrop(**queries.get_canarydrop(canarytoken))
InputChannel.dispatch(self, **kwargs)
1 change: 1 addition & 0 deletions constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
INPUT_CHANNEL_BITCOIN = 'Bitcoin'
INPUT_CHANNEL_SMTP = 'SMTP'
INPUT_CHANNEL_MYSQL = 'MYSQL'
INPUT_CHANNEL_WIREGUARD = 'WireGuard'
8 changes: 8 additions & 0 deletions httpd_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import os
from cStringIO import StringIO
import csv
import wireguard as wg

env = Environment(loader=FileSystemLoader('templates'),
extensions=['jinja2.ext.loopcontrols'])
Expand Down Expand Up @@ -82,6 +83,7 @@ def render_POST(self, request):
'ms_word',
'ms_excel',
'adobe_pdf',
'wireguard',
'windows_dir',
'clonedsite',
'qr_code',
Expand Down Expand Up @@ -309,6 +311,12 @@ def render_POST(self, request):
except:
pass

if token_type == 'wireguard':
canarydrop['wg_key'] = wg.generateCanarytokenPrivateKey(canarydrop["canarytoken"])
save_canarydrop(canarydrop)
response['wg_conf'] = canarydrop.get_wg_conf()
response['qr_code'] = canarydrop.get_wg_qrcode()

except Exception as e:
if response['Error'] is None:
response['Error'] = 255
Expand Down
12 changes: 11 additions & 1 deletion queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
KEY_IMGUR_TOKENS, KEY_LINKEDIN_ACCOUNT, KEY_LINKEDIN_ACCOUNTS,\
KEY_BITCOIN_ACCOUNTS, KEY_BITCOIN_ACCOUNT, KEY_CANARY_NXDOMAINS,\
KEY_CLONEDSITE_TOKEN, KEY_CLONEDSITE_TOKENS, KEY_CANARY_IP_CACHE, \
KEY_CANARY_GOOGLE_API_KEY, KEY_TOR_EXIT_NODES, KEY_WEBHOOK_IDX, KEY_EMAIL_IDX
KEY_CANARY_GOOGLE_API_KEY, KEY_TOR_EXIT_NODES, KEY_WEBHOOK_IDX, KEY_EMAIL_IDX, \
KEY_WIREGUARD_KEYMAP

from twisted.logger import Logger
log = Logger()
Expand Down Expand Up @@ -561,3 +562,12 @@ def update_tor_exit_nodes(contents):
def update_tor_exit_nodes_loop():
d = getPage('https://check.torproject.org/exit-addresses')
d.addCallback(update_tor_exit_nodes)

def wireguard_keymap_add(public_key, canarytoken):
db.hset(KEY_WIREGUARD_KEYMAP, public_key, canarytoken)

def wireguard_keymap_del(public_key):
db.hdel(KEY_WIREGUARD_KEYMAP, public_key)

def wireguard_keymap_get(public_key):
return db.hget(KEY_WIREGUARD_KEYMAP, public_key)
1 change: 1 addition & 0 deletions redismanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@
KEY_TOR_EXIT_NODES = 'tor_exit_nodes'
KEY_WEBHOOK_IDX = 'alertchannel_webhook:'
KEY_EMAIL_IDX = 'alertchannel_email:'
KEY_WIREGUARD_KEYMAP = 'wireguard-keymap'
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ pypng==0.0.18
htmlmin==0.1.10
sendgrid==3.6.5
service_identity
pyblake2==1.1.2
PyNaCl==1.4.0
2 changes: 1 addition & 1 deletion settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
'ALERT_EMAIL_SUBJECT','DOMAINS','NXDOMAINS', 'TOKEN_RETURN', 'MAX_UPLOAD_SIZE',
'WEB_IMAGE_UPLOAD_PATH', 'DEBUG', 'IPINFO_API_KEY', 'SWITCHBOARD_LOG_COUNT',
'SWITCHBOARD_LOG_SIZE', 'FRONTEND_LOG_COUNT', 'FRONTEND_LOG_SIZE', 'MAX_HISTORY',
'MAX_ALERTS_PER_MINUTE']:
'MAX_ALERTS_PER_MINUTE', 'WG_PRIVATE_KEY_SEED', 'WG_PRIVATE_KEY_N']:
try:
setattr(settingsmodule, envvar, os.environ['CANARY_'+envvar])
except KeyError:
Expand Down
4 changes: 4 additions & 0 deletions switchboard.tac
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ from channel_input_linkedin import ChannelLinkedIn
from channel_input_bitcoin import ChannelBitcoin
from channel_input_smtp import ChannelSMTP
from channel_input_mysql import ChannelMySQL
from channel_input_wireguard import ChannelWireGuard
from channel_output_email import EmailOutputChannel
from channel_output_twilio import TwilioOutputChannel
from channel_output_webhook import WebhookOutputChannel
Expand Down Expand Up @@ -81,6 +82,9 @@ canarytokens_mysql = ChannelMySQL(port=settings.CHANNEL_MYSQL_PORT,
switchboard=switchboard)
canarytokens_mysql.service.setServiceParent(application)

canarytokens_wireguard = ChannelWireGuard(switchboard=switchboard)
canarytokens_wireguard.service.setServiceParent(application)

#loop to update tor exit nodes every 30 min
loop_http = internet.task.LoopingCall(update_tor_exit_nodes_loop)
loop_http.start(1800)
31 changes: 31 additions & 0 deletions templates/generate_new.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ <h3 class="text-muted">
<li data-type="ms_word" data-memo-placeholder="Word document placed at U:\Users\Sally\Reports\feb.doc"><a href="#" class="icon icon-word"><span class="title">Microsoft Word Document</span><div class="explanation">Get alerted when a document is opened in Microsoft Word</div></a></li>
<li data-type="ms_excel" data-memo-placeholder="Excel document placed at U:\Users\Sally\Reports\feb.xlsx"><a href="#" class="icon icon-excel"><span class="title">Microsoft Excel Document</span><div class="explanation">Get alerted when a document is opened in Microsoft Excel</div></a></li>
<li data-type="adobe_pdf" data-memo-placeholder="PDF document placed at U:\Users\Sipho\Reports\feb.pdf"><a href="#" class="icon icon-pdf"><span class="title">Acrobat Reader PDF Document</span><div class="explanation">Get alerted when a PDF document is opened in Acrobat Reader</div></a></li>
<li data-type="wireguard" data-memo-placeholder="WireGuard VPN config installed on Siya's phone"><a href="#" class="icon icon-wireguard"><span class="title">WireGuard VPN</span><div class="explanation">Alert when a WireGuard VPN client config is used</div></a></li>
<li data-type="windows_dir" data-memo-placeholder="Directory token placed in U:\Users\Sarah\CreditCardReports\"><a href="#" class="icon icon-folder"><span class="title">Windows Folder</span><div class="explanation">Be notified when a Windows Folder is browsed in Windows Explorer</div></a></li>
<li data-type="signed_exe" data-memo-placeholder="Tokened whoami.exe on web server WEB01"><a href="#" class="icon icon-exe"><span class="title">Custom exe / binary</span><div class="explanation">Fire an alert when an EXE or DLL is executed</div></a></li>
<li data-type="cloned_website" data-memo-placeholder="Cloned website token for https://thinkst.com"><a href="#" class="icon icon-clonedsite"><span class="title">Cloned Website</span><div class="explanation">Trigger an alert when your website is cloned</div></a></li>
Expand Down Expand Up @@ -611,6 +612,31 @@ <h3>Your QR Code token is active!</h3>
</p>
</div>
</div>
<div class="result wireguard">
<h3>Your WireGuard VPN Config token is active!</h3>
<div class="artifacts">
<p style="margin-bottom: 0px;">Scan this QR Code with the WireGuard app on your phone or copy the config below.</p>
<div id="wireguard-app">
<p>Don't have the WireGuard app?</p>
<a href="https://apps.apple.com/us/app/wireguard/id1441195209?itsct=apps_box_badge&amp;itscg=30200" target="_blank">
<img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=250x83&amp;releaseDate=1545264000&amp;h=b15fc494302fdddf3af31ab97784d31d" alt="Download on the App Store">
</a>
<a href="https://play.google.com/store/apps/details?id=com.wireguard.android" target="_blank">
<img class="play-img" alt="Get it on Google Play" src="/resources/google-play.png">
</a>
</div>
<div class="form-control">
<img id="wg_qrcode" />
<pre id="wg_conf">
</pre>
</div>
</div>
<div class="advice">
<p>Whenever someone tries to use this WireGuard VPN config to see what access it gets them, an alert is triggered.</p>
<p>This WireGuard config can be installed anywhere WireGuard is used, such as on phones, laptops and servers.<p>
</p>
</div>
</div>
<div class="result svn">
<h3>Your SVN token is active!</h3>
<div class="artifacts">
Expand Down Expand Up @@ -1045,6 +1071,10 @@ <h3>Your AWS key token is active!</h3>
$('#qrcode_png').siblings('a').prop('download', data['Token']+'.png');
$('#qrcode_png').prop('src', data['qrcode_png']);
}
var _handleWireGuardResponse = function(data) {
$('#wg_qrcode').prop('src', data['qr_code']);
$('#wg_conf').text(data['wg_conf']);
}
var _handleSVNResponse = function(data){
$('#result_svn').val('svn propset svn:externals "extras http://'+data['Hostname']+'" .')
}
Expand Down Expand Up @@ -1115,6 +1145,7 @@ <h3>Your AWS key token is active!</h3>
'signed_exe': _handlerSignedExeResponse,
'fast_redirect': _handleFastRedirectResponse,
'slow_redirect': _handleSlowRedirectResponse,
'wireguard': _handleWireGuardResponse,
'default': _handleDefaultResponse
};

Expand Down
34 changes: 34 additions & 0 deletions templates/history.html
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,40 @@ <h4 style="text-align: center;">Incident List is Currently Empty</h4>
{{ canarydrop['triggered_list'][item][field]['aws_keys_event_user_agent']|e }}
</td>
{% endif %}
{% if canarydrop['type'] == 'wireguard' and field == 'src_data' %}
<tr class="info_row">
<td>
Client Source Port
</td>
<td>
{{ canarydrop['triggered_list'][item][field]['src_port'] |e }}
</td>
</tr>
<tr class="info_row">
<td>
Client Handshake ID
</td>
<td>
{{ canarydrop['triggered_list'][item][field]['session_index'] |e }}
</td>
</tr>
<tr class="info_row">
<td>
Client Public Key
</td>
<td>
{{ canarydrop['triggered_list'][item][field]['client_public_key'] |e }}
</td>
</tr>
<tr class="info_row">
<td>
Server Public Key
</td>
<td>
{{ canarydrop['triggered_list'][item][field]['server_public_key'] |e }}
</td>
</tr>
{% endif %}
{% elif field == 'src_data' and field in canarydrop['triggered_list'][item] and 'generic_data' in canarydrop['triggered_list'][item][field] %}
<tr class="info_row">
<td>
Expand Down
11 changes: 11 additions & 0 deletions templates/manage_new.html
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,17 @@ <h5>Your SVN token:</h5>
</div>
</div>
</div>
<div class="result wireguard">
<h5>Your WireGuard VPN client config:</h5>
<div class="artifacts">
<div class="form-control">
{% if canarydrop['type'] == 'wireguard'%}
<img id="wg_qrcode" src="{{ canarydrop.get_wg_qrcode() }}" />
<pre id="wg_conf">{{ canarydrop.get_wg_conf() }}</pre>
{%endif%}
</div>
</div>
</div>
</div>
<div class="col-md-1">
</div>
Expand Down
Binary file added templates/static/google-play.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions templates/static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,9 @@
a.icon-pdf:before {
background-image: url("/resources/pdf.png");
}
a.icon-wireguard:before {
background-image: url("/resources/wireguard.png");
}
a.icon-folder:before {
background-image: url("/resources/folder.png");
}
Expand Down Expand Up @@ -631,4 +634,30 @@

.mysqldownload {
cursor: pointer;
}

#wg_conf {
background: #f6f6f6;
display: block;
white-space: pre;
overflow-x: scroll;
max-width: 100%;
min-width: 100px;
padding: 0;
text-align: left;
border-radius: 8px;
padding-bottom: 12px;
padding-left: 12px;
padding-top: 12px;
margin-bottom: 7px;
margin-top: 7px;
margin-left: 0px;
}

#wireguard-app {
margin-bottom: 16px;
}

#wireguard-app img {
height: 40px;
}
Loading

0 comments on commit 6aa9c0f

Please sign in to comment.