首页
社区
课程
招聘
[原创]2020KCTF防守方赛题《西西弗斯的滚石》设计说明
2020-3-22 13:10 4642

[原创]2020KCTF防守方赛题《西西弗斯的滚石》设计说明

2020-3-22 13:10
4642

开始没注意提交到题库那个界面了,所以两边出现不一致的情况以这个帖子为准。

基本说明

题目类型:WindowsX64 Reverse
模式Ⅱ
参赛团队:䨻䴎蟗䵻鬮匶䬟㼖龘虪
这题是上次出的一道题的全面升级版,上次的题写的比较随意,但最终也只有5个人做出来。这次重新设计了代码结构,再放出来让dalao们试试。

设计思路

根据上次攻击方的wp,做了以下的改进:
1、整个shellcode全由自己的代码生成(上次的是对编译器生成的机器码进行修改),所以还想利用ida的f5?不存在的。
2、上次的题每条指令只会执行一次,smc自解密后并未再加密回去,所以有了跑一遍再DUMP下来这种"投机取巧"的做法。这次的题所有的指令都位于一个大循环内,每次解密后执行完都会再加密回去。每个CodeBlock里都嵌套了3层的smc。
3、取消了聊胜于无的反调试小trick。
4、添加了指令修改功能,每个codeblock运行时都会随机选择其他两个codeblock的指令进行修改,注意到这时其他codeblock的数据是处于加密状态的。所以这既使得每次循环执行的指令都有不同,也防止了破解者直接把codeblock自解密后的原始指令dump出来。
5、以上其实都不是重点,重点是shellcode生成方式。
本题的shellcode实质上是一个x64架构下的原生虚拟机。(原生的含义是直接使用x64架构中的指令,而不是在其之上再封装一层wrapper)。
虚拟机的指令集:adc,add,and,bswap,bt,btc,btr,bts,dec,inc,jmp,lea,mov,neg,not,or,pop,push,rcl,rcr,rol,ror,sal,sar,sbb,shl,shr,sub,xchg,xor
虚拟机的数据区:
寄存器:
rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15
栈:
进入虚拟机时rsp低地址处的50个qword。
状态寄存器:cf
栈指针:rsp
虚拟机的5种数据类型:
"pwd":变换中的密码数据
"const":与输入无关的常量
"stackptr":指向栈区的指针
"codeptr":指向代码区的指针
"uc":不确定
输入的密码hexdecode后由rcx,rdx表示,传入虚拟机进行可逆运算,运算结束后仍然由rcx,rdx传出,和用户名比较,相等则成功。

解题思路

1、维护一个Context结构,结构里存储了虚拟机的数据区的数据(包括数据类型和数据本身)
2、解析出执行的每一条指令的ins,imm,operand,按照ins,imm,和operand的不同情况更新Context结构(也就是模拟执行)。说起来一句话的事实际写起来很麻烦,比如我就分类讨论写了将近100个指令类。(如果会用unicorn说不定能使问题简单很多,但我不太会 :<)
3.模拟执行的过程中遇到pwd类型的数据,将其运算过程记录到文件。整个模拟执行过程完成之后,这个文件记录的就是简化的正向的对pwd的运算过程,吧这个对Pwd的操作反过来再逆回去就可以得到此题的注册机。

2020-6-22更新(补充解题思路):

上面提到的解题思路大概就是把pwd类型的运算过程trace一遍,但是仔细分析的话会发现pwd类型的数据并不好trace。究其原因,就是在形如mov a,b pop reg/stack push reg/stack 复制值时并不能确定Pwd数据是否发生了转移(用源代码构建的时候是可以确定的,但是确定是否转移的这部分信息在最后的二进制代码里被省略了)。
解决办法就是先倒过来trace一遍,pwd1和pwd2由rcx/rdx传出。倒着trace的过程中,比如遇到mov a,b指令,如果a为pwd数据,那么可知mov a,b这条指令之前b为pwd数据,mov a,b发生了转移。如果b为pwd数据,mov a,b并未发生转移。
倒过来trace又会产生一个小问题,reg可以直接解析出来,但是stack idx就不行了。所以在倒过来trace之前要先模拟执行一边,用以确定每条指令操作的reg和idx.可以注意到pwd数据并不会影响stack idx,所以把pwd数据当成uc再模拟执行一边,把途中指令的stack idx记录下来就行了。

PS

1、虽然这题个人感觉已经挺难的了,但是实际在难度和复杂度上还有很多的提升空间,比如增加外部函数的调用,执行完后抹去数据再换一块地址copy过去。写这题写了10多天,先写这么多,如果还是被dalao轻松破解(not likely?),下次再加上。
2、严格来说这题并不算混淆,没有什么constant blinging或者花指令之类的东西,如果裁判觉得有必要,可以找我公开源码。
3、附件内的public是向攻击方选手公开的文件,内有crackme和公开的一组注册码,secret里有一份我整理出来注册机,可以对任意的用户名生成密码,还有此题正确的flag。
4、有其他问题可联系Q:xxx


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2020-6-22 12:53 被mratlatsn编辑 ,原因:
上传的附件:
收藏
点赞0
打赏
分享
最新回复 (3)
雪    币: 29414
活跃值: (18625)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2020-3-22 13:30
2
0
OK
雪    币: 204
活跃值: (906)
能力值: (RANK:1324 )
在线值:
发帖
回帖
粉丝
mratlatsn 10 2020-4-15 20:44
3
0

更新

上传的附件:
雪    币: 204
活跃值: (906)
能力值: (RANK:1324 )
在线值:
发帖
回帖
粉丝
mratlatsn 10 2020-4-15 20:48
4
1
此题源码,此题结束后公开
最后于 2020-4-15 20:54 被mratlatsn编辑 ,原因:
上传的附件:
游客
登录 | 注册 方可回帖
返回