吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3153|回复: 26
收起左侧

[CTF] 攻防世界-Reverse-logmein

  [复制链接]
NightGlow 发表于 2023-7-24 13:59
步骤一:使用IDA PRO进行反汇编

首先,我们搜索main主函数,并使用F5反汇编得到以下代码:

void __fastcall __noreturn main(int a1, char **a2, char **a3)
{
  size_t v3; // rsi                                // 用于存储字符串长度
  int i; // [rsp+3Ch] [rbp-54h]                   // 循环计数器
  char s[36]; // [rsp+40h] [rbp-50h] BYREF        // 用户输入的字符串
  int v6; // [rsp+64h] [rbp-2Ch]                  // 一个常量,值为7
  __int64 v7; // [rsp+68h] [rbp-28h]              // 一个常量,值为0x65626D61726168
  char v8[28]; // [rsp+70h] [rbp-20h] BYREF       // 一个常量字符串,值为":\"AL_RT^L*.?+6/46"
  int v9; // [rsp+8Ch] [rbp-4h]                   // 一个变量,初始值为0

  v9 = 0;                                         // 设置v9为0
  strcpy(v8, ":\"AL_RT^L*.?+6/46");               // 将常量字符串复制到v8
  v7 = 0x65626D61726168LL;                        // 设置v7为常量值
  v6 = 7;                                         // 设置v6为7
  printf("Welcome to the RC3 secure password guesser.\n"); // 打印欢迎信息
  printf("To continue, you must enter the correct password.\n"); // 打印需要输入密码的提示
  printf("Enter your guess: ");                   // 提示用户输入
  __isoc99_scanf("%32s", s);                      // 读取用户输入的字符串,最多32个字符
  v3 = strlen(s);                                 // 计算用户输入的字符串长度
  if ( v3 < strlen(v8) )                          // 如果用户输入的字符串长度小于v8的长度
    sub_4007C0();                                 // 则调用sub_4007C0函数
  for ( i = 0; i < strlen(s); ++i )               // 对于用户输入的每一个字符
  {
    if ( i >= strlen(v8) )                        // 如果当前字符的位置大于等于v8的长度
      sub_4007C0();                               // 则调用sub_4007C0函数
    if ( s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) ) // 如果当前字符不等于v7的第(i%v6)个字节与v8的第i个字符的异或结果
      sub_4007C0();                               // 则调用sub_4007C0函数
  }
  sub_4007F0();                                   // 如果所有的字符都满足上述条件,则调用sub_4007F0函数
}

我们发现在判断里面调用了两个函数sub_4007C0sub_4007F0,同样反汇编之后得到:

void __noreturn sub_4007C0()
{
  printf("Incorrect password!\n");
  exit(0);
}
void __noreturn sub_4007F0()
{
  printf("You entered the correct password!\nGreat job!\n");
  exit(0);
}

这个循环的目的是检查输入的字符串是否满足某种条件,即输入的每个字符是否等于 v7 的某个字节和 v8 的对应字符的异或结果。如果输入的字符串的任何字符不满足这个条件,程序就会调用 sub_4007C0() 函数。

步骤二:处理字符串v7

v7 是一个64位整数,它被强制转换为字节指针,所以可以通过 *((_BYTE *)&v7 + i % v6) 来获取 v7 的某个字节。v6 是一个常数,值为7,所以 i % v6 会在0到6之间循环。

我们可以通过以下两种方法处理v7:

方法一: 通过脚本进行转换

hex_value = 0x65626D61726168
string_value = bytes.fromhex(hex(hex_value)[2:]).decode('utf-8')
print(string_value)

方法二: 直接在IDA中选中该字符串,按R进行转换,获字符串得:ebmarah

这里有一个非常重要的点:((_BYTE *)&v7 + i % v6) 即为 (char *)v7[i%v6],同时在CPU,x86都是小端序,但是IDA将之转换为了大端序。我们需要翻转字符得到harambe

步骤三:编写脚本

最后,我们使用Python3编写如下代码以获取flag:

v6 = 7
v7 = 'harambe'
v8 = ':\"AL_RT^L*.?+6/46'
flag = []
for i in range(len(v8)):
  flag.append(chr(ord(v7[i % v6]) ^ ord(v8[i])))
print(''.join(flag))

最终我们获得flag:RC3-2016-XORISGUD

免费评分

参与人数 11威望 +1 吾爱币 +29 热心值 +11 收起 理由
DRabbit111 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
amd123 + 1 + 1 我很赞同!
10261805 + 1 + 1 谢谢@Thanks!
kongjubenben + 1 + 1 用心讨论,共获提升!
dimcius + 1 + 1 我很赞同!
9lmr + 1 + 1 我很赞同!
jiojekwjas + 1 + 1 谢谢@Thanks!
HarryPotter01 + 1 用心讨论,共获提升!
WZTong + 1 + 1 用心讨论,共获提升!
coder9527 + 1 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

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

leeyolo 发表于 2023-7-29 07:54
学习学习&#2919;(&#3665;&#8226;&#768;&#9697;&#8226;&#769;&#3665;)&#2797;
binarystudy123 发表于 2023-7-25 00:45
ccslygz6 发表于 2023-7-25 02:04
tp206555 发表于 2023-7-25 07:46
厉害 厉害学习一下
ningmengzhiji 发表于 2023-7-25 08:15
谢谢分享...
z2042489 发表于 2023-7-25 08:34
删点验证那段不行吗?
sodisky 发表于 2023-7-25 08:46

厉害,感谢分享
shikongliangze 发表于 2023-7-25 09:06
吾爱大神太多,多谢分享
chuma521 发表于 2023-7-25 09:19
感谢分享
纯洁一下 发表于 2023-7-25 09:43

厉害 厉害学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-15 12:42

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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