NightGlow 发表于 2023-7-24 13:59

攻防世界-Reverse-logmein


#### 步骤一:使用IDA PRO进行反汇编

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

```c
void __fastcall __noreturn main(int a1, char **a2, char **a3)
{
size_t v3; // rsi                              // 用于存储字符串长度
int i; //                    // 循环计数器
char s; // BYREF      // 用户输入的字符串
int v6; //                   // 一个常量,值为7
__int64 v7; //             // 一个常量,值为0x65626D61726168
char v8; // BYREF       // 一个常量字符串,值为":\"AL_RT^L*.?+6/46"
int v9; //                    // 一个变量,初始值为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 != (char)(*((_BYTE *)&v7 + i % v6) ^ v8) ) // 如果当前字符不等于v7的第(i%v6)个字节与v8的第i个字符的异或结果
      sub_4007C0();                               // 则调用sub_4007C0函数
}
sub_4007F0();                                 // 如果所有的字符都满足上述条件,则调用sub_4007F0函数
}
```

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

```c
void __noreturn sub_4007C0()
{
printf("Incorrect password!\n");
exit(0);
}
```
```c
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:

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

```python3
hex_value = 0x65626D61726168
string_value = bytes.fromhex(hex(hex_value)).decode('utf-8')
print(string_value)
```

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

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

#### 步骤三:编写脚本

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

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


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

leeyolo 发表于 2023-7-29 07:54

学习学习୧(๑•̀◡•́๑)૭

binarystudy123 发表于 2023-7-25 00:45

重要的一点真的很重要{:1_921:}

ccslygz6 发表于 2023-7-25 02:04

厉害,感谢分享{:1_921:}

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


厉害 厉害学习一下
页: [1] 2 3
查看完整版本: 攻防世界-Reverse-logmein