diff --git a/automate.py b/automate.py index a25f908..bc8a725 100644 --- a/automate.py +++ b/automate.py @@ -14,20 +14,15 @@ from selenium.webdriver.chrome.options import Options parser = argparse.ArgumentParser() parser.add_argument("--browser", type=str, choices=["chrome", "firefox", "safari"], default="chrome", help="Browser to run automation in.") parser.add_argument("--domains", type=str, default="google.com,youtube.com,baidu.com,facebook.com", help="Comma-separated list of domain names to collect traces from. Defaults to google.com,youtube.com,baidu.com,facebook.com") -parser.add_argument("--enable_countermeasure", type=bool, default=False, help="Set to true to enable the countermeasure. Browser must be set to Chrome. Defaults to false.") parser.add_argument("--num_traces_per_domain", type=int, default=40, help="Number of traces to collect per domain.") parser.add_argument("--trace_length", type=int, default=5000, help="The length of each recorded trace, in milliseconds. Defaults to 5000.") required = parser.add_argument_group("required arguments") required.add_argument("--out_filename", type=str, required=True, help="Name of the output file to save traces to.") -required.add_argument("--part", type=int, choices=[2, 3, 4], required=True, help="Set to the part of the lab you're working on.") +required.add_argument("--part", type=int, choices=[2, 3], required=True, help="Set to the part of the lab you're working on.") opts = parser.parse_args() -if opts.browser != "chrome" and opts.enable_countermeasure: - print("Browser must be set to Chrome in order to enable the countermeasure.") - sys.exit(1) - if os.path.exists(opts.out_filename): print(f"WARNING: Data already exists at {opts.out_filename}. What do you want to do?") res = input("[C]ancel [O]verwrite ").lower() @@ -40,11 +35,6 @@ if os.path.exists(opts.out_filename): # Start serving attacker app app = Flask(__name__) -# Disable Flask logs -os.environ["WERKZEUG_RUN_MAIN"] = "true" -log = logging.getLogger("werkzeug") -log.disabled = True - @app.route("/") def root(): return send_from_directory(f"part{opts.part}", "index.html") @@ -63,10 +53,6 @@ def get_browser(victim): chrome_opts = Options() chrome_opts.add_experimental_option("excludeSwitches", ["enable-automation"]) - if opts.enable_countermeasure and victim: - # Victim has the extension enabled -- attacker does not - chrome_opts.add_extension("part4/extension.crx") - return webdriver.Chrome(options=chrome_opts) elif opts.browser == "firefox": return webdriver.Firefox() diff --git a/part2/index.html b/part2/index.html deleted file mode 120000 index 79c5d6f..0000000 --- a/part2/index.html +++ /dev/null @@ -1 +0,0 @@ -../index.html \ No newline at end of file diff --git a/part2/index.html b/part2/index.html new file mode 100644 index 0000000..eff4b48 --- /dev/null +++ b/part2/index.html @@ -0,0 +1,185 @@ + + + + + Website Fingerprinting Lab + + + +

Website Fingerprinting Lab

+
+ + +
+
+ + + + diff --git a/part2/worker.js b/part2/worker.js index 5b706ad..fed89d2 100644 --- a/part2/worker.js +++ b/part2/worker.js @@ -1,7 +1,11 @@ -// Duration of your trace, in milliseconds -let TRACE_LENGTH; +// Number of sweep counts +// TODO: Choose an appropriate value! +let P; -// Array of length TRACE_LENGTH with your trace's values +// Number of elements in your trace +let K = 5 * 1000 / P; + +// Array of length K with your trace's values let T; // Value of performance.now() when you started recording your trace @@ -9,7 +13,7 @@ let start; function record() { // Create empty array for saving trace values - T = new Array(TRACE_LENGTH); + T = new Array(K); // Fill array with -1 so we can be sure memory is allocated T.fill(-1, 0, T.length); @@ -17,7 +21,7 @@ function record() { // Save start timestamp start = performance.now(); - // TODO (Exercise 2-2): Record data for TRACE_LENGTH seconds and save values to T. + // TODO: Record data for 5 seconds and save values to T. // Once done recording, send result to main thread postMessage(JSON.stringify(T)); @@ -26,7 +30,6 @@ function record() { // DO NOT MODIFY BELOW THIS LINE -- PROVIDED BY COURSE STAFF self.onmessage = (e) => { if (e.data.type === "start") { - TRACE_LENGTH = e.data.trace_length; setTimeout(record, 0); } }; diff --git a/part3/index.html b/part3/index.html deleted file mode 120000 index 79c5d6f..0000000 --- a/part3/index.html +++ /dev/null @@ -1 +0,0 @@ -../index.html \ No newline at end of file diff --git a/part3/index.html b/part3/index.html new file mode 100644 index 0000000..eff4b48 --- /dev/null +++ b/part3/index.html @@ -0,0 +1,185 @@ + + + + + Website Fingerprinting Lab + + + +

Website Fingerprinting Lab

+
+ + +
+
+ + + + diff --git a/part3/worker.js b/part3/worker.js index 46c8d96..fed89d2 100644 --- a/part3/worker.js +++ b/part3/worker.js @@ -1,7 +1,11 @@ -// Duration of your trace, in milliseconds -let TRACE_LENGTH; +// Number of sweep counts +// TODO: Choose an appropriate value! +let P; -// Array of length TRACE_LENGTH with your trace's values +// Number of elements in your trace +let K = 5 * 1000 / P; + +// Array of length K with your trace's values let T; // Value of performance.now() when you started recording your trace @@ -9,7 +13,7 @@ let start; function record() { // Create empty array for saving trace values - T = new Array(TRACE_LENGTH); + T = new Array(K); // Fill array with -1 so we can be sure memory is allocated T.fill(-1, 0, T.length); @@ -17,7 +21,7 @@ function record() { // Save start timestamp start = performance.now(); - // TODO (Exercise 3-1): Record data for TRACE_LENGTH seconds and save values to T. + // TODO: Record data for 5 seconds and save values to T. // Once done recording, send result to main thread postMessage(JSON.stringify(T)); @@ -26,7 +30,6 @@ function record() { // DO NOT MODIFY BELOW THIS LINE -- PROVIDED BY COURSE STAFF self.onmessage = (e) => { if (e.data.type === "start") { - TRACE_LENGTH = e.data.trace_length; setTimeout(record, 0); } }; diff --git a/part4/eval.py b/part4/eval.py deleted file mode 100644 index 7c13310..0000000 --- a/part4/eval.py +++ /dev/null @@ -1,27 +0,0 @@ -import json -import numpy as np - -from sklearn.ensemble import RandomForestClassifier -from sklearn.metrics import classification_report -from sklearn.model_selection import train_test_split - -def eval(): - y_pred_full, y_test_full = [], [] - - # Re-train 10 times in order to reduce effects of randomness - for i in range(10): - ### TODO: Exercise 4-1 - ### 1. Load data from traces file - ### 2. Split data into X_train, X_test, y_train, y_test with train_test_split - ### 3. Train classifier with X_train and y_train - ### 4. Use classifier to make predictions on X_test. Save the result to a variable called y_pred - - # Do not modify the next two lines - y_test_full.extend(y_test) - y_pred_full.extend(y_pred) - - ### TODO: Exercise 4-1 (continued) - ### 5. Print classification report using y_test_full and y_pred_full - -if __name__ == "__main__": - eval() diff --git a/part4/extension.crx b/part4/extension.crx deleted file mode 100644 index c857b6d..0000000 Binary files a/part4/extension.crx and /dev/null differ diff --git a/part4/extension/background.js b/part4/extension/background.js deleted file mode 100644 index e85606f..0000000 --- a/part4/extension/background.js +++ /dev/null @@ -1,162 +0,0 @@ -const domains = [ - "https://www.google.com/", - "https://www.youtube.com/", - "https://www.tmall.com/", - "https://www.qq.com/", - "https://www.baidu.com/", - "https://www.sohu.com/", - "https://www.facebook.com/", - "https://www.taobao.com/", - "https://www.jd.com/", - "https://www.amazon.com/", - "https://www.yahoo.com/", - "https://www.wikipedia.org/", - "https://www.weibo.com/", - "https://sina.com.cn/", - "https://www.zoom.us/", - "http://www.xinhuanet.com/", - "https://www.live.com/", - "https://www.reddit.com/", - "https://www.netflix.com/", - "https://www.microsoft.com/", - "https://www.instagram.com/", - "https://www.office.com/", - "https://panda.tv/", - "https://www.zhanqi.tv/", - "https://www.alipay.com/", - "https://www.bing.com/", - "https://www.csdn.net/", - "https://www.vk.com/", - "https://www.myshopify.com/", - "https://www.naver.com/", - "https://www.okezone.com/", - "https://www.twitch.tv/", - "https://www.twitter.com/", - "https://www.ebay.com/", - "https://www.adobe.com/", - "https://www.tianya.cn/", - "https://www.huanqiu.com/", - "https://www.yy.com/", - "https://www.aliexpress.com/", - "https://www.linkedin.com/", - "https://www.force.com/", - "https://www.aparat.com/", - "https://www.mail.ru/", - "https://www.msn.com/", - "https://www.dropbox.com/", - "https://www.whatsapp.com/", - "https://www.apple.com/", - "https://www.1688.com/", - "https://www.wordpress.com/", - "https://www.canva.com/", - "https://www.indeed.com/", - "https://www.stackoverflow.com/", - "https://www.ok.ru/", - "https://www.so.com/", - "https://www.chase.com/", - "https://www.imdb.com/", - "https://www.slack.com/", - "https://www.etsy.com/", - "https://www.tiktok.com/", - "https://www.booking.com/", - "https://www.babytree.com/", - "https://rakuten.co.jp/", - "https://www.salesforce.com/", - "https://www.spotify.com/", - "https://www.tribunnews.com/", - "https://www.fandom.com/", - "https://www.tradingview.com/", - "https://www.github.com/", - "https://www.haosou.com/", - "https://www.paypal.com/", - "https://www.cnblogs.com/", - "https://www.alibaba.com/", - "https://www.kompas.com/", - "https://gome.com.cn/", - "https://www.walmart.com/", - "https://www.roblox.com/", - "https://www.6.cn/", - "https://www.zillow.com/", - "https://www.godaddy.com/", - "https://www.imgur.com/", - "https://www.espn.com/", - "https://www.bbc.com/", - "https://www.hao123.com/", - "https://www.pikiran-rakyat.com/", - "https://www.grammarly.com/", - "https://www.cnn.com/", - "https://www.telegram.org/", - "https://www.tumblr.com/", - "https://www.nytimes.com/", - "https://www.detik.com/", - "https://www.wetransfer.com/", - "https://www.savefrom.net/", - "https://www.rednet.cn/", - "https://www.freepik.com/", - "https://www.ilovepdf.com/", - "https://www.daum.net/", - "https://www.pinterest.com/", - "https://www.primevideo.com/", - "https://www.intuit.com/", - "https://www.medium.com/", -]; - -const loadTime = 5000; -let loading = false; -let startTime = 0; - -function randomPing() { - const controller = new AbortController(); - const id = setTimeout( - () => controller.abort(), - loadTime - (performance.now() - startTime) - ); - - fetch( - domains[Math.floor(Math.random() * domains.length)] + - "?" + - new Date().getTime(), - { - signal: controller.signal, - } - ); -} - -function activityBurst() { - switch (Math.floor(Math.random() * 2)) { - case 0: - let start = performance.now(); - let counter = 0; - - while (performance.now() - start < 5) { - counter += 1; - } - - console.log(counter); - break; - case 1: - randomPing(); - break; - } -} - -chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { - if (changeInfo.status === "loading") { - if (loading) { - return; - } - - startTime = performance.now(); - loading = true; - - for (let i = 0; i < 20; i++) { - randomPing(); - } - - for (let i = 0; i < loadTime / 10; i++) { - setTimeout(activityBurst, Math.random() * loadTime); - } - } else if (changeInfo.status === "complete") { - loading = false; - } -}); diff --git a/part4/extension/manifest.json b/part4/extension/manifest.json deleted file mode 100644 index cd43bd6..0000000 --- a/part4/extension/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "Lab Countermeasure", - "version": "1.0", - "manifest_version": 3, - "background": { - "service_worker": "background.js" - }, - "action": {}, - "host_permissions": ["*://*/*"] -} diff --git a/part4/index.html b/part4/index.html deleted file mode 120000 index 79c5d6f..0000000 --- a/part4/index.html +++ /dev/null @@ -1 +0,0 @@ -../index.html \ No newline at end of file diff --git a/part4/worker.js b/part4/worker.js deleted file mode 100644 index 13eb53c..0000000 --- a/part4/worker.js +++ /dev/null @@ -1,32 +0,0 @@ -// Duration of your trace, in milliseconds -let TRACE_LENGTH; - -// Array of length TRACE_LENGTH with your trace's values -let T; - -// Value of performance.now() when you started recording your trace -let start; - -function record() { - // Create empty array for saving trace values - T = new Array(TRACE_LENGTH); - - // Fill array with -1 so we can be sure memory is allocated - T.fill(-1, 0, T.length); - - // Save start timestamp - start = performance.now(); - - // TODO (Exercise 4-4): Copy your solution from part 3. Optionally make changes to your part 3 solution if you need to. - - // Once done recording, send result to main thread - postMessage(JSON.stringify(T)); -} - -// DO NOT MODIFY BELOW THIS LINE -- PROVIDED BY COURSE STAFF -self.onmessage = (e) => { - if (e.data.type === "start") { - TRACE_LENGTH = e.data.trace_length; - setTimeout(record, 0); - } -};