Initial static analysis using Floss (FireEye Labs Obfuscated String Solver)

Hello readers, how are you? Few days ago, I heard from a professional that he hasn’t used the strings command (on Linux and Windows) for making an initial static analysis of a malware because the IDA Pro is enough to make a search for such strings and it is not necessary to use an operating system command to perform the same task.

I believe that, most time, he is right, but I have faced many situations where these strings are encrypted (even using a basic XOR instruction) and it turn the investigation harder. Therefore, I have used a simple and straight tool named Floss (FireEye Labs Obfuscated String Solver, written by Willi Ballenthin) which decodes and show string inside a file, saving our important time during a malware analysis.

Installing and using Floss is trivial. First, download and unpack the Floss package:

root@kali:~# wget https://github.com/fireeye/flare-floss/releases/download/v1.1.0/floss-1.1.0-GNU.Linux.4.2.0-30-generic.x86_64.zip

root@kali:~# unzip floss-1.1.0-GNU.Linux.4.2.0-30-generic.x86_64.zip

It follows below a quick test using Floss with a malware named Carberp:

root@kali:~# /root/floss -a AAA._xe

….(snip)….

Static UTF-16 strings

Offset       String

———-   ————————————-

0x000045B4   # @@

0x00025A60   !x-sys-default-locale

0x00025AB1   >A`

0x00025C5E   VS_VERSION_INFO

0x00025CBA   StringFileInfo

0x00025CDE   040904b0

0x00025CF6   CompanyName

0x00025D10   BuML8ymRlYnf

0x00025D32   FileDescription

0x00025D54   0mJ8otjGpz

0x00025D72   FileVersion

0x00025D8C   S3BF7IZ2ZLiF

0x00025DAE   InternalName

0x00025DC8   KayU1y

0x00025DDE   OriginalFilename

0x00025E00   7AhVva8ai

0x00025E1A   ProductName

0x00025E34   08ZkvxeDt8DPLE

0x00025E5A   ProductVersion

0x00025E78   lxqR7dS

0x00025E8E   VarFileInfo

0x00025EAE   Translation

0x00026021   7?@

 

Most likely decoding functions in: AAA._xe

address:    score:

———-  ——-

0x0041335F 0.90000

0x0040282C 0.60000

0x00411BB0 0.30000

0x00411080 0.10000

0x0041385E 0.00000

0x00411710 -1.00000

 

FLOSS decoded 3 strings

Offset       Called At    String

———-   ———-   ————————————-

0xBFB3F898   0x00411A0D   dAbA

0xBFB3F934   0x00411A0D   cERT

0xBFB3F9A4   0x00411A0D   dAbA

 

FLOSS extracted 4 stack strings

Function:   Frame offset  String:

———-  ————  ——-

0x00411710  0x0118    @(IA

0x00411710  0x0119    c@(IA

0x00411710  0x0014    42Xt

0x00411bb0  0x0538    cERT

Finished execution after 1.808447 seconds

 

Another very useful option is –i option which creates an IDA Python script to annotate the decoded string in an IDB file. Therefore, I made a new test by analyzing the Stuxnet malware, but I created, through Floss, an IDA Python script to decorate it in the IDA Pro, as shown below:

root@kali:~/malwares/malwares_complete/stuxnet# /root/floss -i ida_stuxnet.py malware1

Most likely decoding functions in: malware1
address: score:
———- ——-
0x10002060 0.76667
0x10001F81 0.75000
0x10001F5E 0.73333
0x10001103 0.71667
0x100014A4 0.71667
0x10001DAF 0.63333
0x1000203E 0.40000
0x10002493 0.26667
0x1000202A 0.25000
0x1000204F 0.25000

FLOSS decoded 48 strings
Offset Called At String
———- ———- ————————————-
0xBFB3FFA8 0x100014F8 KERNEL32.DLL.ASLR.%08x
0xBFB3FED4 0x10001FD3 ntdll.dll
0xBFB3FF98 0x10002008 SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
0xBFB3FEB4 0x100012B6 kernel32.dll
0xBFB3FF7C 0x100012B6 lstrcmpiW
0xBFB3FF7C 0x100012B6 lstrcmpiW
0xBFB3FEB4 0x100012C6 kernel32.dll
0xBFB3FF7C 0x100012C6 VirtualQuery
0xBFB3FF7C 0x100012C6 VirtualQuery
0xBFB3FEB4 0x100012D6 kernel32.dll
0xBFB3FF7C 0x100012D6 VirtualProtect
0xBFB3FF7C 0x100012D6 VirtualProtect
0xBFB3FEB4 0x100012E6 kernel32.dll
0xBFB3FF7C 0x100012E6 GetProcAddress
0xBFB3FF7C 0x100012E6 GetProcAddress
0xBFB3FEB4 0x100012F6 kernel32.dll
0xBFB3FF7C 0x100012F6 MapViewOfFile
0xBFB3FF7C 0x100012F6 MapViewOfFile
0xBFB3FEB4 0x10001306 kernel32.dll
0xBFB3FF7C 0x10001306 UnmapViewOfFile
0xBFB3FF7C 0x10001306 UnmapViewOfFile
0xBFB3FEB4 0x10001316 kernel32.dll
0xBFB3FF7C 0x10001316 FlushInstructionCache
0xBFB3FF7C 0x10001316 FlushInstructionCache
0xBFB3FEB4 0x10001326 kernel32.dll
0xBFB3FF7C 0x10001326 LoadLibraryW
0xBFB3FF7C 0x10001326 LoadLibraryW
0xBFB3FEB4 0x10001336 kernel32.dll
0xBFB3FF7C 0x10001336 FreeLibrary
0xBFB3FF7C 0x10001336 FreeLibrary
0xBFB3FEB4 0x10001366 kernel32.dll
0xBFB3FF7C 0x10001366 CreateThread
0xBFB3FF7C 0x10001366 CreateThread
0xBFB3FEB4 0x10001376 kernel32.dll
0xBFB3FF7C 0x10001376 WaitForSingleObject
0xBFB3FF7C 0x10001376 WaitForSingleObject
0xBFB3FEB4 0x10001386 kernel32.dll
0xBFB3FF7C 0x10001386 GetExitCodeThread
0xBFB3FF7C 0x10001386 GetExitCodeThread
0xBFB3FEB4 0x10001346 ntdll.dll
0xBFB3FF7C 0x10001346 ZwCreateSection
0xBFB3FF7C 0x10001346 ZwCreateSection
0xBFB3FEB4 0x10001356 ntdll.dll
0xBFB3FF7C 0x10001356 ZwMapViewOfSection
0xBFB3FF7C 0x10001356 ZwMapViewOfSection
0xBFB3FEB4 0x10001396 ntdll.dll
0xBFB3FF7C 0x10001396 ZwClose
0xBFB3FF7C 0x10001396 ZwClose

FLOSS extracted 19 stack strings
Function: Frame offset String:
———- ———— ——-
0x1000109b 0x0020 ?@@@AAAA
0x100016a5 0x009f EAA|
0x100016a5 0x0098 AAAAAAAA
0x100013a6 0x0054 AAAA
0x100024a7 0x0010 AAAAAA
0x100024a7 0x0018 ?@@@?@@@AAAAAA
0x10002529 0x0024 AAAA
0x10002529 0x002f AAAAAAAAAAAAAAA
0x100021fe 0x0014 AAAAAAAA
0x100021fe 0x0008 AAAA
0x100021fe 0x001c AAAAAAAAAAAAAAAA
0x100021fe 0x0018 AAAAAAAAAAAA
0x100025c7 0x001c ?@@@AAAA
0x100025c7 0x0054 ?@@@
0x10001456 0x000c AAAA
0x10002060 0x00a0 AAAA
0x10002060 0x00a7 EAA|
0x10002060 0x00a0 AAAAAAAA
0x10001070 0x0000 AAAA

Wrote IDAPython script file to /root/malwares/malwares_complete/STUXNET_SLIDES/ida_stuxnet.py

Finished execution after 9.483362 seconds

 

It is interesting to check the script:

root@kali:~/malwares/malwares_complete/stuxnet# more ida_stuxnet.py

from idc import MakeComm, MakeRptCmt
def AppendComment(ea, s, repeatable=False):
# see williutils and http://blogs.norman.com/2011/security-research/improving-ida-analysis-of-x64-exception-handling
string = Comment(ea)
if not string:
string = s
else:
if s in string: # ignore duplicates
return
string = string + “\n” + s
if repeatable:
MakeRptCmt(ea, string)
else:
MakeComm(ea, string)

def main():
print “Annotating decoded strings for malware1”
AppendComment(268440824, “FLOSS: KERNEL32.DLL.ASLR.%08x”)
print “FLOSS: string \”KERNEL32.DLL.ASLR.%08x\” decoded at VA 0x100014F8″
AppendComment(268443603, “FLOSS: ntdll.dll”)
print “FLOSS: string \”ntdll.dll\” decoded at VA 0x10001FD3″
AppendComment(268443656, “FLOSS: SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS”)
print “FLOSS: string \”SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\” decoded at VA 0x10002008″
AppendComment(268440246, “FLOSS: kernel32.dll”)
print “FLOSS: string \”kernel32.dll\” decoded at VA 0x100012B6″
AppendComment(268440246, “FLOSS: lstrcmpiW”)
print “FLOSS: string \”lstrcmpiW\” decoded at VA 0x100012B6″
AppendComment(268440246, “FLOSS: lstrcmpiW”)
print “FLOSS: string \”lstrcmpiW\” decoded at VA 0x100012B6″

…..(snip)….

After copying this script above (ida_stuxnet.py) to C:\Program Files (x86)\IDA 6.9\python directory, execute it (you can use ALT+F7 to pick the script up) and you are going to see lines similar those below in the IDA Pro output window:

Annotating decoded strings for malware1

FLOSS: string “KERNEL32.DLL.ASLR.%08x” decoded at VA 0x100014F8

FLOSS: string “ntdll.dll” decoded at VA 0x10001FD3

FLOSS: string “SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS” decoded at VA 0x10002008

FLOSS: string “kernel32.dll” decoded at VA 0x100012B6

FLOSS: string “lstrcmpiW” decoded at VA 0x100012B6

FLOSS: string “lstrcmpiW” decoded at VA 0x100012B6

FLOSS: string “kernel32.dll” decoded at VA 0x100012C6

FLOSS: string “VirtualQuery” decoded at VA 0x100012C6

FLOSS: string “VirtualQuery” decoded at VA 0x100012C6

FLOSS: string “kernel32.dll” decoded at VA 0x100012D6

FLOSS: string “VirtualProtect” decoded at VA 0x100012D6

FLOSS: string “VirtualProtect” decoded at VA 0x100012D6

FLOSS: string “kernel32.dll” decoded at VA 0x100012E6

…..(snip)….

Finally, you can see the final decorating from Floss  generated script in the IDA Pro as shown below:

Floss_IDA_Image

 

It is very important to highlight that Floss is a recent tool (released few days ago), so there are bugs to be fixed. Anyway, it is already a useful tool in the malware analyst’s arsenal. 🙂

Finally, I know that I am away from the blog, but I have been writing several courses and my time to dedicate to blog is very limited. 😦

I hope you have a nice day.

Alexandre Borges

(LinkedIn: http://www.linkedin.com/in/aleborges and twitter: @ale_sp_brazil)

MindTheSec 2015 Forum Brazil – GPU Malware presentation

Dear readers, how are you? It follows the slides of my simple presentation on MindTheSec 2015 Forum Brazil (http://mindthesec.com.br/alexandre-borges) about GPU Malwares:

https://alexandreborgesbrazil.files.wordpress.com/2015/09/2015-mindthesec-alexandre_borges1.pdf

Enjoy it!

I hope you have a nice day and feel free to comment about the slides.

Alexandre Borges

(LinkedIn: http://www.linkedin.com/in/aleborges)