Stripping Upatre Trojan Downloader

Upatre is a trojan downloader widely used to download banking botnets . It recently started using compression and XOR encoding . Upatre comes with a custom packer . After unpacking real nasty evil code is revealed . Unpacking Upatre is little bit tricky . Following Blog post will show you how to unpack and rebuild Upatre.

This is what Upatre looks like when you open it up in a debugger .

Untitled.jpg

If we skip the decoding routine . We land at OEP which looks something like this.
[Untitled.jpg]

Untitled.jpg

Calls like CALL DWORD PRT SS :[EBP + 30] are windows API calls. Before jumping to the OEP all the API call addresses are pushed on to the stack . So building a IAT for this type of packer would be a tricky job .

Tracing API calls. #

For tracing the destination of all these indirect API calls made after OEP , we will parse a trace file . One thing to take care of is the installer and downloader . So we have to trace for both the installer and downloader basic blocks . This can be done by patching some jumps in the file .

Untitled.jpg

A jump is where the installation path is checked with the current path , another is when the original file is set up for deletion .

After running the trace on both the patched and non-patched binaries , we will concatenate the result and get the following result ( only CALL’s are filtered out )

Untitled.jpg

We will log the destination address of these Each API calls . For that purpose we will create an immunity debugger’s pycommand script to log the API calls .
Sample pycommands file to hook at CALL [EBP =- X ] functions


import immlib
from immlib import LogBpHook
dbg = immlib.Debugger()
import struct
class Myhook(LogBpHook):
def init(self):
LogBpHook.init(self)
return
def run(self, regs):
imm = immlib.Debugger()
opc = imm.disasm(regs['EIP'])
CallDis = opc.getDisasm()
imm.log("Disasm = %s" % CallDis[CallDis.find("[") + 5: CallDis.find("]") ])
disp = int(CallDis[CallDis.find("[") + 5: CallDis.find("]") ], 16)
addrx = regs['EBP'] + disp
imm.log("Address = %d" % addrx)
addr = imm.readLong(addrx)
fp = open("addrs.txt", "a")
fp.write(imm.getFunction(addr).getName() +","+ str(regs['EIP'])"\n")
fp.close()
return
def main(args):
bplist = []
fp =open("Calls.txt", "r")
for i in fp:

bplist.append(int(i.split()[0], 16))
fp.close()
logbp = Myhook()
for i in bplist:
funcName = dbg.getFunction(i).getName()
logbp.add(funcName,i)
return "done..."

This script will parse the run trace file and will put a log breakpoint on each function to recode the destination and save it in a file .

Later on we can read the file and name the indirect functions again using a
pycommands script.


import immlib
def main(args):
fp = open("addrs.txt", "r")
dbg = immlib.Debugger()
for line in fp:
addr = int(line.split(",")[1],10)
name = line.split(",")[0]
dbg.setComment(addr, name)
return "Done..."

Untitled.jpg

This script will automatically generate names at the indirect call addresses.

Creating a Loader for dump file #

Upatre OEP code is a position independent code , but it depends on address pushed on the stack after dumping the .text section we can place it inside a PE skeleton and place our loader there .

For a skeleton exe we will use this awesome nasm file :(http://www.phreedom.org/research/tinype/) by Alexander Sotirov.

Untitled.jpg

And in the loader stub we will copy all the stack address and push it .

Untitled.jpg

After compiling this nasm file , we will get an exe file as an output with all names and strings visible .
Untitled.jpg

Untitled.jpg

Happy Unpacking

Raashid Bhat

http://twitter.com/raashidbhatt

 
58
Kudos
 
58
Kudos

Now read this

Practical Threat Hunting and Incidence Response : A Case of A Pony Malware Infection

Most organizations opt for an incidence response , after a catastrophic cyber security event has taken place . Incidence response and threat hunting focus on events that happen after an endpoint is hit by a cyber attacks ,for example a... Continue →