Malware/malware analysis

[Agent Tesla 뢄석 (2)] .NET λͺ¨λ“ˆ μΆ”μΆœ 및 뢄석

μœ€μ •_ 2025. 4. 3. 16:57

μ§€λ‚œλ²ˆ λΆ„μ„ν•˜λ˜ .NET μ•…μ„±μ½”λ“œλ₯Ό μ΄μ–΄μ„œ λΆ„μ„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

μƒ˜ν”Œ ν•΄μ‹œ(SHA256)λŠ” ed22dd68fd9923411084acc6dc9a2db1673a2aab14842a78329b4f5bb8453215μž…λ‹ˆλ‹€.

 

 

 

β—‹ (stage 3) DotNetZipAdditionalPlatforms λͺ¨λ“ˆ 뢄석

ν•΄λ‹Ή 데이터도 λ‚œλ…ν™” ν•΄μ œλœ λ°μ΄ν„°λ‘œ λ©”λͺ¨λ¦¬μ— λ‘œλ“œν•΄μ£Όκ² μŠ΅λ‹ˆλ‹€.

 

- λ‚œλ…ν™” ν•΄μ œν•˜μ—¬ λ‘œλ“œν•˜κΈ°

μ•„κΉŒμ²˜λŸΌ de4dot λ‚œλ…ν™” ν•΄μ œν•΄μ£Όλ €κ³  ν•©λ‹ˆλ‹€. μ΄λ²ˆμ—λŠ” λ‚œλ…ν™” μ˜΅μ…˜(Deobfuscator option)을 μ§€μ •ν•΄μ„œ,
de4dot <target_file> -p dr3 -o <renamed_file>을 μ‚¬μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€. .NET Reactor 3.x으둜 λ‚œλ…ν™”λ˜μ–΄ μžˆμœΌλ‹ˆ dr3 μ˜΅μ…˜μœΌλ‘œ μ§€μ •ν•΄μ£Όκ² μŠ΅λ‹ˆλ‹€.

λ‚œλ…ν™” ν•΄μ œ (λ‚˜λ¦„) 성곡

κΉ”λ”ν•˜κ²ŒλŠ” μ•ˆλμ§€λ§Œ 이정도면 μ“Έλ§Œν•©λ‹ˆλ‹€.

μ•„κΉŒλž‘ λ˜‘κ°™μ΄ 데이터가 μ €μž₯된 λ³€μˆ˜ byte_의 memory에 λΆ™μ—¬λ„£κ³  μ‹€ν–‰ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

λͺ¨λ“ˆ DotNetZipAdditionalPlatforms이 μΆ”κ°€μ μœΌλ‘œ 잘 λ‘œλ“œλœ 것은 ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

λ‘œλ“œλœ DotNetZipAdditionalPlatforms λͺ¨λ“ˆ

 

 

λ‹€μ‹œ μ½”λ“œλ‘œ λŒμ•„μ˜€λ‹ˆ λ‘œλ“œλ˜λŠ” λͺ¨λ“ˆμ—μ„œ Class12 클래슀의 smethod_10 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ €λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€.

 

ν•΄λ‹Ή λ©”μ„œλ“œμ™€ .cctor에 breakpointλ₯Ό κ±Έκ³  μ‹€ν–‰ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

.cctor()μ—μ„œ 히트

.cctor()μ—μ„œ νžˆνŠΈλ˜μ–΄ λ©ˆμ·„μŠ΅λ‹ˆλ‹€.

 

ν•΄λ‹Ή 클래슀λ₯Ό μžμ„Ένžˆ λΆ„μ„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

- DotNetZipAdditionalPlatforms(stage 3) λΆ„μ„ν•˜κΈ°: β‘  .cctor()

Class12 클래슀

 

[line 6]

λ¦¬μ†ŒμŠ€λ₯Ό λ¦¬μ‘ΈλΉ™ν•˜κΈ° μœ„ν•΄ Class48.smethod_2 λ©”μ„œλ“œλ₯Ό 이벀트 ν•Έλ“€λŸ¬λ‘œ λ“±λ‘ν•©λ‹ˆλ‹€.

ResourceResolve μ΄λ²€νŠΈκ°€ λ°œμƒν•  λ•Œλ§ˆλ‹€ Class48.smethod_2 λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ˜λŠ”λ°, smethod_2 λ©”μ„œλ“œλŠ” λ¦¬μ†ŒμŠ€λ₯Ό 찾을 수 없을 λ•Œ ν•΄λ‹Ή λ¦¬μ†ŒμŠ€λ₯Ό 리쑸빙할 방법이 μ •μ˜λœ λ©”μ„œλ“œμΈ 것 κ°™μŠ΅λ‹ˆλ‹€.

Class48 클래슀 λ‚΄μ—μ„œ ν˜ΈμΆœλ˜λŠ” Class48.smethod_2 λ©”μ„œλ“œ

  • AppDomain.CurrentDomain.ResourceResolve
    • νŠΉμ • λ¦¬μ†ŒμŠ€λ₯Ό λ™μ μœΌλ‘œ λ¦¬μ‘ΈλΉ™ν•˜λŠ”λ° μ‚¬μš©λ˜λŠ” 이벀트
    • 주둜 μ–΄μ…ˆλΈ”λ¦¬ λ‚΄ λ¦¬μ†ŒμŠ€λ‚˜ μ™ΈλΆ€ λ¦¬μ†ŒμŠ€κ°€ λ‘œλ“œλ˜μ§€ μ•Šκ±°λ‚˜ 찾을 수 없을 λ•Œ λ°œμƒ

 

[line 8]

Class44.smethod_11λ₯Ό ν˜ΈμΆœν•˜μ—¬ Class12.string_0 κ°’(deJGfXGlPZoPd)을 κ°€μ Έμ˜΅λ‹ˆλ‹€.

smethod_11λŠ” AES λ³΅ν˜Έν™” λ£¨ν‹΄μœΌλ‘œ μΆ”μΈ‘λ©λ‹ˆλ‹€.

κ³„μ‚°λ˜μ–΄ λ°˜ν™˜λœ string_0

 

[line 72-77]

Class12: line 72-77
λ°˜ν™˜λœ λ¬Έμžμ—΄

smethod_8κ³Ό smethod_11 λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄μ„œ λ³΅ν˜Έν™”λœ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.

smethod_8 λ©”μ„œλ“œλŠ” GetDelegateForFunctionPointer()λ₯Ό 톡해 λ„€μ΄ν‹°λΈŒ ν•¨μˆ˜μ— λŒ€ν•œ 포인터λ₯Ό .NET μ½”λ“œ λ‚΄μ—μ„œ ν˜ΈμΆœν•  수 μžˆλ„λ‘ 델리게이트 νƒ€μž…μœΌλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.

 

  • 델리게이트(delegate)
    • μ •μ˜
      • νŠΉμ • μ‹œκ·Έλ‹ˆμ²˜λ₯Ό κ°€μ§„ λ©”μ„œλ“œλ₯Ό κ°€λ¦¬ν‚€λŠ” νƒ€μž…μœΌλ‘œ νŠΉμ • ν˜•μ‹μ˜ λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό μ €μž₯ν•  수 μžˆλŠ” λ³€μˆ˜
      • μ–Έμ œλ“ μ§€ ν˜ΈμΆœν•  수 μžˆλŠ” λ©”μ„œλ“œ λ˜λŠ” λ©”μ„œλ“œ λͺ©λ‘μ— λŒ€ν•œ μ°Έμ‘°(포인터)λ₯Ό μ œκ³΅ν•˜λŠ” 객체(데이터 ꡬ쑰체/클래슀)

    • νŠΉμ§•
      • λ©”μ„œλ“œμ˜ 포인터라고 생각할 수 μžˆμŠ΅λ‹ˆλ‹€.
      • λ§€κ°œλ³€μˆ˜μ™€ λ°˜ν™˜κ°’μ˜ μ‹œκ·Έλ‹ˆμ²˜κ°€ μΌμΉ˜ν•˜λŠ” λ©”μ„œλ“œλ§Œ μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
      • 델리게이트 νƒ€μž…μ€ λ©”μ„œλ“œμ˜ μ£Όμ†Œ(ν•¨μˆ˜ 포인터와 μœ μ‚¬), ν•΄λ‹Ή νŒŒλΌλ―Έν„°, λ°˜ν™˜ νƒ€μž…μ„ λ³΄μœ ν•˜κΈ° λ•Œλ¬Έμ— ꡬ쑰체둜 해석할 수 μžˆμŠ΅λ‹ˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— λͺ‡λͺ‡ 개의 λ¬Έμžμ—΄μ„ 인수둜 λ°›κ³ , λ‹€λ₯Έ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ— λŒ€ν•œ 델리게이트 νƒ€μž…λ„ λ§Œλ“€ 수 μžˆμ”λ‹ˆλ‹€.
      • 델리게이트 ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 델리게이트 νƒ€μž…μ„ μ •μ˜ν•˜λ©΄ λΈλ¦¬κ²Œμ΄νŠΈμ— ν•„μš”ν•œ λͺ¨λ“  정보λ₯Ό κ³΅μœ ν•˜λŠ” 클래슀(데이터 ꡬ쑰체)κ°€ μƒμ„±λ©λ‹ˆλ‹€.

 

  • GetDelegateForFunctionPointer
    • .NETμ—μ„œ λ„€μ΄ν‹°λΈŒ μ½”λ“œ(ex, C, C++)의 ν•¨μˆ˜ 포인터λ₯Ό 델리게이트둜 λ³€ν™˜ν•˜λŠ” λ©”μ„œλ“œ

 

 

Class12λŠ” λ§Žμ€ 델리게이트λ₯Ό μ‚¬μš©ν•˜κ³  있고 λͺ¨λ‘ λ„€μ΄ν‹°λΈŒ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

Class12μ—μ„œ μ‚¬μš©ν•˜λŠ” 델리게이트 λͺ©λ‘

 

APIλͺ… λ°˜ν™˜: Wow64GetThreadContext
APIλͺ… λ°˜ν™˜: GetThreadContext, VirtualAllocEx, WriteProcessMemory
APIλͺ… λ°˜ν™˜: ReadProcessMemory
APIλͺ… λ°˜ν™˜: ZwUnmapVIewOfSection, CreateProcessA

λ°˜ν™˜λœ APIλ₯Ό λ³΄λ‹ˆ code injection에 μ‚¬μš©λ˜λŠ” VirtualAllocEx, WriteProcessMemory, SetThreadContext, ResumeThreadκ°€ μžˆμŠ΅λ‹ˆλ‹€.

 

 

μ΅œμ’…μ μœΌλ‘œ .cctor()λŠ” λ„€μ΄ν‹°λΈŒ ν•¨μˆ˜μ— λŒ€ν•œ 델리게이트(μ°Έμ‘°)λ₯Ό μƒμ„±ν•˜λŠ”λ° μ‚¬μš©λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

λΈλ¦¬κ²Œμ΄νŠΈμ™€ λ°˜ν™˜λœ APIλ₯Ό μ •λ¦¬ν•˜μžλ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • Class12.delegate0_0 → "ResumeThread"
  • Class12.delegate1_0 → "Wow64SetThreadContext"
  • Class12.delegate2_0 → "SetThreadContext"
  • Class12.delegate3_0 → "Wow64GetThreadContext"
  • Class12.delegate4_0 → "GetThreadContext"
  • Class12.delegate5_0 → "VirtualAllocEx"
  • Class12.delegate6_0 → “WriteProcessMemory"
  • Class12.delegate7_0 → "ReadProcessMemory"
  • Class12.delegate8_0 → "ZwUnmapViewOfSection"
  • Class12.delegate9_0 → "CreateProcessA"

 

 

.cctor()κ°€ μ’…λ£Œλ˜λ©΄ smethod_10 λ©”μ„œλ“œκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

- DotNetZipAdditionalPlatforms(stage 3) λΆ„μ„ν•˜κΈ°: β‘‘ smethod_10()

smethod_10 λ©”μ„œλ“œμ—μ„œλŠ” λ§Žμ€ λ©”μ„œλ“œκ°€ 호좜되고 μžˆμŠ΅λ‹ˆλ‹€.

smethod_10μ—μ„œ μ‚¬μš©λœ λ©”μ„œλ“œλ“€

 

이 μ€‘μ—μ„œ μ–΄λ–€ λ©”μ„œλ“œκ°€ μ˜λ―Έκ°€ μžˆμ„μ§€ μ•Œμ•„λ‚΄κ³  싢은데!!

μ•„κΉŒ .cctorμ—μ„œμ˜ 델리게이트 정보λ₯Ό μ‚΄νŽ΄λ³΄λ©΄ λͺ¨λ“  λΈλ¦¬κ²Œμ΄νŠΈκ°€ smethod_9μ—μ„œ μ‚¬μš©λ˜κ³  μžˆλ‹€λŠ” 것을 μ•Œμ•„λƒˆμŠ΅λ‹ˆλ‹€.

smethod_9μ—μ„œ λͺ¨λ“  λΈλ¦¬κ²Œμ΄νŠΈκ°€ μ‚¬μš©λ¨

 

Analyze - Read By - Used Byμ—μ„œ 호좜 μˆœμ„œλ₯Ό μ‚΄νŽ΄λ³΄λ‹ˆ smethod_10  smethod_12  smethod_9 μˆœμ„œλ‘œ ν˜ΈμΆœλ˜λŠ” 것을 μ•Œκ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

λ©”μ„œλ“œ 호좜 μˆœμ„œ

 

λ‹€μŒ μˆœμ„œλ‘œ smethod_9λ₯Ό 뢄석해보면 쒋을 것 κ°™μŠ΅λ‹ˆλ‹€.

 

 

- DotNetZipAdditionalPlatforms(stage 3) λΆ„μ„ν•˜κΈ°: β‘’ smethod_9()

smethod_9둜 κ°€μ„œ, μ‚¬μš©λ˜λŠ” λΈλ¦¬κ²Œμ΄νŠΈμ— breakpointλ₯Ό μ„€μ •ν•˜κ³  λ””λ²„κΉ…ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

smethod_9μ—μ„œ μ‚¬μš©λ˜λŠ” λͺ¨λ“  λΈλ¦¬κ²Œμ΄νŠΈμ— breakpoint μ„€μ •

 

그리고 smethod_9 μ „ λ‹¨κ³„λ‘œ μ‹€ν–‰λ˜λŠ” smethod_10에도 breakpointλ₯Ό μ„€μ •ν•˜λ €κ³  ν–ˆμœΌλ‚˜, λ„ˆλ¬΄ κΈΈμ–΄μ„œ μ΄ν•΄ν•˜κΈ° νž˜λ“€ 것 κ°™μŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ λ‹€λ₯Έ smethod_#λ“€μ˜ μ—­ν• λΆ€ν„° λΉ λ₯΄κ²Œ μ‚΄νŽ΄λ΄μ•Όκ² μŠ΅λ‹ˆλ‹€.

 

 

smethod_# 뢄석

smethod_0

smethod_0의 Uses

μ•…μ„±μ½”λ“œκ°€ λΆ„석 μ€‘에 μ‚¬μš©λ˜λŠ” λ„ꡬλ₯Ό νƒμ§€ν•˜κΈ° μœ„ν•΄ λ§Žμ΄ μ‚¬μš©ν•˜λŠ” FindWindow()κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

 

 

smethod_1

smethod_1의 Uses

smethod_1λŠ” mutex κ΄€λ ¨ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ 쀑볡 싀행을 νƒμ§€ν•©λ‹ˆλ‹€.

 

 

smethod_2

smethod_2 ν•¨μˆ˜

smethod_2λŠ” smethod_3μ—μ„œ μ œκ³΅λœ μŠ€λ ˆλ“œλ₯Ό μ‹œμž‘ν•˜λŠ” μ—­ν• μ˜ wrapperμž…λ‹ˆλ‹€.

 

 

smethod_3

smethod_3의 Uses

smethod_3은 ν”„λ‘œμ„ΈμŠ€λ‚˜ μŠ€λ ˆλ“œλ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•œ ν•¨μˆ˜λ“€μ„ ν˜ΈμΆœν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

 

 

smethod_4, smethod_5

smethod_4 일뢀
smethod_5 일뢀

 

smethod_4와 smethod_5μ—μ„œλŠ” DirectorySecurity, SetAccessControl, SetAccessRuleProtection, FileSystemAccessRule, AddAccessRule APIκ°€ μ‚¬μš©λ˜λŠ” 것을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 이 API듀은 Windows 파일 μ‹œμŠ€ν…œμ—μ„œ νŒŒμΌμ΄λ‚˜ 디렉터리에 λŒ€ν•œ μ ‘κ·Ό κΆŒν•œμ„ κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λ©°, ACL(Access Contorl List)λ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•œ κ²ƒμž…λ‹ˆλ‹€.

  • DirectorySecurity: ACLλ₯Ό κ΄€λ¦¬ν•˜λŠ”λ° μ‚¬μš©λ©λ‹ˆλ‹€. λ””λ ‰ν„°λ¦¬μ˜ λ³΄μ•ˆ 정보에 μ ‘κ·Όν•˜κ³  μˆ˜μ •ν•˜λŠ” κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.
  • SetAccessControl: νŒŒμΌμ΄λ‚˜ λ””λ ‰ν„°λ¦¬μ˜ ACL을 μ„€μ •ν•˜λŠ”λ° μ‚¬μš©λ©λ‹ˆλ‹€.
  • SetAccessRuleProtection: νŠΉμ • νŒŒμΌμ΄λ‚˜ 디렉터리에 λŒ€ν•œ 상속을 μ œμ–΄ν•˜λŠ”λ° μ‚¬μš©λ©λ‹ˆλ‹€. ACL 상속 μ—¬λΆ€λ₯Ό μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • FileSystemAccessRule: νŠΉμ • 파일 λ˜λŠ” 디렉터리에 λŒ€ν•œ μ ‘κ·Ό κΆŒν•œμ„ μ •μ˜ν•©λ‹ˆλ‹€.
  • AddAccessRule: μƒˆλ‘œμš΄ μ ‘κ·Ό κ·œμΉ™μ„ μΆ”κ°€ν•˜λŠ”λ° μ‚¬μš©λ©λ‹ˆλ‹€.

 

 

smethod_6

smethod_6의 Uses

smethod_6λŠ” μ—¬λŸ¬ APIλ₯Ό ν˜ΈμΆœν•˜μ—¬ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹€ν–‰/κ΄€λ¦¬ν•˜κ±°λ‚˜, νŒŒμΌμ„ μ²˜λ¦¬ν•˜λŠ” 것 같은 μž‘μ—…μ„ ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

 

 

smethod_7

smethod_7 일뢀

smethod_7μ—λŠ” μΈν„°λ„·μ—μ„œ λ‹€μš΄λ‘œλ“œ ν•˜λŠ” κ³Όμ •이 μžˆμŠ΅λ‹ˆλ‹€.

 

 

smethod_8

smethod_8의 Used By 및 Uses

smethod_8은 .cctor()에 μ˜ν•΄ ν˜ΈμΆœλ©λ‹ˆλ‹€. κ·Έλ¦¬κ³  LoadLibraryA와 GetProcAddressλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. μ΄λŠ” λΈλ¦¬κ²Œμ΄νŠΈλ₯Ό ν†΅ν•΄ μ‚¬μš©λ  λ„€μ΄ν‹°λΈŒ API μ£Όμ†Œλ₯Ό μ°ΎλŠ” κ²ƒ κ°™μŠ΅λ‹ˆλ‹€.

 

 

 

smethod_9

smethod_9의 Uses

smethod_9λŠ” Invoke ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. μ΄λ―Έ μ–ΈκΈ‰λœ λ„€μ΄ν‹°λΈŒ API듀을 λΈλ¦¬κ²Œμ΄νŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ ν˜ΈμΆœν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

 

 

smethod_11

smethod_11의 Uses

smethod_11은 μ—¬λŸ¬ APIλ₯Ό ν˜ΈμΆœν•˜μ§€λ§Œ Assembly.Load()κ°€ κ°€μž₯ λˆˆμ—¬κ²¨ λ³Ό λŒ€μƒμž…λ‹ˆλ‹€. ν•΄λ‹Ή μ€„에 breakpointλ₯Ό μ„€μ •ν•˜κ³  μ§„행해보면 μ’‹μ„ κ²ƒ κ°™μŠ΅λ‹ˆλ‹€. μ΄ μƒˆλ‘œμš΄ λͺ¨λ“ˆμ΄ λ‹€μŒ λ‹¨κ³„μ΄κ±°λ‚˜ μ§€μ› λͺ¨λ“ˆ(λ¦¬μ†ŒμŠ€)일 μˆ˜λ„ μžˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

 

 

smethod_12, smethod_13

smethod_12

smethod_12λŠ” smethod_13의 ν”„λ‘μ‹œ λ©”μ„œλ“œμž…λ‹ˆλ‹€. 

 

smethod_13은 GetEntryAssembly, get_Location, GetTypeFromHandle, InvokeMember λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ³  μžˆλŠ” κ²ƒμœΌλ‘œ 보아 λ©”μ„œλ“œ 호좜과 κ΄€λ ¨λœ μž‘μ—…μ„ ν•©λ‹ˆλ‹€.

 

 

글이 κΈΈμ–΄μ Έμ„œ λ‹€μŒ ν¬μŠ€νŒ…μ—μ„œ μ΄μ–΄μ„œ λΆ„μ„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

 

Ref. "Malware Analysis Series(MAS) – Article 4", Alexandre Borges