buuctf GWCTF2019 pyre

(36条消息) GWCTF 2019 pyre YuSec_顾殇の点的博客-CSDN博客https://blog.csdn.net/weixin_43859686/article/details/107877267?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167109495016800184135082%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167109495016800184135082&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-107877267-null-null.142%5Ev68%5Econtrol,201%5Ev4%5Eadd_ask,213%5Ev2%5Et3_esquery_v3&utm_term=gwctf2019pyre&spm=1018.2226.3001.4187详细的wp这个大佬已经写了,我再细读一下代码。

print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
    num = ((input1[i] + i) % 128 + 128) % 128   //这里的两次对128求模是多余的,一次对128求模即可。
替代为num = ((input1[i] + i) % 128

    code += num                  //从下方的代码看出来code是数组,那么这里的+=说明code和num都
                                   是数组,所以可以把它看成code[i]+=num[i]

for i in range(l - 1):
    code[i] = code[i] ^ code[i + 1]    //从第一个元素开始,对下一个元素进行异或得到新的第一个元素

print code
code = [
    '\x1f',
    '\x12',
    '\x1d',
    '(',
    '0',
    '4',
    '\x01',
    '\x06',
    '\x14',
    '4',
    ',',
    '\x1b',
    'U',
    '?',
    'o',
    '6',
    '*',
    ':',
    '\x01',
    'D',
    ';',
    '%',
    '\x13']

这里的是原题的代码。

第一个for循环是对数组code的每一个元素进行加密。

第二个for循环是对新得到的数组code中的元素对其下一位进行异或。

需要注意,只有最后一位是没有异或时改变的。

那么把代码逆向写出来也是需要分成两步。

这里是wp的代码

print('Welcome to Re World!')
print('Your input1 is your flag~')

code = [0x1f,0x12,0x1d, 0x28,0x30,0x34, 0x01,0x06,0x14, 0x34,
        0x2c, 0x1b, 0x55,0x3f,0x6f,0x36,0x2a,0x3a, 0x01, 0x44,
        0x3b,0x25, 0x13]      //全部转化成十六进制的样子

code.reverse()
l = len(code)

for i in range(l-1):
    code[i + 1] = code[i] ^ code[i + 1]

code.reverse()

for i in range(len(code)):
    if code[i] - i < 0:
        code[i] = code[i] + 128 -i
    else:
        code[i] -= i

flag = ''.join(chr(i) for i in code)
print(flag)

# GWHT{Just_Re_1s_Ha66y!}

异或的基本知识,同0异1。

a=1001,b=0100。a对b异或,得到c=1101。

不知道a时,b对c异或,得到a=1001。

所以想对异或进行还原,就要从没有改变的最后一位往前进行异或。

code.reverse()        //先把code数组倒序一下,再正常用for循环
l = len(code)

for i in range(l-1):                     //注意这里l-1是开区间,只能取到[0,l-1)
    code[i + 1] = code[i] ^ code[i + 1]  //举例最后一位,如果10个元素,l=10,code[9]=code[8]^code[9]

第一步完成


第二步:求出flag明文input[i]。

原代码中num = ((input1[i] + i) % 128

所以想求出input1[i]有两种情况

(1)input1[i]+i<128,此时num[i]=num[i]-i=input1[i]

(2)input1[i]+1>128,此时num[i]=num[i]+128-i=input1[i]

又有code[i]=num[i],代码如下了

code.reverse()                 //再把code数组正过来

for i in range(len(code)):         
    if code[i] - i < 0: 
        code[i] = code[i] + 128 -i   
    else:
        code[i] =code[i]-i

再一次用code.reverse()还原回来,是因为原代码第一个for循环中,在算用于加密num时是用到了i的,所以要返回code原来的顺序。

注意,这里得到的code[i]都是数字(wp代码中把字符都转化成十六进制数了),所以需要chr(i)打印出来

flag = ''.join(chr(i) for i in code)
print(flag)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值