主要介绍比赛misc常用的脚本。

1.TTL隐写

1
2
3
4
5
6
7
8
9
10
11
12
13
IP报文在路由间穿梭的时候每经过一个路由,TTL就会减1,当TTL为0的时候,该报文就会被丢弃。
TTL所占的位数是8位,也就是0-255的范围,但是在大多数情况下通常只需要经过很小的跳数就能完成报文的转发,
远远比上限255小得多,所以我们可以用TTL值的前两位来进行传输隐藏数据。
如:须传送H字符,只需把H字符换成二进制,每两位为一组,每次填充到TTL字段的开头两位并把剩下的6位设置为1(xx111111),这样发4个IP报文即可传送1个字节。

根据上述规则,可以知道TTL隐写中用到四个值:
00 111111(63),01 111111(127),10 111111(191),11 111111(255)
解密的时候只取前两位,然后转换成ascii
简化一下,可以这么认为:
00 替换 63
01 替换 127
10 替换 191
11 替换 255

脚本如下

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
import binascii
with open('attachment.txt','r') as fp:
a=fp.readlines()#读取所有的行列
p=[]
for x in range(len(a)):
p.append(int(a[x]))
s=''
for i in p:
if(i==63):
b='00'
elif(i==127):
b='01'
elif(i==191):
b='10'
else:
b='11'
s +=b
# print(s)
flag = ''
for i in range(0,len(s),8):
flag += chr(int(s[i:i+8],2))#转字符
flag = binascii.unhexlify(flag)#编码成二进制
#写入文件,没有自动创建
wp = open('flag.zip','wb')
wp.write(flag)
wp.close()

2.base64

遇到多层加密需要用

1
2
3
4
5
6
7
import base64
f=open("secret.txt","r")
a=f.read()
res=base64.b64decode(a)
while(1):
res=base64.b64decode(res)
print(res)

base64解密并转成文件

1
2
3
4
5
6
7
import  base64
with open("secret.txt", "r") as f:
imgdata = base64.b64decode(f.read())
#imgdata = str(f.read())
file = open('5.zip', 'wb')
file.write(imgdata)
file.close()

base64隐写脚本

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
#base64隐写
import base64

def get_base64_diff_value(s1, s2):
print(s1)
print(s2)
base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
res = 0
for i in range(len(s2)):
if s1[i] != s2[i]:
return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))#返回绝对值
return res

def solve_stego():
with open('1.txt') as f:
file_lines = f.readlines()
bin_str = ''
for line in file_lines:
steg_line = line.replace('\n', '')#从文件中读取出来的字符串,base加密
# norm_line = line.replace('\n', '').decode('base64').encode('base64').replace('\n','')
norm_line = line.replace('\n', '').encode('utf-8')
norm_line = base64.b64decode(norm_line).decode('utf-8')#先去解密
norm_line = base64.b64encode(norm_line.encode('utf-8')).decode('utf-8')#然后加密
norm_line = norm_line.replace('\n', '')
diff = get_base64_diff_value(steg_line, norm_line)#将字符串传进去取绝对值
print(diff)
pads_num = steg_line.count('=')
if diff:
bin_str += bin(diff)[2:].zfill(pads_num * 2)
else:
bin_str += '0' * pads_num * 2
print('-' * 10)
print(bin_str)
print(goflag(bin_str))
def goflag(bin_str):
res_str = ''
for i in range(0, len(bin_str), 8):
res_str += chr(int(bin_str[i:i + 8], 2))
return res_str
if __name__ == '__main__':
solve_stego()

3.CRC

图片CRC爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import struct
import zlib
def hexStr2bytes(s):
b = b""
for i in range(0,len(s),2):
temp = s[i:i+2]
b +=struct.pack("B",int(temp,16))
return b
str1="49484452"#Chunk[0] IHDR
str2="0806000000"#Bit depth、ColorType、Compression method、Filter method、Interlace method
bytes1=hexStr2bytes(str1)
bytes2=hexStr2bytes(str2)
wid,hei = 1308,1280#当前宽高
crc32 = "0x6f03ad71"#图片原来的CRC
for w in range(wid,wid+2000):
for h in range(hei,hei+2000):
width = hex(w)[2:].rjust(8,'0')
height = hex(h)[2:].rjust(8,'0')
bytes_temp=hexStr2bytes(width+height)
if eval(hex(zlib.crc32(bytes1+bytes_temp+bytes2))) == eval(crc32):
print(hex(w),hex(h))
print(w,h)
exit()

图片crc爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import binascii
import struct
import datetime
start=datetime.datetime.now()
crcbp = open("crc1.png", "rb").read()
for i in range(2000):
for j in range(2000):
data = crcbp[12:16] + struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
if crc32 == 0x6f03ad71:#图片CRC值
print(i, j)
print('hex:', hex(i), hex(j))
end=datetime.datetime.now()
print('Running time: %s Seconds'%(end-start))

4.逆序输出文件

v1版本

1
2
3
4
5
6
7
8
f1=open('task_flag.jpg', 'rb').read()
f1_len=len(f1)
f2=open('tt.jpg', 'ab')
i=0
while i<f1_len:
f2.write(f1[i:i+4][::-1])
i=i+4
f2.close()

v2版本

1
2
3
4
5
6
7
from binascii import *
with open('what', 'rb') as f:
hex_data = hexlify(f.read()).decode()[::-1]
with open('data.wav', 'wb') as f1:
for i in range(0, len(hex_data), 2):
data = hex_data[i:i+2][::-1]
f1.write(unhexlify(data))

5.图片opencv

YCrCb隐写

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
import cv2
#需要打开图片的路径,可以是绝对路径或者相对路径,路径中不能出现中文
#读取的彩色图片,是按照 GBR 的形式,数据格式在 0~255
#根据提示不止RGB,opencv中有多种色彩空间,包括 RGB、HSI、HSL、HSV、HSB、YCrCb、CIE XYZ、CIE Lab8种
'''
使用函数cv2.imread(filepath,flags)读入一副图片
filepath:要读入图片的完整路径
flags:读入图片的标志
cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道
cv2.IMREAD_GRAYSCALE:读入灰度图片
cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道
'''
imag=cv2.imread('2021xihulunjian.png')
'''
用法: cv2.cvtColor(src, code[, dst[, dstCn]])
参数:
src:它是要更改其色彩空间的图像。
code:它是色彩空间转换代码。
dst:它是与src图像大小和深度相同的输出图像。它是一个可选参数。
dstCn:它是目标图像中的频道数。如果参数为0,则通道数自动从src和代码得出。它是一个可选参数。
'''
src=cv2.cvtColor(imag,cv2.COLOR_BGR2YCrCb)
Y,Cr,Cb=cv2.split(src)
'''
使用函数cv2.imwrite(file,img,num)保存一个图像。
第一个参数是要保存的文件名,第二个参数是要保存的图像。
可选的第三个参数,它针对特定的格式:对于JPEG,其表示的是图像的质量,
用0 - 100的整数表示,默认95;对于png ,第三个参数表示的是压缩级别,默认为3
'''
cv2.imwrite('./Y.png',(Y%2)*255)
cv2.imwrite('./Cr.png',(Cr%2)*255)
cv2.imwrite('./Cb.png',(Cb%2)*255)

6.二维码识别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os
import qrcode
from PIL import Image
from pyzbar import pyzbar
from bitarray import bitarray
def decode_qr_code(code_img_path):
if not os.path.exists(code_img_path):
raise FileExistsError(code_img_path)
# Here, set only recognize QR Code and ignore other type of code
return pyzbar.decode(Image.open(code_img_path), symbols=[pyzbar.ZBarSymbol.QRCODE])

reslut = ''
file = r'1.png'
data_decode = decode_qr_code(file)
reslut+=data_decode[0].data.decode('utf-8')
print(reslut)

二维码识别,并且写入到文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- coding: utf-8 -*-
from PIL import Image
import pyzbar.pyzbar as pyzbar
import os
def qrcode_parse_content(img_path):
'''
单张图片的二维码解析
'''
img = Image.open(img_path)
#使用pyzbar解析二维码图片内容
barcodes = pyzbar.decode(img)
#打印解析结果,从结果上可以看出,data是识别到的二维码内容,rect是二维码所在的位置
result = []
res=[]
for barcode in barcodes:
barcode_content = barcode.data.decode('utf-8')
barcode_hex=barcode.data
result.append(barcode_content)
res.append(barcode_hex)
return result,res
final=qrcode_parse_content('./file.png')[1][0]
open('test.txt','wb').write(final)

7.gif

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
# 将gif图片转成PNG图片
from PIL import Image
import os
im = Image.open('9266eadf353d4ada94ededaeb96d0c50.gif')
def iter_frames(im):
try:
i = 0
while 1:
im.seek(i)
imframe = im.copy()
if i == 0:
palette = imframe.getpalette()
else:
imframe.putpalette(palette)
yield imframe
i += 1
except EOFError:
pass
for i, frame in enumerate(iter_frames(im)):
frame.save('img\\glance' + str(i) + '.png', **frame.info)
# 最终分割的图片保存形式为:
# 再通过python编程将其组合成对应的一张完整的图片:
IMAGES_PATH = r'.\img\\' # 图片地址
IMAGES_FORMAT = ['.png'] # 图片后缀
IMAGE_SIZE = 2 # 每张小图片的宽度大小
IMAGE_ROW = 600 # 图片的长度
IMAGE_COLUMN = 202 # 图片间隔,也就是合并成一张图后,一共有几列
IMAGE_SAVE_PATH = 'flag.png' # 图片转换后的地址
image_names = sorted([name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT if
os.path.splitext(name)[1] == item])
def image_compose():
to_image = Image.new('RGB', (IMAGE_COLUMN * IMAGE_SIZE, IMAGE_ROW)) # 创建一个新图
# 循环遍历,把每张图片按顺序粘贴到对应位置上
flag = 0
print(image_names)
print(len(image_names))
for name in image_names:
ph = Image.open('img\\'+name)
to_image.paste(ph, (flag, 0))
flag += IMAGE_SIZE
return to_image.save(IMAGE_SAVE_PATH) # 保存新图
image_compose()
# 第三步、答案
# 最终我们凭借的图片为:
# ![在这里插入图片描述](https: // img - blog.csdnimg.cn / 20190820170856345.
# png?x - oss - process = image / watermark, type_ZmFuZ3poZW5naGVpdGk, shadow_10, text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhcnJ5X2M =, size_16, color_FFFFFF, t_70)
# 至此最终的flag为:TWCTF{BlissbyCharlesORear}

gif转换成png

1
2
3
4
5
6
7
# -*- coding: utf-8 -*-
from PIL import Image
images=[]
for i in range(10):
im=Image.open('img/frame{}.png'.format(i+1))
images.append(im)
images[0].save("functions.gif",save_all=True,loop=True,append_images=images[1:],duration=500)

git转换成png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def main():
s=''
waitr=open('gif/0.jpg', 'rb').read()
bakle=open('gif/1.jpg', 'rb').read()
for i in range(0,104):
a=open('./gif/{0}.jpg'.format(i),'rb').read()
if a == waitr:
s+='0'
if a == bakle:
s += 'enter_the_pwn_land'
print(s)
read(s)
#01100110011011000110000101100111011110110100011001110101010011100101111101100111011010010100011001111101
def read(s):
flag=''
for i in range(0,int((len(s)/8))):
flag+=chr(int(s[i*8:(i+1)*8],2))
print(flag)
#flag{FuN_giF}

if __name__ == '__main__':
main()
#黑白图片转成10,然后8位一个字符

8.xor

1
2
3
4
5
6
7
8
9
from base64 import *

b = b64decode("AAoHAR1TIiIkUFUjUFQgVyInVSVQJVFRUSNRX1YgXiJSVyJQVRs=")
data = list(b) # 转成列表
for k in range(200):
flag = ""
for i in range(len(data)):
flag += chr(data[i] ^ k)
print(flag + "\n")

9.循环zip

循环zip

1
2
3
4
5
6
7
import zipfile
name = '0573'
while True:
fz = zipfile.ZipFile('zip\\'+name + '.zip', 'r')
fz.extractall(pwd=bytes(name, 'utf-8'))
name = fz.filelist[0].filename[0:4]
fz.close()

zip转成16进制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
f = open('file.zip', 'rb')
i = 0
while True:
a = f.read(1)
if not a:
break
if i == 16:
print()
i = 0
if i < 15:
print(("%02x" % (ord(a))+'').upper(),end=' ')
else:
print(("%02x" % (ord(a))+'').upper(),end='')
i += 1
f.close()

10.base家族解密

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def base_family(self,content):
try:
num = []
while True:
try:
content = base64.b16decode(content).decode()
num.append('base16')
continue
except:
pass
try:
content = base64.b32decode(content).decode()
num.append('base32')
continue
except:
pass
try:
content = base36.dumps(content).decode()
num.append('base36')
continue
except:
pass
try:
content = base58.b58decode(content).decode()
num.append('base58')
continue
except:
pass
try:
content = base64.b64decode(content).decode()
num.append('base64')
continue
except:
pass
try:
content = base64.b85decode(content).decode()
num.append('base85')
continue
except:
pass
try:
content = base64.a85decode(content).decode()
num.append('base85')
continue
except:
pass
try:
content = base91.decode(content).decode()
num.append('base91')
continue
except:
pass
try:
content = py3base92.b92decode(content).decode()
num.append('base92')
continue
except:
pass
try:
content = b''.join(base128.base128(chars=None, chunksize=7).decode(content)).decode()
num.append('base128')
continue
except:
pass
break
print("加密顺序",num)
print("base族谱解密结果:",content)
return content
except:
print('base族谱解密-------------------------------解密失败')
return False