출처 : http://blog.danggun.net/2040




wcf가 예전에 사용하던 방식과 달라 이것저것 테스트 하다가 간만에 뜬 에러

 

크로스 스레드 작업이 잘못되었습니다.

아....

 

예전에 WPF에서 한번 소개 하긴 했었습니다만 윈폼에서는 약간다르죠.

(참고 : [WPF] 다른 쓰레드에서 UI쓰레드 접근하기 - Dispatcher.Invoke)

 

 

1. 일반적인 방법

일반적으로 인보크(Invoke)를 사용하려면 델리게이트(Delegate)를 만들어야 합니다.

(참고 : MSDN - Control.Invoke 메서드)

 

일반적인 방법에서는 다음과 같은 순서로 인보크를 사용합니다.

1) 델리게이트 선언

2) 델리게이트에 연결할 함수 생성

3) 델리게이트와 생성한 함수 연결

4) 인보크로 델리게이트 호출

 

 

//1) 델리게이트 선언
/// <summary>
/// 델리게이트 선언(연결 할 함수와 같은 모양이 되도록 만든다.)
/// </summary>
/// <param name="sData"></param>
private delegate void DataDelegate(string sData);

//2) 델리게이트에 연결할 함수 생성
/// <summary>
/// 실제 동작하는 함수(연결 할 함수)
/// </summary>
private void DelegteFuntion(string sData)
{
	label2.Text = sData;
}

//3) 델리게이트와 생성한 함수 연결
//4) 인보크로 델리게이트 호출
//사용할때
this.Invoke(new DataDelegate(DelegteFuntion), "Test!");

 

코드 라인끝

 

이 방법의 가장큰 문제는 원하는 동작만큼 델리게이트를 선언해야 한다는 것입니다-_-;;;;;

그래서 간소화 방법을 사용하죠.

 

 

 

 

 

 

2. 간소화 방법

간소화 방법은 일반적인 방법과는 달리 한줄로  델리게이트를 선언하는 방법 입니다.

메소드인보커 대리자(MethodInvoker Delegate)를 이용하는 방법이죠.

(참고 : MSDN - MethodInvoker 대리자)

 

this.Invoke(new Action(
	delegate()
	{
		label2.Text = "Test";
	}));

//혹은

this.Invoke(new MethodInvoker(
	delegate()
	{
		label2.Text = "Test";
	}));

 

 

깔끔하게 됐죠?

 

메소드인보커를 이용하면 델리게이트를 전역으로 선언하지 않고 사용할수 있습니다.

단 해당 데리자를 따로 저장하지 않으면 1회만 사용할 수 있습니다.

 

 

3. 자신의 쓰래드인지 확인하기

하지만 자신의 쓰래드에서 인보크를 시도하면 에러가 납니다.

이걸 해결하려면 'InvokeRequired'속성을 써야 합니다.

'InvokeRequired'속성은 'System.Windows.Forms'에 속해있는 속성으로 호출된 메소드가 같은 쓰래드인지 아닌지 확인해 줍니다.

if( true == InvokeRequired)
{
	//다른 쓰래드다.
}
else
{
	//같은 쓰래드다.
}

다른 쓰래드일때는 인보크를 해야하고 같은 쓰래드일때는 필요없습니다.

마무리

검색하다가 안 사실이지만 의외로 델리게이트를 간략화 해서 쓰는걸 모르시는 분들이 많으시군요 ㅡ.ㅡ;;;

제 기억으론 책에서도 나왔던거 같은데;;;(아닌가?)

이럴줄 알았으면 빨리 포스팅을 하는 거였는데 ㅡ,.ㅡ;;;

 

 

 


저작자 표시 비영리 변경 금지
신고

'language > C#' 카테고리의 다른 글

[.Net] 크로스 스레드(Cross Thread) 오류 해결을 위한 인보크(Invoke)  (0) 2017.09.29
전역 후킹  (0) 2014.08.29
Diskflt.sys 치료 코드  (0) 2014.08.27
디어셈블러  (0) 2013.08.23
[C#] VisualStudio 디버깅 중 Memory 영역을 보는 방법  (0) 2013.07.04
C# DataGridView  (0) 2013.06.05

그 악성코드 키 값

Analysis 2017.09.13 13:23 posted by muhan56

 

 

[사진 1] 정상 모듈에 들어간 코드

 

 

 

[사진 2] DNS 쿼리한 다음에 받은 값을 이용하여 바이너리를 디코딩하는 로직

 

 

원래는 DNS 에서 정상적으로 질의가 되면 키 값을 넣어 내부에 바이너리가 디코딩되지만

 

분석 당시 DNS에 등록된 정보가 없어서 키 값을 알 수 없어 더 이상 분석을 할 수 없었지만

 

분석 정보를 정리하다가 [사진 1]과 [사진 2]의 로직을 봤는데...자세히 보니까 비슷하네요?

 

혹시나? 해서 [사진 1]에 있는 값을 변경(뺄샘 값을 덧샘 값에 맞게 바꿈)하고 [사진 2]에 넣었더니 바로 풀리네요?

 

 

[사진 3] 디코딩을 위한 키 값

 

네..그렇게 해서 풀었고 키 값은 0xC9BED351, 0xA85DA1C9 입니다 :D

 

저작자 표시 비영리 변경 금지
신고

'Analysis' 카테고리의 다른 글

그 악성코드 키 값  (0) 2017.09.13
C#  (0) 2017.07.27
busybox mips 용  (0) 2016.11.02
qemu mips 디버깅  (0) 2016.09.22
IRP MajorFunction  (0) 2016.03.04
코드인젝션에 대해 잘 설명한 자료  (0) 2016.02.17

C#

Analysis 2017.07.27 11:01 posted by muhan56

WEDNESDAY, JULY 19, 2017

Unravelling .NET with the Help of WinDBG

This blog was authored by Paul Rascagneres and Warren Mercer.

INTRODUCTION


.NET is an increasingly important component of the Microsoft ecosystem providing a shared framework for interoperability between different languages and hardware platforms. Many Microsoft tools, such as PowerShell, and other administrative functions rely on the .NET platform for their functionality. Obviously, this makes .NET an enticing language for malware developers too. Hence, malware researchers must also be familiar with the language and have the necessary skills to analyse malicious software that runs on the platform.

Analysis tools such as ILSpy help researchers decompile code from applications, but cannot be used to automate the analysis of many samples. In this article we will examine how to use WinDBG to analyse .NET applications using the SOS extension provided by Microsoft.

This article describes:
  • How to analyse PowerShell scripts by inserting a breakpoint in the .NET API.
  • How to easily create a script to automatically unpack .NET samples following analysis of the packer logic.

Additionally, you can download a Python script (based on the WinDBG pykd extension) on our github to automate analysis of .NET. This script will be described in the article too.



SOS EXTENSION


The SOS Extension provides .NET support for WinDBG. The extension provides a rich set of commands; in this article we will cover only a few that are useful for analysis..

Firstly, the SOS extension is not located in the same library, depending the version of .NET used. Before we are able to use the SOS extension we must load the library into WinDBG.

For .NET 4, the extension is located in CLR.dll and can be loaded with the following command:
.loadby sos clr
In .NET 2 and 3, the SOS extension is located is the mscorwks library:
.loadby sos mscorwks
Here are the commands used in this article:
  • !bpmd: this command is used to put breakpoints in managed code (.NET). The command takes two arguments. The first argument is the .NET dll where the function is located and the second is the function name.
  • !CLRStack: this command displays the CLR stack content. It is useful to identify the arguments of a .NET function.
  • !DumpObj: this command displays information on a specific object specified in an argument.

In this article these 3 commands will be used to create a breakpoint within a specific .NET API, to get the arguments passed to the API, and display the contents.

USE CASE #1: POWERSHELL ANALYSIS


Few people realise that PowerShell can use the .NET framework. By examining .NET API usage, we can easily automate PowerShell analysis.

Example 1: Start-Process API


In this example, we will analyse the following PowerShell code:
PS> start-process notepad.exe
When you perform this task, PowerShell uses the Process.Start() API. So, we can breakpoint, this is where we stop the code execution on purpose, on this API (after loading the SOS extension):
0:011> .loadby sos clr

0:011> !bpmd system.dll System.Diagnostics.Process.Start
Found 6 methods in module 00007fff97581000...
breakpoint: bp 00007FFF977C96D9 [System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo)]
breakpoint: bp 00007FFF97E8057D [System.Diagnostics.Process.Start(System.String, System.String)]
breakpoint: bp 00007FFF97E80539 [System.Diagnostics.Process.Start(System.String)]
breakpoint: bp 00007FFF97E804B6 [System.Diagnostics.Process.Start(System.String, System.String, breakpoint: bp 00007FFF977C72DA [System.Diagnostics.Process.Start()]
Adding pending breakpoints...
Once the breakpoint is set, we can enter the command 'g' to execute the PowerShell script. WinDBG will stop when the Start-Process is executed:
Breakpoint 0 hit
System_ni+0x2496d9:
00007fff`977c96d9 488d0d08711e00  lea     rcx,[System_ni+0x4307e8 (00007fff`979b07e8)]
The CLRStack command displays the argument provided to the Process.Start API. In our case, the argument is a System.Diagnostics.ProcessStartInfo object.
0:008> !CLRStack -p
OS Thread Id: 0x2d34 (8)
        Child SP               IP Call Site
000000a7f9ace700 00007fff977c96d9 System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo)
    PARAMETERS:
        startInfo (<CLR reg>) = 0x0000028cbd5faa18
Finally the DumpObj command shows the contents of this object:
0:008> !DumpObj /d 0000028cbd5faa18
Name:        System.Diagnostics.ProcessStartInfo
MethodTable: 00007fff979ae380
EEClass:     00007fff975e29f0
Size:        144(0x90) bytes
File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
Fields:
              MT    Field   Offset                 Type VT     Attr   Value Name
00007fff9897de98  40027f3    8        System.String  0 instance 28cbd5fde18 fileName
00007fff9897de98  40027f4   10        System.String  0 instance 000 arguments
[...redacted...]
00007fff9897ad70  4002806   58 System.WeakReference  0 instance 000 weakParentProces
00007fff979af0a0  4002807   60 ....StringDictionary  0 instance 000 environmentVaria
00007fff982e5ec0  4002808   68 ...tring, mscorlib]]  0 instance 000 environment
The first field of the ProcessStartInfo object is a System.String object called filename. We can retrieve the contents of the object using DumpObj:
0:008> !DumpObj /d 0000028cbd5fde18
Name:        System.String
MethodTable: 00007fff9897de98
EEClass:     00007fff982d35f0
Size:        88(0x58) bytes
File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String:      C:\WINDOWS\system32\notepad.exe
We can see that the filename string is the path to the notepad binary.

Example 2: DownloadFile API


In this second example, we will analyse the following code:
PS> $a = New-Object System.Net.WebClient
PS> $a.DownloadFile("http://blog.talosintelligence.com/","c:\users\lucifer\demo.txt")
The purpose of this code is to download a file and store it on the hard drive. This is a technique frequently used by malware to download a payload.

If this case, we must put on breakpoint on the DownloadFile AP and press 'g' to execute the PowerShelI:
0:008> .loadby sos clr
0:008> !bpmd system.dll System.Net.WebClient.DownloadFile
Found 2 methods in module 00007fff97581000...
MethodDesc = 00007fff976c1fe8
MethodDesc = 00007fff976c1ff8
Setting breakpoint: bp 00007FFF97DCAE0C [System.Net.WebClient.DownloadFile(System.Uri, System.String)]
Setting breakpoint: bp 00007FFF97DCADBC [System.Net.WebClient.DownloadFile(System.String, System.String)]
Adding pending breakpoints…
0:008> g
When the API is executed, WinDBG will automatically stop the execution of the PowerShell script:
Breakpoint 7 hit
System_ni+0x84adbc:
00007fff`97dcadbc 4885d2          test    rdx,rdx
In this case, we could use the CLRStack and DumpObj commands exactly as previously. Instead, we will get the value directly from the register (the first string is located in RDX+0xC and the second one in R8+0xC, as according to the Microsoft standard for memory location) :
0:008> du rdx+c
0000028c`bd53f13c  "http://blog.talosintelligence.co"
0000028c`bd53f17c  "m/"
0:008> du r8+c
0000028c`bd53f3b4  "c:\users\lucifer\desktop\demo.tx"
0000028c`bd53f3f4  "t"
Here is a snippet of the execution:

USE CASE #2: .NET UNPACK


Talos deals with packed malware samples on a daily basis. We recently identified a packed .NET executable that was being hosted on a Syrian government website: http://www[.]syriantax[.]gov[.]sy/css/igfxCUIService.exe. Initially we wondered if this was part of a targeted attack. After further research, we now believe that the website was compromised and used to deliver this malware. The malware turned out to be njRAT, a well-known public Remote Administration Tool that has been widely distributed for years. While finding njRAT is not particularly interesting, we thought that writing a blog post walking through the process of unpacking njRAT would be beneficial. 

As such, this use case will explain how to deal with unknown .NET packers, using static analysis. We will also cover dynamic analysis using WinDBG as well as how to create a WinDBG script to automate the unpacking process for this type of packer. 

Static Analysis


We started our analysis of this malware sample by using de4dot as it can quickly identify known packers. It is an open source analysis platform available here
C:> de4dot-x64.exe -d -r c:\to_test

de4dot v3.1.41592.3405 Copyright (C) 2011-2015 de4dot@gmail.com

Latest version and source code: https://github.com/0xd4d/de4dot
Detected Unknown Obfuscator (c:\to_test\21acd3457c1a58[...]1bfeeaf3c0cd79bfe)
Detected Unknown Obfuscator (c:\to_test\344ce133363f09[...]bbd2257a298484051)
Detected Unknown Obfuscator (c:\to_test\45c695e610d786[...]af65408fb6080300f)
Detected Unknown Obfuscator (c:\to_test\61653b2811fb7c[...]04f9807a775f25773)
Detected Unknown Obfuscator (c:\to_test\ac7bd77245bdf2[...]aee4d06563f057ca6)
Detected Unknown Obfuscator (c:\to_test\b607e87acdcb2e[...]d30eddddffbeec320)
Detected Unknown Obfuscator (c:\to_test\e93c0aed6bbb4a[...]6c2efe65942f83504)
In this section, we will also be using ILSpy an open source .NET decompiler available here.

XORED VARIANT


Sample: 45c695e610d78178ec5ca6f4e1993afacf4e435b566cd2caf65408fb6080300f

The entry point of the packer is ob6eaGgG7Bht6B35c0.G9puOotvCiNCkEEPD9.XHh0nc9pu, we can identify this information from unpacking with ILSpy:

First, the packer decodes a Base64 encoded string (variable G9puOotvCiNCkEEPD9.EHQI8XHAH ). This decoded string is passed to the function G9puOotvCiNCkEEPD9.vovYCiNCk() along with a second argument that will function as the XOR key:

Scrolling through the output, we are able to identify the XOR operation with ILSpy by looking through the decompiled .NET executable by seeing the '^' function used we can determine this is XOR operation.

Finally the output of the function is passed as an argument to the function Assembly.Load(). This function is used to load .NET binaries.

The argument passed to Assembly.Load() is a byte array and contains a Windows binary (PE32). In this case, the unpacked malware is in the byte array.

AES VARIANT


Sample: 21acd3457c1a589e117988fe0456e50ed627f051a97ccd11bfeeaf3c0cd79bfe

The logic contained within this variant of the packer is the same however instead of using XOR obfuscation, it uses AES encryption (also known as Rijndael):

Finally the decrypted data is then loaded into memory using the Assembly.Load() function.

COMMON POINTS


While the algorithm used by each of the analysed samples is different, encoding versus encryption, the logic is exactly the same. If we can dump the byte array variable found in the argument of the Assembly.Load() function, we have the unpacked malware.

Dynamic Analysis with WinDBG


.NET VERSION 4


In order to perform dynamic analysis of .NET 4 samples, we need to obtain the WinDBG SOS extension available here. This extension allows for .NET 4 debugging using the Microsoft Debugger. 

Let's execute the packed malware…

The first step is to stop the debugger execution when the CLRJIT library is loaded:
0:000> sxe ld clrjit
0:000> g
(dc0.1594): Unknown exception - code 04242420 (first chance)
ModLoad: 70fc0000 71040000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
eax=00000000 ebx=00800000 ecx=00000000 edx=00000000 esi=00000000 edi=0044e000
eip=7736e85c esp=006fe4fc ebp=006fe558 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206

ntdll!NtMapViewOfSection+0xc:
7736e85c c22800          ret     28h
We then load the WinDBG SOS extension to perform analysis on the .NET application (managed application):
0:000> .load "C:\\Psscor4\\x86\\x86\\psscor4.dll"
We now have new WinDBG commands related to .NET debugging available. We can set a breakpoint based on .NET API usage. In this case, we are interested in the Assembly.Load() API:
0:000> !bpmd mscorlib.dll System.Reflection.Assembly.Load
Found 8 methods in module 71041000...
MethodDesc = 71100b50
MethodDesc = 71100b7c
MethodDesc = 71100b88
MethodDesc = 71100b94
MethodDesc = 71100bb8
MethodDesc = 71100bd0
MethodDesc = 71100bdc
MethodDesc = 71100be8
Setting breakpoint: bp 71B29095 [System.Reflection.Assembly.Load(Byte[], Byte[], System.Security.Policy.Evidence)]
Setting breakpoint: bp 71B29037 [System.Reflection.Assembly.Load(Byte[], Byte[], System.Security.SecurityContextSource)]
Setting breakpoint: bp 71B28FFF [System.Reflection.Assembly.Load(Byte[], Byte[])]
Setting breakpoint: bp 71B28F9C [System.Reflection.Assembly.Load(Byte[])]
Setting breakpoint: bp 71395949 [System.Reflection.Assembly.Load(System.Reflection.AssemblyName, System.Security.Policy.Evidence)]
Setting breakpoint: bp 713F3479 [System.Reflection.Assembly.Load(System.Reflection.AssemblyName)]
Setting breakpoint: bp 71B28F3D [System.Reflection.Assembly.Load(System.String, System.Security.Policy.Evidence)]
Setting breakpoint: bp 713C880D [System.Reflection.Assembly.Load(System.String)]
Adding pending breakpoints...
(There is currently a bug in the extension, requiring the command to be executed twice)

The debugger will now stop the execution of the malware when the Assembly.Load() function is executed:
0:000> g

Breakpoint 3 hit
eax=00000000 ebx=006ff2dc ecx=026b30b8 edx=0000000a esi=026b30b8 edi=006ff250
eip=71b28f9c esp=006ff210 ebp=006ff218 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

mscorlib_ni+0xae8f9c:
71b28f9c e80368fdff      call    mscorlib_ni+0xabf7a4 (71aff7a4)
Obviously, we can use the CLRStack and DumpObj commands to get the arguments exactly as mentioned in the previous use case. In this example, we will only use the register content. The argument passed to Assembly.Load() is available on the Stack (ESP):
0:000> dp esp

006ff210  00000000 026b30b8 006ff238 009504ae
006ff220  00000000 00000000 00000000 00000000
006ff230  00000000 00000000 006ff244 7240ea56
006ff240  00a149a8 006ff298 724293ef 006ff2dc
006ff250  006ff288 725b24b0 006ff3b0 724293a8
006ff260  ecebc740 006ff404 006ff370 006ff324
006ff270  7246e611 006ff2dc 00000000 ecebc740
006ff280  006ff250 006ff370 006ff424 725b0890
The second value in the stack is a pointer to the byte array: 0x026b30b8.
0:000> dp 026b30b8 
026b30b8  71504448 00005e00 00905a4d 00000003
026b30c8  00000004 0000ffff 000000b8 00000000

0:000> db 026b30b8+8 L16
026b30c0  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
026b30d0  b8 00 00 00 00 00                                ......
The second argument 0x5e00 is the size of the byte array (in red), after which we can see the file header of the PE file starting with MZ: 0x4d 0x5a (in blue, but reversed due to the data being stored in little endian format). We can now dump the unpacked sample directly from within WinDBG:
.writemem C:\\unpacked_sample.exe 026b30b8+8 L00005e00

.NET VERSION 2 & 3


The dynamic analysis process for malware compiled with .NET Version 2 and 3 is the same. The difference is how the argument is passed to the Assembly.Load() API. In this case, the argument does not use the stack, it is stored in the ECX register instead:
0:000> dp ecx
024ba0b8  71504448 00005e00 00905a4d 00000003
024ba0c8  00000004 0000ffff 000000b8 00000000

0:000> db ecx+8 L16
024ba0c0  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
024ba0d0  b8 00 00 00 00 00     
The format is exactly the same as in the previous example the size of the array is in red and the binary to be loaded is in blue.

Automated Unpacking


Thanks to the analysis described previously, we can create a generic unpacker. You can find this WinDBG script in Appendix 2 for .NET versions 2, 3 and 4. 

This script can be invoked using the following syntax:
"c:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe" -c "$$>a< C:\unpack.script C:\unpacked_sample.exe" "c:\sample.exe"
Here is a screenshot of the script execution:

PYTHON SCRIPT


You can download a python script to automate .NET analysis on our github repository. The script needs the pykd extension in order to allow python execution in WinDBG. The script uses SOS commands previously mentioned in the article, the purpose is to have a better output. The configuration is at the beginning of the script:
dump_byte_array=1
dump_byte_array_path="c:\\path\\to\\directory\\"

bp_list = [ ["system.dll", "System.Diagnostics.Process.Start"],
            ["system.dll", "System.Net.WebClient.DownloadFile"],
            ["mscorlib.dll", "System.Reflection.Assembly.Load"]
          ]
The bp_list variable contains the list of breakpoint. In the example, the script will breakpoint on 3 .NET API (System.Diagnotics.Process.Start, System.Net.WebClient.Download.File and Sysyem.Reflection.Assembly.Load). The arguments of the 3 functions will be display in WinDBG.

If the dump_byte_array variable is set to 1, the script will automatically dump the byte array in provided in the argument on the analysed functions (where the breakpoints are in place). The dump will be located in the dump_byte_array_path directory.

The script allows text or json output. The output of the examples in this article is in text but we can switch in json by setting the JsonDebug variable to "True".

Example 1:


Here is the output of the script when the Assembly.Load function is called:
0:000> .loadby sos clr
0:000> .load pykd.dll
0:000> !py C:\Users\lucifer\NET_plugin.py
[.NET plugin] Beginning, setting breakpoints...
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0xb4fa65
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0xb4fa07
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0xb4f9cf
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0xb4f96c
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0x38a5a1
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0x3bda7d
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0xb4f90d
[.NET plugin] breakpoint: mscorlib.dll System.Reflection.Assembly.Load mscorlib_ni+0x3968dd
[.NET plugin] Let's go...

[.NET plugin] Breakpoint: System.Reflection.Assembly.Load(Byte[])
[.NET plugin] Argument 0: rawAssembly
[.NET plugin] !DumpObj /d 0x02f67e04
        Name:        System.Byte[]
        MethodTable: 6b5f60f8
        EEClass:     6b190878
        Size:        5644(0x160c) bytes
        Array:       Rank 1, Number of elements 5632, Type Byte (Print Array)
        Content:     MZ......................@...............................................!..L.!This program cannot
        Fields:
        None
        
        [.NET plugin] let's dump 0x02f67e04+8 Size:5644
        .writemem c:\users\lucifer\Desktop\dump_1496942775_0x02f67e04_5644.dmp 0x02f67e04+8 L5644
The content of the byte array in argument of Assembly.Load is automatically stored in c:\users\lucifer\Desktop\dump_1496942775_0x02f67e04_5644.dmp

Example 2:


Here is the output of the script on a PowerShell script that execute start-process:
[.NET plugin] Breakpoint: System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo)
[.NET plugin] Argument 0: startInfo
[.NET plugin] !DumpObj /d 0x000001ad173cdb68
        Name:        System.Diagnostics.ProcessStartInfo
        MethodTable: 00007ffd7e3ee798
        EEClass:     00007ffd7e0229f0
        Size:        144(0x90) bytes
        File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
        Fields:
           MT    Field   Offset                 Type VT     Attr      Value Name
        07ffd69e969d0 40027fa   8     System.String  0 instance 01ad173d0f20 fileName
        07ffd69e969d0 40027fb   10    System.String  0 instance 00000000000 arguments
        07ffd69e969d0 40027fc   18    System.String  0 instance 1ad173d4bf8 directory
        07ffd69e969d0 40027fd   20    System.String  0 instance 000000000000 verb
        07ffd7e3c2a50 40027fe   78    System.Int32  1 instance          0 windowStyle
        07ffd69ea1fb0 40027ff   7c    System.Boolean  1 instance        0 errorDialog
        07ffd69eafc48 4002800   70    System.IntPtr  1 instance     0 errorDialogPare
        07ffd69ea1fb0 4002801   7d    System.Boolean  1 instance     1 useShellExecut
        07ffd69e969d0 4002802   28    System.String  0 instance 000000000000 userName
        07ffd69e969d0 4002803   30    System.String  0 instance 000000000000 domain
        07ffd69ea4068 4002804   38 ...rity.SecureString  0 instance 00000000 password
        07ffd69e969d0 4002805   40    System.String  0 instance 0 passwordInClearText
        07ffd69ea1fb0 4002806   7e    System.Boolean  1 instance,  1  loadUserProfile
        07ffd69ea1fb0 4002807   7f    System.Boolean  1 instance   0  redirectStandar
        07ffd69ea1fb0 4002808   80    System.Boolean  1 instance   0 redirectStandard
        07ffd69ea1fb0 4002809   81    System.Boolean  1 instance   0 redirectStandard
        07ffd69e9b048 400280a   48    System.Text.Encoding  0 instance 0 standardOutp
        07ffd69e9b048 400280b   50    System.Text.Encoding  0 instance 0 standardErro
        07ffd69ea1fb0 400280c   82    System.Boolean  1 instance   0 createNoWindow
        07ffd69eadec8 400280d   58 System.WeakReference  0 instance 0000 weakParentPr
        07ffd7e3ef4b8 400280e   60 ....StringDictionary  0 instance 0000 envVariables
        07ffd697a69f0 400280f   68 ...tring, mscorlib]]  0 instance 0000 environment
        
                [.NET plugin] !DumpObj /d 000001ad173d0f20
                Name:        System.String
                MethodTable: 00007ffd69e969d0
                EEClass:     00007ffd697950e0
                Size:        82(0x52) bytes
                File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
                String:      C:\WINDOWS\system32\calc.exe
The script displays the argument and the content of the interesting field (in the example the fileName string).

Example 3:


Here is the output on the script when the DownloadFile API is used in Powershell:
[.NET plugin] Breakpoint: System.Net.WebClient.DownloadFile(System.Uri, System.String)
[.NET plugin] Argument 1: address
[.NET plugin] !DumpObj /d 0x000001ad17315e78
        Name:        System.Uri
        MethodTable: 00007ffd7e3f4cf0
        EEClass:     00007ffd7dfc5fd0
        Size:        72(0x48) bytes
        File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
        Fields:
            MT    Field   Offset             Type VT     Attr            Value Name
        07ffd69e969d0 400040b 8   System.String  0 instance 000001ad172c5ea8 m_String
        07ffd69e969d0 400040c 10  System.String  0 instance 000000000 m_originalUnico
        07ffd7e3f51d8 400040d 18  System.UriParser  0 instance 001ad17032b40 m_Syntax
        07ffd69e969d0 400040e 20  System.String  0 instance 00000000000 m_DnsSafeHost
        07ffd7e3c2788 400040f 30  System.UInt64  1 instance 37615763456 m_Flags
        07ffd7e3f5590 4000410 28  System.Uri+UriInfo  0 instance 01ad17315f00 m_Info
        07ffd69ea1fb0 4000411 38  System.Boolean  1 instance          0 m_iriParsing
        07ffd69e969d0 40003fb 220 System.String  0   shared     static UriSchemeFile
        07ffd69e969d0 40003fc 228 System.String  0   shared     static UriSchemeFtp
        07ffd69e969d0 40003fd 230 System.String  0   shared     static UriSchemeGoph
        07ffd69e969d0 40003fe 238 System.String  0   shared     static UriSchemeHttp
        07ffd69e969d0 40003ff 240 System.String  0   shared     static UriSchemeHttps
        07ffd69e969d0 4000400 248 System.String  0   shared     static UriSchemeWs
        07ffd69e969d0 4000401 250 System.String  0   shared     static UriSchemeWss
        07ffd69e969d0 4000402 258 System.String  0   shared     static UriSchemeMail
        07ffd69e969d0 4000403 260 System.String  0   shared     static UriSchemeNews
        07ffd69e969d0 4000404 268 System.String  0   shared     static UriSchemeNntp
        07ffd69e969d0 4000405 270 System.String  0   shared     static UriSchemeNet
        07ffd69e969d0 4000406 278 System.String  0   shared     static UriSchemeNetP
        07ffd69e969d0 4000407 280 System.String  0   shared     static SchemeDelimit
        07ffd7e3b4bd0 4000412 288 ...etSecurityManager  0       static s_ManagerRef
        07ffd69e96fb0 4000413 290 System.Object  0   shared     static s_IntranetLock
        07ffd69ea1fb0 4000414 9c4 System.Boolean  1   shared    static s_ConfigInitia
        07ffd69ea1fb0 4000415 9c5 System.Boolean  1   shared    static s_ConfigInitia
        07ffd7e3afef8 4000416 9c0 System.Int32  1   shared      static s_IdnScope
        07ffd69ea1fb0 4000417 9c6 System.Boolean  1   shared    static s_IriParsing
        07ffd69e96fb0 4000418 298 System.Object  0   shared     static s_initLock
        07ffd69e97b20 400041c 2a0 System.Char[]  0   shared     static HexLowerChars
        07ffd69e97b20 400041d 2a8 System.Char[]  0   shared     static _WSchars
        
                [.NET plugin] !DumpObj /d 000001ad172c5ea8
                Name:        System.String
                MethodTable: 00007ffd69e969d0
                EEClass:     00007ffd697950e0
                Size:        94(0x5e) bytes
                File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
                String:      http://blog.talosintelligence.com/
                Fields:
                   MT    Field   Offset           Type VT     Attr         Value Name
               07ffd69e99310  400026f  8  System.Int32  1 instance  34 m_stringLength
               07ffd69e97b88  400027   c  System.Char   1 instance  68 m_firstChar
               07ffd69e969d0  4000274  90 System.String 0   shared  static Empty

[.NET plugin] Argument 2: fileName
[.NET plugin] !DumpObj /d 0x000001ad172c61c8
        Name:        System.String
        MethodTable: 00007ffd69e969d0
        EEClass:     00007ffd697950e0
        Size:        92(0x5c) bytes
        File:        C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
        String:      c:\users\lucifer\desktop\demo.txt
        Fields:
             MT    Field   Offset                 Type VT     Attr      Value Name
        07ffd69e99310  400026f  8    System.Int32  1 instance       33 m_stringLength
        07ffd69e97b88  4000270  c    System.Char  1 instance        63 m_firstChar
        07ffd69e969d0  4000274  90   System.String  0   shared      static Empty

The first argument is a System.URI object. The object is automatically parsed and the relevant contents are displayed in WinDBG. In this case, the first field is displayed (the string m_string). This string contains the contacted URL. The second argument is a string which is displayed too.

Example 4:


Here is the output on the script in JSON (start-process execution):
0:020> .loadby sos clr
0:020> .load pykd
0:020> !py c:\Users\lucifer\DotNETPlugin.py
{
  "date": 1500306926,
  "bp": "System.Diagnostics.Process.Start(System.Diagnostics.ProcessStartInfo)",
  "arguments": {
    "0": {
      "fields": {
        "0": {
          "Type": "System.String",
          "Name": "fileName",
          "string": "C:\\WINDOWS\\system32\\calc.exe"
        },
        "1": {
          "Type": "System.String",
          "Name": "arguments",
          "string": ""
        },
        "2": {
          "Type": "System.String",
          "Name": "directory",
          "string": "C:\\Users\\lucifer"
        },
        "3": {
          "Type": "System.String",
          "Name": "verb",
          "string": ""
        },
        [...redacted...]
        "20": {
          "Type": "....StringDictionary",
          "Name": "environmentVariables",
          "value": "0000000000000000"
        },
        "21": {
          "Type": "...tring,",
          "Name": "environment",
          "value": "instance"
        }
      },
      "name": "startInfo",
      "offset": "0x0000025c1c572170"
    }
  }
}

CONCLUSION


WinDBG is a really powerful tool provided by Microsoft. A lack of familiarity with the syntax and interface means that it can be overlooked as a malware analysis tool. With the right extension, it can easily be used for the analysis of managed code (.NET). 

We hope that this article piques your curiosity and that you will think about WinDBG next time you will have to analyse managed code such .NET.

APPENDIX


IOCs


PACKED SAMPLES SHA256


  • 21acd3457c1a589e117988fe0456e50ed627f051a97ccd11bfeeaf3c0cd79bfe
  • 344ce133363f005346210611d5abd2513934a32739bc6e1bbd2257a298484051
  • 45c695e610d78178ec5ca6f4e1993afacf4e435b566cd2caf65408fb6080300f
  • 61653b2811fb7c672584d00417cbc1a56c8372331f1913104f9807a775f25773
  • ac7bd77245bdf284d36ce1f9e2cb6a21d2dbd38aa1964dbaee4d06563f057ca6
  • b607e87acdcb2ef0f102298decc57ca3ea20fabbf02375fd30eddddffbeec320
  • e93c0aed6bbb4af734403e02d399c124f2d07f8e701fb716c2efe65942f83504

UNPACKED SAMPLES SHA256


  • 35dee9106e4521e5adf295cc945355d72eb359d610230142e5dd4adda9678dee
  • b5ce02ee3dfccf28e86f737a6dde85e9d30ff0549ec611d115a1d575b5291c2e
  • d9a732dcf87764a87f17c95466f557fac33f041ac6f244dba006ba155d8e9aea
  • fe068ce56b258762c10cc66525c309e79026c0e44103ca9b223c51382722cb09

WinDBG scripts


BEFORE .NET 4

sxe ld mscorjit
g
.loadby sos mscorwks
!bpmd mscorlib.dll System.Reflection.Assembly.Load
.echo "Weird bug... bp twice..."
!bpmd mscorlib.dll System.Reflection.Assembly.Load
g
r $t1 = ecx
.printf "Byte array: ";r $t1
r $t2 = poi($t1+4)
.printf "Size: ";r $t2
db $t1+8 L$t2
.echo "dump in the file: ${$arg1}"
.writemem ${$arg1} $t1+8 L$t2
.kill
q

.NET 4

sxe ld clrjit
g
.load "C:\\Psscor4\\x86\\x86\\psscor4.dll"
!bpmd mscorlib.dll System.Reflection.Assembly.Load
.echo "Weird bug... bp twice..."
!bpmd mscorlib.dll System.Reflection.Assembly.Load
g
r $t1 = poi(esp+4)
.printf "Byte array: ";r $t1
r $t2 = poi($t1+4)
.printf "Size: ";r $t2
db $t1+8 L$t2
.echo "dump in the file: ${$arg1}"
.writemem ${$arg1} $t1+8 L$t2
.kill
q

출처 : http://blog.talosintelligence.com/2017/07/unravelling-net-with-help-of-windbg.html

저작자 표시 비영리 변경 금지
신고

'Analysis' 카테고리의 다른 글

그 악성코드 키 값  (0) 2017.09.13
C#  (0) 2017.07.27
busybox mips 용  (0) 2016.11.02
qemu mips 디버깅  (0) 2016.09.22
IRP MajorFunction  (0) 2016.03.04
코드인젝션에 대해 잘 설명한 자료  (0) 2016.02.17