Lab 9-1
IDA查看main地址入口
OD打开,F8单步跳过到00403945,可以看到此地址Call了main,
在主函数F7单步执行,进到main函数内部,首先cmp检查是否带参数,我们没有输入参数,零标志位设为1,jnz指令不跳转继续下一步到call 401000
继续单步到0040100,首先尝试打开注册表\HKLM\SOFTWARE\Microsoft \XPS,不存在该项,跳到2410
2410调用GetModuleFileName等系列函数获取文件名和路径
最终拼接成
最终调用ShellExecute和cmd.exe尝试删除自己
运行于此,就知道如果我们不提供任何的参数,程序运行后就会删除自身,那么尝试提供参数,结合IDA看看可以有什么参数
-in,-re,-cc,先加入-in,debug->argument->输入-in
重新回到程序起始点,再单步执行到对比可以看到已经跳过了401000
随后in被传入402510
换IDA,首先关注到返回的是一个布尔值,应当是用来作判断条件
查看交叉引用,被main调用,若result返回的不是1,则会自动进入之前分析的402410自毁过程
在OD中继续单步也验证了这一点
也就是说,应当要传入所谓的密码,经过402510计算验证后返回1,才能顺利进行下一步而不自毁
IDA分析一下402510,a1是命令行传入的最后一个参数,对于传入的参数a1,首先确认长度是否为4,接着依次进行a,b,c,d的字母检查,即传入的参数应当是abcd
我们在OD上传入-in abcd,单步调试查看结果,果然已经绕过了自毁程序,进入了下一步跳到了402B3F
继续看注册服务
复制自身到system32目录下
创建注册表表项
写入键值
另外一种不需要指定密码的方法,分析得,寄存器EAX的值即为整个函数过程的结果,因此直接添加汇编指令修改寄存器的值,使得在没有进入条件语句之前,将EAX的值赋为1,在立刻返回即可跳过下面的参数检查,使得无论-in为何值都能跳过自毁程序
OllyDbg右键中的Assemble选项提供了汇编指令转换,可得需要添加的汇编为
B8 01 00 00 00 MOV EAX,0x1
C3 RET
程序arguments加上-in单步执行到2510内部,在首条指令右键点击Binary,再点击Edit,输入上述字节码,因为push ebp只占一个字节,我们edit之后会改变大小,因此这里取消keep size,使得程序自动更改节的大小
确定OK,再右键,Copy to executable->All modifications->copy,即可保存为另一份新的文件,尝试调试新文件,可以看到直接在-in不加参数值的情况下直接跳过了检查进入了402B3F
除了-in,还有其他的选项-re,-c,-cc,借助ida查看他们具体的功能
-re直接打开服务管理器定位恶意代码删除服务再删除备份代码
-c根据传入的四个值拼接,以此更新HKLM\SOFTWARE\Microsoft \XPS下Configuration的键值
-cc则与-c相对,他是读出注册表中的键值
0x402020处调用了一些后门函数,分别是sleep,upload,download,cmd,nothing
sleep执行睡眠操作
upload远程连接主机,创建文件将内容写入本地文件
download读取文件内容并大送到远程主机
cmd执行Command命令,接着将命令结果发送到远程主机
nothing无操作
Lab 9-2
die打开直接看字符串,除了一些windows api函数之外,存在cmd字符串,说明可能存在命令执行的操作,同时,存在LoadLibraryA函数用来导入函数
运行闪退,无任何输出
OD调试,发现进入main之后,首先程序会GetModuleFileNameA,获取当前程序名对比,若不为ocl.exe,则跳到程序退出
重命令再运行,用火绒剑看看,程序顺利进入了功能区,除了打开了很多dll之外,还存在一个网络连接
用OD详细分析,注意到成功对比文件名之后,还存在一个密钥
断点到401089继续单步
注意到程序在0D4->11B之间反复横跳
ecx加一后会传入ebp+var_108与20h对比,表明这是一个递增计数器,经历了32轮次循环之后即退出跳转到40111D
直接反编译也可分析出是个异或函数
OD继续单步看异或的结果,可以看到最后是一串网址
gethostname获取目标的IP地址,这里即获取上述异或出来网址对应的IP地址又压入了Netshort 0x270F,即9999,如果连接成功,跳到40137A继续执行,如果失败,sleep(30)秒,这里就是上面火绒剑看到网络连接的过程
程序会一直重复这个流程连接目标地址,回到IDA我们注意到连接失败程序会进入sub_401000
首先定义一个STARTUPINFO窗口结构,然后修改窗口结构,wShowWindow=0代表窗口运行时隐藏不可见,hStdInput,hStdError,hStdOutput将输入和输出的数据流绑定到cmd.exe
Commdline指向的是cmd,即CreateProcessA会启动一个cmd.exe,输入指令到cmd.exe,而后cmd.exe的输出再传输回远端,这是一个典型的反向连接shell
综上,程序混淆C2恶意地址,使得静态分析不出隐藏的地址,而后启动cmd,创建一个反向shell连接
Lab 9-3
DIE查看导入表
要观察加载DLL在程序中的位置,首先在IDA中查找LoadLibrary,观察指令前压入堆栈的字符,可以看到压入了user32.dll和DLL3.dll
这俩没有出现在导入表,因此有可能是动态调用,DIE打开三个DLL,基址都是10000000
下面用OD分析三个DLL加载到内存的地址
在LoadLibrary打一个断点,此时程序已经将三个dll都加载到了内存当中
打开内存映射窗口
可以看到DLL1顺利加载到了1000000,DLL2由于被占,加载到了30000,dll3在850000
分析从DLL1.dll中的导入函数DLL1print
IDA反汇编DLL1Print,很明显是获得进程ID并输出
即程序导入DLL1时,程序输出当前进程ID
再看DLL2.dll,导入了DLL2Print和DLL2ReturnJ两个函数
DLL2Print同样是输出eax中的数据,eax的值来自dword_1000B078
这个变量是DLLmain调用CreateFileA的结果,也就是说程序会首先尝试打开temp.txt并返回文件的句柄,如果文件不存在,程序会创建temp.txt
再看DLLReturnJ,将文件句柄返回给了hfile作为WriteFile的参数
WriteFile再将网址写入文件,即网址写入temp.txt
再看DLL3Print,导入的函数是DLL3Print和DLL3GetStructure
DLL3Print输出字符串,输入的内容和全局变量WideChaStr有关
再看之前的调用过程,可以看到在这段代码中,有一个字符串 "ping www.malwareanalysisbook.com"被放在 lpMultiByteStr 变量中。接着,该字符串被传递给 MultiByteToWideChar 函数,并存储在 WideCharStr 变量中
因此DLL3Print应当是输出ping xxx在内存中的地址
DLL3GetStructure返回的是一个指针
注意到程序在收到DLLStructure出传回的指针之后会由&Buffer指向结构体传入到NetScheduleJobAdd
看它的几个参数,应当是创建计时任务
MSDN文档给出了详细的函数结构
其中Buffer知道是指向AI_INFO结构体的指针
IDA Pro中可以手动添加结构体使得代码更加可读
之前提到DLL3中1000B0A0变量即是结构体指针,即程序中的Buffer
那么在打开结构体视图,点击INSERT,添加标准的结构体AT_INFO
现在已经成功导入
然后到达1000B0A0在内存中的位置
点击edit->Struct Var,再回到main即可看到可读性更高的数据
因此我们知道,程序会添加一个计时任务,该任务为:一周内的任意一天的1.00AM ping 网址
最后一问的指定新的基址,在ida加载时勾选选项即可