Baby-XoR

image-20210425193844241

附件给了两个文件分别是

baby_xor.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flag import flag

def xor(u, v):    
	return ''.join(chr(ord(cu) ^ ord(cv)) for cu, cv in zip(u, v))

u = flag
v = flag[1:] + flag[0]

enc = open('flag.enc', 'w')
enc.write(xor(u, v))
enc.close()

flag.enc

1
2
3
4
5
6

EF

GIIsgw=#
'HB-7=
hB-'7=S  \	

一开始使用爆破,可以看到有短flag

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import string

with open("flag.enc", "r") as f:
    words = f.read()
flag=""
for s in string.printable:
    flag=""
    t = s
    for w in words:
        t = chr(ord(w) ^ ord(t))
        flag = flag + t
    print(flag)

image-20210425194259389

后面看了wp,发现别人都是用rb模式读取文件的

所以对脚本进行修改

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import string

with open("flag.enc", "rb") as f:
    words = f.read()
flag=""
for s in string.printable:
    flag=""
    t = s
    for w in words:
        t = chr(w^ ord(t))
        flag = flag + t
    print(flag)

这时候flag就对了

image-20210425194450065


Baby-IQ

image-20210425194542694

附件同样有两个

baby-iq.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from math import sqrt
from flag import flag
import os
import random
import base64

def chunkchunk(msg, l):
	return [msg[l*i:l*(i + 1)] for i in range(0, len(msg) // l)]

def pad(msg):
	r = int(sqrt(len(msg))) + 1
	head = base64.b64encode(os.urandom(r**2))[:r**2 - (len(msg))]
	msg = head + msg.encode('utf-8')
	msg = chunkchunk(msg, r)
	return [list(m) for m in msg]

def encrypt(A):
	row = len(A)
	col = len(A[0])
	top = 0
	left = 0
	tmp = []
	while (top < row and left < col) :       
		for i in range(left, col) : 
			tmp.append(A[top][i])              
		top += 1
		for i in range(top, row) : 
			tmp.append(A[i][col - 1])     
		col -= 1
		if ( top < row) : 
			for i in range(col - 1, left - 1, -1) : 
				tmp.append(A[row - 1][i])  
			row -= 1
		  
		if (left < col) : 
			for i in range(row - 1, top - 1, -1) : 
				tmp.append(A[i][left])   
			left += 1
	result = []
	for i in range(len(A)):
		r = []
		for j in range(len(A[0])):
			r.append(tmp[i*len(A[0]) + j])
		result.append(r)
	return result

A = pad(flag)
for _ in range(len(A)):
	_ = encrypt(A)
	A = _

print('enc =', A)

enc.txt

1
enc = [[122, 83, 52, 67, 84, 70], [89, 114, 79, 48, 67, 125], [95, 121, 114, 53, 116, 55], [123, 95, 80, 51, 52, 95], [102, 115, 114, 95, 119, 107], [52, 117, 109, 33, 97, 112]]

这题说来也惭愧,没注意到坑

用任意明文去试了下题目给的脚本,发现实际是一个位置变化的脚本,只是将明文中的字符进行位置变换。所以可以对比变换前后的差别,进行逆变换即可

假设明文是1234567890qwertyuiopasdfghjklzxcvbn

pad后的结果是f1234567890qwertyuiopasdfghjklzxcvbn

变换后的结果是f123450zugwnqreayo6dt7lif9hjks8cxbpv

所以求变换矩阵,并将flag还原

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
flag = "f1234567890qwertyuiopasdfghjklzxcvbn"
cipher = "f123450zugwnqreayo6dt7lif9hjks8cxbpv"
index_list = []
for a in cipher:
    index_list.append(flag.find(a))

A = [[122, 83, 52, 67, 84, 70], [89, 114, 79, 48, 67, 125], [95, 121, 114, 53, 116, 55], [123, 95, 80, 51, 52, 95],
     [102, 115, 114, 95, 119, 107], [52, 117, 109, 33, 97, 112]]
n = ""
for a in A:
    n = n + "".join(chr(s) for s in a)
print(n)

print(len(n))
ss = [""] * 36
for i in range(len(index_list)):
    ss[index_list[i]] = n[i]
print("".join(ss))

image-20210425201137117

去掉第一个字符。提交后,发现不对。懵逼

后面看了题解然后发现答案和我的就差一个字符f,原来是因为str.find()永远返回第一个字符的索引,导致了中间的字符索引丢了

修改脚本,粗暴的将首字符去掉了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
flag = "1234567890qwertyuiopasdfghjklzxcvbn"
cipher = "123450zugwnqreayo6dt7lif9hjks8cxbpv"
index_list = []
for a in cipher:
    index_list.append(flag.find(a))

A = [[83, 52, 67, 84, 70], [89, 114, 79, 48, 67, 125], [95, 121, 114, 53, 116, 55], [123, 95, 80, 51, 52, 95],
     [102, 115, 114, 95, 119, 107], [52, 117, 109, 33, 97, 112]]
#密文也去掉首字符,这样索引就对上了
n = ""
for a in A:
    n = n + "".join(chr(s) for s in a)

ss = [""] * 36
for i in range(len(index_list)):
    ss[index_list[i]] = n[i]
print("".join(ss))

image-20210425202000732

ninidibi

image-20210425202141565

附件是一个文件,用文本打开如下

image-20210425202355826

有点像sqlite3的文件,但是确实了文件头,修复文件头后如下

image-20210425202923084

用工具打开数据库,可以看到两张表

image-20210425202831917

其中flag表是字符,order代表对于该字符的索引,但是order表的第一个记录是null

image-20210425203041646

需要找到缺少的索引,所以脚本如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
flag = [52, 95, 95, 85, 55, 48, 97, 33, 77, 83, 48, 110, 114, 125, 97, 83, 105, 97, 82, 67, 53, 67, 66, 89, 75, 102, 98,
        95, 52, 108, 82, 51, 87, 104, 33, 70, 98, 104, 102, 95, 95, 95, 95, 95, 80, 95, 108, 123, 95, 65, 98, 84, 33,
        115]
orders = [12, 11, 38, 25, 31, 48, 51, 37, 21, 14, 17, 15, 53, 35, 0, 19, 43, 32, 2, 18, 20, 6, 9, 28, 30, 8, 23, 1, 42,
          36, 16, 34, 44, 50, 4, 46, 49, 13, 10, 22, 40, 29, 45, 39, 33, 47, 5, 24, 26, 41, 3, 52, 27]
sort_orders = orders[:]
sort_orders.sort()
for i in range(len(sort_orders)):
    if i != sort_orders[i]:
        orders.insert(0, i)
        break
output=[""]*100
for i in range(len(orders)):
    output[orders[i]] =chr(flag[i])
print("".join(output))

image-20210425204208840