Y1rannn 发表于 2022-1-27 05:53

[红帽2019] calc


## 红帽2019 calc

唉, 用Arm的mac真的挺痛苦的,但是mac上的IDA又是正版,Intel mac还有点老

这道题就是mac的pd没法动调,qemu也不行,只好又回到win的本子上用7.6了..讲真,7.7在m1上跑的真的快

----

因为静态分析是在mac上完成的,所以静态部分可能写的不是很全,不过也没分析出来太多东西.废话到此为止



这题一共输入了三次, 而且看上去对这三个东西的操作是相同的, 我想试试直接动调看看它对输入做了什么(其实是自己动调能力太弱,想针对性的训练一下)

每次输入之后都有一个很长的sleep, 先把它们扬了才能动调

![屏幕截图 2022-01-27 034100.png](https://tianyu.xin/usr/uploads/2022/01/792270636.png)

![屏幕截图 2022-01-27 034121.png](https://tianyu.xin/usr/uploads/2022/01/2798619539.png)

![屏幕截图 2022-01-27 034133.png](https://tianyu.xin/usr/uploads/2022/01/826061993.png)


输入一个1234abcd, 栈上的cin参数变成了这样:
![屏幕截图 2022-01-27 041429.png](https://tianyu.xin/usr/uploads/2022/01/3083260304.png)


应该是个内存地址0x1D7FF4658D30, 跳一下发现了对应的堆上内存存放着刚刚输入的1234abcd, 打上一个内存硬件断点, 直接执行遇到了一个C++的错误,不对,再来.

第二次没有下内存断点,结合内存在堆上推测出两个奇怪的函数应该分别是new和构造函数(瞎猜的), 在读入一个之后, 执行了两个函数设置了两个变量的值,之后分别执行了三次这样奇怪的东西:
![屏幕截图 2022-01-27 042623.png](https://tianyu.xin/usr/uploads/2022/01/957580767.png)


现在能确定input里面存的还是指针, 感觉是一个类似string的东西, 下面得摸一摸FF0和A90两个函数,看看它们到底干了什么. 再来一遍惊奇的发现输入竟然不在input指向的地址里了,我猜这应该是IDA的锅, input在BASE+8490H,而输入的abcd1234则在堆的最末尾BASE+F5C0H,感觉这是构造之后, string太长重新申请但是指针没跟过去...

管他呢,先分析这两个函数, 发现FF0里还是调用了A90,而且FF0还是个递归函数.那不妨先看A90, A90里又发现了这种奇怪的片段,我现在觉得这片段没啥用, 应该是编译器加上的,先进行一个忽略, 第一次调用, a2和a3传的都是输入的这组void* , 这样可以猜测**第二个和第三个参数**应该是并列的, 检查第一个参数,发现第一个参数都是表达式左值,基本上是一个不参与运算,当返回值用的东西, 审计过后发现FF0函数也同样是把它当返回值用那这样逻辑就有一点眉目了:把a2和a3进行一个处理,结果放回a1,

下面通过一个调用动态看看到底是进行了什么处理(不特殊说明测试输入都使用1234abcd了)

```c
__int64 __fastcall sub_7FF666A81A90(__int64 a1, __int64 *a2, _QWORD *a3)
{
int v6; // ebp
__int64 v7; // r8
__int64 v8; // rax
__int64 v9; // rsi
__int64 v10; // r11
int v11; // er10
__int64 v12; // r9
__int64 v13; // rax
void *v14; // rcx
_DWORD v16; // BYREF
void *Block; // BYREF
__int64 v18; //

v16 = HIDWORD(a1);
v16 = 0;
*(_OWORD *)Block = 0i64;
v18 = 0i64;
maybe_new((const void **)Block, 0i64, v16);
maybe_cons((__int64)Block);
v16 = 0;
sub_7FF666A83CE0(Block, ((__int64)(a3 - *a3) >> 2) - 1 + ((a2 - *a2) >> 2), v16);
v6 = 0;
v7 = *a2;
if ( (unsigned __int64)(a2 - *a2) >= 4 )
{
    v8 = a3 - *a3;
    v9 = 0i64;
    v10 = 0i64;
    do
    {
      v11 = 0;
      if ( (unsigned __int64)v8 >= 4 )
      {
      v12 = v10;
      do
      {
          *(_DWORD *)((char *)Block + v12) += *(_DWORD *)(*a2 + v10) * *(_DWORD *)(*a3 + v9 + v12);
          ++v11;
          v12 += 4i64;
          v8 = a3 - *a3;
      }
      while ( v11 != v8 >> 2 );
      v7 = *a2;
      }
      ++v6;
      v10 += 4i64;
      v9 -= 4i64;
    }
    while ( v6 != (a2 - v7) >> 2 );
}
v13 = maybe_cons((__int64)Block);
sub_7FF666A81700(a1, v13);
return a1;
}
```

直接进这个函数然后再看看参数指向了哪里.
![屏幕截图 2022-01-27 044655.png](https://tianyu.xin/usr/uploads/2022/01/1209779582.png)


它让我意识到我犯了一个错误,不是IDA处理错误, 这个4, 3, 2, 1不是指针指向的地方错了,而是真的就是4321,和输入相关,我们把输入变成987123试试


![屏幕截图 2022-01-27 045011.png](https://tianyu.xin/usr/uploads/2022/01/473067430.png)


奇怪,这次是数字了,但是你发现上一张图的字符4321下面也有数字4321,而且正好都是逆序的, 我猜想...

```python
ord('a') - ord('0') => 0x31
```

这个结果印证了我的猜想,这中间某步应该是把输入都减掉'0'的ascii,应该是要把数字字符转数字. 这样可以猜测输入要求上是数字.(话说这也太巧了,我要是没输入abcd, 也就不出1234,那我是不是也就不会走这儿的弯路..离谱)

那对于数字的处理就好猜了,无非是运算嘛,我们直接跑完这个函数, 看看返回值是啥样的

FF0(987123) == 974411817129, emm 这啥也看不出来,我们输入小一点

FF0(15) == 225, 袜, 这不一眼平方么, 上面的987123的平方也印证了这个结果.

我们发现FF0用的是三个参数, 第一个参数是返回值,第二个参数是底数,第三个参数发现正好是2, 这样就可以猜出来第三个应该是指数, 那9A0是干嘛的?

![屏幕截图 2022-01-27 045708.png](https://tianyu.xin/usr/uploads/2022/01/2215949236.png)


此时v10存的是一个15^2 == 225, 而A90又把v10传进去了,我们看一眼124是4,运算结果是900, 那么结果很明了了:

FF0<=>pwr(res, p, q) : res = p^q

A90<=>mul(res, x, y) : res = x*y

把三个输入都做了这样的操作后,我们来到这里, LABEL_47是win后面的,换言之就是不能跳, 动调到这也明白了,inputi是起始地址,inputi是结尾地址, v25是数字长度(一个数字占4), 这里大概就是验证的一部分了, 至少我输入15 20 25 是过不去这里的.读代码之后知道这里是相当于一个格式验证, 第一个数不能大于第三个数, 第二个数不能大于第一个数

![屏幕截图 2022-01-27 050158.png](https://tianyu.xin/usr/uploads/2022/01/1126297723.png)


尝试输入100, 50, 150后成功bypass到下一部分

![屏幕截图 2022-01-27 051812.png](https://tianyu.xin/usr/uploads/2022/01/3423858849.png)


最后这里v46的值是750000,

![屏幕截图 2022-01-27 052533.png](https://tianyu.xin/usr/uploads/2022/01/2011906391.png)


这个v56是3375000

![屏幕截图 2022-01-27 052711.png](https://tianyu.xin/usr/uploads/2022/01/1717177695.png)


3652264, 不是整的数,多少有点奇怪, 动调出550函数是减, 7E0是加, 这应该是个自己实现的高精度类 再继续往下走就直接failed了.我决定直接分析这些函数到底最后对输入做了什么

$(x+y)^3 - 3\times x\times(y^2) - 3\times y\times(x^2) == (z+4)^3 - 12(z^2) - z\times 48 - 22$

最后这些式子化简的约束是x^3+y^3-z^3==42,flag就是三个数字合一起的, 著名的"宇宙终极问题"

[知乎问题链接](https://www.zhihu.com/question/432232685), 把它们按上面的大小排序之后合一起md5就是flag

不过网上的wp都是比赛wp或者干脆是瞎扯淡, 比赛wp往往没有思考的过程和思路,我认为对我没什么帮助

瞎扯淡的wp就是看了别人wp在瞎扯淡, 我很鄙视这种人.抄了flag还不够还非要假装自己会了, 虽然我有的时候也出来抄flag, 但是至少不出来瞎说(

这是一道从凌晨四点做到六点的题,脑子多少有些不灵光了(


Hmily 发表于 2022-1-27 18:55

Y1rannn 发表于 2022-1-27 05:54
本来还发了一个Hardcpp插桩的wp,但是会被网站拦截,死活发不出来...

把报错代码私聊发我,我查下原因

Y1rannn 发表于 2022-1-27 05:54

本来还发了一个Hardcpp插桩的wp,但是会被网站拦截,死活发不出来...

tl;dr 发表于 2022-1-27 06:57

liuxia 发表于 2022-1-27 07:52

学习学习

cheny12120 发表于 2022-1-27 08:48

感谢楼主,学习了

yahoo1920 发表于 2022-1-27 09:31

感谢楼主,学习了{:1_904:}

夕阳枫 发表于 2022-1-27 09:45

深奥,继续学习。

xz91168 发表于 2022-1-27 12:21

有一张图看起像门禁卡的数据.{:1_905:}

muyu1314520 发表于 2022-1-27 14:37

tl;dr 发表于 2022-1-27 06:57
这是计算器吗?


这是计算器吗?

zhang-sy 发表于 2022-1-27 15:43

对于开发来说,很麻烦吗
页: [1] 2
查看完整版本: [红帽2019] calc