从零开始的[BUUCTF-xor]

[BUUCTF-xor]

前言:

认识了简单的伪代码之后,要开始看复杂的了。

1.

在exeinfo中确认信息后,放入ida,找到main函数,f5查看伪代码

image-20201008111053312

直接从网上扒来的图,因为我第一眼真的看不懂啊呜呜

逻辑具体是:首先判断我们的输入v6长度是否为33,不是就进入label_12,下面可以看到就是返回"Failed"。

然后i=1,v6[1]代表从输入的第二位开始,^=表示异或(即xor)。即把两个数据二进制化,对位相同则输出0,不同输出1,再以输出的二进制转换回来。

例子:5和3转为二进制分别为:0101 、0011,异或结果0110,转换为十进制的6,即5^3=6.

但是a^=b是什么操作?应该是把异或好的数据赋值给a。

之后,比较v6global,(33uLL我不明白什么意思,uLL应该是数据类型,unsiged Long Long,33应该就是长度吧,但不知道这里面为什么说的是前31位)

2.

跟进global,里面有一串存储数据aFKWOXZUPFVMDGH,再跟进

__cstring:0000000100000F6E aFKWOXZUPFVMDGH db 'f',0Ah              ; DATA XREF: __data:_global↓o
__cstring:0000000100000F6E                 db 'k',0Ch,'w&O.@',11h,'x',0Dh,'Z;U',11h,'p',19h,'F',1Fh,'v"M#D',0Eh,'g'
__cstring:0000000100000F6E                 db 6,'h',0Fh,'G2O',0

既然知道了求得global的原理是异或,那么就反着来求出flag。异或反运算就是再异或一次。

0Ah0ch这些其实是十六进制,其他为字符串。

于是写python脚本,第一位f是不变的,从第二位0Ah开始。

str1 = ['f', 0x0A, 'k', 0x0C, 'w', '&', 'O', '.', '@', 0x11, 'x', 0x0D, 'Z', ';', 'U', 0x11, 'p', 0x19, 'F', 0x1F, 'v',
        '"', 'M', '#', 'D', 0x0E, 'g', 6, 'h', 0x0F, 'G', '2', 'O']

x = 'f'

for i in range(1, len(str1)):
    if (isinstance(str1[i], str)):
        if (isinstance(str1[i - 1], str)):
            x += chr(ord(str1[i]) ^ ord(str1[i - 1]))
        else:
            x += chr(ord(str1[i]) ^ str1[i - 1])
    else:
        x += chr(str1[i] ^ ord(str1[i - 1]))

print(x)

首先把我们的数据输入,把16进制的数据写成python能识别的。查看第i位是不是字符串类型,不是就让第二位和第一位异或,输出加在x后面。

ord表示把字符串转化为十进制数字,因为ord()内只能是字符串类型,所以要先isinstance判断。

这个脚本其实有bug,连续两个数字就出错了。改正也很简单,最下面的else内改为
(代码网上找的,基于我这个菜编程能力稍微理解了一点)

if (isinstance(str1[i - 1], str)):
    x += chr(str1[i] ^ ord(str1[i - 1]))
else:
    x += chr(str1[i] ^ str1[i - 1])

3.

得出结果,flag{QianQiuWanDai_YiTongJiangHu},完事!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值