01 · INTRODUCTION

💎 What Is Ruby?

Ruby is a dynamic, open-source programming language created by Yukihiro "Matz" Matsumoto in 1995. It was designed with a single guiding principle: programmer happiness. Ruby's syntax is elegant, expressive, and a joy to read — it often reads like plain English.

Ruby became globally famous thanks to the Ruby on Rails web framework, which powered companies like GitHub, Shopify, Airbnb, and Basecamp. But Ruby's influence goes far beyond web development — it's also the language behind Metasploit, the world's most-used penetration testing framework.

For ethical hackers and security researchers, learning Ruby is a strategic investment. It opens the door to writing custom Metasploit modules, building security tools, and understanding the internals of one of the most important hacking frameworks ever built.

💡 Note: Ruby comes pre-installed on Kali Linux and macOS. To check your version, run ruby -v in the terminal. We recommend Ruby 3.x for modern features.
02 · WHY RUBY MATTERS

💡 Why Learn Ruby for Hacking?

You might wonder: "Why Ruby when Python, Bash, and Go exist?" The answer is simple: Metasploit. The most widely used exploitation framework in the world is written in Ruby. If you want to write custom modules, understand its internals, or extend its capabilities, you need Ruby.

💥

Metasploit Language

Write custom exploits, payloads, and post-exploitation modules for Metasploit.

📖

Elegant Syntax

Ruby reads like English. Code is beautiful, concise, and expressive.

🎯

Everything is an Object

Pure OOP — even numbers and strings are objects. Clean, consistent design.

⚡

Metaprogramming

Write code that writes code. Extremely powerful for building tools and DSLs.

📦

Rich Gem Ecosystem

RubyGems gives you 170,000+ libraries for everything from HTTP to crypto.

🔧

Security Tooling

Many pentest tools (BeEF, Ronin, WPScan) are written in Ruby.

🔑 Key Insight: Python is your general-purpose hacking language. Ruby is your Metasploit-language. Learning both makes you a much more versatile hacker.
03 · FUNDAMENTALS

📚 Ruby Fundamentals

Ruby is famous for its readability. Let's start with the classic first program — but Ruby-style.

Your First Ruby Script

# hello.rb — your first Ruby script puts "Hello, Ethical Hacker!" puts "Welcome to Ruby Programming"

Run it from the terminal:

ruby hello.rb
💡 Note: In Ruby, puts (put string) prints text with a newline. print prints without a newline. p prints with quotes (for debugging).

Variables & Data

# Local variables (lowercase) target = "192.168.1.100" port = 22 is_open = true version = 3.2 # String interpolation (double quotes only) puts "Target: #{target} on port #{port}" # Constants (start with uppercase) DEFAULT_PORT = 22 # Symbols (immutable identifiers, very common in Ruby) status = :open

Basic Operators

OperatorMeaningExample
+Addition5 + 3 = 8
-Subtraction5 - 3 = 2
*Multiplication5 * 3 = 15
/Division10 / 3 = 3
%Modulus5 % 3 = 2
**Exponent2 ** 8 = 256
==Equal5 == 5 → true
!=Not equal5 != 3 → true
&& / andLogical ANDtrue && false → false
|| / orLogical ORtrue || false → true
!Logical NOT!true → false
04 · DATA TYPES

📦 Data Types & Structures

In Ruby, everything is an object. Even numbers, strings, and booleans have methods you can call on them. This elegant design makes Ruby remarkably consistent.

Strings

url = "https://target.com/admin" puts url.upcase # HTTPS://TARGET.COM/ADMIN puts url.length # 27 puts url.include?("admin") # true puts url.split("/") # ["https:", "", "target.com", "admin"] puts url.reverse puts url[8..17] # target.com # String interpolation user = "admin" puts "Logged in as #{user}"

Arrays — Ordered Collections

ports = [21, 22, 80, 443, 3306] ports.push(8080) # Add to end ports.delete(21) # Remove value ports.sort # Returns sorted array puts ports[0] # 22 puts ports[-1] # Last element puts ports.length # 5 puts ports.first # 22 # Iterate with each ports.each do |port| puts "Scanning port #{port}" end # Map — transform each element doubled = ports.map { |p| p * 2 } puts doubled.inspect # Select — filter elements low_ports = ports.select { |p| p < 1000 } puts low_ports.inspect

Hashes — Key-Value Pairs

# Modern hash syntax (symbols as keys) target = { ip: "192.168.1.1", ports: [22, 80, 443], os: "Linux", vulnerable: true } puts target[:ip] # 192.168.1.1 target[:country] = "IN" # Add new key # Iterate over hash target.each do |key, value| puts "#{key}: #{value}" end # Keys and values puts target.keys.inspect puts target.values.inspect

Symbols — Ruby's Secret Weapon

# Symbols are immutable, reusable identifiers status = :open status2 = :open puts status.object_id == status2.object_id # true (same object!) # Strings create new objects each time a = "open" b = "open" puts a.object_id == b.object_id # false # Symbols are used as hash keys and method names config = { host: "localhost", port: 8080 }
05 · CONTROL FLOW

🔀 Control Flow — Making Decisions

If / Elsif / Else

port = 443 if port == 22 puts "SSH detected" elsif port == 80 puts "HTTP detected" elsif port == 443 puts "HTTPS detected" else puts "Unknown service" end # Modifier form (very Ruby!) puts "Port is open" if port == 443

Unless — Ruby's Unique Conditional

# unless = "if not" authenticated = false unless authenticated puts "Access denied" end puts "Granting access" unless authenticated

Case Statement

port = 443 case port when 22 puts "SSH" when 80, 443 puts "Web service" when 3306 puts "MySQL" else puts "Unknown" end

Loops

# Times — run block N times 5.times do |i| puts "Attempt #{i + 1}" end # Each — iterate over collection [22, 80, 443].each do |port| puts "Scanning #{port}" end # Range (1..10).each { |n| puts n } # While loop i = 0 while i < 5 puts "Count: #{i}" i += 1 end # Upto and Downto 1.upto(5) { |n| puts n } 5.downto(1) { |n| puts n }

Loop Control

(1..100).each do |n| next if n.even? # Skip evens break if n > 20 # Stop at 20 puts n end
06 · METHODS & BLOCKS

🧩 Methods, Blocks & Procs

Defining Methods

def scan_port(host, port) require 'socket' begin sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM) sock.connect(Socket.sockaddr_in(port, host)) sock.close true rescue false end end if scan_port("192.168.1.1", 22) puts "[+] Port 22 is OPEN" end

Default & Keyword Arguments

def brute_force(target, port: 22, threads: 10, verbose: false) puts "Attacking #{target}:#{port}" if verbose # ... logic ... end brute_force("10.0.0.1") brute_force("10.0.0.1", port: 21, verbose: true)

Implicit Return

# The last expression is automatically returned def add(a, b) a + b # returned implicitly end puts add(5, 3) # 8

Blocks — Ruby's Superpower

# Block with do...end (multi-line) [1, 2, 3].each do |n| puts n end # Block with { } (single-line) [1, 2, 3].each { |n| puts n } # Custom method that yields to a block def with_timing start = Time.now yield puts "Took #{Time.now - start} seconds" end with_timing do sleep 1 end

Procs and Lambdas

# Proc — a block stored in a variable greet = Proc.new { |name| puts "Hello, #{name}" } greet.call("Hacker") # Lambda — stricter version of proc square = ->(x) { x ** 2 } puts square.call(5) # 25 # Passing procs to methods puts [1, 2, 3].map(&square).inspect # [1, 4, 9]
07 · OBJECT-ORIENTED RUBY

🏛️ Classes & Objects

Ruby is a pure object-oriented language. Everything — even nil — is an object. Classes define blueprints for objects, complete with attributes (state) and methods (behavior).

class Target # Attributes with getters and setters attr_accessor :ip, :ports attr_reader :os attr_writer :vulnerable # Constructor def initialize(ip, os: "Unknown") @ip = ip @os = os @ports = [] end # Instance method def add_port(port) @ports << port end def to_s "Target(#{@ip}, OS: #{@os}, Ports: #{@ports.join(', ')})" end end # Create objects t1 = Target.new("192.168.1.1", os: "Linux") t1.add_port(22) t1.add_port(80) puts t1 # Target(192.168.1.1, OS: Linux, Ports: 22, 80)

Inheritance

class WebTarget < Target def initialize(ip, domain) super(ip, os: "Linux") @domain = domain end def to_s "#{super} [#{@domain}]" end end web = WebTarget.new("10.0.0.1", "example.com") puts web

Method Visibility

class Exploit def run # public by default setup execute end private def setup puts "Setting up..." end def execute puts "Executing..." end end Exploit.new.run
08 · MODULES & MIXINS

🧬 Modules, Mixins & Namespaces

Modules are Ruby's answer to multiple inheritance. They let you share behavior across classes without the complications of traditional inheritance. This is called a mixin.

module Scannable def scan(target) puts "Scanning #{target}..." end def report puts "Report generated by #{self.class}" end end class NmapScanner include Scannable end class NiktoScanner include Scannable end NmapScanner.new.scan("192.168.1.1") NiktoScanner.new.report

Module Methods & Namespacing

module Security def self.hash_md5(data) require 'digest' Digest::MD5.hexdigest(data) end class Analyzer def analyze(file) puts "Analyzing #{file}" end end end puts Security.hash_md5("password") analyzer = Security::Analyzer.new analyzer.analyze("malware.bin")
09 · FILE HANDLING

📁 File Handling & I/O

Reading wordlists, writing scan results, parsing logs — file I/O is critical for security scripting.

# Read a file line by line File.open("wordlist.txt", "r") do |file| file.each_line do |line| puts line.strip end end # Read entire file content = File.read("config.txt") # Read all lines into array lines = File.readlines("targets.txt", chomp: true) # Write to a file (overwrites) File.write("results.txt", "Scan complete\n") # Append to a file File.open("log.txt", "a") do |f| f.puts "[+] Target scanned at #{Time.now}" end # Check if file exists puts File.exist?("scan.txt") # true/false # Parse JSON require 'json' data = JSON.parse(File.read("scan.json")) puts data["hosts"] # Write JSON File.write("output.json", JSON.pretty_generate(data))
10 · GEMS & BUNDLER

📦 Gems — Ruby's Package Manager

Gems are Ruby's libraries. With over 170,000 gems available, you'll find a tool for almost anything. bundler manages project dependencies.

# Install a gem globally gem install requests # List installed gems gem list # Update all gems gem update # Search for a gem gem search -r http

Essential Gems for Security

🌐 httparty

Simple HTTP client. Great for API hacking and web scraping.

🕸️ nokogiri

HTML/XML parser. Ruby's answer to BeautifulSoup.

🔗 net-ssh

SSH client library. Automate SSH operations and brute-force.

💥 metasploit-framework

The pentesting framework itself — used as a library in scripts.

📡 packetfu

Packet crafting and sniffing library for network attacks.

🔐 openssl

Built-in crypto library. Encrypt, decrypt, hash, sign.

🔍 whois

WHOIS lookups from Ruby scripts.

📊 colorize

Colorful terminal output. Makes scripts and reports prettier.

11 · RUBY IN METASPLOIT

💥 Ruby & Metasploit — Writing Custom Modules

Metasploit is written entirely in Ruby. Every exploit, payload, and post-exploitation module is a Ruby class. Learning Ruby lets you write your own modules and extend the framework.

Anatomy of a Metasploit Module

require 'msf/core' class MetasploitModule < Msf::Auxiliary def initialize(info = {}) super( 'Name' => 'Custom SSH Scanner', 'Description' => 'Scans for open SSH ports', 'Author' => 'Hacker', 'License' => MSF_LICENSE ) register_options([ Opt::RHOSTS.new(true), Opt::RPORT.new(true, 'SSH port', 22) ]) end def run print_status("Scanning #{rhost}:#{rport}") begin connect print_good("SSH is open on #{rhost}") disconnect rescue print_error("Cannot connect") end end end

Module Types in Metasploit

TypePurposeExample
exploitVulnerability exploitationms17_010_eternalblue
auxiliaryScanning, fuzzing, sniffingssh_login
payloadCode that runs on targetreverse_tcp
encoderEncode payloads to bypass AVshikata_ga_nai
postPost-exploitation actionshashdump
nopNOP generatorsx64/single_byte
💡 Pro Tip: The best way to learn to write Metasploit modules is to study the existing ones. Browse /usr/share/metasploit-framework/modules/ on Kali Linux and study the structure.
12 · SECURITY SCRIPTING

🛡️ Security Scripts in Ruby

Script 1: Simple Port Scanner

require 'socket' def scan_port(host, port, timeout: 1) Socket.tcp(host, port, connect_timeout: timeout) true rescue Errno::ECONNREFUSED, SocketError false end target = ARGV[0] || "127.0.0.1" puts "[*] Scanning #{target}..." (1..1024).each do |port| if scan_port(target, port) puts "[+] Port #{port} OPEN" end end puts "[✓] Scan complete"

Script 2: Multi-Threaded Scanner

require 'socket' target = "192.168.1.1" threads = [] (1..1024).each do |port| threads << Thread.new do begin Socket.tcp(target, port, connect_timeout: 1) puts "[+] Port #{port} OPEN" rescue # closed end end end threads.each(&:join) puts "Scan complete."

Script 3: HTTP Directory Brute-Forcer

require 'net/http' url = "http://target.com" wordlist = "/usr/share/wordlists/dirb/common.txt" File.foreach(wordlist) do |line| path = line.strip next if path.empty? begin uri = URI.parse("#{url}/#{path}") response = Net::HTTP.get_response(uri) unless response.code == "404" puts "[+] #{response.code} — #{uri}" end rescue # skip errors end end

Script 4: Hash Cracker

require 'digest' target_hash = "5f4dcc3b5aa765d61d8327deb882cf99" # md5("password") File.foreach("/usr/share/wordlists/rockyou.txt") do |line| word = line.strip if Digest::MD5.hexdigest(word) == target_hash puts "[+] CRACKED: #{word}" break end end

Script 5: Subdomain Enumerator

require 'resolv' domain = "example.com" subs = %w[www mail api dev admin test ftp blog shop] subs.each do |sub| begin ip = Resolv.getaddress("#{sub}.#{domain}") puts "[+] #{sub}.#{domain} → #{ip}" rescue Resolv::ResolvError # not found end end
13 · ADVANCED

🚀 Advanced Ruby Topics

Metaprogramming — Code That Writes Code

class Exploit [:scan, :exploit, :report].each do |method| define_method(method) do puts "Running #{method}..." end end end e = Exploit.new e.scan # Running scan... e.exploit # Running exploit...

method_missing — Dynamic Method Handling

class FlexibleScanner def method_missing(name, *args) if name.to_s.start_with?("scan_") protocol = name.to_s.sub("scan_", "") puts "Scanning via #{protocol}..." else super end end def respond_to_missing?(name, include_private = false) name.to_s.start_with?("scan_") || super end end s = FlexibleScanner.new s.scan_tcp s.scan_udp s.scan_http

Regular Expressions

text = "Contact: admin@target.com or support@target.com" # Extract emails emails = text.scan(/[\w\.-]+@[\w\.-]+\.\w+/) puts emails.inspect # Match IP addresses log = "Failed login from 192.168.1.45 and 10.0.0.7" ips = log.scan(/\b(?:\d{1,3}\.){3}\d{1,3}\b/) puts ips.inspect # Substitution clean = text.gsub(/@target\.com/, "@hacked.io") puts clean

Error Handling

begin # risky code result = 10 / 0 rescue ZeroDivisionError => e puts "Error: #{e.message}" rescue StandardError => e puts "General error: #{e.message}" ensure puts "This always runs" end # Custom exceptions class ScanError < StandardError; end begin raise ScanError, "Target unreachable" rescue ScanError => e puts e.message end
14 · BEST PRACTICES

✅ Ruby Best Practices

  1. Follow the Ruby Style Guide — 2-space indentation, snake_case for methods/variables.
  2. Use bundler — Manage gem dependencies with a Gemfile.
  3. Prefer each over for — Ruby's iterators are idiomatic.
  4. Use symbols for hash keys — Faster and cleaner than strings.
  5. Favor blocks over loops — map, select, reduce are more expressive.
  6. Use attr_accessor — Instead of manual getters/setters.
  7. Handle exceptions — Wrap risky operations in begin/rescue.
  8. Write tests — RSpec or Minitest keeps your code reliable.
  9. Use freeze for constants — CONST = "value".freeze.
  10. Comment intelligently — Explain "why", not "what".

Gemfile Example

# Gemfile source 'https://rubygems.org' gem 'httparty' gem 'nokogiri' gem 'net-ssh' gem 'colorize'
# Install dependencies bundle install # Run with bundler bundle exec ruby script.rb
16 · CONCLUSION

🎓 Final Thoughts

Ruby is one of the most elegant and enjoyable programming languages ever created. Its philosophy of programmer happiness shines through in every line of code. And in the security world, Ruby's importance is cemented by its role as the language of Metasploit — the framework that virtually every penetration tester uses.

Whether you want to write custom Metasploit modules, build security tools, or simply enjoy writing beautiful code, Ruby is a fantastic choice. It's beginner-friendly, yet powerful enough for advanced metaprogramming.

The journey follows a clear path:

  1. Learn the basics — syntax, variables, control flow, methods.
  2. Master OOP — classes, modules, inheritance, mixins.
  3. Explore the gems — httparty, nokogiri, net-ssh.
  4. Study Metasploit — read its source code on GitHub.
  5. Write your own modules — start simple, then advance.
  6. Practice daily — try new things, build small tools.
🚀 Next Steps: Install Ruby, write a simple port scanner, then dive into the Metasploit source. Within weeks, you'll be writing modules like a pro.

Happy hacking — ethically. 💎