1/3 考前复习
考试说明
选择题,10道,共20分
填空题,10道,共20分
计算题,10道,共30分
问答题,3道,共30分
良心资料:密码:4k3z
注:虚拟化环境搭建流程图忘放了,在文章最下面。考试时确实考到了,96分的都灵前来还愿 ~
考前复习
一、相关工具
1、二进制查看工具
Winhex/Ultraedit/exeScope
2、二进制查壳工具
PEID/LoadPE/DIE/手动分析
识别加密壳 zprotect、识别压缩壳 UPX。
3、静态分析工具
Windows:IDA(R3)and plungins(插件)
与Vmware联动,调试程序。与Qemu联动,调试固件。
4、动态调试工具
Windows:OllyDbg(R3)、WinDbg(R0)
Linux:gdb(R3)、kgdb(R0)
VM image(虚拟机):Vmware、VirtualBox、Qemu。
注:应用调试为 R3,内核调试为 R0。
5、非主流工具
符号执行:Angr、Z3
污点跟踪:Pin、Valgrind、TraintDroid
模糊测试:FileFuzz、AFL、Trinity、Peach
Android专用:apktool、Dex2JAR、JD-GUI、SMALI/BAKSMALI
固件专用:Qemu(动态模拟环境)、KVM(底层虚拟化环境)
二、Pwn环境搭建 - LInux工具
ida pro:静态反编译
gdb:动态调试
peda/gef/gdbinit:gdb插件
Checksec:elf安全性及运行平台
Objdump/readelf:elf的关键信息
ROPgadget:rop利用
pwntools:写exp和poc
Pwntools/zio:必备的库
one_gadget:寻找libc中exec('bin/sh')的位置
libc-database:通过泄露的libc中函数地址查libc版本
三、OllyDbg工具的使用
1、基本用法
F2:设置断点
F3:打开文件
F7:单步步入
F8:单步步过
Ctrl+F7:忽略异常,单步步入
Ctrl+F8:忽略异常,单步步过
F4:运行,到光标位置暂停
F9:运行,到程序结束暂停
Alt+F9:执行到用户代码
Ctrl+F9:执行到返回指令
Alt+M:查看模块
Ctrl+E:编辑数据
Ctrl+F2:重新调试
2、汇编指令
MOV 传送字(节)
PUSH 压字入栈
CALL 子程序调用
RET 子程序返回
XOR 异或
CMP 比较
JNZ/JNE 结果不为零跳转
JZ/JE 结果为零跳转
DEC 减1
INC 加1
SUB 减法
ADD 加法
TEST测试
LEA 装入地址
MOVSX 先符号扩展再传送
REP 当 CX/ECX≠0 时重复
四、WinDbg工具的使用
1、符号表
链接器自动生成 PED文件,它由两个部分构成:
① 私有符号数据:函数、全局变量、局部变量,用户定义的结构体、类、数据类型,源文件的名称、源文件中每个二进制指令的行号。
② 公共符号表:静态函数、全局变重。
2、案例:爆破程序注册码
找到关键点 -> 长度判断 -> 逐个字符判断。
五、SEH 结构体异常处理
① SWH 检测调试器
1、异常处理结构体(Structure Exception Handler)是Windows异常处理机制所采用的重要数据结构。
2、GUI应用触发消息(异常)-> 放入消息队列(SEH结构体)-> 查找回调函数(异常处理函数)
② 手动脱壳:
定位到 OEP 之后,使用 LordPE 等工具把程序的镜像 dump 出来。但 dump 得到的镜像无法运行,因为无法自动获取导入函数的地址,为此需要修复导入表( Import Address Table, IAT)。通常使用 importrec 工具进行修复,从原文件提取信息后,对脱壳文件进行修复。
六、花指令
1、花指令是程序中的无用指令,干扰反汇编静态分析工具,但是程序不受影响。
2、加花指令后,可以隐藏自身的程序结构和算法,从而较好的保护自己。
3、花指令有可能利用各种指令:jmp,call,ret 的一些堆栈技巧,位置运算等。
七、寻找程序入口点(Original Entry Point,OEP)
1、软件加壳就是隐藏了OEP,找到程序真正的OEP就可以脱壳。查壳工具无法识别OEP。
2、ESP定律(堆栈平衡定律)
应用频率最高的脱壳方法之一,可以应对简单的压缩壳。最后一次异常法也常用于识别OEP。
壳实质上是一个子程序,它在程序运行时首先取得控制权并对程序进行压缩,同时隐藏OEP。
① 当壳在自解压代码时,会将当前寄存器值压栈,如PUSHAD。解压结束后,寄存器值出栈,如POPAD。
② 基于PUSHAD和POPAD的对称性,可以利用硬件断点定位OEP。
例:PUSHAD的时候将寄存器值0012FFC0压入了0012FFA4的栈中。在0012FFA4下硬件断点,等POPAD恢复堆栈,即可停在OEP处,这就是ESP定律。
2/3 课后作业
-
2.25 作业
列举本次课程中提到的二进制查看工具、静态分析工具、动态分析工具、污点跟踪工具和模糊测试工具。每种类型的分析工具至少列举2种。
①二进制查看工具:Winhex,Ultraedit,exeScope
②查壳脱壳工具:PEiD,LoadPE,DIE
③静态分析工具:IDAandplugins
④动态调试工具:R3:OllyDbg,gdb;R0:Windbg,kgdb
⑤渗透测试工具:Metasploit,W3AF,NMAP,php,JavaScript
⑥虚拟机:Vmware,Qemu
⑦非主流工具:符号执行:Angr,Z3
污点跟踪:Pin,Valgrind,TraintDroid
模糊测试:FileFuzz,AFL,Trinity,Peach
⑧平台专用工具:固件专用:Binwalk,firmware-mod-kit,Qemu
Android专用:apktool,SMAL/BAKSMALI,Dex2JAR,JD-GUl
-
3.4 作业
简述本次课程中的Reverse实战示例实现破解的过程。
静态分析:
① 打开 IDA 反编译,进入 main 函数
② 由变量定义可知 v5-v12 是字符数组
③ 由判断语句可知字符串 v5 就是 flag
④ 将数组转换为字符串,输入flag破解成功
动态分析:
① 运行程序,打开 OllyDbg,进入 WinMain 函数
② 找到 GetDlgItemTextA 函数
③ 地址空间是模块 USER32,在对应处 F2 下断点
④ F9 运行至截停,Alt+B 即可跳转断点;判断语句改为NOP保存,破解成功
-
3.18 作业
简述本次课程中用OllyDbg找到程序入口的过程。
1、用 IDA 打开程序,在左边列表找到 _main 函数。
2、看反汇编窗口,push 四个参数 0、"you have been hacked"、"warning"、0。call 调用指令 messagebox,说明这确实是程序入口。
3、IDA 下面看到地址 401500,来到 OllyDbg, 右键-go to-expression 搜索地址跳转就行了。
-
3.24 作业
利用OllyDbg,参照课程中的爆破示例对该程序中的Serial功能进行爆破。
-
3.25 作业
1.以下哪一种工具是二进制查看工具?(C)
A. IDA B. gdb C. WinHex D. Ollydbg
2.以下哪一种工具是压缩壳加壳工具?(B)
A. PEiD B. UPX C. Zprotect D. Vmware
3.以下哪一种是Linux平台常用的动态分析工具?(A)
A. gdb B. WinDbg C. Ollydbg D. IDA
4.以下哪一种是Windows平台常用的静态分析工具?(D)
A. gdb B. WinDbg C. Ollydbg D. IDA
5.以下哪一种工具可以提供Ring0级的动态分析?(C)
A. OllyDbg B. PEiD C. WinDbg D. IDA
6.进程地址空间分为哪些部分?
答:Text 文本、Data 数据、Heap 堆、Unused Memory 未用空间、Stack 栈
7.栈顶保存在哪个寄存器?栈底保存在哪个寄存器?
答:SP、BP
8.简述栈帧是什么。
答:指系统为函数调用单独分配的那部分栈空间。当运行中的程序调用另一个函数时,就要进入一个新的栈帧。
-
4.7 作业
search 来到关键函数GetDlgItemTexA。
第一个cmp,输入长度eax=0x8,否则跳转
第二个cmp,第6位=char(0x2D)='-',否则跳转
第三个cmp,第1位 shl ecx,1 表示左移一位,char(0x64/2)=char(0x32)='2',否则跳转
第四个cmp,第8位 test al,al 表示可以随意输入,否则跳转
第五个cmp,第5位=char(0x2B)='+',否则跳转
第六个cmp,第2位 add edx,0xA 表示加0xA,char(0x44-0xA)=':'
第七个cmp,第4位=char(0x2E)='.'
第八个cmp,第7位=char(0x4D)='M'
第九个cmp,第3位 add ecx,0xA 表示加0xA,char(0x33-0xA)=')'
-
4.22 作业
1、简述 JNZ 和 JZ 指令的用法及区别。
JNZ(jump if not zero):结果不为0(或不相等)则转移。
JZ(jump if zero):结果为0(或相等)则转移。
2、简述 TEST 指令的用法。
TEST:对两个参数逻辑与运算,并根据结果设置标志寄存器,结果不会保存。
3、简述 MOVSX 指令的用法。
MOVSX:带符号扩展传送指令。
MOVZX:无符号扩展传送指令。
例1、MOV BX,-12;10001100 符号位为1
MOVSX EBX,BX;(EBX)= FFFF FFF4H
例2、MOV CL,8;00001000 符号位为0
MOVSX EDX,CL;(EDX)= 0000 0008H
例3、MOV AH,11;无符号位
MOVZX ECX,AH;(ECX)= 0000 0011H
例4、MOV AX,9H;无符号位
MOVZX EBX,AX;(EBX)= 0000 0009H
4、简述进行程序爆破的思路。
通过search找到相关函数,跳转指令(如JNZ、JZ)一般就是爆破点,然后在程序中输入参数调试,看懂汇编代码和栈帧中的变量,就能逐个比对得到正确序列号。
5、一条注册码判断指令为cmp byte ptr ss:[esp+0x9],0x2D。请解释:
a)这条指令是如何访问内存的;
通过栈指针访问栈顶esp向上第9个地址。
b)这条指令的含义是什么。
通过cmp比较字符串ss和十六进制数2D。
6、简述MD5算法流程。
1、Append Padding Bits(填充bits)
2、Append Length(填充长度)
3、Initialize MD Buffer(初始化向量)
4、Process Message in 16-Word Blocks(复杂的函数运算)
-
5.3 作业
方法一、动态分析
先在ida打开,看到两个关键函数(md5加密和异或函数),对name进行加密,再一系列异或。最终得到的十六进制数组就是注册码。
再od打开,下断点,name输入'yydl',运行。直接看到经过两个函数后的序列号。
方法二、静态分析
md5加密直接用网站,主要分析异或函数。
加密的函数被分为四段,各个段进行各自的运算操作,如图。最终根据name'yydl'写脚本计算出注册码。(截图中少写了一段:v0^=0xf,0xbd,0x00,0x99)
学有余力的话可以写一个注册机,如上图。
-
5.26 作业
(1)文字简述PE文件编译器的编程思路。
1、编写DOS头:IMAGE_DOS_HEADER
2、编写NT头:IMAGE_NT_HEADERS
3、编写文件头:IMAGE_FILE_HEADER
4、编写数据目录:IMAGE_DATA_DIRECTORY
5、编写节头:IMAGE_SECTION_HEADER
6、编写导入表:IMAGE_DIRECTORY_ENTRY_IMPORT
7、编写导出表:IMAGE_DIRECTORY_ENTRY_EXPORT
8、编写主函数 int main( )
(2)PE文件解析器核心代码截图。
(3)PE文件解析器代表性运行结果截图。
-
5.26 作业
一、比较三者的分析结果,找出差异。
1、文件头(FileHeader):字节数(NumberOfSection)变化。
2、扩展PE头(OptionHeader):程序的真正入口点(ImageBase+AddressOfEntryPoint)提前。
3、节表(SectionTable):地址变化。
4、导出表(ExportTable):地址变化。
1、扩展PE头(OptionHeader):内存镜像基址/程序默认载入基址(ImageBase)变化。
2、导出表(ExportTable):地址变化。
二、分析为什么会出现这样的差异。
1、UPX(压缩程序):可以完成代码的压缩和实时解压执行,且不会影响程序的执行效率。
① UPX加壳:先在程序的开头插入一段代码,再将程序的其他地方做压缩(加密),因为压缩后的程序比较难看懂。
最初代码的形式:7==>8==>9==>5==>6
UPX压缩后形式:1==>2==>3==>4==>5==>6
执行时候的形式:1==>7==>8==>9==>5==>6
② UPX脱壳:解压缩功能是依靠第一步时插入的代码完成。
因为开头插入了代码,所以文件头字节数、程序入口改变。因为部分代码进行了加密,所以节表地址改变,进而引起之后的导出表地址改变。
2、Zprotect(加密程序):注重对代码的处理,拥有良好的稳定性和兼容性。
① ZProtect加壳包含IAT(Import Address Table,导入地址表)加壳技术,导致表的地址都发生了变化。
② ZProtect加壳过程中需要去掉随机基址,所以程序默认载入基址(ImageBase)变化。
-
6.9 作业
1.PE文件格式是什么?在WINDOWS系统中有哪些类型的文件属于PE文件?
Portable Execaple(可移植,可执行),它是 Win32 可执行文件的标准格式。
Win32 可执行文件,*.EXE、*.DLL、*.OCX 等,都是 PE 格式。
2.简述WINDOWS平台下病毒运行的一般流程。
一般来说,病毒先于HOST程序获得控制权。运行Win32病毒的流程如下:
① 用户点击或系统自动运行HOST程序;
② 装载HOST程序到内存;
③ 通过PE文件中的 AddressOfEntryPoint+imageBase,定位程序入口;
④ 从第一条语句开始执行病毒代码;
⑤ 病毒主体代码执行完毕,将控制权交给HOST程序原来的入口代码;
⑥ HOST程序继续执行。
3.简述获取PE文件中重要数据结构(数据目录表中各个项目)的方法。
① 从 DOS header 定位到 PE header;
② 从 optional header 读取到 data directory 地址;
③ 将 IMAGE_DATA_DIRECTORY 结构尺寸(8 bytes)乘上1(索引号),得到 import symbols 的位置信息;
④ 将上面结果加上 data directory 地址,就得到了所查询数据结构信息的 IMAGE_DATA_DIRECTORY 结构项。
4.一个程序要调用外部DLL中的函数,是直接调用这个函数吗?如果不是,是如何调用的?
不是。而是将CALL指令转到同一个 .text 节中的 JMP DWORD PTR[XXXXXXXX] 类型的指令。
5. DLL/EXE要引出一个函数给其他DLL/EXE使用,有两种实现方法。分别是什么?
① 通过函数名引出。例:DLL可以通过函数名引出,假设要引出名为 GetSysConfig 的函数,那么其他DLL/EXE若要调用这个函数必须以该函数名。
② 通过序数引出。 序数是唯一指定DLL中某个函数的16位数字,在所指向的DLL里是独一无二的。例:DLL可以通过序数引出,假设是16,那么其他DLL/EXE若要调用这个函数必须以该值作为GetProcAddress调用参数。
-
6.18 作业
1.列举3种可以用于调试器检测的Windows API。
GetDlgItemTextA()、strcmp()、ShellExecute()等。
2.列举3种可以用于调试器检测的Windows数据结构。
哈希表、递归、链表等。
3.简述用软件断点识别调试器的原理。
① 软件断点:X86系统中为中断指令INT 3。当程序执行到 INT 3 时,引发软件中断。
操作系统的 INT 3 中断处理器会寻找注册在该进程上的调试处理程序,因而调试器就有了上下其手的机会。
② 硬件断点:X86系统提供8个调试寄存器(DR0~DR7)和2个MSR用于硬件调试。
4.列举3种可以干扰调试器的方法。
① 花指令:隐藏指令,干扰分析。
② 动态加/解密代码:干扰分析。
③ 异常处理机制:加大跟踪难度。
5.花指令是什么?有什么作用?
花指令:故意将错误的机器指令放在了错误的位置。
作用:设计者希望使破解者反汇编的时候出错。
6.简述手动脱壳的常用技术。
单步跟踪法、ESP定律法、内存镜像法、一步到达OEP法、最后一次异常法、模拟跟踪法、“SFX”法。
7.Stolen code是什么技术?如何解决?
Stolen code:软件脱壳中被修改的代码。
解决:到达OEP后补上stolen code里的代码。
8.SEH是什么?有什么作用?
SEH:Structured Exception Handling,结构化异常处理。
作用:Windows提供给程序设计者强有力的处理程序异常的武器。
3/3 学习笔记
Ⅰ、二进制安全应用背景
Crack(程序破解)、Reverse(程序逆向)、Unpack(程序脱壳)、Pwn
1.1 现实案例
2010.4:Shadowsinthecloud:赛博空间下的信息收集
2010.9:Stuxnet:著名核工业系统攻击案例(样本分析)
2010.11:Koobface:利用社交网站盗取信用卡信息
2011.2:NightDragon:针对石油公司窃取文档信息(word;pdf)
2011.10:Duqu:与Stuxnet同源的敏感信息窃取行为(样本分析)
2012.2:ACAD/Medre.A:窃取AutoCAD制作的图纸及文档
2012.5:Flame:盗取文件、联系人等等大量敏感信息(已分析)
2013.1:RedOctober:以政府、使馆、能源为对象窃取机密
2013.3:PT1:基于RAT(远程管理)的系统入侵
2013.6:PRM棱镜门,全方面的信息监听及数据挖掘
2013.9:Icefog:“三尖刀”,规模化的APT攻击组织
2014.8:MonsterMind:自动反击可导致误伤(地址伪装)
2016.8:食尸鬼行动:伪装阿联酋国家银行对中东定向入侵
2016.10:黑色能量:利用Excel邮件附件渗透电网工作站
2016.11:大坝事件伊朗黑客入侵小型防洪控制系统
2017.6:WannaCry:英国医院及诊所;雷诺工厂
2017.7:Scythe锁住固件来勒素的软件
2017.11:PLCrootkit:利用驱动hook持PLC的远程通信数据
2018.1:熔断与幽灵:芯片级漏洞
2018.3:思科高危漏洞:CVE-2018-0171(score:9.8)
2018.5:NotPetya俄罗斯电网攻击
2018.7:hn:基于Mirai变种的loT僵尸网络
2018.11:Lojax:ThefirstwildUEFIbootkitattack
1.2 相关基础
1)语言基础
汇编:逆向之源,漏洞之本
C语言:算法实现,目标恢复
python:脚本处理,高效轻量
2)操作系统
Windows、Linux、Android、Others
3)相关工具及平台
① 二进制查看工具:Winhex,Ultraedit,exeScope
② 查壳脱壳工具:PEiD,LoadPE,DIE
③ 静态分析工具:IDA and plugins
④ 动态分析工具:R3:OllyDbg,gdb;R0:Windbg,kgdb
⑤ 渗透测试工具:Metasploit,W3AF,NMAP,php,JavaScript
⑥ 虚拟机:Vmware,Qemu
⑦ 非主流工具:符号执行:Angr,Z3
污点跟踪:Pin,Valgrind,TraintDroid
模糊测试:FileFuzz,AFL,Trinity,Peach
⑧ 平台专用工具:固件专用:Binwalk,firmware-mod-kit,Qemu
Android专用:apktool,SMAL/BAKSMALI,Dex2JAR,JD-GUl
Ⅱ、Reverse 实战示例
2.1 静态分析 - IDA
Text Segment:代码段 — 指令
Data Segment:数据段 — 全局变量)
Heap Segment:堆 — malloc/free、存储动态分配数据
Stack Segment:栈 — 函数参数、局部变量、返回地址
栈的操作方式:push/pop
栈的生长方向:高地址→低地址
栈帧:指系统为函数调用单独分配的那部分栈空间。
当运行中的程序调用另一个函数时,就要进入一个新的栈帧。
原来函数的栈帧称为调用者的帧,新的栈帧称为当前帧。
被调用的函数运行结束后当前帧全部收缩,回到调用者的帧。
ebp 指向当前帧底部
esp 指向当前帧顶部
2.2 动态分析 - OllyDbg
一、基本用法
F2:设置断点。在光标位置按F2键即可,再按则会删除。
F7:单步步入。每按一次执行一条指令,遇到CALL等子程序进入。
F8:单步步过。每按一次执行一条指令,遇到CALL等子程序不进入。
F4:被调试的程序将直接开始运行,到光标所在位置处暂停。
F9:被调试的程序将直接开始运行。
Ctrl+F9:执行到返回指令。用于从系统地址空间返回到我们调试的程序地址空间。
Alt+F9:执行到用户代码。用于从系统地址空间快速返回到我们调试的程序地址空间。
ALT+M:查看程序的加载模块,用于分析程序主文件结构。
二、汇编基本指令
MOV:传送字或字节。如 MOV A B ,就是将B中的字传给A。
PUSH:把字压入堆栈。如 PUSH A ,就是把A中的字压入栈。
CALL:子程序调用指令。如 CALL SUM,调用子程序 SUM。
JNZ/JNIE:运算结果不为零转移,标志位 ZF=0 时跳转。
JZ/JE:运算结果为零转移,标志位 ZF=1 时跳转。
LEA :装入有效地址。如 LEA DX,string,把偏移地址存到DX。
REP :按计数寄存器 CX/ECX 中指定的次数重复执行。
MOVSX:先符号扩展,再传送。
RET :子程序返回指令。
XOR :异或运算。
AND :与运算。
CMP :比较。
DEC :减1。
INC:加1。
ADD:加法。
SUB:减法。
TEST :测试。
三、OllyDbg 工具的使用
1、跳转
2、爆破
3、保存修改后的代码
4、找到程序真正入口
5、栈
2.3 内核调试 - WinDbg
一、什么是 WinDbg
WinDbg 是 windows 平台下对内核、应用程序、服务程序进行调试的工具。相
对 VS 而言更小巧,功能却更丰富,支持内核模式和用户模式的调试。
二、WinDbg 的调试模式
1、内核模式(Kernel-Mode)
为了不让程序任意存取资源,对应 x86 的 ring0 层。操作系统的核心部分、设备驱动程序都运行在该模式
2、用户模式(User-Mode)
当 CPU 运行于 User Mode 时,对应于 x86 的 ring3 层。操作系统的用户接口部分、所有的用户应用程序都运行在该级别
三、符号表
1、PDB文件
链接器自动生成,文件由两个部分构成:私有符号数据、公共符号表。
① 私有符号数据:函数、全局变量、局部变量,用户定义的结构体、类、数据类型,源文件的名称、源文件中每个二进制指令的行号。
② 公共符号表:静态函数、全局变重。
四、内核调试环境