From c681c45ddd6cecfa3b83984336699b410638b8af Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Thu, 27 Feb 2025 20:52:09 -0800 Subject: [PATCH 01/14] get container ready for Lua code --- .devcontainer/devcontainer.json | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d43136b..1de1dd3 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,9 +1,16 @@ { - "onCreateCommand": "sudo apt-get update && sudo apt-get -y install libldap2-dev libsasl2-dev && pip3 install pyOpenSSL && pip3 install -r requirements.txt", + "onCreateCommand": "sudo apt-get update && sudo apt-get -y install libldap2-dev libsasl2-dev lua5.4 && pip3 install pyOpenSSL && pip3 install -r requirements.txt", "customizations": { "vscode": { - "extensions": ["ms-python.python", "ms-python.vscode-pylance", "ms-vscode.cpptools-extension-pack", "redhat.vscode-yaml", "golang.go"] + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-vscode.cpptools-extension-pack", + "redhat.vscode-yaml", + "golang.go", + "sumneko.lua" + ] } }, "postCreateCommand": "npm install --prefix Season-2/Level-3/ Season-2/Level-3/ && npm install --global mocha" -} \ No newline at end of file +} From f6d51b6d2b3e9dd078d5dce8f36682f3dd8df9eb Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Fri, 28 Feb 2025 01:52:47 -0800 Subject: [PATCH 02/14] Made the majority of the hack code --- Season-3/Level-1/code.lua | 29 +++++++++++++++++++++++++++++ Season-3/Level-1/hack.lua | 36 ++++++++++++++++++++++++++++++++++++ Season-3/Level-1/tests.lua | 1 + 3 files changed, 66 insertions(+) create mode 100644 Season-3/Level-1/code.lua create mode 100644 Season-3/Level-1/hack.lua create mode 100644 Season-3/Level-1/tests.lua diff --git a/Season-3/Level-1/code.lua b/Season-3/Level-1/code.lua new file mode 100644 index 0000000..5919866 --- /dev/null +++ b/Season-3/Level-1/code.lua @@ -0,0 +1,29 @@ +-- Welcome to Secure Code Game Season-3/Level-1! +local module = {} + +local secret_key = "I love my mama" + + +--- Generates a bitmap image +-- @param request: The table which we will populate with images +-- @return table: Of the sources now with the generated bitmaps to display +module.generate_bmps = function(request) + local secret_key = "I love my mama" + + if type(request) ~= "table" then + return "Invalid request" + end + for i = 1, #request, 1 do + if type(request[i].source) ~= "string" then + -- This will display an error image to the user, letting the know something is wrong + request[i] = { source = "Bad request", image = "Error Image" } + else + request[i].image = "Cat pictures" + end + end + return request +end + + + +return module diff --git a/Season-3/Level-1/hack.lua b/Season-3/Level-1/hack.lua new file mode 100644 index 0000000..a211116 --- /dev/null +++ b/Season-3/Level-1/hack.lua @@ -0,0 +1,36 @@ +local code = require("code") + +local malicous_code_executed = false + +local malicous_metatable = { + __index = function(og_table, index) + print("[SCRIPT EXECUTING]") + malicous_code_executed = true + local variables = {} + local idx = 1 + while true do + local ln, lv = debug.getlocal(2, idx) + if ln ~= nil then + variables[ln] = lv + else + break + end + idx = 1 + idx + end + + og_table.recieving_payload = variables["secret_key"] + + return "Get PWNED" + end +} + +local odd_request = { { source = "Legit link", image = nil }, nil, { source = "Another legit link", image = nil } } +local malicous_metatable = setmetatable(odd_request, malicous_metatable) +local result = code.generate_bmps(malicous_metatable) + +setmetatable(result, {}) +if result.recieving_payload ~= nil then + print("Malicous payload recieved: ", result.recieving_payload) +end + +print(malicous_code_executed) diff --git a/Season-3/Level-1/tests.lua b/Season-3/Level-1/tests.lua new file mode 100644 index 0000000..4d14cbe --- /dev/null +++ b/Season-3/Level-1/tests.lua @@ -0,0 +1 @@ +local code = require("code") From 912f5d2741df3f276a028f3a3ecdf3c1492c5bf0 Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Sat, 1 Mar 2025 13:20:56 -0800 Subject: [PATCH 03/14] finished the hack codes and tests (not using a test library yet) --- Season-3/Level-1/code.lua | 2 + Season-3/Level-1/hack.lua | 97 ++++++++++++++++++++++++++++---------- Season-3/Level-1/tests.lua | 57 ++++++++++++++++++++++ 3 files changed, 131 insertions(+), 25 deletions(-) diff --git a/Season-3/Level-1/code.lua b/Season-3/Level-1/code.lua index 5919866..bd75ba8 100644 --- a/Season-3/Level-1/code.lua +++ b/Season-3/Level-1/code.lua @@ -8,7 +8,9 @@ local secret_key = "I love my mama" -- @param request: The table which we will populate with images -- @return table: Of the sources now with the generated bitmaps to display module.generate_bmps = function(request) + -- Do not delete local secret_key = "I love my mama" + -- End of do not delete if type(request) ~= "table" then return "Invalid request" diff --git a/Season-3/Level-1/hack.lua b/Season-3/Level-1/hack.lua index a211116..b4808d9 100644 --- a/Season-3/Level-1/hack.lua +++ b/Season-3/Level-1/hack.lua @@ -1,36 +1,83 @@ local code = require("code") -local malicous_code_executed = false - -local malicous_metatable = { - __index = function(og_table, index) - print("[SCRIPT EXECUTING]") - malicous_code_executed = true - local variables = {} - local idx = 1 - while true do - local ln, lv = debug.getlocal(2, idx) - if ln ~= nil then - variables[ln] = lv - else - break + +local indexHookExploit = function() + local malicous_code_executed = false + + local malicous_metatable = { + __metatable = {}, + __index = function(og_table, index) + print("[SCRIPT EXECUTING]") + malicous_code_executed = true + local variables = {} + local idx = 1 + while true do + local ln, lv = debug.getlocal(2, idx) + if ln ~= nil then + variables[ln] = lv + else + break + end + idx = 1 + idx end - idx = 1 + idx + + og_table.recieving_payload = variables["secret_key"] + + return "Get PWNED" end + } - og_table.recieving_payload = variables["secret_key"] + local odd_request = { { source = "Legit link", image = nil }, nil, { source = "Another legit link", image = nil } } + local malicous_metatable = setmetatable(odd_request, malicous_metatable) + local result = code.generate_bmps(malicous_metatable) - return "Get PWNED" + if result.recieving_payload ~= nil then + print("Malicous payload recieved: ", result.recieving_payload) end -} -local odd_request = { { source = "Legit link", image = nil }, nil, { source = "Another legit link", image = nil } } -local malicous_metatable = setmetatable(odd_request, malicous_metatable) -local result = code.generate_bmps(malicous_metatable) + print(not malicous_code_executed) +end + +local lengthHookExploit = function() + local malicous_code_executed = false + + local malicous_metatable = { + __metatable = {}, + __len = function(og_table) + print("[SCRIPT EXECUTING]") + malicous_code_executed = true + local variables = {} + local idx = 1 + while true do + local ln, lv = debug.getlocal(2, idx) + if ln ~= nil then + variables[ln] = lv + else + break + end + idx = 1 + idx + end + + og_table.recieving_payload = variables["secret_key"] + + return 3 + end + } + + local odd_request = { + { source = "Legit link", image = nil }, + { source = "Another legit link", image = nil }, + { source = "Another legit boring link", image = nil } + } + local malicous_metatable = setmetatable(odd_request, malicous_metatable) + local result = code.generate_bmps(malicous_metatable) + + if result.recieving_payload ~= nil then + print("Malicous payload recieved: ", result.recieving_payload) + end -setmetatable(result, {}) -if result.recieving_payload ~= nil then - print("Malicous payload recieved: ", result.recieving_payload) + print(not malicous_code_executed) end -print(malicous_code_executed) +lengthHookExploit() +indexHookExploit() diff --git a/Season-3/Level-1/tests.lua b/Season-3/Level-1/tests.lua index 4d14cbe..bf53af2 100644 --- a/Season-3/Level-1/tests.lua +++ b/Season-3/Level-1/tests.lua @@ -1 +1,58 @@ local code = require("code") + +local does_it_return_cats = function() + local our_normal_request = { + { source = "Legit link", image = nil }, + { source = "Another legit link", image = nil }, + { source = "Another legit boring link", image = nil } + } + + local expected_result = { + { source = "Legit link", image = "Cat pictures" }, + { source = "Another legit link", image = "Cat pictures" }, + { source = "Another legit boring link", image = "Cat pictures" } + } + + local result = code.generate_bmps(our_normal_request) + + local isValid = true + + + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end + end + + print(isValid) +end + +local does_it_hanlde_malformed_requests = function() + local our_normal_request = { + { source = "Legit link", image = nil }, + { source = 1, image = nil }, + { source = "legit boring link", image = nil } + } + + local expected_result = { + { source = "Legit link", image = "Cat pictures" }, + { source = "Bad request", image = "Error Image" }, + { source = "legit boring link", image = "Cat pictures" } + } + + local result = code.generate_bmps(our_normal_request) + + local isValid = true + + + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end + end + + print(isValid) +end + +does_it_return_cats() +does_it_hanlde_malformed_requests() From 610d2cb5a56721467d8a64d6aa5d3614f259d304 Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Sat, 1 Mar 2025 13:31:39 -0800 Subject: [PATCH 04/14] Made solution --- Season-3/Level-1/hack.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Season-3/Level-1/hack.lua b/Season-3/Level-1/hack.lua index b4808d9..6283191 100644 --- a/Season-3/Level-1/hack.lua +++ b/Season-3/Level-1/hack.lua @@ -31,7 +31,7 @@ local indexHookExploit = function() local malicous_metatable = setmetatable(odd_request, malicous_metatable) local result = code.generate_bmps(malicous_metatable) - if result.recieving_payload ~= nil then + if type(result) == "table" and result.recieving_payload ~= nil then print("Malicous payload recieved: ", result.recieving_payload) end @@ -72,7 +72,7 @@ local lengthHookExploit = function() local malicous_metatable = setmetatable(odd_request, malicous_metatable) local result = code.generate_bmps(malicous_metatable) - if result.recieving_payload ~= nil then + if type(result) == "table" and result.recieving_payload ~= nil then print("Malicous payload recieved: ", result.recieving_payload) end From e119b0bc54d1bc022975fecdecd866dd3f2e0230 Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Sat, 1 Mar 2025 13:31:43 -0800 Subject: [PATCH 05/14] Completed solution, TODO: Finish comments and use test library --- Season-3/Level-1/solution/solution.lua | 40 ++++++ Season-3/Level-1/solution/solution_test.lua | 141 ++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 Season-3/Level-1/solution/solution.lua create mode 100644 Season-3/Level-1/solution/solution_test.lua diff --git a/Season-3/Level-1/solution/solution.lua b/Season-3/Level-1/solution/solution.lua new file mode 100644 index 0000000..90b548b --- /dev/null +++ b/Season-3/Level-1/solution/solution.lua @@ -0,0 +1,40 @@ +-- Welcome to Secure Code Game Season-3/Level-1! +local module = {} + +local secret_key = "I love my mama" + + +--- Generates a bitmap image +-- @param request: The table which we will populate with images +-- @return table: Of the sources now with the generated bitmaps to display +module.generate_bmps = function(request) + -- Do not delete + local secret_key = "I love my mama" + -- End of do not delete + + if type(request) ~= "table" then + return "Invalid request" + end + + local isNotMalicous, errVal = pcall(function() + setmetatable(request, {}) + end) + + if not isNotMalicous then + return "Invalid request" + end + + for i = 1, #request, 1 do + if type(request[i].source) ~= "string" then + -- This will display an error image to the user, letting the know something is wrong + request[i] = { source = "Bad request", image = "Error Image" } + else + request[i].image = "Cat pictures" + end + end + return request +end + + + +return module diff --git a/Season-3/Level-1/solution/solution_test.lua b/Season-3/Level-1/solution/solution_test.lua new file mode 100644 index 0000000..c4e60ae --- /dev/null +++ b/Season-3/Level-1/solution/solution_test.lua @@ -0,0 +1,141 @@ +local code = require("solution") + + +local indexHookExploit = function() + local malicous_code_executed = false + + local malicous_metatable = { + __metatable = {}, + __index = function(og_table, index) + print("[SCRIPT EXECUTING]") + malicous_code_executed = true + local variables = {} + local idx = 1 + while true do + local ln, lv = debug.getlocal(2, idx) + if ln ~= nil then + variables[ln] = lv + else + break + end + idx = 1 + idx + end + + og_table.recieving_payload = variables["secret_key"] + + return "Get PWNED" + end + } + + local odd_request = { { source = "Legit link", image = nil }, nil, { source = "Another legit link", image = nil } } + local malicous_metatable = setmetatable(odd_request, malicous_metatable) + local result = code.generate_bmps(malicous_metatable) + + if type(result) == "table" and result.recieving_payload ~= nil then + print("Malicous payload recieved: ", result.recieving_payload) + end + + print(not malicous_code_executed) +end + +local lengthHookExploit = function() + local malicous_code_executed = false + + local malicous_metatable = { + __metatable = {}, + __len = function(og_table) + print("[SCRIPT EXECUTING]") + malicous_code_executed = true + local variables = {} + local idx = 1 + while true do + local ln, lv = debug.getlocal(2, idx) + if ln ~= nil then + variables[ln] = lv + else + break + end + idx = 1 + idx + end + + og_table.recieving_payload = variables["secret_key"] + + return 3 + end + } + + local odd_request = { + { source = "Legit link", image = nil }, + { source = "Another legit link", image = nil }, + { source = "Another legit boring link", image = nil } + } + local malicous_metatable = setmetatable(odd_request, malicous_metatable) + local result = code.generate_bmps(malicous_metatable) + + if type(result) == "table" and result.recieving_payload ~= nil then + print("Malicous payload recieved: ", result.recieving_payload) + end + + print(not malicous_code_executed) +end + + +local does_it_return_cats = function() + local our_normal_request = { + { source = "Legit link", image = nil }, + { source = "Another legit link", image = nil }, + { source = "Another legit boring link", image = nil } + } + + local expected_result = { + { source = "Legit link", image = "Cat pictures" }, + { source = "Another legit link", image = "Cat pictures" }, + { source = "Another legit boring link", image = "Cat pictures" } + } + + local result = code.generate_bmps(our_normal_request) + + local isValid = true + + + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end + end + + print(isValid) +end + +local does_it_hanlde_malformed_requests = function() + local our_normal_request = { + { source = "Legit link", image = nil }, + { source = 1, image = nil }, + { source = "legit boring link", image = nil } + } + + local expected_result = { + { source = "Legit link", image = "Cat pictures" }, + { source = "Bad request", image = "Error Image" }, + { source = "legit boring link", image = "Cat pictures" } + } + + local result = code.generate_bmps(our_normal_request) + + local isValid = true + + + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end + end + + print(isValid) +end + +does_it_return_cats() +does_it_hanlde_malformed_requests() + +lengthHookExploit() +indexHookExploit() From 483028593cbd59b38071a4e354c070849a82a0aa Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Sat, 1 Mar 2025 13:57:36 -0800 Subject: [PATCH 06/14] Pretty much finished just need to know how they'd like it to be tested --- Season-3/Level-1/code.lua | 12 ++++++++++-- Season-3/Level-1/hack.lua | 6 ++++++ Season-3/Level-1/hint-1.txt | 4 ++++ Season-3/Level-1/hint-2.txt | 1 + Season-3/Level-1/solution/solution.lua | 11 +++++++++-- Season-3/Level-1/solution/solution_test.lua | 8 ++++++++ Season-3/Level-1/tests.lua | 5 +++++ 7 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 Season-3/Level-1/hint-1.txt create mode 100644 Season-3/Level-1/hint-2.txt diff --git a/Season-3/Level-1/code.lua b/Season-3/Level-1/code.lua index bd75ba8..c8749af 100644 --- a/Season-3/Level-1/code.lua +++ b/Season-3/Level-1/code.lua @@ -1,7 +1,15 @@ -- Welcome to Secure Code Game Season-3/Level-1! -local module = {} -local secret_key = "I love my mama" +-- Follow the instructions below to get started: + +-- 1. tests.lua is passing but the code is vulnerable +-- 2. Review the code. Can you spot the bugs(s)? +-- 3. Fix the code.lua, but ensure that tests.lua passes +-- 4. Run hack.lua and if passing then CONGRATS! +-- 5. If stuck then read the hint +-- 6. Compare your solution with solution/solution.go + +local module = {} --- Generates a bitmap image diff --git a/Season-3/Level-1/hack.lua b/Season-3/Level-1/hack.lua index 6283191..aa72740 100644 --- a/Season-3/Level-1/hack.lua +++ b/Season-3/Level-1/hack.lua @@ -1,3 +1,9 @@ +-- This file exploits the vulnerabilities in code. Running this file will fail initially +-- (it contains failing tests). As all other levels, your goal is to get this file to pass. + +-- Run them by opening a terminal and running the following: +-- $ (cd Season-3/Level-1/ && lua hack.lua) + local code = require("code") diff --git a/Season-3/Level-1/hint-1.txt b/Season-3/Level-1/hint-1.txt new file mode 100644 index 0000000..06ac31e --- /dev/null +++ b/Season-3/Level-1/hint-1.txt @@ -0,0 +1,4 @@ +Seems like when we index the table something else happens. +What is hack.lua doing to enable it to run the code? + +Try to solve it without hint 2 \ No newline at end of file diff --git a/Season-3/Level-1/hint-2.txt b/Season-3/Level-1/hint-2.txt new file mode 100644 index 0000000..680cf1e --- /dev/null +++ b/Season-3/Level-1/hint-2.txt @@ -0,0 +1 @@ +This has got to do with metatables. Maybe read the docs to find out how we could detect if a metatable is set? \ No newline at end of file diff --git a/Season-3/Level-1/solution/solution.lua b/Season-3/Level-1/solution/solution.lua index 90b548b..18665f8 100644 --- a/Season-3/Level-1/solution/solution.lua +++ b/Season-3/Level-1/solution/solution.lua @@ -1,8 +1,15 @@ -- Welcome to Secure Code Game Season-3/Level-1! -local module = {} -local secret_key = "I love my mama" +--[[Attempt to sanitize the request by calling setmetatable on it + We know that if the __metatable property is set setmetatable will fail + thus why we make a protected call, and if it succeeds we can continue. + If it fails we know someone is trying to do a metatable exploit +--]] + +-- Full solution: + +local module = {} --- Generates a bitmap image -- @param request: The table which we will populate with images diff --git a/Season-3/Level-1/solution/solution_test.lua b/Season-3/Level-1/solution/solution_test.lua index c4e60ae..fbeb457 100644 --- a/Season-3/Level-1/solution/solution_test.lua +++ b/Season-3/Level-1/solution/solution_test.lua @@ -1,3 +1,11 @@ +-- Run solution_test.lua by following the instructions below: + +-- This file is a copy of code_test.go and hack_test.go +-- It tests the solution for failing and passing payloads + +-- Run them by opening a terminal and running the following: +-- $ (cd Season-3/Level-1/solution && lua solution_test.lua) + local code = require("solution") diff --git a/Season-3/Level-1/tests.lua b/Season-3/Level-1/tests.lua index bf53af2..5726d17 100644 --- a/Season-3/Level-1/tests.lua +++ b/Season-3/Level-1/tests.lua @@ -1,3 +1,8 @@ +-- This file contains passing tests. + +-- Run them by opening a terminal and running the following: +-- $ (cd Season-3/Level-1/ && lua tests.lua) + local code = require("code") local does_it_return_cats = function() From d7f6a732cc3fc4c70da8d5850480a697922afcd3 Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Sat, 1 Mar 2025 14:14:28 -0800 Subject: [PATCH 07/14] Added Lua to list of languages to test in codeql analysis --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6abb0af..2c20514 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - language: ['python', 'go', 'javascript'] + language: ["python", "go", "javascript", "lua"] steps: - name: Checkout repository From 8440d02e648286c7f6195cfc5126c5c88c4a6db7 Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Sat, 1 Mar 2025 14:18:12 -0800 Subject: [PATCH 08/14] undo changes as lua is not supported by codeql --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2c20514..58b2cc0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -18,7 +18,7 @@ jobs: strategy: fail-fast: false matrix: - language: ["python", "go", "javascript", "lua"] + language: ["python", "go", "javascript"] steps: - name: Checkout repository From 68771523d4f8f55299a545ec000b68673cb942de Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Mon, 3 Mar 2025 13:27:53 -0800 Subject: [PATCH 09/14] finished level --- Season-3/Level-1/solution/solution.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Season-3/Level-1/solution/solution.lua b/Season-3/Level-1/solution/solution.lua index 18665f8..0cf9a99 100644 --- a/Season-3/Level-1/solution/solution.lua +++ b/Season-3/Level-1/solution/solution.lua @@ -32,6 +32,14 @@ module.generate_bmps = function(request) end for i = 1, #request, 1 do + local isNotMalicous, errVal = pcall(function() + setmetatable(request[i], {}) + end) + + if not isNotMalicous then + return "Invalid request" + end + if type(request[i].source) ~= "string" then -- This will display an error image to the user, letting the know something is wrong request[i] = { source = "Bad request", image = "Error Image" } From 45e231c49b4215602ead7506e865d2d441070b15 Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Tue, 4 Mar 2025 20:12:29 -0800 Subject: [PATCH 10/14] Moved to 4 and changed secret_key to a SHA1 hash of ABCD --- {Season-3 => Season-4}/Level-1/code.lua | 4 ++-- {Season-3 => Season-4}/Level-1/hack.lua | 0 {Season-3 => Season-4}/Level-1/hint-1.txt | 0 {Season-3 => Season-4}/Level-1/hint-2.txt | 0 {Season-3 => Season-4}/Level-1/solution/solution.lua | 4 ++-- {Season-3 => Season-4}/Level-1/solution/solution_test.lua | 0 {Season-3 => Season-4}/Level-1/tests.lua | 0 7 files changed, 4 insertions(+), 4 deletions(-) rename {Season-3 => Season-4}/Level-1/code.lua (91%) rename {Season-3 => Season-4}/Level-1/hack.lua (100%) rename {Season-3 => Season-4}/Level-1/hint-1.txt (100%) rename {Season-3 => Season-4}/Level-1/hint-2.txt (100%) rename {Season-3 => Season-4}/Level-1/solution/solution.lua (93%) rename {Season-3 => Season-4}/Level-1/solution/solution_test.lua (100%) rename {Season-3 => Season-4}/Level-1/tests.lua (100%) diff --git a/Season-3/Level-1/code.lua b/Season-4/Level-1/code.lua similarity index 91% rename from Season-3/Level-1/code.lua rename to Season-4/Level-1/code.lua index c8749af..2c94d00 100644 --- a/Season-3/Level-1/code.lua +++ b/Season-4/Level-1/code.lua @@ -16,8 +16,8 @@ local module = {} -- @param request: The table which we will populate with images -- @return table: Of the sources now with the generated bitmaps to display module.generate_bmps = function(request) - -- Do not delete - local secret_key = "I love my mama" + -- Do not delete example SHA1 hash + local secret_key = "fb2f85c88567f3c8ce9b799c7c54642d0c7b41f6" -- End of do not delete if type(request) ~= "table" then diff --git a/Season-3/Level-1/hack.lua b/Season-4/Level-1/hack.lua similarity index 100% rename from Season-3/Level-1/hack.lua rename to Season-4/Level-1/hack.lua diff --git a/Season-3/Level-1/hint-1.txt b/Season-4/Level-1/hint-1.txt similarity index 100% rename from Season-3/Level-1/hint-1.txt rename to Season-4/Level-1/hint-1.txt diff --git a/Season-3/Level-1/hint-2.txt b/Season-4/Level-1/hint-2.txt similarity index 100% rename from Season-3/Level-1/hint-2.txt rename to Season-4/Level-1/hint-2.txt diff --git a/Season-3/Level-1/solution/solution.lua b/Season-4/Level-1/solution/solution.lua similarity index 93% rename from Season-3/Level-1/solution/solution.lua rename to Season-4/Level-1/solution/solution.lua index 0cf9a99..b7e92aa 100644 --- a/Season-3/Level-1/solution/solution.lua +++ b/Season-4/Level-1/solution/solution.lua @@ -15,8 +15,8 @@ local module = {} -- @param request: The table which we will populate with images -- @return table: Of the sources now with the generated bitmaps to display module.generate_bmps = function(request) - -- Do not delete - local secret_key = "I love my mama" + -- Do not delete example SHA1 hash + local secret_key = "fb2f85c88567f3c8ce9b799c7c54642d0c7b41f6" -- End of do not delete if type(request) ~= "table" then diff --git a/Season-3/Level-1/solution/solution_test.lua b/Season-4/Level-1/solution/solution_test.lua similarity index 100% rename from Season-3/Level-1/solution/solution_test.lua rename to Season-4/Level-1/solution/solution_test.lua diff --git a/Season-3/Level-1/tests.lua b/Season-4/Level-1/tests.lua similarity index 100% rename from Season-3/Level-1/tests.lua rename to Season-4/Level-1/tests.lua From 276fc012ea4b29904e1051e6c5f32d50287614c6 Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Tue, 4 Mar 2025 21:21:37 -0800 Subject: [PATCH 11/14] Created README.md --- Season-4/README.md | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 Season-4/README.md diff --git a/Season-4/README.md b/Season-4/README.md new file mode 100644 index 0000000..de14568 --- /dev/null +++ b/Season-4/README.md @@ -0,0 +1,77 @@ +# Secure Code Game + +_Welcome to Secure Code Game - Season 4!_ :wave: + +To get started, please follow the 🛠️ set up guide (if you haven't already) from the [welcome page](https://gh.io/securecodegame). + +## Season 4 - Level 1: That's not a Billboard + +_Welcome to Level 1!_ :robot: + +Languages: `Lua` + +### 🚀 Credits + +The author of this level is Abdullah [@TheDarkThief](https://github.com/TheDarkThief). + +You can be next! We welcome contributions for new game levels! Learn more [here](https://github.com/skills/secure-code-game/blob/main/CONTRIBUTING.md). + +### 📝 Storyline + +Your company sells low-powered E-ink displays powered by a small embedded system; they are called E-Boards. Because they are so weak, they send a request to the server with the RSS feeds the user has configured; the server proceeds to generate a bitmap image and returns the request to the board, which will eventually display the images to the user. No one will abuse this right? Do you have what it takes to fix the bug and progress to Level 2? + +### :keyboard: What's in the repo? + +- `code` includes the vulnerable code to be reviewed. +- `hack` exploits the vulnerabilities in `code`. Running `hack.lua` will fail initially, your goal is to get this file to pass. +- `tests.lua` contains the unit tests that should still pass after you have implemented your fix. +- `hint` files offer guidance if you get stuck. We provide 2 hints for this level. +- `solution` offers a working solution. Remember, there are several possible solutions. + +### 🚦 Time to start! + +1. Review the code in `code.lua`. Can you spot the bug(s)? +1. Try to fix the bug. Ensure that unit tests are still passing 🟢. +1. You successfully completed the level when both `hack.lua` and `tests.lua` pass 🟢. +1. If you get stuck, read the hints and try again. +1. Compare your solution with `solution.lua` remember there are multiple solutions. + +If you need assistance, don't hesitate to ask for help in our [GitHub Discussions](https://github.com/skills/secure-code-game/discussions) or on our [Slack](https://gh.io/securitylabslack) in the [#secure-code-game](https://ghsecuritylab.slack.com/archives/C05DH0PSBEZ) channel. + + + +## Finish + +_Congratulations, you've completed the Secure Code Game!_ + +Here's a recap of all the tasks you've accomplished: + +- You practiced secure code principles by spotting and fixing vulnerable patterns in real-world code. +- You assessed your solutions against exploits developed by GitHub Security Lab experts. +- You utilized GitHub code scanning features and understood the security alerts generated against your code. + +### What's next? + +- Follow [GitHub Security Lab](https://twitter.com/ghsecuritylab) for the latest updates and announcements about this course. +- Contribute new levels to the game in 3 simple steps! Read our [Contribution Guideline](https://github.com/skills/secure-code-game/blob/main/CONTRIBUTING.md). +- Share your feedback and ideas in our [Discussions](https://github.com/skills/secure-code-game/discussions) and join our community on [Slack](https://gh.io/securitylabslack). +- [Take another skills course](https://skills.github.com/). +- [Read more about code security](https://docs.github.com/en/code-security). +- To find projects to contribute to, check out [GitHub Explore](https://github.com/explore). + +
+ + + +--- + +Get help: Email us at securitylab-social@github.com • [Review the GitHub status page](https://www.githubstatus.com/) + +© 2024 GitHub • [Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md) • [MIT License](https://gh.io/mit) + +
From 648eeb25fecd3e01f60b304fc076cd338c1422fa Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Tue, 4 Mar 2025 21:23:34 -0800 Subject: [PATCH 12/14] working on using Lua rocks instead of just print statments --- .devcontainer/devcontainer.json | 2 +- Season-4/Level-1/hack.lua | 35 +++++++++++++-------- Season-4/Level-1/solution/solution_test.lua | 26 ++++++++++----- Season-4/Level-1/tests.lua | 25 ++++++++++----- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1de1dd3..ea64762 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "onCreateCommand": "sudo apt-get update && sudo apt-get -y install libldap2-dev libsasl2-dev lua5.4 && pip3 install pyOpenSSL && pip3 install -r requirements.txt", + "onCreateCommand": "sudo apt-get update && sudo apt-get -y install libldap2-dev libsasl2-dev lua5.4 luarocks && pip3 install pyOpenSSL && pip3 install -r requirements.txt && sudo luarocks install busted 2.2.0-1", "customizations": { "vscode": { "extensions": [ diff --git a/Season-4/Level-1/hack.lua b/Season-4/Level-1/hack.lua index aa72740..1911789 100644 --- a/Season-4/Level-1/hack.lua +++ b/Season-4/Level-1/hack.lua @@ -2,7 +2,9 @@ -- (it contains failing tests). As all other levels, your goal is to get this file to pass. -- Run them by opening a terminal and running the following: --- $ (cd Season-3/Level-1/ && lua hack.lua) +-- $ (cd Season-4/Level-1/ && lua hack.lua) + +require 'busted.runner' () local code = require("code") @@ -34,14 +36,14 @@ local indexHookExploit = function() } local odd_request = { { source = "Legit link", image = nil }, nil, { source = "Another legit link", image = nil } } - local malicous_metatable = setmetatable(odd_request, malicous_metatable) - local result = code.generate_bmps(malicous_metatable) + local malicous_request = setmetatable(odd_request, malicous_metatable) + local result = code.generate_bmps(malicous_request) if type(result) == "table" and result.recieving_payload ~= nil then print("Malicous payload recieved: ", result.recieving_payload) end - print(not malicous_code_executed) + return result end local lengthHookExploit = function() @@ -70,20 +72,27 @@ local lengthHookExploit = function() end } - local odd_request = { - { source = "Legit link", image = nil }, - { source = "Another legit link", image = nil }, - { source = "Another legit boring link", image = nil } - } - local malicous_metatable = setmetatable(odd_request, malicous_metatable) - local result = code.generate_bmps(malicous_metatable) + local odd_request = { { source = "Legit link", image = nil }, { source = "boring legit link", image = nil }, { source = "Another legit link", image = nil } } + local malicous_request = setmetatable(odd_request, malicous_metatable) + local result = code.generate_bmps(malicous_request) if type(result) == "table" and result.recieving_payload ~= nil then print("Malicous payload recieved: ", result.recieving_payload) end - print(not malicous_code_executed) + return result end + +-- describe("Length Hook exploit", function() +-- it("result", function() +-- assert.are.equals("Invalid request", lengthHookExploit()) +-- end) +-- end) +-- describe("index Hook exploit", function() +-- it(" result", function() +-- assert.are.equals("Invalid request", indexHookExploit()) +-- end) +-- end) + lengthHookExploit() -indexHookExploit() diff --git a/Season-4/Level-1/solution/solution_test.lua b/Season-4/Level-1/solution/solution_test.lua index fbeb457..592ead7 100644 --- a/Season-4/Level-1/solution/solution_test.lua +++ b/Season-4/Level-1/solution/solution_test.lua @@ -4,7 +4,7 @@ -- It tests the solution for failing and passing payloads -- Run them by opening a terminal and running the following: --- $ (cd Season-3/Level-1/solution && lua solution_test.lua) +-- $ (cd Season-4/Level-1/solution && lua solution_test.lua) local code = require("solution") @@ -106,9 +106,15 @@ local does_it_return_cats = function() local isValid = true - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false + if type(result) ~= "table" then + isValid = false + end + + if isValid then + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end end end @@ -133,9 +139,15 @@ local does_it_hanlde_malformed_requests = function() local isValid = true - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false + if type(result) ~= "table" then + isValid = false + end + + if isValid then + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end end end diff --git a/Season-4/Level-1/tests.lua b/Season-4/Level-1/tests.lua index 5726d17..67fa20c 100644 --- a/Season-4/Level-1/tests.lua +++ b/Season-4/Level-1/tests.lua @@ -1,7 +1,7 @@ -- This file contains passing tests. -- Run them by opening a terminal and running the following: --- $ (cd Season-3/Level-1/ && lua tests.lua) +-- $ (cd Season-4/Level-1/ && lua tests.lua) local code = require("code") @@ -23,9 +23,15 @@ local does_it_return_cats = function() local isValid = true - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false + if type(result) ~= "table" then + isValid = false + end + + if isValid then + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end end end @@ -49,10 +55,15 @@ local does_it_hanlde_malformed_requests = function() local isValid = true + if type(result) ~= "table" then + isValid = false + end - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false + if isValid then + for key, value in pairs(result) do + if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then + isValid = false + end end end From 79e983dd4bb53bfee4b796303798a278c3fb870c Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Fri, 14 Mar 2025 16:54:30 -0700 Subject: [PATCH 13/14] Made requested changes and switched to busted for unit tests --- Season-4/Level-1/code.lua | 17 +- Season-4/Level-1/hack.lua | 80 +++------ Season-4/Level-1/hint-1.txt | 4 - Season-4/Level-1/hint-2.txt | 1 - Season-4/Level-1/hint.txt | 3 + Season-4/Level-1/solution/solution.lua | 26 +-- Season-4/Level-1/solution/solution_test.lua | 175 +++++++------------- Season-4/Level-1/tests.lua | 87 ++++------ 8 files changed, 147 insertions(+), 246 deletions(-) delete mode 100644 Season-4/Level-1/hint-1.txt delete mode 100644 Season-4/Level-1/hint-2.txt create mode 100644 Season-4/Level-1/hint.txt diff --git a/Season-4/Level-1/code.lua b/Season-4/Level-1/code.lua index 2c94d00..77f9218 100644 --- a/Season-4/Level-1/code.lua +++ b/Season-4/Level-1/code.lua @@ -7,14 +7,15 @@ -- 3. Fix the code.lua, but ensure that tests.lua passes -- 4. Run hack.lua and if passing then CONGRATS! -- 5. If stuck then read the hint --- 6. Compare your solution with solution/solution.go +-- 6. Compare your solution with solution/solution.lua local module = {} ---- Generates a bitmap image --- @param request: The table which we will populate with images --- @return table: Of the sources now with the generated bitmaps to display +--- Given a request table with empty image entries it should populate it with bitmap images +--- Currently uses a placeholder of 'PLACEHOLDER IMAGE' +--- @param request table: The request table which we will populate with images +--- @return string|table: Of the sources now with the generated bitmaps to display module.generate_bmps = function(request) -- Do not delete example SHA1 hash local secret_key = "fb2f85c88567f3c8ce9b799c7c54642d0c7b41f6" @@ -25,10 +26,12 @@ module.generate_bmps = function(request) end for i = 1, #request, 1 do if type(request[i].source) ~= "string" then - -- This will display an error image to the user, letting the know something is wrong - request[i] = { source = "Bad request", image = "Error Image" } + --[[ If the user provides us with a bad entry, set the returned image to an error message. + Letting the user know something is wrong --]] + request[i] = { source = "Bad request", image = "ERROR IMAGE" } else - request[i].image = "Cat pictures" + -- This is a placeholder for a bitmap blob generator + request[i].image = "PLACEHOLDER IMAGE" end end return request diff --git a/Season-4/Level-1/hack.lua b/Season-4/Level-1/hack.lua index 1911789..6920591 100644 --- a/Season-4/Level-1/hack.lua +++ b/Season-4/Level-1/hack.lua @@ -9,70 +9,35 @@ require 'busted.runner' () local code = require("code") -local indexHookExploit = function() - local malicous_code_executed = false - +local index_hook_exploit = function() local malicous_metatable = { __metatable = {}, - __index = function(og_table, index) + __index = function(original_table, index) print("[SCRIPT EXECUTING]") - malicous_code_executed = true local variables = {} - local idx = 1 + local varIndex = 1 while true do - local ln, lv = debug.getlocal(2, idx) - if ln ~= nil then - variables[ln] = lv + -- extracts a local variables down 2 from the call stack + local extractedVarIndex, extractedVal = debug.getlocal(2, varIndex) + if extractedVarIndex ~= nil then + variables[extractedVarIndex] = extractedVal else break end - idx = 1 + idx + varIndex = 1 + varIndex end - og_table.recieving_payload = variables["secret_key"] + original_table.success = false + original_table.recieving_payload = variables["secret_key"] - return "Get PWNED" + return "Hook executed" end } - local odd_request = { { source = "Legit link", image = nil }, nil, { source = "Another legit link", image = nil } } - local malicous_request = setmetatable(odd_request, malicous_metatable) - local result = code.generate_bmps(malicous_request) - - if type(result) == "table" and result.recieving_payload ~= nil then - print("Malicous payload recieved: ", result.recieving_payload) - end - - return result -end - -local lengthHookExploit = function() - local malicous_code_executed = false - - local malicous_metatable = { - __metatable = {}, - __len = function(og_table) - print("[SCRIPT EXECUTING]") - malicous_code_executed = true - local variables = {} - local idx = 1 - while true do - local ln, lv = debug.getlocal(2, idx) - if ln ~= nil then - variables[ln] = lv - else - break - end - idx = 1 + idx - end - - og_table.recieving_payload = variables["secret_key"] - - return 3 - end - } + -- Requests shouldn't have nil values but nothing about this table is malicous + local odd_request = { { source = "Link 1", image = nil }, nil, { source = "Link 2", image = nil } } - local odd_request = { { source = "Legit link", image = nil }, { source = "boring legit link", image = nil }, { source = "Another legit link", image = nil } } + -- We exploit the fact that when you try to index a nil value in a table the metatable will be called local malicous_request = setmetatable(odd_request, malicous_metatable) local result = code.generate_bmps(malicous_request) @@ -84,15 +49,8 @@ local lengthHookExploit = function() end --- describe("Length Hook exploit", function() --- it("result", function() --- assert.are.equals("Invalid request", lengthHookExploit()) --- end) --- end) --- describe("index Hook exploit", function() --- it(" result", function() --- assert.are.equals("Invalid request", indexHookExploit()) --- end) --- end) - -lengthHookExploit() +describe("Does it reject a table with hooks", function() + it("it should give us a 'Invalid request'", function() + assert.are.equals("Invalid request", index_hook_exploit()) + end) +end) diff --git a/Season-4/Level-1/hint-1.txt b/Season-4/Level-1/hint-1.txt deleted file mode 100644 index 06ac31e..0000000 --- a/Season-4/Level-1/hint-1.txt +++ /dev/null @@ -1,4 +0,0 @@ -Seems like when we index the table something else happens. -What is hack.lua doing to enable it to run the code? - -Try to solve it without hint 2 \ No newline at end of file diff --git a/Season-4/Level-1/hint-2.txt b/Season-4/Level-1/hint-2.txt deleted file mode 100644 index 680cf1e..0000000 --- a/Season-4/Level-1/hint-2.txt +++ /dev/null @@ -1 +0,0 @@ -This has got to do with metatables. Maybe read the docs to find out how we could detect if a metatable is set? \ No newline at end of file diff --git a/Season-4/Level-1/hint.txt b/Season-4/Level-1/hint.txt new file mode 100644 index 0000000..1bbb6a3 --- /dev/null +++ b/Season-4/Level-1/hint.txt @@ -0,0 +1,3 @@ +Seems like this has to do with a particualarity of how Lua handles indexing a table. +What is hack.lua doing to enable it to run the code? +Maybe we should read the docs about tables: https://www.lua.org/manual/5.3/manual.html#2.1 or https://www.luadocs.com/docs/functions/table diff --git a/Season-4/Level-1/solution/solution.lua b/Season-4/Level-1/solution/solution.lua index b7e92aa..9840301 100644 --- a/Season-4/Level-1/solution/solution.lua +++ b/Season-4/Level-1/solution/solution.lua @@ -1,9 +1,7 @@ --- Welcome to Secure Code Game Season-3/Level-1! - --[[Attempt to sanitize the request by calling setmetatable on it - We know that if the __metatable property is set setmetatable will fail + We know that if the __metatable property is set setmetatable will throw an exception thus why we make a protected call, and if it succeeds we can continue. - If it fails we know someone is trying to do a metatable exploit + If it fails we know someone is trying to do a metatable exploit. --]] @@ -11,9 +9,10 @@ local module = {} ---- Generates a bitmap image --- @param request: The table which we will populate with images --- @return table: Of the sources now with the generated bitmaps to display +--- Given a request table with empty image entries it should populate it with bitmap images +--- Currently uses a placeholder of 'PLACEHOLDER IMAGE' +--- @param request table: The request table which we will populate with images +--- @return string|table: Of the sources now with the generated bitmaps to display module.generate_bmps = function(request) -- Do not delete example SHA1 hash local secret_key = "fb2f85c88567f3c8ce9b799c7c54642d0c7b41f6" @@ -23,6 +22,9 @@ module.generate_bmps = function(request) return "Invalid request" end + --[[ Sanitizes the root table by setting the metatable; if it throws an exception + __metatable was set meaning someone is activly trying to do a metatable hook exploit + --]] local isNotMalicous, errVal = pcall(function() setmetatable(request, {}) end) @@ -30,8 +32,10 @@ module.generate_bmps = function(request) if not isNotMalicous then return "Invalid request" end + -- end of first sanitization for i = 1, #request, 1 do + -- Sanitizes subtables local isNotMalicous, errVal = pcall(function() setmetatable(request[i], {}) end) @@ -41,10 +45,12 @@ module.generate_bmps = function(request) end if type(request[i].source) ~= "string" then - -- This will display an error image to the user, letting the know something is wrong - request[i] = { source = "Bad request", image = "Error Image" } + --[[ If the user provides us with a bad entry, set the returned image to an error message. + Letting the user know something is wrong --]] + request[i] = { source = "Bad request", image = "ERROR IMAGE" } else - request[i].image = "Cat pictures" + -- This is a placeholder for a bitmap blob generator + request[i].image = "PLACEHOLDER IMAGE" end end return request diff --git a/Season-4/Level-1/solution/solution_test.lua b/Season-4/Level-1/solution/solution_test.lua index 592ead7..83bddd7 100644 --- a/Season-4/Level-1/solution/solution_test.lua +++ b/Season-4/Level-1/solution/solution_test.lua @@ -1,161 +1,112 @@ -- Run solution_test.lua by following the instructions below: --- This file is a copy of code_test.go and hack_test.go +-- This file is a copy of tests.lua and hack.lua -- It tests the solution for failing and passing payloads +-- This file should always pass as it is testing the solution -- Run them by opening a terminal and running the following: -- $ (cd Season-4/Level-1/solution && lua solution_test.lua) +require 'busted.runner' () local code = require("solution") -local indexHookExploit = function() - local malicous_code_executed = false - +--- This function sends a malicous request, and returns +--- the result given by the code. +--- @return table: +local index_hook_exploit = function() local malicous_metatable = { __metatable = {}, - __index = function(og_table, index) + __index = function(original_table, index) print("[SCRIPT EXECUTING]") - malicous_code_executed = true local variables = {} - local idx = 1 + local varIndex = 1 while true do - local ln, lv = debug.getlocal(2, idx) - if ln ~= nil then - variables[ln] = lv + -- extracts a local variables down 2 from the call stack + local extractedVarIndex, extractedVal = debug.getlocal(2, varIndex) + if extractedVarIndex ~= nil then + variables[extractedVarIndex] = extractedVal else break end - idx = 1 + idx + varIndex = 1 + varIndex end - og_table.recieving_payload = variables["secret_key"] + original_table.success = false + original_table.recieving_payload = variables["secret_key"] - return "Get PWNED" + return "Hook executed" end } - local odd_request = { { source = "Legit link", image = nil }, nil, { source = "Another legit link", image = nil } } - local malicous_metatable = setmetatable(odd_request, malicous_metatable) - local result = code.generate_bmps(malicous_metatable) - - if type(result) == "table" and result.recieving_payload ~= nil then - print("Malicous payload recieved: ", result.recieving_payload) - end - - print(not malicous_code_executed) -end - -local lengthHookExploit = function() - local malicous_code_executed = false + -- Requests shouldn't have nil values but nothing about this table is malicous + local odd_request = { { source = "Link 1", image = nil }, nil, { source = "Link 2", image = nil } } - local malicous_metatable = { - __metatable = {}, - __len = function(og_table) - print("[SCRIPT EXECUTING]") - malicous_code_executed = true - local variables = {} - local idx = 1 - while true do - local ln, lv = debug.getlocal(2, idx) - if ln ~= nil then - variables[ln] = lv - else - break - end - idx = 1 + idx - end - - og_table.recieving_payload = variables["secret_key"] - - return 3 - end - } - - local odd_request = { - { source = "Legit link", image = nil }, - { source = "Another legit link", image = nil }, - { source = "Another legit boring link", image = nil } - } - local malicous_metatable = setmetatable(odd_request, malicous_metatable) - local result = code.generate_bmps(malicous_metatable) + -- We exploit the fact that when you try to index a nil value in a table the metatable will be called + local malicous_request = setmetatable(odd_request, malicous_metatable) + local result = code.generate_bmps(malicous_request) if type(result) == "table" and result.recieving_payload ~= nil then print("Malicous payload recieved: ", result.recieving_payload) end - print(not malicous_code_executed) + return result end -local does_it_return_cats = function() +-- Given a normal request does it return the proper placeholder image +local does_it_handle_requests = function() local our_normal_request = { - { source = "Legit link", image = nil }, - { source = "Another legit link", image = nil }, - { source = "Another legit boring link", image = nil } - } - - local expected_result = { - { source = "Legit link", image = "Cat pictures" }, - { source = "Another legit link", image = "Cat pictures" }, - { source = "Another legit boring link", image = "Cat pictures" } + { source = "Link 1", image = nil }, + { source = "Link 2", image = nil }, + { source = "Link 3", image = nil } } local result = code.generate_bmps(our_normal_request) - local isValid = true - - - if type(result) ~= "table" then - isValid = false - end - - if isValid then - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false - end - end - end - - print(isValid) + return result end + +-- Given a malformed request does it handle it gracefully local does_it_hanlde_malformed_requests = function() local our_normal_request = { - { source = "Legit link", image = nil }, - { source = 1, image = nil }, - { source = "legit boring link", image = nil } + { source = "Link 1", image = nil }, + { source = 1, image = nil }, + { source = "Link 3", image = nil } } - local expected_result = { - { source = "Legit link", image = "Cat pictures" }, - { source = "Bad request", image = "Error Image" }, - { source = "legit boring link", image = "Cat pictures" } - } - - local result = code.generate_bmps(our_normal_request) - local isValid = true - - - if type(result) ~= "table" then - isValid = false - end - if isValid then - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false - end - end - end + local result = code.generate_bmps(our_normal_request) - print(isValid) + return result end -does_it_return_cats() -does_it_hanlde_malformed_requests() - -lengthHookExploit() -indexHookExploit() +describe("Does it handle requests properly", function() + it("should return a populated table", function() + local expected_result = { + { source = "Link 1", image = "PLACEHOLDER IMAGE" }, + { source = "Link 2", image = "PLACEHOLDER IMAGE" }, + { source = "Link 3", image = "PLACEHOLDER IMAGE" } + } + assert.are.same(expected_result, does_it_handle_requests()) + end) +end) + +describe("Does it handle malformed requests properly", function() + it("should return a populated table with a bad image entry", function() + local expected_result = { + { source = "Link 1", image = "PLACEHOLDER IMAGE" }, + { source = "Bad request", image = "ERROR IMAGE" }, + { source = "Link 3", image = "PLACEHOLDER IMAGE" } + } + assert.are.same(expected_result, does_it_hanlde_malformed_requests()) + end) +end) + +describe("Does it reject a table with hooks", function() + it("it should give us a 'Invalid request'", function() + assert.are.equals("Invalid request", index_hook_exploit()) + end) +end) diff --git a/Season-4/Level-1/tests.lua b/Season-4/Level-1/tests.lua index 67fa20c..cc08c2e 100644 --- a/Season-4/Level-1/tests.lua +++ b/Season-4/Level-1/tests.lua @@ -3,72 +3,57 @@ -- Run them by opening a terminal and running the following: -- $ (cd Season-4/Level-1/ && lua tests.lua) +require 'busted.runner' () local code = require("code") -local does_it_return_cats = function() - local our_normal_request = { - { source = "Legit link", image = nil }, - { source = "Another legit link", image = nil }, - { source = "Another legit boring link", image = nil } - } - local expected_result = { - { source = "Legit link", image = "Cat pictures" }, - { source = "Another legit link", image = "Cat pictures" }, - { source = "Another legit boring link", image = "Cat pictures" } +-- Given a normal request does it return the proper placeholder image +local does_it_handle_requests = function() + local our_normal_request = { + { source = "Link 1", image = nil }, + { source = "Link 2", image = nil }, + { source = "Link 3", image = nil } } local result = code.generate_bmps(our_normal_request) - local isValid = true - - - if type(result) ~= "table" then - isValid = false - end - - if isValid then - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false - end - end - end - - print(isValid) + return result end + +-- Given a malformed request does it handle it gracefully local does_it_hanlde_malformed_requests = function() local our_normal_request = { - { source = "Legit link", image = nil }, - { source = 1, image = nil }, - { source = "legit boring link", image = nil } - } - - local expected_result = { - { source = "Legit link", image = "Cat pictures" }, - { source = "Bad request", image = "Error Image" }, - { source = "legit boring link", image = "Cat pictures" } + { source = "Link 1", image = nil }, + { source = 1, image = nil }, + { source = "Link 3", image = nil } } - local result = code.generate_bmps(our_normal_request) - - local isValid = true - if type(result) ~= "table" then - isValid = false - end - if isValid then - for key, value in pairs(result) do - if not (value.source == expected_result[key].source and value.image == expected_result[key].image) then - isValid = false - end - end - end + local result = code.generate_bmps(our_normal_request) - print(isValid) + return result end -does_it_return_cats() -does_it_hanlde_malformed_requests() +describe("Does it handle requests properly", function() + it("should return a populated table", function() + local expected_result = { + { source = "Link 1", image = "PLACEHOLDER IMAGE" }, + { source = "Link 2", image = "PLACEHOLDER IMAGE" }, + { source = "Link 3", image = "PLACEHOLDER IMAGE" } + } + assert.are.same(expected_result, does_it_handle_requests()) + end) +end) + +describe("Does it handle malformed requests properly", function() + it("should return a populated table with a bad image entry", function() + local expected_result = { + { source = "Link 1", image = "PLACEHOLDER IMAGE" }, + { source = "Bad request", image = "ERROR IMAGE" }, + { source = "Link 3", image = "PLACEHOLDER IMAGE" } + } + assert.are.same(expected_result, does_it_hanlde_malformed_requests()) + end) +end) From e3427f638c9d2f3f076d20ccc9aed08e31b2fa2c Mon Sep 17 00:00:00 2001 From: TheDarkThief Date: Fri, 14 Mar 2025 17:10:15 -0700 Subject: [PATCH 14/14] One comment --- Season-4/Level-1/hack.lua | 3 +++ Season-4/Level-1/solution/solution_test.lua | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Season-4/Level-1/hack.lua b/Season-4/Level-1/hack.lua index 6920591..e93092f 100644 --- a/Season-4/Level-1/hack.lua +++ b/Season-4/Level-1/hack.lua @@ -9,6 +9,9 @@ require 'busted.runner' () local code = require("code") +--- This function sends a malicous request, and returns +--- the result given by the code. +--- @return table | string: the resulting response local index_hook_exploit = function() local malicous_metatable = { __metatable = {}, diff --git a/Season-4/Level-1/solution/solution_test.lua b/Season-4/Level-1/solution/solution_test.lua index 83bddd7..0800bdf 100644 --- a/Season-4/Level-1/solution/solution_test.lua +++ b/Season-4/Level-1/solution/solution_test.lua @@ -13,7 +13,7 @@ local code = require("solution") --- This function sends a malicous request, and returns --- the result given by the code. ---- @return table: +--- @return table | string: the resulting response local index_hook_exploit = function() local malicous_metatable = { __metatable = {},