记一次ctf比赛EzXor的WriteUp

admin 2023年1月17日19:02:10评论42 views字数 1574阅读5分14秒阅读模式

·点击蓝字 关注我们·

记一次ctf比赛EzXor的WriteUp


记一次ctf比赛EzXor的WriteUp


EzXor WriteUp


我们拿到题后先运行一遍看看

记一次ctf比赛EzXor的WriteUp

Ok,上调试器,这里选择使用x64dbg动态调试,一个面向未来的调试器!

记一次ctf比赛EzXor的WriteUp

此时,我们是在ntdll中,并非用户模块中,这是因为设置里勾选了系统断点

我们再次点击运行就可以中断到程序入口点了AddressOfEntryPoint + ImageBase(未开随机基址的情况下) 具体可参考PE结构

记一次ctf比赛EzXor的WriteUp

我们直接搜字符串,看看有没有可以利用的字符串来帮助我们定位到关键点

记一次ctf比赛EzXor的WriteUp

发现这正是程序输出的,我们双击它

记一次ctf比赛EzXor的WriteUp

调试器已经帮助我们转到了这里,把这个字符串的地址给了rax,再赋给rcx

由于是64位程序,我们可以得知是fastcall调用约定,在Windows系统上rcx就是第一个参数,rdx是第二个参数r8 r9分别存储第三第四个参数,多余的会被压入栈中

由此断定,下面那个call就是printf函数

进入这个call,我们直接给它一个标签

记一次ctf比赛EzXor的WriteUp
记一次ctf比赛EzXor的WriteUp

为了防止标签冲突,我们在前面加个下划线

之后我们按减号键返回

记一次ctf比赛EzXor的WriteUp

我们再看下面那个lea rax, ds:[0x00007FF70BD71016]

我们发现这个地址里存着%s

记一次ctf比赛EzXor的WriteUp

字符串以00结尾

疑似是scanf函数

我们在这个call下断点

记一次ctf比赛EzXor的WriteUp

断下后我们F8单步步过,发现程序阻塞住了, 让我们输入flag, 由此我们断定这个call就是scanf,防止命名冲突,我们给它标签: _scanf

输入flag后单步走到下一个call

记一次ctf比赛EzXor的WriteUp

观察此时寄存器状态

Rcx也就是第一个参数为我们输入的flag

Edx也就是第二个参数是一个常数

我们通过这个信息,可以判断函数原型为 func(char* arg1, int arg2);

我们跟F7(单步步入)进去看一看,没病走两步~

记一次ctf比赛EzXor的WriteUp

注意这三条指令,它们把我们的参数1和参数2分别放入了[rbp+0x20]和[rbp+0x28],我们发现第二个参数放进去的是一个字节,由此我们推翻我们之前的定论

函数原型应为:

func(char* arg1, unsigned char arg2);


往下走,走过那个jmp后发现是个循环

记一次ctf比赛EzXor的WriteUp

没错,strlen比较的正是我们第一个参数(我们输入的flag),这个函数返回的数据给了rax寄存器

记一次ctf比赛EzXor的WriteUp

我们观察此处寄存器状态,发现它把我们flag的每个字节都给al,然后与我们第二个参数进行异或,rcx作为一个迭代计数器(index)但第二个参数为什么变成了6呢?往上翻发现

记一次ctf比赛EzXor的WriteUp

原来是自己加了自己

由此我们可以推出函数具体做的事情:

Int func(char* a1, unsigned char a2){
Int tmp = a2 * 2;// 或a2 + a2;
For(int i = 0; i < strlen(a1); i++)
{
// *(a1 + i) = *(a1 + i) ^ a2;
a1[i] = a1[i] ^ a2;
}
}

此处我们推断的函数不关心返回值

我们可以选择jb 0x00007FF70BD615FE指令的下一行,运行至此

然后一路f8返回出去

记一次ctf比赛EzXor的WriteUp

我们发现它拿着异或加密完的数据跟另一个数据比较

记一次ctf比赛EzXor的WriteUp

这个跳转,我们走过去是肯定要失败的,我们既然都弄明白了它的算法,我们又知道异或算法可逆,那我们知道了key,我们只需要把它比较的密文再进行一次异或运算就能拿到正确的flag了,我们直接编写代码:

char buffer[255] = "BGUER@}GuYSYEghY5Y^6tY7uYC|{";

for (size_t i = 0; i < strlen(buffer); i++)
{
printf("%c", buffer[i] ^ 6);
}

最后得到flag为: DASCTF{As_U_Can_3_X0r_1s_Ez}

最后

记一次ctf比赛EzXor的WriteUp
记一次ctf比赛EzXor的WriteUp

团队招新啦~

招新规则:想加入团队,可以留言联系我,需要自行录制或者直播一次技术分享,技术内容不限~

我们团队秉承着互相学习互相分享,共同进步的精神进行学习哒~


原文始发于微信公众号(鸿鹄空间安全实验室):记一次ctf比赛EzXor的WriteUp

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年1月17日19:02:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次ctf比赛EzXor的WriteUphttps://cn-sec.com/archives/1428198.html

发表评论

匿名网友 填写信息