AWDP-总结笔记
没咋打过AWDP,就连AWD打的也很少,因为第一次打线下赛,所以准备写个笔记记录一下,完事之后在准备在补点笔记。
Web那边我不知道,只记录了pwn这块的
唉,菜就多练。
简介
没啥说的,就是跟AWD差不多
漏洞加固技巧
在AWD中每个选手会分配到一个运行了漏洞程序的靶机,我们可以找到自己靶机中的PWN附件(也就是漏洞程序)进行分析,发现漏洞来编写exp攻击其他队伍的靶机,同时我们需要用一些手段加固漏洞防止被其他选手攻击得分。
patch-PWN
patch就是通过修改漏洞程序的漏洞汇编代码从而防止其他选手进行漏洞利用,不同的awd平台检查机制各不相同,原则上是只能针对漏洞点进行 patch 加固
工具介绍:ida插件keypatch
链接:通过百度网盘分享的文件:IDA_Pro_7.7.zip
链接:https://pan.baidu.com/s/1M2OunlHHhSjwCaWLyGsQNA
提取码:Rweb
整数溢出
跳转指令
有符号跳转
思路:所以patch整数溢出便是针对于汇编中的跳转指令进行patch
这里没找到合适的例题先放着
栈溢出
通常是限制长度就行
x64
栈溢出还是比较好修的。直接patch就行了
x86
因为是栈传参,所以直接修改push就行了
格式化字符串
常规方法:
可以将call printf改成call puts
本来是像网鼎杯线下准备的,结果换了
就先放着等有时间再来接着写
OK!!2025.3.3
回来继续写!
方法二:
缺点:
像前面的情况puts 函数会自动在输出的字符串尾部加入一个回车符,某些情况下导致 check 脚本不通过。
SO,
修改printf参数,将printf(format)
修改为printf("%s",format)
,修改 printf 前面的传参指令:
1 | mov edi, offset 0x400c01 ;地址为%s的地址 |
eg:
1 |
|
x64
我们ida打开看见printf
1 | mov rdi ,offset 0x000000000402004 |
path之后
但是这种也有局限性吧,也就是如果找不到%S的地址,就会patch失败
一般是在data段上
—-2025.3.11
例题:2024年国赛-where is my stdout
回来补充一下,当我们在data段上找不到我们的data段上找不到**%s的时候,我们就需要在.eh_frame段上写一个%s**就可以了
随便找一个位置,修改字节码为
1 | 25 |
然后我们就可以看见字符串%s了
ok了,图上只是大小段序的问而已不影响做题。
1 | mov rdi ,offset 0x04020EB |
就不知道这样行不行,check机制不知道能不能过。
x86
主要区别就是在于传参的方式
1 | ;lea eax, [ebx + (0804A008-0x804A00)] |
但是换成这样的话,你会发现我们的字节不够,会把后面的指令覆盖掉
准备暂时先这样,一般也不会出32位的吧
只能写到eh_frame段上,这样的化就是只改call _printf改为跳转
在en_frame段上写指令就行了吧
更换危险函数
这里就是把gets函数换成read函数
例题:BUUCTF-ciscn 2019_c_1
没啥说的,溢出点一下就找到了
这块看字节长度是不够的
so我们只能把这个修改为我们自定义的read函数,让函数跳转到我们自定义的汇编程序上
1 | mov rax,0 |
我们ctrl+s打开找到.en_frame段并且看一下它的的权限
我们看见是没有可执行的权限的
但是!!!!!!
这里看一下其实我们gdb调试的时候我们是可以看见这段是由可执行权限的
so,我们不改的话,其实也是没有问题的
但是我们F2查看ELF头的时候
我们发现整段都是可执行的,可能这也是gdb调试的时候发现有可执行权限的原因吧
如果没有怎么办
我们翻到elf头改为可执行,这里是直接给了所有权限
修改如下:
改为:
这里笔者用的change byte改的,注意一下大小端序的问题就可以了
跟换函数
在我们的.en_frame段找到一段空白的地方
首先重命名一下
然后我们依次patch就ok了
在最后一个跳转回来的时候
这里使用ret而不是jmp loc_400AB4(call 0x0000000004009E2)
原因是
so ,最后patch我们的call _gets即可
然后我们正常打补丁就可以了
验证一下
我们发现我们打完补丁之后的验证会发现我们打完补丁会多一个回车。
至于为什么会多一个回车原因如下:
简化原因就是:
1
2 >"hello world\0" //gets
>"hello world\n" //read所以多了一个回车,当然这只是笔者这么觉得
UAF
例题:ctfshow-pwn141
UAF没啥说的user-after-free漏洞
定位到我们的漏洞函数着,函数释放完堆块,指针没有置NULL
但是为什么和我看的文章不一样呢?
尝试patch
这里还是直接去看.eh_frame段,老这样还是先起一个名字然后看一下权限
明显的没有执行权限,但是根据上面的做题技巧,我们去看一眼.eh_frame的ELF头
坏了这下真得改了
这里直接改成可读可写可执行,打个补丁,验证一下
但是!!!!!
patch完之后,我们看见我们的权限是没有变的!
这里还是准备尝试打一下补丁
看文章说是复制前面的指令到.eh_frame段上
啥意思就是最后给pr指针只为0呗
1 | call 0x8049134 ;_free |
例题:2023-StrangeTalkBot和2024决赛ezheap
笔者找啊找!
我靠这里笔者是复现的[第十七届CISCN总决赛-AWDP-PWN部分题解](file:///D:/Astudy/title/pwnCTF/AWDP/国赛/看雪/[原创] 第十七届CISCN总决赛-AWDP-PWN部分题解-CTF对抗-看雪-安全社区_安全招聘_kanxue.com.html#msg_header_h2_3)
找猫画虎的
ok,我们先看一下StrangeTalkBot这道题
这里没啥说的,直接就是UAF漏洞
看一眼反编译
但是笔者这么改不知道能不能过check机制了
AwdPwnPatcher
我靠,看下这个自动化脚本
依赖环境
1 | sudo pip install pwntools |
设置环境变量
1 | export PYTHONPATH=/path/to/AwdPwnPatcher:$PYTHONPATH |
脚本
1 | from AwdPwnPatcher import * |
脚本跑不起来,注意一下环境变量即可
但是这里笔者不建议用工具修,还是自己修来的快一些。
2024-CISCNx长城杯铁人三项-半决赛
果然线下被打爆了
这里笔者想总结一下自己第一次打AWDP也算是最后一次打线下赛了
AWDP
typo
这里笔者也是比较幸运,在第一轮就修成功了
这里笔者推荐一个插件Accenture/VulFi。
插件用法我就不介绍了,扫到两个洞,笔者歪打正着整好给修了
思路如下:改snprintf为puts,修改溢出的8字节
漏洞1:这里是直接改call plt表就行。(不会的直接call back)
漏洞2:这里是直接keypatch抹去八字节即可
prompt(赛后复现)
这里笔者也是赛后复现的,怎么说呢?想歪了,到最后是没有次数了
笔者刚开始改的这个的大小,后面就是越改越远了
这里老样子改写eh_frame段的可执行权限
这里可以用010改,或者用上面的方法改应该没啥问题,都试试
或者改010这里也没啥问题
这里赛后是复现了一下,真正的漏洞是在这里
限制一下最大长度就好,正常跳转到en_frame段上就好
然后patch即可
渗透
这里渗透的靶机入口也是一道pwn,web手把elf文件提出来,扫一下端口(65533)
没啥说的,ret2libc
1 | from pwn import* |
得到权限后,有个sudo提权,然后之后的反弹shell打内网就是web手接手了
附件
通过网盘分享的文件:比赛附件.zip
链接: https://pan.baidu.com/s/1ftbu75MbKZVy2gF_PopcDw 提取码: Rweb
总结
AWDP对我来说,不会打不一定不会修,怎么说,临近比赛前突击一下即可。还有就是要对渗透那边至少应该多少会一点,比如基本的外网打点,扫扫端口和域名啥的。对web的一下语言应该也要有些了解,比如php语言之类的,感觉那道phppwn就是纯web,可以让队里面的web手看看。
笔者觉得在修这方面,主要修的越快越好,修的轮数越早吃的分越高。刚开始不用太着急审代码,直接插件扫一遍,简单修一下,说不定就修掉了,因为他不会都出难的,肯定是有简单的,修完一遍之后在,在着重去审计代码,还有就是不要太死嗑一道题,因为是有次数限制的。
最后就是,在最后几轮的时候,就可以随便修了,碰碰运气。
参考文献:
AWDPwn 漏洞加固总结 - FreeBuf网络安全行业门户
AWD PWN方法总结 - 先知社区 (aliyun.com)
pwn patch ciscn_2019_c_1 - 叶际参差 - 博客园 (cnblogs.com)
aftern00n/AwdPwnPatcher (github.com)
AwdPwnPatcher/Tutorial.md at master · aftern00n/AwdPwnPatcher (github.com)
特别感谢:
什么时候才能学成CTF高手哇~~
-2025.3.8 回“这辈子别想了”
-2025.3.19 回尽力就好,别想太多。