西湖论剑2020Misc复现

Yusa_yyds

      这道题很明显是USB流量分析,先提取流量数据:

1
tshark -r game.pcap -T fields -e usb.capdata | sed '/^\s*$/d' > usbdata.txt

该命令可以帮助我们在提取时删去空行,然后得到提取出来的数据:

000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
01000000650000000000005300000000000000000000050400000000000000450000050000000400020bb8050000000400020bb9020000000400000001060000000800000005250378ce050000000400020bb9020000000400000002010000000400000001
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
01000000650000000000005300000000000000000000050400000000000000450000050000000400020bb8050000000400020bb9020000000400000001060000000800000005259030ce050000000400020bb9020000000400000002010000000400000002
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000
000800ff00000000
0008000000000000

谜一样的数据,既不是键盘也不是鼠标,看到官方wp才知道这是xbox手柄流量。。。贫穷限制了我的想象,做不起,告辞......

带师傅的题解:https://bbs.zafu-polaris.cn/d/13-2020-usbyusa-yyds

指鹿为马

      nc获取源码:

  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
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import numpy as np
from PIL import Image
import math
import operator
import os
import time
import base64
import random

def load_horse():
    data = []
    p = Image.open('./horse.png').convert('L')
    p = np.array(p).reshape(-1)
    p = np.append(p,0)
    data.append(p)
    return np.array(data)

def load_deer():
    data = []
    p = Image.open('./deer.png').convert('L')
    p = np.array(p).reshape(-1)
    p = np.append(p,1)
    data.append(p)
    return np.array(data)

def load_test(pic):
    data = []
    p = Image.open(pic).convert('L')
    p = np.array(p).reshape(-1)
    p = np.append(p,1)
    data.append(p)
    return np.array(data)


def euclideanDistance(instance1, instance2, length):
    distance = 0
    for x in range(length):
        distance += pow((instance1[x] - instance2[x]), 2)
    return math.sqrt(distance)


def getNeighbors(trainingSet, testInstance, k):
    distances = []
    length = len(testInstance) - 1
    for x in range(len(trainingSet)):
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
        return neighbors


def getResponse(neighbors):
    classVotes = {}
    for x in range(len(neighbors)):
        response = neighbors[x][-1]
        if response in classVotes:
            classVotes[response] += 1
        else:
            classVotes[response] = 1
    sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)
    return sortedVotes[0][0]


def getAccuracy(testSet, predictions):
    correct = 0
    for x in range(len(testSet)):
        if testSet[x][-1] == predictions[x]:
            correct += 1
    return (correct / float(len(testSet))) * 100.0

def check(pic):
    source_p = Image.open('deer.png')
    try:
        c_p = Image.open(pic)
    except:
        print("Please upload right picture.")
        exit()
    diff_pixel = 0
    a, b = source_p.size
    if c_p.size[0] != a and c_p.size[1] != b:
        print("Please upload right picture size("+str(a)+','+str(b)+')')
        exit()
    for y in range(b):
        for x in range(a):
            diff_pixel += abs(source_p.getpixel((x, y)) - c_p.getpixel((x, y)))
    return diff_pixel

def main():
    while 1:
        print('-' * 134)
        print('''      ____       __            _          _   _                _                              _   _            _                         
     |  __ \     / _|          | |        | | | |              | |                            | | | |          | |                        
     | |__) |___| |_ ___ _ __  | |_ ___   | |_| |__   ___    __| | ___  ___ _ __    __ _ ___  | |_| |__   ___  | |__   ___  _ __ ___  ___ 
     |  _  // _ \  _/ _ \ '__| | __/ _ \  | __| '_ \ / _ \  / _` |/ _ \/ _ \ '__|  / _` / __| | __| '_ \ / _ \ | '_ \ / _ \| '__/ __|/ _ \\
     | | \ \  __/ ||  __/ |    | || (_) | | |_| | | |  __/ | (_| |  __/  __/ |    | (_| \__ \ | |_| | | |  __/ | | | | (_) | |  \__ \  __/
     |_|  \_\___|_| \___|_|     \__\___/   \__|_| |_|\___|  \__,_|\___|\___|_|     \__,_|___/  \__|_| |_|\___| |_| |_|\___/|_|  |___/\___|
    ''')
        print('-'*134)
        print('\t1.show source code')
        print('\t2.give me the source pictures')
        print('\t3.upload picture')
        print('\t4.exit')
        choose = input('>')
        if choose == '1':
            w = open('run.py','r')
            print(w.read())
            continue
        elif choose == '2':
            print('this is horse`s picture:')
            h = base64.b64encode(open('horse.png','rb').read())
            print(h.decode())
            print('-'*134)
            print('this is deer`s picture:')
            d = base64.b64encode(open('deer.png', 'rb').read())
            print(d.decode())
            continue
        elif choose == '4':
            break
        elif choose == '3':
            print('Please input your deer picture`s base64(Preferably in png format)')
            pic = input('>')
            try:
                pic = base64.b64decode(pic)
            except:
                exit()
            if b"<?php" in pic or b'eval' in pic:
                print("Hacker!!This is not WEB,It`s Just a misc!!!")
                exit()
            salt = str(random.getrandbits(15))
            pic_name = 'tmp_'+salt+'.png'
            tmp_pic = open(pic_name,'wb')
            tmp_pic.write(pic)
            tmp_pic.close()
            if check(pic_name)>=100000:
                print('Don`t give me the horse source picture!!!')
                os.remove(pic_name)
                break
            ma = load_horse()
            lu = load_deer()
            k = 1
            trainingSet = np.append(ma, lu).reshape(2, 5185)
            testSet = load_test(pic_name)
            neighbors = getNeighbors(trainingSet, testSet[0], k)
            result = getResponse(neighbors)
            if repr(result) == '0':
                os.system('clear')
                print('Yes,I want this horse like deer,here is your flag encoded by base64')
                flag = base64.b64encode(open('flag', 'rb').read())
                # flag
                print(flag.decode())
                os.remove(pic_name)
                break
            else:
                print('I want horse but not deer!!!')
                os.remove(pic_name)
                break
        else:
            print('wrong choose!!!')
            break
    exit()

if __name__=='__main__':
    main()

      这里有两个思路,一个是官网给出的高大上脚本式解题;另一个是带师傅通过PS合成(PS永远的神!)

贴一下官网脚本:

 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
#!/usr/bin/env python
# coding: utf-8

from PIL import Image

h = Image.open('horse.png')
d = Image.open('deer.png')
a,b = h.size
h_pixels = []
d_pixels = []
for y in range(b):
    for x in range(a):
        h_pixels.append(h.getpixel((x,y))//50)
        d_pixels.append(d.getpixel((x,y)))  
plt.imshow(np.array(h_pixels).reshape(72,72))
plt.show()
plt.imshow(np.array(d_pixels).reshape(72,72))
plt.show()
res1_png = Image.new('L',(a,b))
for y in range(b):
    for x in range(a):
        if d_pixels[x+a*y] != 0:
            res1_png.putpixel((x,y),d_pixels[x+a*y]-100)
        else:
            res1_png.putpixel((x,y),0)
for y in range(b):
    for x in range(a):
        res1_png.putpixel((x,y),res1_png.getpixel((x,y))+h_pixels[x+a*y]*33)
res1_png.save('deer1.png')
plt.imshow(res1_png)
plt.show()

Barbar

      得到一张二维码,扫后得到密‍‌‍‎‌‍‌‏‎‍‍‎‌‌‍‏‍‌‎‌‍‌‍‌‍‎‌‍‏‍‍‎‌‎‌‍‌‌‌‌‏‌‌‎‎‍‌‌‍‏‌‏‌‍‎‍‍‏‍‏‌‏‍‌‌‍‎‍‍‎‍‎码是在哪啊,是零宽字符隐写了解一下,拿去解密网站(试了好几个网站,就这个网站解出来的密钥是对的),得到一串字符YcfVgMBUraXftwO6Cp92YBGAbyRyWNOO

      接着binwalk分析png图片,发现zip文件,分离,得到描述

Length of the password is 32 bytes. Good Luck.

      输入密码解压获得一张png图片和一份word文档

Docx gfxdata隐写介绍:(假)

      在http://www.datypic.com/sc/ooxml/a-o_gfxdata.html中我们可以得到gfxdata的value类型是xsd:base64Binary,而该类型使用base64编码,允许的字符包括:字母、数字、+、/、=xml空白字符。然后,怎么完成隐写???

word文档直接改后缀为zip打开,在document.xml中的o:gfxdata属性找到base64字符,解码发现头部字符是png的,转化png图片得到一张疑似二维码的码--AZTEC码。

关于解码,根据官方wp图片找到该产品官网主页存在解码功能,解码得到

AZTEC:di`f{e1c64e14db14c6bb8faabab5bd7be1dc}

花里胡哨的图片是"npiet代码":

npiet介绍:

      程序是一张图片。在这种面向堆栈的语言中,颜色区域代表数字,颜色的变化决定了要做什么-例如。将数字按入堆栈,下一个颜色更改可能会命令:将其打印到终端。 -- https://www.bertnase.de/npiet/

https://www.bertnase.de/npiet/npiet-execute.php输入上面那串字符后运行,得到

? f? l? a? g? {? f? 2? d? 7? 6? g? 3? 6? f? d? 1? 6? c? ? ? bb6? ? ? ? ? ? abaaf8? ? ? ? db5? 7? cb? ? ? d1e? d? }? ?

去掉?就是flag(PS:真的找不到官方wp图片上的解释器)

参考

指鹿为马

Barbar