本文章仅提供学习,切勿将其用于不法手段!
逆向工程,是高级渗透测试工程师必须掌握的一项技能!
挖掘二进制安全领域的0day漏洞,逆向功能方面的技术能力起着决定性的作用!
为什么要掌握逆向工程技术呢?
C/C++语言,属于编译型语言,生成的代码为机器码(二进制码),可被翻译成汇编语言代码!
Java语言,属于编译+解释型语言,生成的代码为JVM机器码(字节码),可被翻译成Java代码!
如果您希望从事二进制安全方向的渗透测试工作,或者去挖掘二进制安全领域的0day安全漏洞!
那么,您必须具有进行代码审计的能力!
代码审计,被审计的代码并不会仅局限于C/C++/JAVA/PHP/PYTHON/GO/SQL等编程语言的源代码范畴。当被审计的软件并未对外提供相关的源代码文件时(例如,某个突然被发现的未知程序),那么针对二进制代码进行反编译,并翻译成汇编代码,会是一种不错的选择!
二进制代码的可阅读性很差,但汇编语言阅读起码,体验还是比较美好的(因人而异!笔者认为:汇编语言,是这个世界上最强大、最美好的语言!汇编语言,也是学习成本最低,最容易入门的编程语言(但这取决于,您是否能够用机器思维在阅读代码并进行思考))!
比较好的逆向软件,可以把二进制代码直接翻译成C语言代码!
这对于熟悉C语言的代码审计人员来说,无疑是一个不错的福利!
笔者推荐使用IDA软件进行二进制安全领域的软件代码静态分析工作!它真的非常不错!
笔者比较喜欢社区版本的IDA软件,虽然功能没有专业版本的多,但是胜在免费!
为什么IDA软件值得去学习与使用呢?
IDA软件是跨平台的!这是一个非常不错的优势!
对于二进制安全领域的软件代码动态追踪与调试工作,笔者推荐您在沙箱环境下进行!docker容器和VirtualBox虚拟机等,都是不错的选择!
docker容器和VirtualBox虚拟机,在一般情况下,都是免费的!
为什么对于二进制代码的动态追踪与调试工作,最好在沙箱环境下进行呢?
注意,您正在尝试执行的未知软件代码中可能会存在恶意代码内容(这可能会对您的机器与数据造成损害)!在沙箱环境下对恶意代码进行调试或分析(例如,提取并分析恶意程序的特征码内容,优化或增强杀毒软件的防杀病毒能力等),病毒代码绕过沙箱环境去对真实环境下的数据或硬件造成损害的可能性将大幅降低(但是,绕过沙箱环境去对真实环境造成损害的病毒程序,也是存在的!100%的绝对性安全,并会不存在)!
应该如何进行二进制代码的动态追踪与调试工作呢?
GDB软件,是Linux操作系统环境下的首选!它可以集成很多的插件(例如,pwndbg等)!
OllyDbg软件,是Windows操作系统环境下的首选!
但是,OllyDbg软件仅能用于32位环境下二进制代码的动态追踪与调试工作!
在Windows操作系统环境下,替代OllyDbg软件的二进制代码动态追踪与调试工具为64dbg!
在这里,科普一些比较重要的基础知识点内容!
Linux操作系统环境下,二进制可执行代码的统一文件格式类型为“ELF”(可执行与可链接格式)!
ELF格式,英文全称为 “ Executable and Linkable Format ” ,分别由ELF头(ELF header)、程序头表(Program header table)、节头表(Section header table)、节(Section)等部分共同组合而成!
一个ELF格式文件,不一定会包含 ELF头(ELF header)、程序头表(Program header table)、节头表(Section header table)、节(Section)等的全部内容,这主要由具体的ELF格式文件的文件类型决定(ELF格式文件的相应文件类型,包括:可执行文件、可重定位文件(.o)、共享目标文件(.so)、核心转储文件等)!
在进行ELF格式文件的内容分析时,我们应该注意!
ELF头部内容的位置是相对固定的,而其它部分内容的具体位置和大小等信息,将由ELF头部内容中的各项值而决定!笔者强烈建议您,去阅读下 elf.h 文件的内容!里面定义了各种数据结构!
一般情况下,您可以在这个路径“ /usr/include/linux/elf.h ”,找到这个文件!
如果您有兴趣,您也可以阅读下面这些的C语言头部文件!
/usr/include/x86_64-linux-gnu/sys/elf.h
/usr/include/linux/elf.h
/usr/include/elf.h
/usr/include/sys/elf.h
另外,一位代号为” huc0day “的道德黑客,在其发布的开源渗透测试软件 Phpsploit-Framework 中,也提供了对于ELF格式文件的内容解析功能!可以方便白帽黑客在从事透测试与安全审计工作时,进行PWN相关的安全测试!这位代号为 huc0day 的白帽黑客,在其 Phpsploit-Framework软件的官方说明中,也特别强调了 Phpsploit-Framework软件在CTF竞赛时的作用与价值!
对于Web安全和Pwn安全有兴趣的童鞋儿,可以去了解下这款专业的渗透测试框架软件!
话题回到我们这篇文章的主题《逆向工程系列教程之寄存器基础知识》上来!
有哪些寄存器,是我们必要记住的呢?
首先,RAX寄存器,是我们必须要记住的!
RAX寄存器,有什么重要作用呢?
记住,C语言函数代码的函数返回值,是存储在这个”RAX寄存器“中的!当我们想要去了解一个函数的返回值内容是什么的时候,可以动态追踪并观察下这个”RAX寄存器“中的内容值!
然后,RDI寄存器,是我们需要重点关注的!
为什么要去重点关注”RDI“寄存器的内容值呢?
RDI寄存器,被用于存储C语言函数代码中的第一个函数参数的内容值!
我们在进行逆向工程和PWN渗透测试行为时,会经常看到下面这样类似的代码!
mov rdi,<函数第一个参数的内容值>
call _<具体的函数符号名称>
我们在进行栈溢出类的安全测试(例如,相对高级的栈溢出技术 ROP 返回导向编程)时,会经常用到这样的机器码 ” 5FC3 “,对应的shellcode代码为 ” \x5F\xC3 “ ,对应的汇编代码,如下所示:
pop rdi
ret
可以这样说!RDI寄存器,是我们从事二进制安全领域的渗透测试与审计工作时,经常会用到的一个非常重要的寄存器!
接下来,还有哪些寄存器,也非常的重要呢?
RSP寄存器,它是栈指针寄存器!RSP寄存器,存储着栈指针的偏移量!入栈和出栈行为,都是针对RSP寄存器中的栈指针寄存器来进行计算操作的(入栈时,RSP寄存器中的栈指针偏移量将自动减少8个字节,之后入栈的数据会被存放到RSP寄存器中的栈指针偏移量所指向的地址空间!出栈时,会先将RSP寄存器中的栈指针偏移量所指向的地址空间上的数据弹出到指定的寄存器中,之后RSP寄存器中的栈指针偏移量将自动增加8个字节)!
在C语言对于栈结构空间的调用规则方面,会有哪些汇编指令会使用到RSP寄存器呢?
笔者举几个最常用的例子
1、使用栈帧基址寄存器来存放当前函数的栈帧基址(注意这条指令的上面为push rbp指令)
mov rbp,rsp
2、为当前函数的局部变量分配足够的栈结构空间(局部变量赋值:n>=1 mov [rbp-n],val)
sub rsp,20h
3、恢复栈指针偏移量的内容值为当前函数的栈帧基址(注意这条指令的下面为pop rbp指令)
mov rsp,rbp
那么,在ROP返回导向编程中,RSP寄存器又是被如何利用的呢?
大家先思考下,下面这条指令的作用是什么?
mov rsp,rbp
答案是,使用rbp寄存器中的内容来覆盖掉rsp寄存器中的内容。
那么,如果我们在执行了 mov rsp,rbp 这条指令之前,先执行了下面这条指令,会发生什么呢?
pop rbp
大家有没有思考过?
如果栈中的数据,是经过我们特定构造的,会发生什么呢?
如果出栈到RBP寄存器中的数据,是另一片内存区域的内存地址,会发生什么呢?
答案是:会发生”栈迁移“!
是的!我们之前说过,RBP寄存器是栈帧基址寄存器,RBP寄存器存放的是当前函数的栈帧基址!
RSP寄存器,是做什么用的呢?RSP寄存器,是栈指针偏移寄存器!RSP寄存器,存储着栈指针偏移的内存地址!当我们对RSP寄存器的内容进行改写,也就等于更改了栈结构空间的内存地址!
逆向工程技术,是渗透测试领域二进制漏洞挖掘的基础技术!
想进行二进制领域的漏洞挖掘工作,就必须要掌握逆向工程技术!
大家思考一下,XOR RAX,RAX 这条汇编指令,实现的是什么?XOR指令的作用是什么?
XOR指令,也被称为”异或“指令!思考一下,异或运算的规则,是什么呢?
异或运算,当两个值进行按位异或时,只有在两个值中当前位的值只有一个为1(真)时,两个值中当前位的运算结果才为1(真),否则为0(假)。
0 和 0 进行异或运算,结果是多少?答案:0(假);
1 和 1 进行异或运算,结果是多少?答案:0(假);
0 和 1 进行异或运算,结果是多少?答案:1(真)。
0b11111111 xor 0b11111111 = ?
答案,是多少呢?
答案,是 0 !
0b11100111 xor 0b11100111 = ?
答案,是多少呢?
答案,还是 0 !
当两个相同的数值进行异或运算时,结果值为 0 !
XOR RAX,RAX 这条汇编指令的作用,等同于 MOV RAX,0
之所以没有使用 MOV RAX,0 这条指令,是因为 XOR RAX,RAX 具有更高的执行效率!
未完待续