Bug #2465

msfrpcd has activerecord weirdness

Added by Ryan Linn over 1 year ago. Updated over 1 year ago.

Status:Closed Start date:08/27/2010
Priority:Normal Due date:
Assignee:- % Done:

100%

Category:-
Target version:-
Resolution: Release Note:

Description

Scriptjunkie pointed me to some oddness with msfrpcd. When loading xmlrpc plugin through msfconsole, report_host works when db is connected. With msfrpcd it seems to have problems, although deleting hosts still works. After applying the db_connect patch (in another ticket) here is how you replicate:

Step 1: Run msfrpcd -P abc123
Step 2:
(my postgres database has username msf and database name is msf, fill in your own stuff below)

root@bt:~/msfclean# ./msfrpc -P abc123 -a 127.0.0.1
[*] The 'rpc' object holds the RPC client interface

rpc.call('db.driver',{})

=> {"driver"=>"postgresql"}

rpc.call('db.connect',{:database => 'msf', :username => 'msf'})

=> {"result"=>"success"}

rpc.call('db.status')

=> {"driver"=>"postgresql", "db"=>"msf"}

rpc.call('db.hosts',{})

=> {"hosts"=>[]}

rpc.call('db.report_host',{:host => '192.168.5.75'})

=> {"result"=>"success"}

rpc.call('db.hosts',{})

=> {"hosts"=>[]} #NOTE: This should have 192.168.5.75 in it

rpc.call('module.execute','auxiliary','scanner/discovery/udp_sweep',{:RHOSTS => '192.168.1.1/26'})

=> {"result"=>"success"}

rpc.call('job.list')

=> {"jobs"=>{"1"=>"Auxiliary: scanner/discovery/udp_sweep"}}

rpc.call('job.list')

=> {"jobs"=>{"1"=>"Auxiliary: scanner/discovery/udp_sweep"}}

rpc.call('job.list')

=> {"jobs"=>{}}

rpc.call('db.hosts',{})

=> {"hosts"=>[]}

Ok, so neither the udp_sweep or our manual add worked

Now lets try through msfconsole

Step 3) ./msfconsole
Step 4) load xmlrpc Pass=abc123
Step 5)

oot@bt:~/msfclean# ./msfrpc -P abc123 -S -a 127.0.0.1
[*] The 'rpc' object holds the RPC client interface

rpc.call('db.driver',{})

=> {"driver"=>"postgresql"}

rpc.call('db.connect',{:database => 'msf', :username => 'msf'})

=> {"result"=>"success"}

rpc.call('db.status')

=> {"db"=>"msf", "driver"=>"postgresql"}

rpc.call('db.hosts',{})

=> {"hosts"=>[]}

rpc.call('db.report_host',{:host => '192.168.5.75'})

=> {"result"=>"success"}

rpc.call('db.hosts',{})

=> {"hosts"=>[{"address"=>"192.168.5.75", "name"=>"", "created_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "state"=>"alive", "purpose"=>""}]}

rpc.call('module.execute','auxiliary','scanner/discovery/udp_sweep',{:RHOSTS => '192.168.1.1/26'})

=> {"result"=>"success"}

rpc.call('job.list')

=> {"jobs"=>{"0"=>"Auxiliary: scanner/discovery/udp_sweep"}}

rpc.call('job.list')

=> {"jobs"=>{}}

rpc.call('db.hosts',{})

=> {"hosts"=>[{"address"=>"192.168.1.1", "name"=>"", "created_at"=>"Sat Aug 28 06:52:26 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:26 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "state"=>"alive", "purpose"=>""}, {"address"=>"192.168.1.20", "name"=>"\001\002__msbrowse__\002", "created_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "state"=>"alive", "purpose"=>""}, {"address"=>"192.168.1.26", "name"=>"", "created_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "state"=>"alive", "purpose"=>""}, {"address"=>"192.168.5.75", "name"=>"", "created_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "state"=>"alive", "purpose"=>""}]}

#NOTE Both our scan and our manual report worked

Step 5) Kill all that stuff off then restart msfrpcd -P abc123
Step 6)
root@bt:~/msfclean# ./msfrpc -P abc123 -a 127.0.0.1
[*] The 'rpc' object holds the RPC client interface

rpc.call('db.driver',{})

=> {"driver"=>"postgresql"}

rpc.call('db.connect',{:database => 'msf',:username => 'msf'})

=> {"result"=>"success"}

rpc.call('db.status')

=> {"driver"=>"postgresql", "db"=>"msf"}

rpc.call('db.hosts',{})

=> {"hosts"=>[{"name"=>"", "address"=>"192.168.1.1", "created_at"=>"Sat Aug 28 06:52:26 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:26 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}, {"name"=>"\001\002__msbrowse__\002", "address"=>"192.168.1.20", "created_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}, {"name"=>"", "address"=>"192.168.1.26", "created_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}, {"name"=>"", "address"=>"192.168.5.75", "created_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}]} #NOTE 192.168.1.1 is here, db stuff is generally working

rpc.call('db.del_host',{:host => '192.168.1.1'})

=> {"result"=>"success", "deleted"=>["192.168.1.1"]} #delete went through

rpc.call('db.hosts',{})

=> {"hosts"=>[{"name"=>"\001\002__msbrowse__\002", "address"=>"192.168.1.20", "created_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}, {"name"=>"", "address"=>"192.168.1.26", "created_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}, {"name"=>"", "address"=>"192.168.5.75", "created_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}]} #host really was deleted

rpc.call('db.report_host',{:host => '192.168.1.1'})

=> {"result"=>"success"}

rpc.call('db.hosts',{})

=> {"hosts"=>[{"name"=>"\001\002__msbrowse__\002", "address"=>"192.168.1.20", "created_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:25 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}, {"name"=>"", "address"=>"192.168.1.26", "created_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:52:24 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}, {"name"=>"", "address"=>"192.168.5.75", "created_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_lang"=>"", "updated_at"=>"Sat Aug 28 06:51:38 UTC 2010", "os_sp"=>"", "mac"=>"", "os_flavor"=>"", "info"=>"", "os_name"=>"", "address6"=>"", "purpose"=>"", "state"=>"alive"}]}

  1. So end game, adds fail, deletes work under msfrpcd, everything works correctly under msfconsole. The only odd error i'm getting is that new_record isn't defined when you run msfrpcd under ruby -d

msfrpcdfix.diff (1.3 kB) Matthew Weeks, 08/30/2010 06:09 pm

Associated revisions

Revision 9e86da57
Added by Matt Weeks over 1 year ago

Initialize framework after forking when running msfrpcd as a daemon. Fixes #2465 by running database task thread in daemon.

git-svn-id: file:///home/svn/framework3/trunk@10207 4d416f70-5f16-0410-b530-b9f4589650da

History

Updated by Matthew Weeks over 1 year ago

What I'm seeing with debug statements is that in lib/msf/core/db.rb the report_host function calls

task = queue( Proc.new {
    if opts[:comm] and opts[:comm].length > 0
        host = wspace.hosts.find_or_initialize_by_address_and_comm(addr, opts[:comm])
    ...

but the queue'd Proc never executes, like it does when run from msfconsole. The TaskManager (lib/msf/core/task_manager.rb) is not processing queue'd items, but I am not sure why; I think it should have been started.

Updated by Matthew Weeks over 1 year ago

The processing seems to die as soon as the rpcd backgrounds. Everything will function correctly when -f is used to keep msfrpcd from backgrounding.

Updated by Matthew Weeks over 1 year ago

Ok, the problem is the thread dies on the line

exit(0) if Process.fork()

in msfrpcd. The fix is to spawn the required worker thread after the fork, and the easiest way to make that happen is to initialize the framework after the fork. That would also solve any problems in case any other required worker threads are being killed too.

One problem that would come up for the gui is that it would have to wait longer after the fork waiting for the server to come up. I don't know if any other problems would be caused, so I'll test things out, but if I still don't find or hear of any problems I'll commit it.

Updated by Matthew Weeks over 1 year ago

  • Status changed from New to Resolved
  • % Done changed from 0 to 100

Applied in changeset r10207.

Updated by James Lee over 1 year ago

  • Status changed from Resolved to Closed

Also available in: Atom PDF