题目:

or的敌人,and 有个兄弟叫or,or有个敌人叫xor,那么你能帮助or战胜他的敌人xor吗,xor的奥秘就在附件中,开始战斗吧! 注意:得到的 flag 请包上 flag{} 提交

拿到题目,xor 用die 看一下

image-20230523180025934

看到了是一个Mach-064 , mach 不知道是啥,但是知道是64位的。

https://product.pconline.com.cn/itbk/software/os/1112/2610866.html

百度解释:

Mach是一个由卡内基梅隆大学开发的用于支持操作系统研究的操作系统内核,为了用于操作系统之研究,特别是在分布式与并行运算上。是最早实现微核心操作系统的例子之一,是许多其它相似的项目的标准。

这个都是无所谓的,不影响我写这个题。

得知这个是64位的,并且没有壳,用IDA打开

image-20230523180234632

看得出来,我很依赖F5 , 【这里我是用IDA7.7反编译出来的。它和7.0出来的不太一样,但是整体上是差不多的】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [rsp+2Ch] [rbp-124h]
char __b[264]; // [rsp+40h] [rbp-110h] BYREF

memset(__b, 0, 0x100uLL);
printf("Input your flag:\n");
get_line(__b, 0x100u);
if ( strlen(__b) != 33 )
goto LABEL_7;
for ( i = 1; i < 33; ++i )
__b[i] ^= __b[i - 1];
if ( !strncmp(__b, global, 33uLL) )
printf("Success");
else
LABEL_7:
printf("Failed");
return 0;
}
  • memset(__b, 0, 0x100uLL);

这句话就是把__b中的内容全部替换成0

  • get_line(__b, 0x100u);

虽然我不知道这个是干嘛的,但是我知道,上面有一个printf(“Input your flag:\n”);,大概就能猜测这个就是叫我们输入的东西,也就是我们传入的参数,接收我们的传入的东西,然后保存到__b中

  • if ( strlen(__b) != 33 )
    goto LABEL_7;
    

说明__b的长度必须得是33,不然就跳走了

  • ```
    for ( i = 1; i < 33; ++i )
    __b[i] ^= __b[i - 1];
    
    1
    2
    3
    4
    5
    6

    这个是xor 进行一次操作,看到这里,和题目相互对应,我就知道位置肯定是对的了

    - ```
    if ( !strncmp(__b, global, 33uLL) )
    printf("Success");

这里是比对,进行变换后的__b和程序中原本自带的global 进行比对,如果是对的,那么就能得到flag 。

image-20230523180859668

这个global 点过去,就看到这个是一个offset 偏移地址 【肯定是一个数组】然后下面耶写出了这个数组的内容。

当然我们再点过去

image-20230523181011753

现在就完美的看到了数组里面的内容。

这里按下shift + e【新学的东西】 可以直接提取出来

image-20230523181333279

这个就是global 数组中的数据。

ok 现在就是写脚本,然后就能得到flag

第一种

1
2
3
4
5
s = ""
a =[102, 10, 107, 12, 119, 38, 79, 46, 64, 17,120, 13, 90, 59, 85, 17, 112, 25, 70, 31,118, 34, 77, 35, 68, 14, 103, 6, 104, 15,71, 50, 79, 0];
for i in range(len(a)-1):
s+= chr(a[i]^a[i-1])
print(f"{s}")

第二种

1
2
3
4
5
6
7
8
9
s = ['f',0xA,'k',0xC,'w','&','O','.','@',0x11,'x',0xD,'Z',';','U',0x11,'p',0x19,'F',0x1F,'v','"','M','#','D',0xE,'g',6,'h',0xF,'G','2','O']
flag = 'f'
for i in range(1,len(s)):
if(isinstance(s[i],int)):#将数字转化为字符
s[i] = chr(s[i])
for i in range(1,len(s)):
flag += chr(ord(s[i]) ^ ord(s[i-1]))
print(f"{flag}")


用c 语言写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
unsigned char a[] =
{
102, 10, 107, 12, 119, 38, 79, 46, 64, 17,
120, 13, 90, 59, 85, 17, 112, 25, 70, 31,
118, 34, 77, 35, 68, 14, 103, 6, 104, 15,
71, 50, 79, 0
};
char b[1000];

for (int i = 0; i < 33; ++i)
{
b[i] = a[i]^a[i+1];
printf("%c", b[i]);
}
return 0;

}

我想说能不能爆破呢?