新手小白,开启CTF刷题之路(持续更新)
此处主要在NSSCTF平台(NSSCTF | 在线CTF平台)上开展刷题
[SWPUCTF 2021 新生赛]简简单单的逻辑
下载附件,内容如下:
flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
key = (list[i]>>4)+((list[i] & 0xf)<<4)
result += str(hex(ord(flag[i])^key))[2:].zfill(2)
print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec
麻……真的麻,年轻时没有好好学习,后果就是一把年纪重新捡起这些玩意看到程序就头皮发麻……慢慢分析开始吧唉
len()函数用于返回字符串、列表、字典、元组等长度,语法为【len(str)】,其中str是要计算的字符串、列表、字典、元组等。
range()函数是Python中的内置函数,用于生成一系列连续的整数,一般用于for循环体中。
在本题中,len(list)的结果是17,嵌套了range()函数后,结果是(0,17)
接下来for循环里设置了一个key变量,变量从list数组中取值,从第0位即47开始,分别使list数组中各个数值执行x向右移4位(相当于除以16并取整)的结果与同一个值的按位与运算(使用符号为&,即如果前后两个值相应的二进制位都为1,则该位的结果值为1;否则为0)的结果左移4位(相当于乘以16)的结果相加,获得的key数组为(242,168,247,147,87,51,248,17,69,162,120,196,150,193,154,145)。
result使用了ord、hex、zfill、str函数,用途分别为:
ord()用来返回对应字符的ascii码
hex()用于将10进制整数转换成16进制,以字符串形式表示
str.zfill(width)根据width长度对str进行切片
对for循环进行分析,转换和注释如下:
flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
m=list[i]
print(m)
print('__m__')
j=m>>4 # >>按位右移,左移n位相当于除以2的n次方,此处相当于除以16并取整
print(j)
print('__j__')
n=list[i] & 0xf # &按位与,如果两个相应的二进制位都为1,则该位的结果值为1;否则为0。本题中所取值的转化为二进制后与0xF(即1111,高位自动补0)进行按位“与”运算,取得值再转换为十进制表示
print(n)
print('__n__')
k=n<<4 # <<按位左移,左移n位相当于乘以2的n次方,此处相当于乘以16
print(k)
print('__k__')
key = j+k
print(key)
print('__key__')
i+=1
# result += str(hex(ord(flag[i])^key))[2:].zfill(2)
# result=bcfba4d0038d48bd4b00f82796d393dfec
得出key值
47 __m__ 2 __j__ 15 __n__ 240 __k__ 242 __key__
138 __m__ 8 __j__ 10 __n__ 160 __k__ 168 __key__
127 __m__ 7 __j__ 15 __n__ 240 __k__ 247 __key__
57 __m__ 3 __j__ 9 __n__ 144 __k__ 147 __key__
117 __m__ 7 __j__ 5 __n__ 80 __k__ 87 __key__
188 __m__ 11 __j__ 12 __n__ 192 __k__ 203 __key__
51 __m__ 3 __j__ 3 __n__ 48 __k__ 51 __key__
143 __m__ 8 __j__ 15 __n__ 240 __k__ 248 __key__
17 __m__ 1 __j__ 1 __n__ 16 __k__ 17 __key__
84 __m__ 5 __j__ 4 __n__ 64 __k__ 69 __key__
42 __m__ 2 __j__ 10 __n__ 160 __k__ 162 __key__
135 __m__ 8 __j__ 7 __n__ 112 __k__ 120 __key__
76 __m__ 4 __j__ 12 __n__ 192 __k__ 196 __key__
105 __m__ 6 __j__ 9 __n__ 144 __k__ 150 __key__
28 __m__ 1 __j__ 12 __n__ 192 __k__ 193 __key__
169 __m__ 10 __j__ 9 __n__ 144 __k__ 154 __key__
25 __m__ 1 __j__ 9 __n__ 144 __k__ 145 __key__
再对原题给的py程序转换如下:
flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
key = (list[i]>>4)+((list[i] & 0xf)<<4)
a=flag[i]
print(i)
print('__i__')
print(key)
print('__key__')
print(a)
print('__a__')
b=ord(a)
print(b)
print('__b__')
c=b^key # ^按位异或操作
print(c)
print('__c__')
d=hex(c)
print(d)
print('__d__')
result += str(d)[2:].zfill(2)
print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec
# result += str(hex(ord(flag[i])^key))[2:].zfill(2)
给出的结果如下:
0 __i__ 242 __key__ x __a__ 120 __b__ 138 __c__ 0x8a __d__ 8a
1 __i__ 168 __key__ x __a__ 120 __b__ 208 __c__ 0xd0 __d__ 8ad0
2 __i__ 247 __key__ x __a__ 120 __b__ 143 __c__ 0x8f __d__ 8ad08f
3 __i__ 147 __key__ x __a__ 120 __b__ 235 __c__ 0xeb __d__ 8ad08feb
4 __i__ 87 __key__ x __a__ 120 __b__ 47 __c__ 0x2f __d__ 8ad08feb2f
5 __i__ 203 __key__ x __a__ 120 __b__ 179 __c__ 0xb3 __d__ 8ad08feb2fb3
6 __i__ 51 __key__ x __a__ 120 __b__ 75 __c__ 0x4b __d__ 8ad08feb2fb34b
7 __i__ 248 __key__ x __a__ 120 __b__ 128 __c__ 0x80 __d__ 8ad08feb2fb34b80
8 __i__ 17 __key__ x __a__ 120 __b__ 105 __c__ 0x69 __d__ 8ad08feb2fb34b8069
9 __i__ 69 __key__ x __a__ 120 __b__ 61 __c__ 0x3d __d__ 8ad08feb2fb34b80693d
10 __i__ 162 __key__ x __a__ 120 __b__ 218 __c__ 0xda __d__ 8ad08feb2fb34b80693dda
11 __i__ 120 __key__ x __a__ 120 __b__ 0 __c__ 0x0 __d__ 8ad08feb2fb34b80693dda00
12 __i__ 196 __key__ x __a__ 120 __b__ 188 __c__ 0xbc __d__ 8ad08feb2fb34b80693dda00bc
13 __i__ 150 __key__ x __a__ 120 __b__ 238 __c__ 0xee __d__ 8ad08feb2fb34b80693dda00bcee
14 __i__ 193 __key__ x __a__ 120 __b__ 185 __c__ 0xb9 __d__ 8ad08feb2fb34b80693dda00bceeb9
15 __i__ 154 __key__ x __a__ 120 __b__ 226 __c__ 0xe2 __d__ 8ad08feb2fb34b80693dda00bceeb9e2
16 __i__ 145 __key__ x __a__ 120 __b__ 233 __c__ 0xe9 __d__ 8ad08feb2fb34b80693dda00bceeb9e2e9
这样一看好像清晰了点儿,那么,接下来要干的活就是一层层的解题了。
首先,回忆下异或,异或的基本性质就是若 a^b=c,那么 c^b=a,所以在这里,key的值可以直接用。要做的,就是把题目给的result值按照两位一切,加上0x构造十六进制值,使用int函数转换为十进制,与key异或运算后取得ASCII值,然后使用chr函数转换为字符串,最终构造flag,代码如下:
result = 'bcfba4d0038d48b