前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DASCTF|June GKCTF X DASCTF应急挑战杯WriteUP-PWN&REVERSE篇

DASCTF|June GKCTF X DASCTF应急挑战杯WriteUP-PWN&REVERSE篇

作者头像
安恒网络空间安全讲武堂
发布2021-07-09 15:47:21
1.3K0
发布2021-07-09 15:47:21
举报

June GKCTF X DASCTF PWN&REVERSE篇

2021年6月26日,GKCTF X DASCTF应急挑战杯圆满落幕。

本次竞赛涵盖WEB、CRYPTO、MISC、PWN、REVERSE常规CTF五大类赛题。

本篇主要分享PWN&REVERSE方向writeup,一起来看看吧~

NO.00

PWN类榜单

排名

战队名称

单位

积分

解题数

1

d1p

安徽土木工程学院

1926

2

2

EDI

EDI

1926

2

3

WaterDrop

中山大学

1926

2

4

flyfly

CNU

1926

2

5

Matr1X

/

928

1

NO.00

REVERSE类榜单

排名

战队名称

单位

积分

解题数

1

NAN

成都信息工程大学

4069

5

2

b8***5a1

Single

3069

4

3

ccc4

信安stdio

2869

3

4

Res0nat

SCUT

2070

3

5

打CTF不靠实力靠运气

浙江师范大学行知学院

2070

3

NO.01

PWN-Checkin

这⾥的sub_401974其实是md5加密对⽐(出题人:当时寻思平时登录框也都是加密与数据库对⽐, 我直接脑袋⼀抽,整了个加密算法进去。这⾥我没有对md5进⾏魔改⼀类的,我以为家⼈们都能mio杀,这波我的,但其实我认为逆向⼀个没有魔改过的常⻅算法应该问题不⼤,跪了。)

漏洞在输⼊buf的时候能够多输⼊0x8字节,刚好覆盖放置rbp的位置,在经过两次leave_ret 之后就能控制rsp,然后再输⼊s1也就是name的地⽅放置rop,这⾥由于⻓度刚好不够 pop_rdi_ret+rdi+puts+main_addr,所以直接跳转到sub_401876的地⽅(跳转到main函数会在执 ⾏setvbuf(stderr, 0LL, 1, 0LL)的时候报错)。

这⾥a135m_*的地⽅在data段,在调⽤函数的会在上⾯覆盖libc地址,构造如图payload

然后梅开⼆度就可以,挺简单的。

NO.02

PWN-edemo_catRoom

程序实现了⼀个聊天室(出题人:这⾥名字起错了,他喵的应该叫chatroom,少打⼀个h,⻅笑了。) 这⾥的洞其实就是在服务端接受通讯包的时候结构体的⻓度是0x68

但是在添加⽤户的时候malloc的时候只是0x48,这⾥就导致了堆溢出。

server端在刚开始的时候检测第⼀个⽤户有没有被注册,如果未注册,⾃动注册⽤户admin

其中admin密码为0x10位随机数

在登录那里有判断登录⽤户是否是admin,如果是就打印flflag

其实有了上⾯的堆溢出漏洞,就⾮常简单了,覆盖存放admin密码的heap,然后修改密码或者 更改admin⽤户名,然后登录admin⽤户,打印flflag即可。

这道题⽬确实很简单的,⽽且其实就是平时菜单堆的socket版本,要是换成菜单的估计要被mio 杀,当时对他的定位也确实是⼀个简单题,并且由于出题时间问题,这道题确实是demo版本, 还有挺多bug的,所以应该会有挺多⾮预期的,但是⼤家可能并不擅⻓去审或者没有耐⼼去审server端代码,所以这道题答题情况并不太理想。

还有个地⽅就是socket只能ip连接,所以要ping下buu平台取ip。

NO.03

PWN-EsapeSH

程序实现了⼀个简单的shell功能,并且提供了monitor管理员功能,不过monitor需要检测 malloc_hook的值为monitor,在程序将输⼊拷⻉到heap中的时候使⽤了strcpy函数,出现offff- by-null,然后利⽤echo功能泄露libc,然后利⽤offff-by-null来构造覆盖malloc_hook即可,这 ⾥麻烦的是每⼀次输⼊都是⼀次heap的申请与free,需要合理构造heap布局。

程序将输⼊以空格分隔,分割出来的字符串⽤strcpy复制进heap,这⾥strcpy可以实现offff-by- null。⾸先申请0x40heap ,⽤以填充(出题人:最后看来这个填充的似乎与主线关系不⼤,只是最开始的时候整的,然后忘记删除了)

然后构造如下heap布局,⽤来伪造

堆布局如下

然后申请0x10⼤⼩heap,来修改0x100heap的头

此时,已经修改了heap的头等于0x100,如下图。

接下来就是伪造存放判断上⼀个heap⼤⼩的地⽅了(出题人:原谅我忘求了那个地⽅叫啥了,我平时不喜欢记这些结构体变量名,导致这⾥哄堂⼤笑了,我直接给师傅们跪下) 这⾥由于是strcpy函数,没法⼦直接写\x00进去,就⼀个字节⼀个字节的减⼩,然后就可以将 辣个地⽅清零。

然后再写⼤⼩进去,在把这个0x100的heap申请出来free⼀下,就可以实现堆重叠

如图,就给0x71⼤⼩的heap堆重叠了。

然后就是把0x71的heap结构恢复⼀下。

然后就⽅便⽤echo来泄露地址

⾸先申请出0x20heap,来存放echo,然后申请出0x70也就是0x5621c5ac4310,然后申请出 0x5621c5ac43a0,在申请0x5621c5ac4240时刚好将0x70的heap的内容改为main_arena的 地址,然后echo就泄露出来libc地址了。

接下来就简单了,其实还是⼀样的操作,来改写malloc_hook的值="monitor"

这个脚本的话因为完成的⽐较早(出题人:这个题在很早之前就出出来了,所以在现在看来有些不成熟的地⽅,但是因为wp要发早点,就没时间让我在推倒重写了(其实是懒),所以有些地⽅写的⾮常繁琐,师傅们尽可以在了解堆布局后⾃⼰写,觉得哪⾥有问题也可以跟我聊下,呜呜呜。) 最后的exp

NO.04

REVERSE-QQQQT

PS:下⾯所说的⼀切思路可以在题⽬开源后⾃⾏通过源码对⽐和IDA加载可执⾏⽂件进⾏验证。

Enigma Virtual Box打包的QT程序,可以解包其实也可以不解包,因为这⾥并没有对字符串做 隐藏,按钮事件函数可以很块通过flflag字符串定位,按根据钮事件的逻辑也⼗分好猜,base系列 加密特征明显,对base系列算法稍有了解的即可识别。若还是⽆法识别,建议查看⼀些base系 列算法C实现,⾃⾏积累⼀些识别特征的⽅法。

最终是⽤了⼀个base58进⾏加密,加密字符串也是写脸上,可以直接百度或⾕歌在线⽹站解密即可。

flflag: flflag{12t4tww3r5e77}

PS:学弟出的这个题⽬没有对字符串做隐藏,使得选⼿不⽤了解QT任何机制就能解出来。

NO.05

REVERSE-Crash

可根据字符串信息也可根据段gopclntab判别是golang elf程序。符号表可以在IDA7.5中通过 IDAGolanHelper(出题人:该插件近⼀个⽉有更新,可以⽀持⾼版本go符号还原)还原符号。

有了符号信息后静态审代码就⾮常清晰明了,⽤了3DES CBC, SHA256, SHA512, MD5,对四 部分数据进⾏验证,⽽对应的密⽂也都可以简单的提取出来。

3DES CBC的密钥为⼀个txt⽂件,利⽤golang新版特性附加到来了⼆进制⽂件中,可以⽅便的 找到,因此直接解密即可。

hash系列函数都是4字节爆破,⽤python的itertools可以快速爆破。

NO.06

REVERSE-App-debug

出题人:这个题⽬⽐赛过程中出来⼀些情况,这⾥对造成不便的师傅说⼀声道歉。

安卓逆向题⽬,主要验证逻辑在native层,因此直接进⼊native层即可。对输⼊进⾏tea加密验 证,delta是0x458BCD42,并且有利⽤TracerPid的反调试,当发现调试器时,会使⽤假的 key,只要没有检测到调试器才会使⽤真key。

因为key是⼀个全局变量可以通过引⽤找到在哪⾥替换为了真key,再找到⽐对的密⽂后即可进 ⾏解密函数的编写。

NO.07

REVERSE-KillerAid

程序结构分为两部分,⼀个C# 前端GUI,⽤于获取ID和Code,并将ID⽤Code进⾏循环异或处理,最后⽐对ID。需要获得ID的前提必须有正确的Code,因此必须先解出Code。

Code的验证逻辑在⼀个⽤C++编写的KillerAid.Core.dll中。Core.dll中主要由两部分组成,⼀部分是⽤于反调试的检测代码,⼀部分是基于AES-CBC的⼀个简单对称加密体系算法。

反调试检测代码主要有三部分,⼀部分是利⽤WIN32 API以及⼀些Windows下⽐较常规的反调 试技巧;另⼀部分是通过便于隐藏特征的动态CRC32算法对ntdll、Core.dll、exe的代码段进⾏ 冗余码校验;最后⼀部分是,基于xd4d⼤佬⼀篇解析Net内核调试机制的C++代码实现⽅案,⽤于切断.net 内核调试线程(即杀死调试线程实例)与dnSpy和IDA这类托管调试器的通信。

调试启动的⼿段通过C++ 语⾔机制,⽤于⼀个全局委托类进⾏构造,它会在dll被加载时,⼗分 早的调⽤委托类的构造函数,⽽所以反调试⼿段都是通过调⽤win32 API创建⼀个反调试线程进⾏检测。

这期为了实现这些功能所调⽤的所有Win 32 api以及⼀些native api都是定义成为函数指针集成 到⼀个代理类中,调⽤进⾏动态函数地址获取,可以⽐较有效隐藏win32 api的调⽤以及⼀部分抗静态分析的效果。

由于反调试⽐较多,虽然可找到⼀个反调试的主调⽤函数,进⾏⽂件patch,但最简单的⽅法仍 然是将反调试线程挂起。但没有做好的⼀点是动态crc32的调⽤时机相对于exe的运⾏时机来说 还是太滞后了,后⾯想考虑加⼀个隐蔽的使⽤⽂件CRC32进⾏检测,但由于时间原因并没有加上。

⾄于加密函数的设计,是⼀个基于AES-CBC模式设计的简单对称加密体系,具体设计如下图所示:

具体的解密部分并没有写多少,但可以参照AES的解密思路,⼀个道理,这⾥不多做赘述。

AES算法的初始key和iv向量都是定义为全局变量,并使⽤rand函数动态获取。由于iv向量是全 局变量,dll⼀加载即有数据了,所以这⾥即便没过反调试,也可通过实际加载的ImageBase计 算偏移获得key和iv向量的地址(PE的知识),提取数据即可。

⾄于解密函数,可在源码中dllmain.cpp中找到,当然这⾥也贴出来了。

NO.08

REVERSE-SoMuchCode

这个题⽬的混淆思路⼗分简单,即再真实逻辑中插⼊⼤量的有引⽤的垃圾代码,⽤来将真实的逻辑变得更加复杂难看,其实从CFG图中可以看出,并没有任何复杂分⽀,基本是⼀条流程⾛到底,⽽具体垃圾代码的插⼊的实现思路是使⽤编译器预处理的宏展开机制进⾏的。

程序的原始逻辑⼗分简单,获取输⼊,进⾏xxtea加密,与密⽂⽐较。然⽽真正分析起来,代码量可能令⼈头疼。

本题希望选⼿能够在⼤量的垃圾逻辑中抓住关键部分进⾏逆向,因此xxtea加密函数中进⾏⼀部分混淆,但关键特征并没有进⾏混淆,只要通过⻓⻓的程序流程追踪到了加密函数,即可识别出 是xxtea加密,后续解题思路也会明了起来。

具体解密函数可参考源码给出的实现。

flflag:GKCTF{9b34a61df773acf0e4dec25ea5fb0e29}

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档