From 4b77784e134de1505e9bc6cefbc1040c42535a1c Mon Sep 17 00:00:00 2001 From: Sir AppSec Date: Sat, 7 Sep 2024 23:23:00 +0300 Subject: [PATCH 1/2] Introduce hashing without salt --- README.md | 31 ++++++-- lua/hacker-helper.lua | 90 ++++++++++++++++++++++ lua/hacker-helper/selection_util.lua | 58 ++++++++++++++ tests/hacker-helper/hacker_helper_spec.lua | 64 +++++++++++++++ 4 files changed, 235 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 10e7735..ba9216c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ sudo apt install luarocks -y sudo luarocks install luasocket sudo luarocks install lua-zlib sudo luarocks install luabitop +sudo luarocks install bcrypt +sudo pip install bcrypt argon2-cffi +sudo apt-get install libssl-dev +sudo luarocks install luacrypto + ``` ## Using it @@ -28,21 +33,31 @@ return { prefix = "r", -- Change base prefix to r keys = { run_exec = "e", -- re (Execute Command in Terminal) + encode_prefix = "de", -- rde (Encode Group) - decode_prefix = "d", -- rd (Decode Group) - encode_url = "u", -- rdeu (URL Encode) - decode_url = "u", -- rdu (URL Decode) - encode_base64 = "b", -- rdeb (Base64 Encode) - encode_html = "h", -- rdeh (HTML Encode) - decode_html = "h", -- rdh (HTML Decode) - encode_ascii_hex = "x", -- rdex (ASCII Hex Encode) - decode_ascii_hex = "x", -- rdx (ASCII Hex Decode) + decode_prefix = "d", -- rd (Decode Group) + encode_url = "u", -- rdeu (URL Encode) + hash_prefix = "c", -- rc (Hash Group) + + decode_url = "u", -- rdu (URL Decode) + encode_base64 = "b", -- rdeb (Base64 Encode) + decode_base64 = "b", -- rdb (Base64 Decode) + encode_html = "h", -- rdeh (HTML Encode) + decode_html = "h", -- rdh (HTML Decode) + encode_ascii_hex = "x", -- rdex (ASCII Hex Encode) + decode_ascii_hex = "x", -- rdx (ASCII Hex Decode) encode_gzip = "g", -- rdeg (Gzip Encode) decode_gzip = "g", -- rdg (Gzip Decode) encode_binary = "i", -- rdei (Binary Encode) decode_binary = "i", -- rdi (Binary Decode) encode_octal = "o", -- rdeo (Octal Encode) decode_octal = "o", -- rdo (Octal Decode) + hash_md5 = "m", -- rcm (MD5 Hash) + hash_sha1 = "s", -- rcs (SHA-1 Hash) + hash_sha256 = "S", -- rcS (SHA-256 Hash) + hash_crc32 = "c", -- rcC (CRC32 Hash) + hash_scrypt = "y", -- rcy (Scrypt Hash) + hash_bcrypt = "b", -- rcb (Bcrypt Hash) }, }, }, diff --git a/lua/hacker-helper.lua b/lua/hacker-helper.lua index b69af42..a5f2015 100644 --- a/lua/hacker-helper.lua +++ b/lua/hacker-helper.lua @@ -54,9 +54,12 @@ local config = { prefix = "r", -- Default prefix for Hacker Helper keys = { run_exec = "e", -- Default mapping for executing in terminal + encode_prefix = "de", -- rde (Encode Group) decode_prefix = "d", -- rd (Decode Group) encode_url = "u", -- rdeu (URL Encode) + hash_prefix = "c", -- rc (Hash Group) + decode_url = "u", -- rdu (URL Decode) encode_base64 = "b", -- rdeb (Base64 Encode) decode_base64 = "b", -- rdb (Base64 Decode) @@ -70,6 +73,12 @@ local config = { decode_binary = "i", -- rdi (Binary Decode) encode_octal = "o", -- rdeo (Octal Encode) decode_octal = "o", -- rdo (Octal Decode) + hash_md5 = "m", -- rcm (MD5 Hash) + hash_sha1 = "s", -- rcs (SHA-1 Hash) + hash_sha256 = "S", -- rcS (SHA-256 Hash) + hash_crc32 = "c", -- rcC (CRC32 Hash) + hash_scrypt = "y", -- rcy (Scrypt Hash) + hash_bcrypt = "b", -- rcb (Bcrypt Hash) }, opt = "Hello!", } @@ -216,6 +225,48 @@ vim.keymap.set("v", M.config.prefix .. M.config.keys.decode_prefix .. M.config.k end) end, { noremap = true, silent = true, desc = "Octal Decode" }) +-- MD5 Hash +vim.keymap.set("v", M.config.prefix .. M.config.keys.hash_prefix .. M.config.keys.hash_md5, function() + M.transform_selection(function(text) + return M.hash_text(text, "md5") + end, "hash", "md5") -- Passing "hash" as the mode and "md5" as the encoding type +end, { noremap = true, silent = true, desc = "MD5 Hash" }) + +-- SHA-1 Hash +vim.keymap.set("v", M.config.prefix .. M.config.keys.hash_prefix .. M.config.keys.hash_sha1, function() + selection_util.hash_selection(function(text) + return M.hash_text(text, "sha1") + end) -- Mode: "hash", Encoding: "sha1" +end, { noremap = true, silent = true, desc = "SHA-1 Hash" }) + +-- SHA-256 Hash +vim.keymap.set("v", M.config.prefix .. M.config.keys.hash_prefix .. M.config.keys.hash_sha256, function() + selection_util.hash_selection(function(text) + return M.hash_text(text, "sha256") + end) -- Mode: "hash", Encoding: "sha256" +end, { noremap = true, silent = true, desc = "SHA-256 Hash" }) + +-- CRC32 Hash +vim.keymap.set("v", M.config.prefix .. M.config.keys.hash_prefix .. M.config.keys.hash_crc32, function() + selection_util.hash_selection(function(text) + return M.hash_text(text, "crc32") + end) -- Mode: "hash", Encoding: "crc32" +end, { noremap = true, silent = true, desc = "CRC32 Hash" }) + +-- Bcrypt Hash +vim.keymap.set("v", M.config.prefix .. M.config.keys.hash_prefix .. M.config.keys.hash_bcrypt, function() + selection_util.hash_selection(function(text) + return M.hash_text(text, "bcrypt") + end) -- Mode: "hash", Encoding: "bcrypt" +end, { noremap = true, silent = true, desc = "Bcrypt Hash" }) + +-- Scrypt Hash +vim.keymap.set("v", M.config.prefix .. M.config.keys.hash_prefix .. M.config.keys.hash_scrypt, function() + selection_util.hash_selection(function(text) + return M.hash_text(text, "scrypt") + end) -- Mode: "hash", Encoding: "scrypt" +end, { noremap = true, silent = true, desc = "Scrypt Hash" }) + -- Function to handle encoding/decoding based on selection -- Base64 encoding and decoding utility functions M.base64_encode = function(text) @@ -371,6 +422,45 @@ M.transform_func = function(text, selection_type, encode_or_decode, encoding_typ return text end +M.hash_text = function(text, algorithm) + local python_cmd = "" + + -- Define Python commands for each hashing algorithm + if algorithm == "md5" then + python_cmd = string.format("python3 -c 'import hashlib; print(hashlib.md5(\"%s\".encode()).hexdigest())'", text) + elseif algorithm == "sha1" then + python_cmd = string.format("python3 -c 'import hashlib; print(hashlib.sha1(\"%s\".encode()).hexdigest())'", text) + elseif algorithm == "sha256" then + python_cmd = string.format("python3 -c 'import hashlib; print(hashlib.sha256(\"%s\".encode()).hexdigest())'", text) + elseif algorithm == "bcrypt" then + python_cmd = string.format( + "python3 -c 'import bcrypt; print(bcrypt.hashpw(\"%s\".encode(), bcrypt.gensalt()).decode())'", + text + ) + elseif algorithm == "crc32" then + python_cmd = + string.format('python3 -c \'import binascii; print(format(binascii.crc32(b"%s") & 0xffffffff, "08x"))\'', text) + elseif algorithm == "scrypt" then + python_cmd = string.format( + 'python3 -c \'import hashlib; print(hashlib.scrypt("%s".encode(), salt=b"", n=16384, r=8, p=1, dklen=64).hex())\'', + text + ) + else + vim.notify("Hacker Helper: unsupported algorithm " .. algorithm, vim.log.levels.ERROR) + end + + -- Execute the Python command and capture the output + local handle = io.popen(python_cmd) + if handle then + local result = handle:read("*a") + handle:close() + -- Remove trailing newlines from the result + return result:gsub("%s+", "") + else + vim.notify("Hacker Helper: Python dependencies for hashing are missing", vim.log.levels.ERROR) + end +end + M.hello = function() return module.my_first_function(M.config.opt) end diff --git a/lua/hacker-helper/selection_util.lua b/lua/hacker-helper/selection_util.lua index 0c6abd4..527a148 100644 --- a/lua/hacker-helper/selection_util.lua +++ b/lua/hacker-helper/selection_util.lua @@ -83,5 +83,63 @@ M.transform_selection = function(transform_func, encode_or_decode, encoding_type -- Reset the cursor position to prevent jumping to another line vim.cmd("normal! gv") -- Ensure the visual selection is active end +-- Utility function to capture the visual selection, apply a hash, and insert the hash one line above the selection +M.hash_selection = function(hash_func) + -- Reselect the current visual block to ensure the latest selection is active + vim.cmd("normal! gv") + + -- Get the visual selection range using visual marks + local start_pos = vim.fn.getpos("'<") -- Start of the visual selection + local end_pos = vim.fn.getpos("'>") -- End of the visual selection + + -- Ensure start_pos and end_pos are valid + start_pos = start_pos or { 0, 0, 0 } + end_pos = end_pos or { 0, 0, 0 } + + -- Adjust to capture the correct lines in visual line mode (V) + local start_line = math.min(start_pos[2], end_pos[2]) + local end_line = math.max(start_pos[2], end_pos[2]) + + local start_col = math.max(0, start_pos[3] - 1) -- 0-based index for inline selection + local end_col = math.max(0, end_pos[3]) -- inclusive for inline selection + + -- Get the selected lines, replacing nil values with empty strings + local lines = vim.fn.getline(start_line, end_line) or {} + for i = 1, #lines do + lines[i] = lines[i] or "" -- Ensure no nil values + end + + -- Handle visual line selection (V) and inline selection (v) + if vim.fn.visualmode() == "V" then + -- Full line selection + local selected_text = table.concat(lines, "\n") + local hash_result = hash_func(selected_text) + -- Insert the hash result above the first line + vim.fn.append(start_line - 1, hash_result) + else + -- Inline selection (v mode) + if start_line == end_line then + -- Handle inline selection on a single line + local line = lines[1] or "" + start_col = math.max(0, start_col) + end_col = math.min(#line, end_col) + local selection = string.sub(line, start_col + 1, end_col) + local hash_result = hash_func(selection) + -- Insert the hash result above the current line + vim.fn.append(start_line - 1, hash_result) + else + -- Multi-line partial selection + local first_line = string.sub(lines[1] or "", start_col + 1) + local last_line = string.sub(lines[#lines] or "", 1, end_col) + local selected_text = first_line .. "\n" .. table.concat(lines, "\n", 2, #lines - 1) .. "\n" .. last_line + local hash_result = hash_func(selected_text) + -- Insert the hash result above the first line + vim.fn.append(start_line - 1, hash_result) + end + end + + -- Reselect the visual selection after transformation (optional) + vim.cmd("normal! gv") +end return M diff --git a/tests/hacker-helper/hacker_helper_spec.lua b/tests/hacker-helper/hacker_helper_spec.lua index 6f6160a..b72b9c2 100644 --- a/tests/hacker-helper/hacker_helper_spec.lua +++ b/tests/hacker-helper/hacker_helper_spec.lua @@ -130,4 +130,68 @@ describe("encoding/decoding", function() local decoded = plugin.transform_func(encoded_text, "specific_selection", "decode", "octal") assert.are.equal("Hello", decoded) end) + + describe("Hashing Functions", function() + -- Test MD5 hashing + it("hashes text using MD5", function() + local text = "hello" + local hashed = plugin.hash_text(text, "md5") + assert.are.equal("5d41402abc4b2a76b9719d911017c592", hashed) + end) + + -- Test SHA-1 hashing + it("hashes text using SHA-1", function() + local text = "hello" + local hashed = plugin.hash_text(text, "sha1") + assert.are.equal("aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d", hashed) + end) + + -- Test SHA-256 hashing + it("hashes text using SHA-256", function() + local text = "hello" + local hashed = plugin.hash_text(text, "sha256") + assert.are.equal("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hashed) + end) + + -- Test CRC32 hashing + it("hashes text using CRC32", function() + local text = "hello" + local hashed = plugin.hash_text(text, "crc32") + assert.are.equal("3610a686", hashed) + end) + + -- Test Scrypt hashing + it("hashes text using Scrypt", function() + local text = "hello" + local hashed = plugin.hash_text(text, "scrypt") + assert.are.equal( + "de9f496a91b7c783c46a1841f71b4500210adec570f4407fcb2975d8e97e7e747a35816a9988959a6c9d921bbc8b7ea9caa0059e154b732850da77db18497072", + hashed + ) + end) + it("hashes test using Bcrypt", function() + local text = "hello" + local hashed = plugin.hash_text(text, "bcrypt") + + -- Extract the salt and hashed part from the Bcrypt hash + local salt = string.sub(hashed, 8, 29) -- Salt is from positions 8 to 29 (22 characters) + local hashed_part = string.sub(hashed, 30, 60) -- Hashed part is from positions 30 to 60 (31 characters) + + -- Verify Salt + assert.are.equal(22, #salt, "Salt length is incorrect") + for i = 1, #salt do + local char = string.sub(salt, i, i) + local is_valid = string.match(char, "[./A-Za-z0-9]") + assert.is_true(is_valid ~= nil, "Salt contains invalid characters at position " .. i .. ": " .. char) + end + + -- Verify Hashed Part + assert.are.equal(31, #hashed_part, "Hashed part length is incorrect") + for i = 1, #hashed_part do + local char = string.sub(hashed_part, i, i) + local is_valid = string.match(char, "[./A-Za-z0-9]") + assert.is_true(is_valid ~= nil, "Hashed part contains invalid characters at position " .. i .. ": " .. char) + end + end) + end) end) From 89f90f5b004a15da55e5affcefdaf31b2c5b6684 Mon Sep 17 00:00:00 2001 From: Sir AppSec Date: Sun, 8 Sep 2024 00:13:46 +0300 Subject: [PATCH 2/2] fix --- lua/hacker-helper.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/hacker-helper.lua b/lua/hacker-helper.lua index a5f2015..efd670a 100644 --- a/lua/hacker-helper.lua +++ b/lua/hacker-helper.lua @@ -227,9 +227,9 @@ end, { noremap = true, silent = true, desc = "Octal Decode" }) -- MD5 Hash vim.keymap.set("v", M.config.prefix .. M.config.keys.hash_prefix .. M.config.keys.hash_md5, function() - M.transform_selection(function(text) + selection_util.hash_selection(function(text) return M.hash_text(text, "md5") - end, "hash", "md5") -- Passing "hash" as the mode and "md5" as the encoding type + end) -- Passing "hash" as the mode and "md5" as the encoding type end, { noremap = true, silent = true, desc = "MD5 Hash" }) -- SHA-1 Hash