本次比賽純划水,就做了兩個baby題,主要負責下附件、簽到填問卷、膜Firebasky。結束前差點因為太菜坑了隊友嗚嗚嗚。
開局一個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。
原始碼:
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。
偷偷再膜一下大周師傅!!