Skip to content

Instantly share code, notes, and snippets.

@landaire
Created July 22, 2012 21:19
Show Gist options
  • Save landaire/3161073 to your computer and use it in GitHub Desktop.
Save landaire/3161073 to your computer and use it in GitHub Desktop.
Ruby implementation of Redline99's "X" value decryption code (Xbox 360)
# xval.rb - Ruby implementation of Redline99's "X" value decryption code for the Xbox 360 by CLK
# See https://gist.github.com/2669789 for Python code
require 'optparse'
require 'openssl'
# Define our constants
FLAG_SSB_NONE = 0x0000
FLAG_SSB_AUTH_EX_FAILURE = 0x0001
FLAG_SSB_AUTH_EX_NO_TABLE = 0x0002
FLAG_SSB_AUTH_EX_RESERVED = 0x0004
FLAG_SSB_INVALID_DVD_GEOMETRY = 0x0008
FLAG_SSB_INVALID_DVD_DMI = 0x0010
FLAG_SSB_DVD_KEYVAULT_PAIR_MISMATCH = 0x0020
FLAG_SSB_CRL_DATA_INVALID = 0x0040
FLAG_SSB_CRL_CERTIFICATE_REVOKED = 0x0080
FLAG_SSB_UNAUTHORIZED_INSTALL = 0x0100
FLAG_SSB_KEYVAULT_POLICY_VIOLATION = 0x0200
FLAG_SSB_CONSOLE_BANNED = 0x0400
FLAG_SSB_ODD_VIOLATION = 0x0800
def DecryptXval(serial, xval)
# Remove dashes from the xval
xval = xval.delete('-')
# Convert the xval to a byte array
xval = xval.scan(/../).map(&:hex)
# Conver that back into a string
xval = xval.pack('c*')
# Make sure that the serial/xval lengths are good
fail if serial.length != 0xC
fail if xval.length != 0x8
# Get the DES key (bytes 0-8 of the hash)
serial.encode!("ascii")
deskey = OpenSSL::HMAC.digest("sha1", serial + "\0", "XBOX360SSB")[0, 8]
fail if deskey.length != 0x8
# Decrypt the X value
cipher = OpenSSL::Cipher::Cipher.new("des-ecb")
cipher.decrypt
cipher.key = deskey
# Must set the padding to 0
cipher.padding = 0
ciphertext = cipher.update(xval) + cipher.final
return ciphertext
end
def GetResults(result)
xval = result.unpack('LL*')
xval_h = xval[0]
xval_l = xval[1]
if(xval_h == 0 && xval_l == 0) # nothing is flagged in secdata.bin, all is good from this standpoint
return "Secdata is Clean"
elsif(xval_h == 0xFFFFFFFF && xval_l == 0xFFFFFFFF) # secdata was prob tampered with
return "Secdata is invalid"
elsif (xval_h != 0 && xval_l != 0) # most likely the serial or xval is incorrect
return "Secdata decryption error. Check your serial number and X value to ensure they are correct"
else # the high dword = 0 and low dword not 0
# afaik best check. have to look at disassembly more
if(xval_l & FLAG_SSB_AUTH_EX_FAILURE)
return "AuthEx Challenge Failure" # AP25 related
end
if(xval_l & FLAG_SSB_AUTH_EX_NO_TABLE)
return "AuthEx Table missing" # AP25 related
end
if(xval_l & FLAG_SSB_AUTH_EX_RESERVED)
return "AuthEx Reserved Flag" # AP25 related
end
if(xval_l & FLAG_SSB_INVALID_DVD_GEOMETRY)
return "Invalid DVD Geometry"
end
if(xval_l & FLAG_SSB_INVALID_DVD_DMI)
return "Invalid DVD DMI"
end
if(xval_l & FLAG_SSB_DVD_KEYVAULT_PAIR_MISMATCH)
return "DVD Keyvault Pair Mismatch"
end
if(xval_l & FLAG_SSB_CRL_DATA_INVALID)
return "Invalid CRL Data"
end
if(xval_l & FLAG_SSB_CRL_CERTIFICATE_REVOKED)
return "CRL Certificate Revoked"
end
if(xval_l & FLAG_SSB_UNAUTHORIZED_INSTALL)
return "Unauthorized Install"
end
if(xval_l & FLAG_SSB_KEYVAULT_POLICY_VIOLATION)
return "Keyvault Policy Violation"
end
if(xval_l & FLAG_SSB_CONSOLE_BANNED)
return "Console Banned"
end
if(xval_l & FLAG_SSB_ODD_VIOLATION)
return "ODD Violation"
end
if(xval_l & 0xFFFFF000) # mask for bits we dont have a description for,
# note: we are not looking at the hi dword yet
return "Unknown Violation(s)"
end
end
end
# Parse the input arguments
options = {}
optparser = OptionParser.new do |opts|
opts.banner = "Usage: xval.rb [options]"
# Serial switch
opts.on('-s', '--serial SERIAL', 'Console serial number') do |v|
options[:serial] = v
end
# X value switch
opts.on('-x', '--xval XVAL', '"X:" Value shown on the dashboard') do |v|
options[:xval] = v
end
# Help switch
opts.on( '-h', '--help', 'Display this screen' ) do
puts opts
exit
end
end
# Parse the args and clear ARGV
optparser.parse!
# Make sure that we were given some args
if (options.length == 0)
puts optparser
return
elsif (options[:serial] == nil)
puts "No serial number passed"
puts optparser
return
elsif (options[:xval] == nil)
puts "No X value passed"
puts optparser
return
end
# Get some results
puts GetResults(DecryptXval(options[:serial], options[:xval]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment