BUUCTF-pyre

下载附件是一个.pyc文件,在pyc在线反编译工具里反编译一下,代码如下:

`

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
  code += num
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",
]

`

这个代码直接copy是不能运行的,有的地方读起来很奇怪,需要连蒙带猜。

代码的结构是输入我的flag,flag经过两次变换生成了code。

`

code += num

`

第一个for结构里的第二条语句需要结合最终的code来看,code是一个有许多元素的列表,可以看出num是列表中带引号的ASCII码,所以这条语句的含义可以被猜出:将num放入code列表。

代码是先运算再异或得到结果,已知结果的情况下,应该先异或再逆运算。

由于异或运算的特殊性,A^B=C,B^C=A。原先的`code[i]^code[i+1]=code[i]=A`,那么已知变换后的code[i]也就是A的情况下,只需要将`code[i+1]^A`即可得到原先的code[i]。

不难看出,由于循环到l-1,所以code的最后一个元素是未经过change的。因此我们只需要从最后一位开始,逐次异或回来即可。代码写作:

`

for i in range(l-1):

  code[l-i-2]=code[l-i-1]^code[l-i-2]

`

  这也就是说,从倒数第二位开始,其本身和其后一位(也就是从倒数第一位开始)进行异或。

接着进行第二步逆运算。取模的逆运算我不会,而且感觉取模不能逆运算(。

既然让我逆,说明确实可逆。这里有运气成分(。)不知道怎么就想到了ASCII码,查了一下发现它只有128个数字。那么这个128保证的就是num在0-128的范围内。

`

num = ((input1[i] + i) % 128 + 128) % 128

`首先分析最外面的%128。已知:(A+B)%C=A%C+B%C是取模运算的法则(即使不知道的话,用(1+128)%128=129%128这样的数据测试一下也能猜到)

128%128=0,由于input1[i]+j先对128取模,此时(input1[i] + i) % 128已经是一个小于128的数字了,故再对其取模没意义,所以原式被化简为:(input1[i] + i) % 128

如果(input1[i] + i)整体小于128,那么这个取模相当于没有。所以我想知道的是整体大于128的情况要如何运算。所以我其实要探索的是(input1[i] + i) % 128的本质。假设input1[i]=126,i=5,先进行一个运算:

(input1[i] + i) % 128=(126+5)%128=(128+3)%128=3

我现在已知code列表,也就是各个num的值,也就是(input1[i] + i) % 128的结果。同时我也知道每个num所对应的i,一个未知数一个方程,input1[i]首先可以确定是可求的。

根据我上面假定数值的运算过程,很容易发现我想求input1[i]+5,只需要求n*128+3即可。那么n是多少呢?首先我的input1范围是0-127,i的范围是0-22,那么input1[i]+i显然小于150,也就是不可能超过128*2,那么n最大只能是1才能保证n*128+num小于150 。

所以input1[i]=128+num-i。但是这里又出现一个问题,也就是说,如果我的128+num-i大于128怎么办呢?我的flag是0-127的数值呀。所以我需要对它再进行一次取模:

`

(input1[i] +num- i) % 128

`

即为所求。

脚本如下:

`

code = [
"\x1f",
"\x12",
"\x1d",
"(",
"0",
"4",
"\x01",
"\x06",
"\x14",
"4",
",",
"\x1b",
"U",
"?",
"o",
"6",
"*",
":",
"\x01",
"D",
";",
"%",
"\x13",
]
input=[]
l = len(code)

for i in range(l - 1):
code[l-i-2]=chr(ord(code[l-i-2])^ord(code[l-i-1]))
for i in range(l):
code[i]=(ord(code[i])-i)%128
for i in range(l):
print(chr(code[i]),end="")
`
上一篇:【C语言】char类型如何在内存中存储?


下一篇:java static/final关键字及128陷阱