Skip to content

Instantly share code, notes, and snippets.

@dwalters-zz
Created June 14, 2012 16:42
Show Gist options
  • Save dwalters-zz/2931407 to your computer and use it in GitHub Desktop.
Save dwalters-zz/2931407 to your computer and use it in GitHub Desktop.
Script to encrypt/decrypt config backups of a Linksys EA3500 V1 router (on stock firmware.)
#!/usr/bin/env ruby
#
# Script to decrypt (and reencrypt) Linksys EA3500 v1.0 configuration file backups, e.g.,
# Linksys_EA3500V1_v1.0.30.126544.cfg . The result of decryption is a plain text nvram dump that
# can be edited, re-encrypted, and uploaded back into the router.
#
# Depends on Ruby 1.9 and an openssl command line binary.
require 'optparse'
require 'tempfile'
require 'zlib'
CFG_MAGIC = 0xfeeddade
CFG_VERSION = 1
CFG_DES_KEY = '2f8a36e8a92aa7b02f64ec77f85643de'
def encrypt_config(config_file)
payload = File.read(config_file, :encoding => 'binary')
crc = Zlib::crc32(payload) ^ 0xffffffff
header = [CFG_MAGIC, payload.length, CFG_VERSION, crc].pack('L4')
temp_file = Tempfile.new 'config', :encoding => 'binary'
begin
temp_file.write(header + payload)
temp_file.close
system 'openssl', 'des', '-in', temp_file.path, '-out', config_file, '-e', '-k', CFG_DES_KEY or raise "encryption failed"
ensure
temp_file.unlink
end
end
def decrypt_config(config_file)
temp_file = Tempfile.new 'config', :encoding => 'binary'
data = begin
temp_file.close
system 'openssl', 'des', '-in', config_file, '-out', temp_file.path, '-d', '-k', CFG_DES_KEY or raise "decryption failed"
File.read(temp_file.path, :encoding => 'binary')
ensure
temp_file.unlink
end
header = data[0, 0x10].unpack('L4')
payload = data[0x10..-1]
raise "incorrect magic" unless header[0] == CFG_MAGIC
raise "incorrect version" unless header[2] == CFG_VERSION
File.write(config_file, payload, :encoding => 'binary')
end
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: linksys-config.rb [options] linksys.cfg"
opts.on("-e", "--encrypt", "Encrypt the given configuration.") do |e|
options[:encrypt] = e
end
opts.on("-d", "--decrypt", "Decrypt the given configuration.") do |d|
options[:decrypt] = d
end
end.parse!
config_file = ARGV.first
raise "configuration file does not exist: #{config_file}" unless config_file && File.exist?(config_file)
raise "must choose only one operation!" if options[:encrypt] && options[:decrypt]
if options[:encrypt] then
encrypt_config(config_file)
puts "#{config_file} successfully encrypted."
elsif options[:decrypt]
decrypt_config(config_file)
puts "#{config_file} successfully decrypted."
else
raise "must specify whether you wish to encrypt or decrypt the config file."
end
@dmitrievav
Copy link

Thank you very much! It also works for Linksys_EA2700-EUV1_v1.0.14

@Shivomz
Copy link

Shivomz commented Nov 1, 2015

Hi. how to run this script? I have to edit my Linksys_E2500V3_v3.0.00.cfg file. But I am clueless. Please help.

@shyjuk
Copy link

shyjuk commented Feb 14, 2017

Hi getting following error

/usr/lib/ruby/1.8/tempfile.rb:52:in initialize': cannot generate tempfile ' (RuntimeError)
from ./linksys-config.rb:33:in new' from ./linksys-config.rb:33:in decrypt_config'
from ./linksys-config.rb:69

@requeijaum
Copy link

requeijaum commented Dec 12, 2018

Does it work for LinkSys EA6200 ?

rafaelfrequiao@laptoplogin:~/Downloads$ ruby linksys-config.rb -d '/home/rafaelfrequiao/Downloads/Rede Norsul/Backup Firmware/LinkSys EA6200/backup_201115.cfg' 
bad magic number
Traceback (most recent call last):
	1: from linksys-config.rb:69:in `<main>'
linksys-config.rb:36:in `decrypt_config': decryption failed (RuntimeError)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment