西湖论剑wp

    科技2026-08-07  1

    西湖论剑wp

    综述

    本次比赛纯划水,就做了两个baby题,主要负责下附件、签到填问卷、膜Firebasky。结束前差点因为太菜坑了队友呜呜呜。

    misc4 指鹿为马

    开局一个nc,连上去发现长这样

    直接获取源码外加附件可爱的小🦌和小🐎。 源码如下:

    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): #(np.append(ma, lu).reshape(2, 5185),pic,1) 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()) 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()

    大概就是要传一个72*72的图,欧氏距离和小🐎更近一点。手动输出了一下两张图每个点像素数值肉眼观察了一下,感觉稍微改改就行了。exp如下:

    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): #(np.append(ma, lu).reshape(2, 5185),pic,1) distances = [] length = len(testInstance) - 1 for x in range(len(trainingSet)): dist = euclideanDistance(testInstance, trainingSet[x], length) distances.append((trainingSet[x], dist)) print('distances: ',distances) 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 print('classVotes: ',classVotes) sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True) print('sortedVotes: ',sortedVotes) 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 print_pic(x,y): for i in range(521,5185): print('(' +str(i)+','+ str(x[i]) + ',' + str(y[i]) + ')',end=' ') print('') pic_name = 'deer.png' ma = load_horse() lu = load_deer() print_pic(ma[0],lu[0]) k = 1 trainingSet = np.append(ma, lu).reshape(2, 5185) testSet = load_test(pic_name) testSet[0][-1] = 1 print("testSet[0]: ",testSet[0]) for i in range(950,3300): testSet[0][i] = ma[0][i] print("testSet[0]: ",testSet[0]) neighbors = getNeighbors(trainingSet, testSet[0], k) print(len(neighbors)) print(getResponse(neighbors)) print(len(testSet[0])) res = np.delete(testSet[0],-1).reshape(72,72) print(res) print(type(res)) im = Image.fromarray(np.uint8(res)) im.save("my.png")

    从🦌开始随手改了几个像素点为🐎同位置的数值,然后保存为my.png,base64提交一下就过了。 收到一大串base64,扔进cyberchef解一下里面又有个base64,转图片得到flag。

    crypto1

    源码:

    from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from secret import flag import os rsa = RSA.generate(2048) public_key = rsa.publickey().exportKey() f=open("public.key","w") f.write(public_key.decode()) f.close() rsakey=RSA.importKey(open("public.key","r").read()) rsa = PKCS1_OAEP.new(rsakey) msg=rsa.encrypt(flag.encode()) f=open("message","wb") f.write(msg) f.close()

    打开附件看看公钥,发现n,e都特别大,就试试rsa-wiener-attack。直接得出d,然后谷歌了一番怎么自定义一个RSAKey,只找到了一个用construct方法的,而且需要(n,e,d,p,q),就只得复杂一下再通过ned分解出pq,然后去解密文了。脚本如下:

    from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP from Crypto.Util.number import * import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator def hack_RSA(e, n): ''' Finds d knowing (e,n) applying the Wiener continued fraction attack ''' frac = ContinuedFractions.rational_to_contfrac(e, n) convergents = ContinuedFractions.convergents_from_contfrac(frac) for (k, d) in convergents: # check if d is actually the key if k != 0 and (e * d - 1) % k == 0: phi = (e * d - 1) // k s = n - phi + 1 # check if the equation x^2 - s*x + n = 0 # has integer roots discr = s * s - 4 * n if (discr >= 0): t = Arithmetic.is_perfect_square(discr) if t != -1 and (s + t) % 2 == 0: print("Hacked!") return d # print("Testing Wiener Attack") # f=open("message","rb") # c=bytes_to_long(f.read()) e=3683191938452247871641914583009119792552938079110383367782698429399084083048335018186915282465581498846777124014232879019914546010406868697694661244001972931366227108140590201194336470785929194895915077935083045957890179080332615291089360169761324533970721460473221959270664692795701362942487885620152952927112838769014944652059440137350285198702402612151501564899791870051001152984815689187374906618917967106000628810361686645504356294175173529719443860140795170776862320812544438211122891112138748710073230404456268507750721647637959502454394140328030018450883598342764577147457231373121223878829298942493059211583 n=24493816160588971749455534346389861269947121809901305744877671102517333076424951483888863597563544011725032585417200878377314372325231470164799594965293350352923195632229495874587039720317200655351788887974047948082357232348155828924230567816817425104960545706688263839042183224681231800805037117758927837949941052360649778743187012198508745207332696876463490071925421229447425456903529626946628855874075846839745388326224970202749994059533831664092151570836853681204646481502222112116971464211748086292930029540995987019610460396057955900244074999111267618452967579699626655472948383601391620012180211885979095636919 # d = hack_RSA(e, n) # print(d) d = 1779217788383673416690068487595062922771414230914791138743960472798057054853883175313487137767631446949382388070798609545617543049566741624609996040273727 p = 149604112324264915811376746906108325951188179904814259006959765070266946659481820938211689946210254302179197289522748397160602946376246768419310765669852537378426700376878745285639531531077237124655345323906476180103106894642043615024716862503414785057646920410083538192951872861366496901158348770066798098371 q=163724217068973025857079545677048587508164102644298632911494474022224582218067057349189211462632427829087720476013052665037199232658015194718500750961261016558605363103092187533086949903145449057015220561698195502163792192055762108803714387175594231859738263839090338762578040513451585421537323416472060788989 rsa_components=(n,e,d,p,q) arsa=RSA.construct(rsa_components) c_bytes = open("message","rb").read() rsakey = RSA.importKey(arsa.exportKey()) rsakey = PKCS1_OAEP.new(rsakey) decrypted = rsakey.decrypt(c_bytes) print(decrypted)

    ned分解pq的脚本原封不动抄自wiki。

    结尾

    偷偷再膜一下大周师傅!!

    Processed: 0.008, SQL: 9