Saving Results
This step saves information collected by a module to the Metasploit DB or loot files. The main API owner is Msf::Auxiliary::Report (lib/msf/core/auxiliary/report.rb). Including HttpClient also includes Report.
Which API to use for each result
Section titled “Which API to use for each result”| Result | API | Reason |
|---|---|---|
| Attributes of a live host | report_host | OS and similar data; other APIs often cover this too |
| Open port / banner | report_service | Appears in services |
| Credentials ready to use | create_credential / create_credential_login / create_credential_and_login | Appears in creds |
| Failed login | invalidate_login | Retry control or recordkeeping |
| Confirmed vulnerability | report_vuln | A successful exploit session may also be reported automatically |
| Configuration file, command output, or dump | store_loot | Actual file + loot index |
| Observation that does not fit above | report_note | Use a dot-separated type |
| Interesting web page / form | report_web_* | Web-related helper |
Bundled wiki: How-to-do-reporting-or-store-data-in-module-development.md
report_service
Section titled “report_service”report_service( host: rhost, port: rport, proto: 'tcp', name: ssl? ? 'https' : 'http', info: res.headers['Server'].to_s)If a scanner gets a banner, consider this first.
store_loot
Section titled “store_loot”Use this for data you want to save as a file. It returns the saved path.
path = store_loot( 'example.config', # ltype (type label) 'text/plain', # ctype (approximate MIME type) rhost, # host; a post module may use session res.body, # Data 'config.php', # Suggested file name 'ExampleApp config' # Description)print_good("Loot saved to #{path}")A post module example:
data = read_file('/etc/passwd')store_loot('linux.passwd', 'text/plain', session, data, 'passwd', 'passwd file')For hashes or passwords ready for immediate login, use the credential API as well as loot.
Credential API
Section titled “Credential API”create_credential_and_login( workspace_id: myworkspace_id, origin_type: :service, module_fullname: fullname, address: rhost, port: rport, protocol: 'tcp', service_name: 'ssh', username: user, private_data: pass, private_type: :password, status: Metasploit::Model::Login::Status::SUCCESSFUL)| Method | Purpose |
|---|---|
create_credential | The credential itself |
create_credential_login | Record of a login to a service |
create_credential_and_login | Both together |
invalidate_login | Failed combination |
Examples of private_type: :password, :ntlm_hash, :ssh_key.
report_vuln / report_note
Section titled “report_vuln / report_note”report_vuln( host: rhost, port: rport, name: name, refs: references, info: 'command injection confirmed via id')
report_note( host: rhost, type: 'example.users', data: { users: users }, update: :unique_data)Use a dot-separated type such as domain.hosts for report_note. That makes it easier for other modules to find.
When there is no DB
Section titled “When there is no DB”Modules still run if msfdb is not started, but storage features are less useful. In a test environment, set up Basic Operations and DB first.
db_statuscredsserviceslootvulnsImplementation guidelines
Section titled “Implementation guidelines”- Save successful logins as credentials and large text or binary data as loot.
- Avoid sending the same data indiscriminately to both
report_noteandstore_loot. Give each a clear role. - When an exploit opens a session, the framework may also report the vulnerability. Use
report_vulnfor auxiliary modules or explicit confirmation.
Next is Cleanup.

