Created
January 17, 2012 13:09
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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