关于AWD的几种玩法

关于AWD的几种玩法。

什么是AWD

​ CTF竞赛分为解题模式和AWD(攻防演练)模式。

​ AWD是"Attack With Defense"的缩写,它指的是一种网络安全竞赛形式,也称为攻防赛。AWD比赛旨在模拟真实网络环境中的攻击与防御情境,参赛者将被分为攻击方和防守方,相互进行攻击和防守的对抗。

在AWD比赛中,攻击方的任务是发起各种网络攻击,如漏洞利用、拒绝服务攻击、入侵等,以获取对手系统中的敏感信息、控制权或破坏系统功能。而防守方的任务是保护自己的系统,及时发现和阻止攻击行为,修复漏洞,并确保系统的安全性和可用性。

​ AWD比赛强调攻守兼备的能力,参赛者既需要具备攻击者的思维和技术,能够发现系统中的弱点并利用它们,也需要具备防守者的技能,能够分析攻击行为、快速做出反应并保护系统免受攻击。

​ 通过参与AWD比赛,安全从业者可以提高自己的技术水平、增强实战能力,并深入理解攻击与防御的原理和技术。同时,AWD比赛也促进了安全社区之间的交流与合作,推动网络安全技术的发展。

简单地说:

​ 对于pwn,在比赛时每支队伍会维护一台服务器,服务器上运行着一些存在漏洞的程序,不同队伍的服务器状况是相同的,选手可以从服务器上下载程序附件,分析漏洞,再针对此漏洞对其他队伍的服务器进行攻击从而得分,同时也要尽快修补好自己服务器上的这个漏洞防御其他队伍的攻击。(发现漏洞后一般优先攻击,因为攻击得分要高于防守得分)

漏洞利用与漏洞修补

漏洞利用

​ 服务器上的题目附件和平常打的解题模式相似,漏洞利用攻击服务器的思路和手法也就是平常做题的思路和手法,这里不再赘述。

漏洞修补

​ 漏洞修补就比如说有一道题存在栈溢出漏洞,缓冲区有0x10字节却允许输入0x20字节,漏洞修补就是去把0x20改为0x10字节让其无法溢出。值得注意的是

​ 修补时最好不要破坏程序原本的功能,因为有的比赛会check程序的功能是否被改变。比如说程序本来的作用是输入0x20个字节数据再将其打印出来(可以泄露出libc地址打ret2libc),你修补漏洞时直接用nop指令把打印函数的汇编给覆盖了,这时虽然阻止了针对该漏洞的攻击,但是程序也不会再打印数据了,这就是改变了程序本来的功能,如果比赛时被check出来就会扣分。

​ 比赛时我们拿到的题目附件是编译好的二进制文件,也就是说我们只能在IDA中对汇编代码进行修补而不是说能拿到源码去对c语言代码进行修补。这就需要一个功能强大的IDA插件了。Keypatch是一个利用keystone框架修改二进制可执行文件的插件。由于IDA自带的patch功能只能使用机器码进行修改,且修改后不能撤销,Keypatch就应运而生了。安装该插件的步骤放在文章末尾

常见的修补漏洞:

索引越界漏洞、格式化字符串漏洞、溢出漏洞、整数溢出漏洞、UAF漏洞。之后会逐一进行举例介绍。

索引越界漏洞

以一个数组索引越界举例。

img

可以看到数组a为全局变量处在bss段的位置
img

并且在输入索引后,程序并未对索引进行检查,针对这类漏洞的利用方法之一是让索引为负值去篡改got表。

img

在安装了Keypatch插件后可以很方便的进行漏洞修补。首先定位到输入索引的汇编位置,可以看到索引在距离栈底偏移为8的位置,修补思路就是对它做一个if判断,如果超出范围就把它的值改成一个范围内的值。

img

keypatch的快捷键是ctrl Alt+k,当然右键单击也可看到。
img

​ 现在到底应该怎么改呢,想要加入一个if判断需要很多字节的汇编代码这是毋庸置疑的,如果把这些汇编直接放0x400651显然是不可行的,因为它们会覆盖大量0x400651以下的汇编代码。这时我们可以在这里写一个跳转指令,把if判断放在一个不重要的位置再跳转到那里执行,最后再跳转回来。那么这个“不重要的位置”是哪里呢,它至少应该有执行权限。

eh_frame_hdr节和eh_frame节就符合我们的要求,它是用于支持异常处理(Exception Handling)的信息。在程序运行时并不是必要的。这个节一般是只读权限的,但是加载到内存的时候是有可能和.text节在同一个页,具有执行权限,测试发现ubuntu22.04编译出来程序在运行时eh_frame无可执行权限,而在ubuntu18.04编译出来的程序却无一例外,eh_frame都具有可执行权限。笔者认为这是由于不同版本ubuntu所安装的编译器版本不同引起

​ 题目附件的.eh_frame节不一定具有可执行权限,这就需要我们去加一个可执行权限,用010editor就可以很方便的修改ELF段的权限,步骤放在文末,我们先来看如何修补漏洞。

​ eh_frame一般在程序链接时被用到,在程序运行时是不重要的。所以,我们要做的就是把if判断放在eh_frame并跳转执行再跳转回去。

​ 本例中eh_frame_hdr的起始地址为0x4007e4,现在在0x400651处改第一条汇编。

jmp 0x4007e4

img
接着到0x4007e4布置if判断的汇编。

cmp dword ptr[rbp-8],0

将索引和0作比较。

img

jl 0x400810

当索引小于0时跳转到0x400810(0x400810处放的是将索引设置为0的汇编,因为检查出索引越界后还需要将索引设置一个正常值让程序继续运行,这里的0x400810是另一个“不重要的位置”。当然,你可以不使用这个地址另找一个地址,只要这个地方不会干扰程序正常运行并且具有可执行权限。)

img

cmp dword ptr[rbp-8],7

将索引和合法索引的最大值(本例为7)作比较。

img

jg 0x400860

当索引大于7时跳转到0x400860

img

如果以上两种情况程序均未跳转,则说明索引未越界,这时就需要跳转回text段让程序正常执行下去。值得注意的是,刚开始在text添加的跳转指令覆盖了程序原来正常的汇编指令,在跳转回去之前需要将他们补到eh_frame.

mov eax,[rbp-8] 

这是在text段被覆盖的第一条指令。

img

movsxd rdx,eax

这是在text段被覆盖的第二条指令

img

jmp 0x400657

跳转回text段继续执行程序(注意汇编指令的衔接)

img

接下来别忘了补上在0x400810和0x400860放重新设置索引的汇编代码。

mov dword ptr[rbp-8],0

将索引设置为最小值0

img

然后同样需要补上text被覆盖的汇编代码再跳转回text,操作和上面一样就不再一步一步截图啦。

img

接着去0x400860设置汇编

mov dword ptr[rbp-8],7

img

将索引设置为最大值7

同样需要补上text段被覆盖的汇编再跳转回text。

img

到这里漏洞修补的技术活儿就结束了,最后别忘记还需要去设置里应用这些更改之后才能退出。否则之前所有努力白费。

点击edit的patch program中的“Apply patches to input file...”然后点ok再退出就行了。

img
将修改后的附件放在ubuntu进行验证。

img

可以看到当输入越界索引后程序实际上还是在合法索引中写入了我们输入的内容,并且打印的地址也都没有超出范围。

在IDA中动态调试可以就看到程序确实是进行了跳转,并且汇编也和我们所更改的一样。

img

这说明漏洞修补成功。

格式化字符串漏洞

img

没开pie保护

修补思路是把printf函数原本的第一个参数放在第二个参数,添加占位符例如“%s”作为第一个参数。具体步骤如下:

img

定位到printf传参的地方,从0x4007f4开始修改,因为它传递了第一个参数。

img

eh_frame_hdr起始地址为(0x4008ec)

img

第一步还是跳转到eh_frame_hdr(0x4008ec)

jmp 0x4008ec

img

接着先传递第二个参数(顺序无所谓,只要能把参数改对就行了,条条大路通罗马)

mov rsi,rax

img

再传递第一个参数,这里选择传递一个%s作为占位符,这个占位符视情况而定。%s在3程序中本来是没有的,需要我们去写入一个,把它的ascii码 “25 73”写到一个地址,再给rdi传递该地址即可,这个地址同样是不重要的位置,随便取一个数据段地址或者就在eh_frame节找一个这里取了0x400928。

mov rdi,0x400928

img

然后跳转回text就行了,不过跳转回之前要把在text段被覆盖的指令补上

mov eax,0

img

跳转回text段,注意应该跳转到哪一条指令,注意上下衔接。这里应该跳转到call printf(0x4007fc)了。

jmp 0x4007fc

img

对了,别忘了去0x400928(计划存放%s的地方)写一个%s,这个直接去表头“Hex View-1”改机器码就行了,把光标放在0x400928的位置再点击该表头就可以切换到该地址对应的机器码。

img

14就是该地址所对应位置的机器码,按F2进入编辑模式,键盘直接敲输入25 73, 再按一次F2进行保存即可

img

如下图所示已经修改成功

img

到这漏洞已经修补完毕,最后点击“Edit>Patch program>apply patch to input file ...”进行应用再退出即可。

img

在修改过程中可以多看IDA下方的输出信息来确定每一步操作是否执行成���。

img

将修补过的漏洞程序放在ubuntu中查看修改结果,可以看到此时程序已经不会泄露栈中数据了,而且程序也未放生改变,仍然是将输入的数据打印出来。

img

开了pie保护

​ 在解题模式如果碰到开了pie的题目,往往需要想办法泄露程序基地址,所以我总觉得开了pie的题比较恶心,不过好在现在是要修漏洞,经过测验,jmp等跳转指令lea寻址指令在开了pie的程序中可以进行相对寻址,这使得我们补漏洞时不需要去借助当前寄存器的值去计算程序基地址,这意味着修补的操作步骤和没开pie的一样,只是需要将原来放完整地址的地方改为该地址相对于程序基地址的偏移使用lea指令传递地址而不是用mov指令。具体步骤如下:

img

img

eh_frame_hdr的首地址的相对偏移为0xA4C

jmp 0xA4C 

在未开pie的情况下这里放的是一个完整地址,开pie时就放一个相对偏移就行了,jmp 等跳转指令会进行相对寻址

img

mov rsi,rax

img

lea rdi,[0xA88] 

注意刚才在没开pie的情况下,使用了mov指令将%s的地址复制给rdi,当时的地址是完整的地址,在开pie的情况下完整的地址被替换为相对偏移,就不能再使用mov去给rdi传地址了,因为mov是单纯的复制指令,并不会进行相对寻址,而lea是可以相对寻址的所以可以用lea指令加偏移别忘了还有中括号去进行相对寻址

img

mov eax,0

img

jmp 0x95f

img

最后写入%s

img

img

应用、保存、退出、即可。

如下图已经修补成功。

img

在GDB看到放了相对偏移的地方指令执行结果如我们所愿。

img

img

溢出漏洞

img

该程序存在栈溢出,可以溢出0x10字节修补思路就是允许输入0x10字节,也就是把read的三个参数改回0x10

mov edx,0x10

img

一步到位,应用、保存、退出即可。

img

整数溢出漏洞

以BJDCTF的一道赛题进行举例。

很明显程序存在整数溢出漏洞,并且存在backdoor,打ret2text就可以拿到flag了。

img

修补思路是在输入名字长度后对length进行一个if判断,或者把强转给去掉。这里以加if判断举例。

先跳转到eh_frame_hdr

jmp 0x4009f0

img

cmp dword ptr [rbp-4],0

先去栈中取nbytes和0进行比较。

img

jl 0x400a10

如果小于零就跳转到一个“不重要的位置”,这里选择的是0x400a10(这里需要放重置nbytes的汇编,将nbytes设置为0)

img

程序本身就对nbytes做了大于10的判断,所以这里就不需要做大于的判断了,接下来把在text段被覆盖的汇编补上

mov eax,dword ptr [rbp-4]

img

cmp eax,0xa

img

jmp 0x4007e8

跳转回text段

img

最后去0x400a10放上重置nbytes为0的汇编代码。

mov dword ptr [rbp-4],0

img

补上text被覆盖的汇编再跳转回text

img

最后应用保存退出即可。

可以看到试图输入负数来进行攻击时第二步输入直接关闭了,因为我们在修补时直接把字节数设置为0了

img

在GDB中可以看到结果如我们所愿。

img

img

修改eh_frame所属段权限

010 Editor 是一款强大的二进制文件编辑器和数据处理工具。它允许用户以十六进制视图或文本视图的形式浏览、编辑和分析二进制文件、文本文件和数据结构。

​ 可以看到这个程序的eh_frame_hdr节和eh_frame节无执行权限。

img

img

​ 首先下载010editor,把要修改的ELF文件拖入010editor,刚进去的界面如图所示。
img

接着点击菜单栏的“模板”,再点击“模板存储库”,在里面找到“ELF.bt”模板安装。

img

接着回到机器码的位置右键单击运行模板,选择刚才安装的ELF模板运行。

img
再去上面菜单视图里找到“模板结果”单击,你会看到刚才运行的模板结果。找到struct_program_header_table

img

点击元素4,

img

找到enum p_flags64_e p_flags 如图黑框所示便是eh_frame节所对应的段的权限,选择读和执行权限就行。

img

最后点击保存即可。权限已经修改成功。

img

在IDA里查看的load具有了X权限。
img

在GDB查看,eh_frame节(0x40205c)已经被划为代码段。
img

IDA插件keypatch的安装

我的IDA版本为7.7,如果通过以下步骤安装失败,可能与IDA版本有关

1、将keypatch.py文件放入ida的plugins目录下

(keypatch.py可以从网上找到,开源社区GITHUB。

img

2、在主机的命令行窗口执行如下两条命令。(需要主机先安装python环境)

pip install keystone-engine
pip install six

3、重启IDA并进入edit查看插件是否安装成功

img

相关链接

参考文章:

https://bbs.kanxue.com/thread-273437.htm

例题附件:

https://pan.baidu.com/s/1OOUsE71rwJwJFmWHjFmk5w?pwd=1234

工具附件:

010editor:
https://pan.baidu.com/s/1UvOlCeMcte8Qitiiq4jE0g?pwd=1234
Keypatch.py:
https://pan.baidu.com/s/19Trr2CAbi4PO67AGTJBZAw?pwd=1234

posted @ 2023-06-21 16:39  Sta8r9  阅读(1122)  评论(0编辑  收藏  举报