FlyFar

Hello-Virus | Ruby | Source Code

Jul 1st, 2023
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 5.62 KB | Cybersecurity | 0 0
  1. #Key=
  2.  
  3. =begin
  4. Assignment compiled on Ruby (requires the OpenSSL, Digest (MD5), and Base64 libraries to function)
  5. How the program works:
  6. * On first run...
  7.     - the program goes through all of the code, executing each and everything
  8.     - on closing, the program runs an encryptor function
  9.     - the encryptor code takes in a key of random alphanumeric string (between 1 and 65536) and generates an MD5 hash
  10.     - the hash, as MD5 produces a 32 character long string, is perfect and used in an AES CTR (Counter) encryption algorithm
  11.     - the AES encrypted byte string is now passed through a Base64 algorithm to be encrypted into a readable format
  12.     - all of the driver code that needs to be encrypted is now replaced with the encrypted code, and the key saved within itself
  13. * On subsequent run...
  14.     - the program retrieves the stored key and uses it to decrypt the driver code
  15.     - the base64 string is decoded into an AES byte string, which is decoded by using the MD5 hash generated from the retrieved key, and the line of code retrieved
  16.     - the deciphered line of code is now written and called through metaprogramming (as you are unable to alter any executing file under Windows standard)
  17.     - after execution the encryption process takes place (see "On first run...")
  18. =end
  19.  
  20. require 'openssl' # Library required for AES encryption
  21. require 'digest' # Used explicitly for MD5 hash algorithm (key generation)
  22. require 'base64' # Convert encryption to readable Base64 format ('readable' is subjective here)
  23.  
  24. #Sequence (for initial execution)
  25. $f_data = nil # This is where we'll store our file's data
  26. $payload = '' # Our code that needs to be deciphered (made it generic for multiple lines of code (does not work as intended however, so left it with "Hello World!" only))
  27. # Let's store the data into a variable
  28. file = File.open(File.basename(__FILE__))
  29. $f_data = file.readlines.map(&:chomp)
  30. file.close
  31.  
  32. #Functions
  33. def decryptor(key)
  34.     cipher = OpenSSL::Cipher::AES.new(256, :CTR)
  35.     # Using the key and iv, decrypt it
  36.     cipher.decrypt
  37.     hash = Digest::MD5.hexdigest(key)
  38.     cipher.key = hash
  39.     # After receiving the text, overwrite the payload
  40.     rewrite = false
  41.     new_data = []
  42.     for i in (0..$f_data.length()-1) do
  43.         if $f_data[i] == "#Start"
  44.             new_data.push($f_data[i])
  45.             rewrite = true
  46.         elsif $f_data[i] == "#End"
  47.             rewrite = false
  48.             ciphertext = Base64.strict_decode64($payload)
  49.             plaintext = cipher.update(ciphertext) + cipher.final
  50.             new_data.push(plaintext)
  51.             new_data.push($f_data[i])
  52.             $payload = ''
  53.         elsif rewrite == true and $f_data[i] != ""
  54.             $payload += $f_data[i][1..-1] # 1 to -1 because the first character will be for commenting the ciphertext
  55.         else
  56.             new_data.push($f_data[i])
  57.         end
  58.     end
  59.     $f_data = new_data
  60. end
  61.  
  62. #Start
  63. # It's a seecret!
  64. #End
  65.  
  66. def encryptor(key)
  67.     new_data = [] # This is where we store contents of file for now
  68.     $payload = ''
  69.     cipher = OpenSSL::Cipher::AES.new(256, :CTR)
  70.     cipher.encrypt
  71.     hash = Digest::MD5.hexdigest(key)
  72.     cipher.key = hash # The hash is used as a key to encrypt the lines
  73.     rewrite = false
  74.     for i in (0..$f_data.length()-1) do
  75.         if $f_data[i][0..4] == "#Key=" # Store Key
  76.             $f_data[i] = "#Key=" + key
  77.             new_data.push($f_data[i])
  78.         elsif $f_data[i] == "#Start" # Check where payload begins
  79.             rewrite = true
  80.             new_data.push($f_data[i])
  81.         elsif $f_data[i] == "#End" # Check where payload ends
  82.             rewrite = false
  83.             ciphertext = cipher.update($payload) + cipher.final
  84.             text = Base64.strict_encode64(ciphertext)
  85.             new_data.push("#" + text)
  86.             new_data.push($f_data[i])
  87.             $payload = ''
  88.         elsif rewrite == true and $f_data[i] != "" # Update deciphered payload with ciphered text
  89.             if not ($f_data[i].is_a? String) # Failsafe as the data itself is treated like an array at times
  90.                 $f_data[i] *= ""
  91.             end
  92.             $payload += $f_data[i] + "\n"
  93.         else
  94.             new_data.push($f_data[i])
  95.         end
  96.     end
  97.     $f_data = new_data
  98. end
  99.  
  100. def generate_key(len=32) # A (pretty useless) code self-written that produces an arbitrary key of specified length (or if unspecified, of length 32)
  101.     $i = 0
  102.     key = ''
  103.     while $i < len do
  104.         $r = rand(48..122)
  105.         if ($r >= 48 and $r <= 57) or ($r >= 65 and $r <= 90) or ($r >= 97 and $r <= 122) # accept only alphanumeric keys (case-insensitive)
  106.             key += $r.chr
  107.             $i += 1
  108.         end
  109.     end
  110.     return key
  111. end
  112.  
  113. # Now let's retrieve the key (if any)
  114. key = $f_data[0][5..-1]
  115. if key.length != 0 # If true, a key is present so we have to decrypt the payload first
  116.     # Retrieve the MD5 hash for the key
  117.     # Launch the decryptor method to decrypt the payload before running it
  118.     decryptor(key)
  119.     evaluation = false
  120.     for i in (0..$f_data.length()-1)
  121.         if $f_data[i] == "#Start"
  122.             evaluation = true
  123.         elsif $f_data[i] == "#End"
  124.             evaluation = false
  125.         elsif evaluation
  126.             code = $f_data[i].split("\n")
  127.             for j in code
  128.                 eval(j)
  129.             end
  130.         end
  131.     end
  132. end # If false, the code is executing for the first time (or if a key is not provided, it will work as intended, since all of the encrypted code is commented, so the program will ignore it)
  133.  
  134. key = generate_key(rand(1..65536)) # This is going to emotionally hurt someone
  135.  # This will work whether it's first time or subsequent execution - a new key will be generated, mimicking a polymorphic malware
  136. # Now the actual code/payload will be located in here
  137. #Start
  138. puts "Hello World!"
  139. #End
  140.  
  141. encryptor(key)
  142.  
  143. #Start
  144. puts "I can en/decrypt multiple lines of code at multiple locations!"
  145. puts "I don't think you've seen the secret message inside my code..."
  146. #End
  147.  
  148. # The next line is for exclusively updating the file to encrypt the payload with new ciphertext
  149. at_exit do
  150.     File.open(File.basename(__FILE__), "w+") do |i|
  151.         i.puts($f_data)
  152.     end
  153. end
Tags: Ruby
Add Comment
Please, Sign In to add comment