Skip to content

Instantly share code, notes, and snippets.

@zed-0xff
Created January 17, 2012 13:09
Show Gist options
  • Save zed-0xff/1626577 to your computer and use it in GitHub Desktop.
Save zed-0xff/1626577 to your computer and use it in GitHub Desktop.
script for decoding JPG / DOC / XLS / etc files that were encoded with Trojan.Siggen3.35000
#!/usr/bin/env ruby
#coding: binary
#
# script for decoding JPG / DOC / XLS / etc files that were encoded with
# Trojan.Siggen3.35000
# Trojan.Dropper-31300
#
#
# some useful links:
#
# * http://zed.0xff.me/2012/01/17/raskodiruem-trojan-siggen3-35000
# * http://pedump.me/2a8242105fed0d1708f56ae251c45e7e/
# * https://twitter.com/#!/zed_0xff
#
require 'find'
require 'stringio'
STDOUT.sync = true
@debug = false
class Record < Struct.new(:saved_data_size, :offset, :saved_data_offset)
FORMAT = "cVV"
SIZE = 9
def self.read io
new(*io.read(SIZE).unpack(FORMAT))
end
end
def process_file fname, args = {}
File.open(fname, args[:decrypt] ? "r+b" : "rb") do |f|
printf "[.] %-20s .. ", fname if @debug
f.seek -1, IO::SEEK_END
nRecords = f.read(1).ord
puts "[.] #{nRecords} records" if @debug
next if nRecords <= 0
t = nRecords*Record::SIZE
next if (t+1) >= f.size
f.seek(-t-1, IO::SEEK_END)
records = []
nRecords.times do
record = Record.read(f)
puts "\t" + record.inspect if @debug
if record.saved_data_size != 20
puts "[!] BAD RECORD" if @debug
return
end
records << record
end
if records.first.offset != 0
puts "[!] BAD 1st RECORD" if @debug
return
end
return unless args[:decrypt]
was = false
records.each do |r|
f.seek r.saved_data_offset
data = f.read(r.saved_data_size)
data = data.scan(/../).map{ |x| x.to_i(16).chr }.join
bdata = data.scan(/../).map{ |x| x.to_i(16).chr }.join
f.seek r.offset
if f.read(bdata.size) != bdata
if !was && !@debug
puts "[.] #{fname}"
end
was = true
puts "\twriting #{data} at offset #{r.offset}"
f.seek r.offset
f.write bdata
end
end
end
rescue
raise if @debug
puts "[!] #{$!}"
end
def check_file fname
process_file fname, :decrypt => false
end
def decrypt_file fname
process_file fname, :decrypt => true
end
def process_mask mask
Find.find(mask) do |fname|
next unless File.file?(fname)
decrypt_file fname
end
end
if ARGV.any?
ARGV.each do |mask|
process_mask mask
end
else
process_mask 'c:/Documents and Settings'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment