吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4085|回复: 34
收起左侧

[CTF] 学破解第196天,《攻防世界reverse练习区hackme》学习

  [复制链接]
小菜鸟一枚 发表于 2022-6-10 19:38

前言:

  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1582287-1-1.html

立帖为证!--------记录学习的点点滴滴

0x1 正向分析

  1.将程序拖进IDA,没有看到main函数,打开字符串窗口,看到关键字符串

https://s1.ax1x.com/2022/06/09/Xy8tuq.png

  2.查看引用地址所在的函数,F5伪代码查看,可以看到关键在v26必须为true,再看看v26会赋值0,必须过掉v21的那个循环判断,v21可以看到是直接从数据段取地址。

https://s1.ax1x.com/2022/06/09/XyYHM9.png

  3. 去看看byte_6B4270这个数组,可以看到数组长度24,一共22个数据。

https://s1.ax1x.com/2022/06/09/Xyd4gS.png

  4.再往上看,可以知道我输入的密码必须是22位,v26才会被赋值true。

 sub_407470((unsigned int)"Give me the password: ", a2, a3, a4, a5, a6, a2);
  sub_4075A0((unsigned int)"%s", (unsigned int)v16, v6, v7, v8, v9, v14);
  for ( i = 0; v16[i]; ++i )
    ;
  v26 = i == 22;
  v25 = 10;

  5.再看看这个循环,就是处理的关键点,sub_406D90这个函数执行的返回值可以看到是int,猜测是随机数对22取余,然后v21就是从数组中对应下标取值,v20就是从我输入的密码字符串下标取值,然后v24那个循环有点看不明白。

do
  {
    v10 = (int)sub_406D90() % 22;
    v22 = v10;
    v24 = 0;
    v21 = byte_6B4270[v10];
    v20 = v16[v10];
    v19 = v10 + 1;
    v23 = 0;
    while ( v23 < v19 )
    {
      ++v23;
      v24 = 1828812941 * v24 + 12345;
    }
    v18 = v24 ^ v20;
    if ( v21 != ((unsigned __int8)v24 ^ v20) )
      v26 = 0;
    --v25;
  }

  6.到这里静态已经看不出什么了,程序的流程已经理清楚了,接下来的关键是弄清楚循环中v24的由来和sub_406D90是不是符合我前面的猜想。

0x2 逆向解密

  1.本来想用IDA动态调试看看,验证我的猜想,一直失败,不知道啥原因。

  2.不能完全搞清楚也不要紧,按照前面的逻辑,涉及到运算的,代码反转即可,但是这里那个循环没弄明白,可不好反转,将ida中代码重命名一下,再看看。

 do
  {
    j = (int)sub_406D90() % 22;
    v22 = j;
    sum = 0;
    pwd_ch = password[j];
    input_ch = intput[j];
    k = j + 1;
    m = 0;
    while ( m < k )
    {
      ++m;
      sum = 1828812941 * sum + 12345;
    }
    v18 = sum ^ input_ch;
    if ( pwd_ch != ((unsigned __int8)sum ^ input_ch) )
      v26 = 0;
    --v25;
  }
  while ( v25 );
  if ( v26 )
    v17 = sub_407470((unsigned int)"Congras\n", (unsigned int)intput, sum, j, v11, v12, v15);

  3.现在我们看,就是从input和password中取值比较,最后的比较是异或,sum的计算只与k有关,和两个数组本身无关,异或的特性我们知道,可以直接颠倒运算,那么我可以把password作为输入,计算出input。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int password[]={0x5F,0xF2,0x5E,0X8B,0X4E,0XE,0XA3,0XAA,0XC7,0X93,0X81,
    0X3D,0X5F,0X74,0XA3,9,0X91,0X2B,0X49,0X28,0X93,0X67,0x0};

    char input[23];

    int v25 = 22; //结束外层循环
    int i = 0;//下标,遍历每一个元素

    do
    {
        int sum = 0;
        int j = i + 1;
        int m = 0;
        while ( m < j )
        {
        ++m;
        sum = 1828812941 * sum + 12345;
        }

        input[i] = (unsigned __int8)sum ^ password[i];

        i++;
        --v25;
    }while(v25);

    printf("%s\n",input);
    system("pause");

    return 1;
}

  4.运行上面这段代码得到flag:

flag{d826e6926098ef46}
请按任意键继续. . .

0x3 总结

  1.在分析遇到困难,不能理解代码含义的时候,可以靠猜想和保持逻辑不变去计算flag。

  2.编写flag计算时,可以将IDA中的伪代码重命名,方面理解,还可以直接搬运使用。

免费评分

参与人数 19威望 +1 吾爱币 +37 热心值 +17 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yueryoufeng + 1 + 1 谢谢@Thanks!
funzeroo + 1 + 1 我很赞同!
hebo308 + 1 + 1 我很赞同!
skiss + 1 + 1 谢谢@Thanks!
timeni + 1 + 1 用心讨论,共获提升!
ZJH1112 + 1 + 1 谢谢@Thanks!
Chenda1 + 1 + 1 我很赞同!
yx69 + 1 + 1 我很赞同!
qsj521521 + 1 + 1 谢谢@Thanks!
冥界3大法王 + 1 菜鸟兄已经成精了。。。
lovecarbon + 1 + 1 我很赞同!
BBridgeW + 1 + 1 用心讨论,共获提升!
唐小样儿 + 1 + 1 我很赞同!
woyucheng + 1 + 1 谢谢@Thanks!
coder9527 + 1 + 1 热心回复!
1MajorTom1 + 1 热心回复!
初玖呢 + 1 + 1 我很赞同!
pokp + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

马西瓜 发表于 2022-6-10 23:04
我爱你我爱你我爱你
马西瓜 发表于 2022-6-10 23:13
马西瓜 发表于 2022-6-10 23:17
马西瓜 发表于 2022-6-10 23:24
太刻意了兄弟比
q935849597 发表于 2022-6-10 23:39
厉害了,加油哦
bigbeer321 发表于 2022-6-10 23:44
厉害了,兄弟
qqxiazhitmac 发表于 2022-6-11 00:02
好厉害坚持下去了
bj9ye666 发表于 2022-6-11 00:04
白嫖是中华民族传统美德
0mengzi0 发表于 2022-6-11 00:10
这个好,支持一波
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 15:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表