作者:immenma
来源:i春秋社区
第一章:使用PEDoll调戏cmd调用类型的锁机程序
在讨论这个锁机程序之前,我们先来讨论一下如果我们想要改动我们电脑的账户和密码,应该怎么办
当然在控制面板上的创建用户密码,可以非常容易而且非常人性化的完成这一过程
当然这不是唯一的办法,还有一种比较高逼格的办法是使用cmd命令行来完成
就像上面这样,当然,你还可以把它做成批处理或者是VBS/VBE的形式类似这个样子
Wscript.CreateObject("Wscript.Shell").Run "net user dbinary 12345",0,true
这种把戏如果不想那么快被人识破,也就是在文件中右键点编辑的就能查看到密码的话,一种办法是对vbs脚本进行加密,微软显然也发布过这种加密工具,另一种办法就是以其他语言的将这个功能编译为exe,鉴于大部分的锁机软件作者水平也就那么样了,所以几乎都是易语言版本的
代码类似这样
运行("net user 用户名 密码",假,#隐藏窗口)
运行("net user 用户名 密码 /add",假,#隐藏窗口)
运行("net user administrators 同上用户名 /add",假,#隐藏窗口)
当然假如你想进一步提升逼格使用C语言的话
#include <windows.h>
main(){system("net user 用户名 密码");}
两句就能够轻松搞定,其中易语言后面两句,大概就是创建一些名字是提示信息的账户,比如想要密码你需要联系谁之类的,不管怎么样,这种锁机的开发成本实在是太低了,如果我教我那小学的弟弟玩玩,我打赌他也只需要十分钟就能学会,而且他也可以开始吹我也会编程我也是黑客了
但不管上面的代码怎么写,其实本质上仍然是调用了cmd.exe这个程序,通过对这个程序传递命令行参数,来达到修改密码勒索钱财的目的。在编程语言中,基本上可以肯定会调用到CreateProcess(A/W)这个函数(ShellExeC,WinExec底层也调用该函数,当然不排除直接调用更底层的CreateProcessInternalW的可能性,但非常少),因此对付这种锁机程序,我们只需要监视CreateProcess(A/W)就可以了。
我首先收集了一个锁机程序,并通过PeDoll来破解它们。
首先我们来到这个所谓的无成本刷q币,这是一个锁机程序,从文件名的vmp来看,这个软件显然是加了VMP壳的,因此,网上很多流传的更改后缀名txt搜索密码的方法肯定是不管用了,使用ollydbg的话,对没有多少逆向基础的是大大的不友好,并且,这个软件在火眼和哈勃中同样没有结果,不过,这并不影响PeDoll对其进行分析。我们先将它拷贝到虚拟机当中(如图4.1)。
图4.1
然后我们将它的文件名改为sample.exe,以管理员身份运行PeDolls.exe,如图4.2
图4.2
然后我们打开控制器PeDollc.exe,在菜单中点击监视器->连接,然后将虚拟机PeDolls中显示的IP地址输入进去
点击确定按钮,同时按下工具条中的 按钮连接到虚拟机
在控制器的命令框中输入doll db <Sample.exe>
其中,doll命令可以理解为注入调试程序,参数db表示使用创建远程线程的方式注入监视dll(参考dll注入章节),当然还有di(注入到运行进程),iti导入表注入,(bi)OEP篡改注入,(mi)启用输入法注入模式,但目前来看,以db参数使用兼容性较好。
<Sample.exe>就是被监视的可执行文件路径,因为他和pedolls在同一目录下,所以这里我们直接输入文件名就可以了。
现在按下回车,然后点击 按钮连接到监视程序,当你看到下面这个界面,表示监视程序已经准备好了
现在点击规则加载规则脚本,在PeDoll三个文件夹中常用脚本中,选择锁机分析
点击 按钮来hook相关API函数,最后点击
按钮启动调试,当然调试过程中可能会如果没有响应,你也可以通过点击按钮来恢复,很快,PeDoll就拦截了这个锁机程序的结果
从它企图执行的命令来看,他将我们的密码改为了xiaoke,并且创建了勒索信息,它还企图关闭我们的计算机,但是在脚本中,我们已经设置拦截了。
现在这个锁机程序就被破解了,我们可以找到这个qq,并狠狠调戏一番
第二章:使用PEDoll调戏磁盘锁(MBR)锁机程序
在完成前面第一章的小菜后,显然下一步我们要面对一些更加高端点的锁机程序,在此之前,我想先来介绍一下MBR是什么东西。
主引导记录(MBR,Main Boot Record)是位于磁盘最前边的一段引导(Loader)代码,如果你有过文件系统或者是BootLoader的开发经验,你应该对它再熟悉不过了,一般的,你读写一块磁盘(或者是你的SD,TF卡)第一扇区。它负责磁盘分区引导信息的定位,如果没有MBR区,根本就不用谈文件系统。它就像计算机磁盘数据的向导,假如它丢失了,那么你磁盘上的文件很可能就完蛋了(因为缺少文件系统计算机根本没有办法定位识别他们在哪)。
磁盘锁做的工作基本就是将你MBR的数据藏起来,换成它自己的引导代码,很遗憾的是,它必须要你输入密码才给你恢复MBR(当然经常因为代码的兼容性处理的并不好,就是我们说的代码写的和屎一样,所以常常也会及时密码正确仍然没有办法恢复)
当然,在行家手上这种锁基本是非常容易解决的,一般这种锁机程序就是将你的MBR拷贝到了第二或者第三扇区,只要将MBR找回来还原回去,一般都能万事大吉但是在小白手上,这事就变得没那么多简单了。
如果你有仔细阅读前两个章节,这个问题当然我也说过了,绝大部分的磁盘锁程序,会使用CreateFile(A/W)去打开设备符\\\\.\\PHYSICALDRIVE0,引导程序肯定是写在第一扇区也就是MBR区,写大小几乎也是512字节,也就是刚刚好一个扇区大小。
那么,也就是说,我们只需要它打开设备符的时候,将它写进去的数据给dump下来,当中肯定是包含这个磁盘锁的锁机密码了,知道原理后,这个锁机调戏起来一样简单(样本位于附件A04)。
这里我收集了一个磁盘锁的锁机样本,我们将它拷贝到虚拟机中,显然即便是易语言玩家智商也都+1了,他们都不会忘记给自己的玩意加个壳来给大多数小白设置逆向分析障碍。
我们将它重命名为Sample2.exe,重复我们第一章加载规则脚本之前的的步骤(当然命令也变为了doll db <Sample2.exe>)
那么,写文件数据的API是WirteFile,所以,现在,在我们的命令窗口中,
输入hook WriteFile,然后按下回车
现在,完事具备了,我们点击按钮,然后观察结果
现在,在下面的菜单栏中,选择“数据”
一般情况下,第一个512字节的数据,是我们的MBR,这个字符串表明了这点,它就是引导失败时你在电脑屏幕上看到的那段文字。
因此我们点击第二个数据包
在右边的文本显示框可以看到,密码仿佛就唾手可得了,但仍然不是那么明显,因为这种类似BootLoader的代码一般是16位汇编代码写成的,因此我们在编码栏中选择反汇编16位
当然我们没必要看懂16位汇编的代码,没关系,密码一般是以资源的形式存在大,拉到汇编代码的底部,看,密码出现了
没错,密码就是15939477681,看样子应该是这个作者的电话号码?,现在,磁盘锁也在行为分析中宣告沦陷了。
第三章:使用PEDoll调戏钓鱼程序
如果你觉得,前面两个章节仍然不够excited的话,那么接下来两个章节,将会有趣的多,在00年左右的计算机程序开发者,即便是恶意程序的开发者,普遍的质量都会高得多,当时并没有什么所谓打着爱国旗号的“中文开发语言”,当然互联网在国内还是新兴事物,可以查找到的资料也不多,如果希望开发程序,往往意味着需要相当的英语基础,对数据结构了如指掌,熟悉操作系统,各类通讯协议,同时并不高的计算机性能对性能与空间要求更多的优化,所以那时候自由软件的质量,虽然看上去不怎么地,但着实质量会高得多,随着电脑性能的提升,一系列“三个月”培训上岗或是一天入门的编程语言就如雨后春笋一般的冒出,随着开发者的低龄化与编程门槛的大众化,不好的一面是一些技术含量并不高但是烦人的恶意程序越来越多的,显然的,这些水平低劣的恶意程序,除了确实能制造不少麻烦之外,内容也着实令人啼笑皆非。
笔者曾在不少地方下载过这类恶意程序,当然,最有趣的应该就要数钓鱼程序或是远控木马了,当恶意程序的作者仍然在幻想着如何调取他人的账户密码或控制他人的电脑时,殊不知他那相当于裸奔的数据包也彻底将他的钓鱼邮箱或者是服务器的安全漏洞暴露给了恶意程序的分析者
如果你想具体看故事,那么这里就有一个:http://bbs.ichunqiu.com/thread-16392-1-1.html?from=oschina
当然,本篇要讲的是另一个故事。
话说打人不打脸,所以这里这个人物我就以大神甲代替,话说这个大神甲,乃一易语言估计两年或者三年用户,自觉学有所成,自打旗号号称国内知名**,会做锁机和钓鱼程序似乎最近进化到能做聊天室了,后发展到反逆向领域,他的反逆向手段也相当的独特,就是定义多个字符串常量,上书曰:“就你这渣渣也想破解的的程序”,这样当你在ollydbg中查看find references strings时就会看到一堆这种恐吓语句,谓之曰“恐吓法”反逆向,后来发觉这个逆向手段似乎吓不着某些人,遂创建一线程不断枚举进程表,当发现ollydbg.exe字样时,就释放“致命”病毒,删除关键注册表,系统文件,格式化硬盘,让人无法开机,后涉足人工智能领域,开发一人工智能框架名“**”机器人(caffe哭晕在厕所),能达到到人类6岁智力(目测就是有限状态机,如果你不清楚,可以理解为一段又长又臭的switch判断语句),后觉学已大成,但门下无徒,遂开办“xx军团”广招门徒,下面分析的这个恶意程序,就是这名大神甲近期开发的作品,他将该作品发布于笔者某群下企图骗取群员账号密码后,警告无效仍拒绝删除,当中仍然移植了这位大神的反逆向反分析模块,还有神奇的“假蓝屏”,但这些似乎并没有什么卵用。现在我们就来看看这个恶意程序。首先它是这个样子的:
当然,程序的标题都是忽悠人的,我们同样和第一章节一样,将它拷贝到虚拟机中,并且重命名为Sample3.exe
在控制台中,输入doll db <Sample3.exe>,按下回车,建立连接
然后我们点击将软件运行起来
那么软件的意图就非常明显了,它想通过一些根本就不存在的功能,骗取我们的账户与密码,但不管怎么样,它钓取的账号密码数据,肯定是会通过网络发送出去的,因此我们回到控制台,在菜单中选择->规则->加载规则脚本,然后将TCP分析和UDP分析加载进来。
点击按钮,执行函数监视
回到这个钓鱼程序中,随便输入一个账号和密码,然后点击登录
回到PeDoll的控制界面,可以看到,这个钓鱼程序很快露出了马脚
虽然我们并不知道14.17.57.241:25指向的是什么地址,但是端口25常见于SMTP邮件服务器,基本上我们可以猜测到他是将我们的账户游戏使用邮件形式发送出去了。在下菜单点击数据,基本可以看到,它在使用QQ的SMTP服务器
(***)到这里,需要先科普一下SMTP是如何实现发送邮件的,为了讲解方便,这里我们就举一个实际的例子
首先,SMTP协议也是一种telnet,当我们使用TCP连接到SMTP服务器时它会给我们返回一个欢迎信息(下面S表示服务器,C表示我们的客户端)
S:220 * .com Anti-spam GT for Coremail System (*com[****])//欢迎信息
C:HELO smtp.**.com //哈喽,然后这里相当于给服务器打招呼
S:250 OK //返回OK,表示服务器正常可以开始操作了
C:auth login //告诉服务器我们想要登陆
S:334 …….
C:base64编码后的用户名
S:334 …….
C:base64编码后的密码
S:235 Authentication successful //登陆成功
C:MAILFROM:XXX @XXX .COM //正如其名
S:250 Mail OK
C:RCPTTO:XXX @xxx .COM
S:250 Mail OK
C:DATA //smtp邮件数据
S:354 End data with .XXX //同意发送数据,以xxx结束
C:QUIT
S:250 Mail OK //发送成功
很显然,需要登陆SMTP服务器,客户端肯定会暴露自己的账号与密码,这个账户密码肯定也是这个钓鱼软件作者的,小心的钓鱼软件作者使用小号来完成这一操作,而不知道smtp通信协议的钓鱼软件作者,仍然天真的以为加密了软件里的密码账户数据,或者把smtp登陆密码和邮箱的登陆密码不一样就可以高枕无忧,然而他们却忽略了,smtp的账户密码和IMAP或者是POP3收信服务是绑定的,通过相关的邮箱软件,我们非常容易地就能够侵入他的邮箱账户,截取我们需要的一切信息甚至使用安全邮箱的手段让他的其他账户一同沦陷。
显然有了这套理论,大神甲的钓鱼程序就非常的不幸了。他不仅没能成功在我群钓到账户密码,反而把他自己给深深的出卖了。
很容易的,在AUTH LOGIN之后的第一和第三个SEND数据包,我们找到了大神甲经过base64编码后的账号与密码
(图5.1 AUTH LOGIN)
(图5.2 BASE64编码后的SMTP账户)
(图5.2 BASE64编码后的SMTP密码)
将这个Base64的账户和密码进行解码
这位大神的账户密码就暴露无遗了,打开foxmail,以IMAP的形式登录
登录成功,看来大神甲似乎收获还不少
可惜悲剧的事情也发生了,他的邮箱也深深的把他的一堆账户给出卖了。
话说做人留一线日后好相见,大神甲虽然有错在先,但这里我并不打算披露这位大神甲什么信息,也不会对他一堆的个人账户做些什么损害他个人利益的事(当然为了避免各位看官按照教程整倒大神甲,所以我并不打算将这个钓鱼程序样本放在附件中),希望大神甲在看到本文后,早点删了他的钓鱼程序把密码改了早点收手,最后,为了在本章节留下点什么,另一种整蛊邮件钓鱼程序的方案是他的smtp邮箱账户不断给自己发送垃圾邮件,那么不一会儿他的账号就会被服务器封停了,这个smtp攻击器你可以在附件(A05)中找到,当然阅读它需要一些C++的基础。
最后告诫各位仍然在制作钓鱼或锁机程序并期望以此获利并抱有一丝侥幸的“黑客”,损人利己正是多行不义必自毙,这里只是其中一个非常基础的手段,当某天真惹恼了某个码了几十年的码农老妖怪,以他的专业知识和怨念,给这些钓鱼锁机作者点厉害看看真是太轻松了。
第四章:栈中的明文陷阱,使用PeDoll堆栈功能获取软件中的注册码
早期的软件开发如果要做到希望别人注册,手段可以做的很单纯,当然当时的软件破解动机往往也很单纯并不像今天一样出于那么多商业利害的关系。很多只是出于好玩与成就感才去破解。
当然说了那么多,不如给出一段代码
char *GetRegistryCodes()
{
//do something
}
int main()
{
char *regCode= GetRegistryCodes();
if(strcmp(UserInput(),regCode)==0)
{
//registry ok;
}
else
{
//code error
}
}
或者更加简单暴力比如这样
if(strcmp(UserInput(),“abcd-efgh-1234-5678”)==0)
{
//registry ok;
}
else
{
//code error
}
即时是在今天,这种简单的软件加密注册手段仍然非常的多,这一般出于几种原因,一种是这个软件的作者本身水平不高,当然这种情况比较少,另一种是这个软件作者本身就是想把这软件半卖半送,说不定某天就开源了,最后一种是这个软件作者清楚反正破解这软件在行家手上只是时间问题,自己本身不是反破解的行家,做的复杂无非就是一小时被破解变成一天被破解,并没有什么本质上的区别,随手做做,与其在卖注册码上盈利倒不如在别的地方搞出收益。
当然,破解这种注册代码在od老司机的手上,除去那些准备工作,确实也是分分钟能够搞定的事情,但我们今天并不说OD,我想说的是,使用行为分析,这种软件一样能够被破解!你没听错,只用行为分析,不用开OD
为此,我们先打开Visual Studio编写一个小小的软件做为本次分析的小白鼠。代码如下,(你可以在附件A06找到它)
#include <stdio.h>
#include <string.h>
#include <Windows.h>
char input[32];
char *GetRegistryCodes()
{
return "abcd-efgh-1234-5678";
}
int main()
{
char *regCode= GetRegistryCodes();
printf("请输入密码:");
gets_s(input);
if(strcmp(input,regCode)==0)
{
MessageBoxA(NULL,"密码正确","",MB_OK);
}
else
{
MessageBoxA(NULL,"密码错误","",MB_OK);
}
;
}
编译执行,输入一个错误密码,正如我们预期的那样报错了。
观察上面的代码,实际上有个致命的问题,这里我想继续科普一个关于调用栈的问题。
如果你使用的是汇编语言(我指的是那种最纯粹不用伪指令的那种),那么你可能对函数调用参数传递并不感冒,参数对你来说完全可控,但是在一些高级语言看来,函数的调用,常常伴随着参数和局部变量压栈
打个比方你需要给你的朋友几份文件,你可能会把这几份文件一份一份的叠好,然后告诉你朋友,最上面的那份文件是关于什么内容的,下面一份是关于什么内容的…..这样,在你朋友拿到这叠文件的时候就可以从上往下一份一份的读了。
((***)实际上C语言中允许你去定义这种调用一种叫cdecl,一种是stdcall(当然还有fastcall寄存器传参,这种在单片机开发或编译器优化过程中会比较常见),这两种调用方式都和栈有关,他们都会将参数压入栈中,不同的是一种是从左到右,一种是从右到左,在本章中这些都没有关系。)
但一旦局部变量在栈中,这个代码的问题也就非常的明显了,要知道密码的明文也被压到了栈中,不管你GetRegistryCodes写的多么的风生水起,最终的密码明文都暴露了一个最致命的漏洞,它在栈中!,现在 PEDoll存在这种扫描堆栈的功能,我们只需要让程序在MessageBox执行之前停下来就行了,我们就在那个时候扫描程序的堆栈。显然的,肯定能够找到密码
为此,我们需要编写一个过滤脚本
hook MessageBoxA正如它描述的这样
FILTER_START表示下面的文本都是过滤器脚本
MESSAGEBOXA表示对MessageBoxA这个函数执行过滤
<*>两个表示对这个函数的两个参数进行匹配,*表示任意内容(实际上过滤器第一个字符为操作字符,如果匹配下面字符中的一个,就会触发匹配规则)
* 总是匹配
*字符串 查找匹配
\ 转义下一个字符
= 全等,对参数是数字有效
> 大于时触发,对参数是数字有效
< 小于时触发,对参数是数字有效
& 与不为0时触发,对参数是数字有效
! 不等于,对参数是数字时有效
QUERY表示询问断点,就是执行到这个API时,控制器会触发一个中断
SHOW 表示它将在控制台中显示,当然不写也没有什么关系
(更多的脚本编写规则你可以通过阅读常用脚本来学习或者加入pedoll的群直接问)
点击控制台,将这个脚本加载进来
然后我们执行这个小白鼠
在pedoll中枚举进程,使用命令enumprocess
按下回车没找到test.exe的PID
这里我们使用远程线程注入DLL,输入命令
doll di <8068>然后按下回车,点击连接按钮,再按下执行函数监视
点击一次让程序继续运行,然后在测试程序中乱输入一个密码,可以看到,程序触发了断点:
到这一步,我们并不去操作这个断点在下菜单中选择堆栈,并点击更新按钮
那么,你发现了什么?没错,这个软件正确的密码明文就在我们眼前
在本章节中,我们使用行为分析,就截获了一个软件的密码,其中当然因为这个字符串长得太像注册码了,所以我们才能如此轻易的找出它来,当然,这种方法并不是适用于所有的软件,要不然Crackers们今天就得丢了饭碗了,但在今天这个章节中,我们仍然可以收获不少的知识,我们看到了,将一个密码明文直接存在于栈中,并且紧随其后暴露一个明显的API有多么的不安全,假设我们在strcmp中后面马上清空密码明文,能够很大程度上的避免密码被这种手段给直接分析出来。当然如果你想要更深一层的保护,就不在本篇的讨论范凑了。
第五章:使用PeDoll调戏远控木马
在PeDoll被开发出来后,死在笔者这种行为分析下的远控木马服务端已经不是少数了,个人尤其喜欢的就是使用PeDoll来调戏这种远控,木马,通过这种行为分析,你可以很容易就找到大部分远程木马将自己藏到了计算机的哪里,动了哪些文件与注册表,与哪个服务器进行了通讯,发送了什么数据包。
这样,我们就可以通过对数据包的分析,给那些企图加害本人的服务端一点厉害瞧瞧了。当然,当中的知识与抓包分析有更多关系,不过鉴于篇幅问题到这里已经写了非常的长的,而本章节内容也不少,我决定先挖个坑放着,并在此贴上一句未完待续。
后记:
在本文中我希望各位读者确实的体会到了行为分析的快乐,有时它就像是一本书等待我们去阅读,也许在看完本文恰好你也是个初学者时,你也许会在下次的分析中不再嚷嚷着要开od迷失在一堆call当中了,实际上本文中的技术并不是什么新兴玩意,52,CU的老司机早在十几年前就已经玩的很熟练了,但是我认为技术没有新旧,只有实用,就像达尔文的物竞天择适者生存一样,适合时代的技术被流传下去,而生产力低下的技术被淘汰,只要你能用得好,简单的老技术一样可以做的快捷与实用。就像我的一个学长大神说的那样,别小看hello world这个程序,把我惹急了,我能把它从软件层做到硬件层(事实上他也做到了。它用FPGA实现了一个8b CPU,并且把hello world打印在了LCD1602上),不管怎么说,对技术的学习与求知永无止境,在学海无涯苦作舟的同时,我也由衷的希望你在阅读本文的过程中得到了快乐。
DBinary/论坛ID immenma
2016/12/15 完文于某地