从hex生成bin文件。bin文件用ida打开,选择arm架构。分析程序发现从spi接口读取了512字节的数据。通过tips链接下载的logic2软件打开logic.sal可以看到4个波形图,其中chall 2为输入,根据波形提取出512字节数据。继续分析LightningSystem.bin代码,可以看出是个vm,写脚本得到vmcode的功能。继续分析vmcode的代码,得到算法,最后求解exp如下:
求解
def brute(v4, v5, a, b, j):
should_out = [0x12, 0x67, 0x0F, 0xDB, 0xF6, 0x0A, 0x0F, 0x39, 0xF6, 0xC9, 0xF5, 0xC1, 0xF2, 0xA3, 0x0D, 0xD0, 0xF5, 0x01, 0x0C, 0x6F, 0x0E, 0x39, 0xF2, 0x80, 0xF5, 0xE4, 0x0C, 0xD7, 0xF8, 0x68, 0x0C, 0x96, 0xF5, 0xA5, 0x0F, 0x9F, 0x0F, 0x31, 0xF9, 0x2E, 0x1B, 0x07]
v13 = a
v14 = b
v15 = 7 * (j ^ 0x4D)
v16 = (v5 7 * (j ^ 0x4D)) & 0xff
v18 = v13 - 0x20 v16
v19 = (v14 - 0x20) << 7
o1 = ((v4 ((v19 v18) >> 8) ((v15 v5) >> 8)) & 0xff)
o2 = ((v18 v19) & 0xff)
if (o1 == should_out[2*j]) & (o2 == should_out[2*j 1]):
print a, b
return True
return False
v4 = 234
v5 = 6
s = ''
for k in range(21):
find = False
for a in range(0x20, 0x80):
for b in range(0x20, 0x80):
if brute(v4, v5, a, b, k):
s = chr(a) chr(b)
find = True
break
if find:
break
if not find:
print ('fail')
print s
得到flag如下:flag{31fd5c30-dc82-abd0-741b-9ba425f2e692}
4、**Rev_Dizzy**看反编译的代码,完了拿比较的数据反过来进行加减异或
代码太大,就不贴了,在附属文档(命名为deal.cpp)
跑出flag如下:
crypto1、**Guess**先是一个sha256的爆破,一共要爆破四位,10秒内出结果,第一关就过去了,第二关和矩阵运算有关,key的矩阵给了第一列的数据【119,201,718,647】,有了这行数据和最后矩阵相乘的结果,可以通过sage函数key.solve_left()来求得中间生成的随机矩阵。
但这个函数的限制条件没调好,现在只能解出一个无用的特解。
首先求key,key是一个204的矩阵,乘以一个412的矩阵得到hint中的矩阵。也就是A*R=B,已知B求A。https://ctf.njupt.edu.cn/546.html#diamond该博客中有解法,其中的代码稍微修改修改即可
msg = open(r'C:\\Users\\wcj\\Desktop\\guess_c31fa29ffba2ff77b12dec354b8909e6\\hint', 'r').readlines()
B = []
for var in msg:
var = var[1:-2].split(' ')
for x in var:
B.append(int(x))
BB = []
for i in range(0, len(B), 20):
BB.append(B[i: i 20])
As = []
for i in range(1000):
shuffle(BB)
for line in matrix(len(BB), 20, BB).LLL(delta=float(randint(30000, 99999)/100000)):
if line[0] < 0:
line = -line
if line not in As and all(map(lambda x: 100 <= x <= 1000, line)):
print(len(BB), line)
As.append(line)
a = [241, 232, 548, 400, 186, 333, 646, 727, 286, 877, 810, 121, 237, 745, 201, 542, 244, 396, 158, 641]
b = [119, 521, 142, 637, 614, 746, 299, 416, 638, 288, 995, 498, 639, 585, 114, 885, 558, 783, 899, 751]
c = [718, 550, 349, 939, 148, 355, 942, 685, 313, 577, 184, 130, 307, 983, 611, 903, 271, 530, 566, 427]
d = [647, 918, 613, 936, 461, 281, 977, 888, 128, 653, 309, 780, 526, 216, 944, 123, 430, 860, 113, 129]
m = matrix([b, a, c, d])
K = []
for i in range(20):
for j in range(4):
K.append(m[j][i])
print(K)
print(len(K)==80)
题目使用的加密算法是paillier,该算法有乘法同态性质,也就是D(c1c2)=m1 m2,因此有D(c^k)=km。第三步传给服务器两个明文,服务器返回一个密文。第四步可以将这个密文的平方传回给服务器,服务器返回的就是明文的二倍,这样就可以计算出使用的key,进而判断出第三步传回的是哪个密文
import socket
from pwn import *
from pwnlib.util.iters import mbruteforce
from hashlib import sha256
K = [119, 241, 718, 647, 521, 232, 550, 918, 142, 548, 349, 613, 637, 400, 939, 936, 614, 186, 148, 461, 746, 333, 355, 281, 299, 646, 942, 977, 416, 727, 685, 888, 638, 286, 313, 128, 288, 877, 577, 653, 995, 810, 184, 309, 498, 121, 130, 780, 639, 237, 307, 526, 585, 745, 983, 216, 114, 201, 611, 944, 885, 542, 903, 123, 558, 244, 271, 430, 783, 396, 530, 860, 899, 158, 566, 113, 751, 641, 427, 129]
def main():
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.connect(('47.104.85.225', 57811))
msg = sk.recv(1024).decode()
suffix = msg[10:msg.find(')')]
cipher = msg[msg.find('==') 3:-1]
proof = mbruteforce(lambda x: sha256((x suffix).encode()).hexdigest() == cipher, string.ascii_letters string.digits, length=4, method='fixed')
sk.send((proof '\n').encode())
for _ in range(32):
msg = sk.recv(1024).decode()
while True:
if msg.find('Please give me one decimal ciphertext.') != -1:
break
msg = sk.recv(1024).decode()
n = int(msg[msg.find('n = ') 4: msg.find('g = ') - 1])
sk.send('1\n'.encode())
msg = sk.recv(1024).decode()
msg = sk.recv(1024).decode()
sk.send('4\n'.encode())
msg = sk.recv(1024).decode()
sk.send('5\n'.encode())
msg = sk.recv(1024).decode()
msg = sk.recv(1024).decode()
cipher_text = int(msg[:msg.find('Step') - 1])
cipher_text = (cipher_text ** 2) % (n ** 2)
sk.send((str(cipher_text) '\n').encode())
msg = sk.recv(1024).decode()
msg = sk.recv(1024).decode()
plaint = int(msg[:msg.find('Step') - 1])
m = plaint // 40
index = K.index(m)
if index % 2 == 0:
sk.send('0\n'.encode())
else:
sk.send('1\n'.encode())
msg = sk.recv(20).decode()
if(msg == 'sorry'):
exit(1)
flag = sk.recv(1024).decode()
print(flag)
if __name__ == '__main__':
main()
flag{e87fdfb6-8007-4e1c-861f-5bde3c8badb3}
2、**myRSA**根据加密函数推导
def encry(message,key,p,q,e):
k1,k2 = key[random.randint(0,127)],key[random.randint(0,127)]
x = p**2 * (p 3*q - 1 ) q**2 * (q 3*p - 1)
y = 2*p*q p q
z = k1 k2
c = pow(b2l(message),e,p*q)
return x * c y * c z
n == p*q
encry == x*c y*c z
== c*(x y) z
== c*(p^2*(p 3*q-1) q^2*(q 3*p-1) 2*p*q p q) z
== c*(p^3 3*q*p^2-p^2 q^3 3*q*p^2-q^2 2*p*q p q) z
== c*( (p^3 3*q*p^2 3*q*p^2 q^3) - (p^2-2*p*q q^2) (p q) ) z
== c*( (p q)^3 - (p^2 2*p*q q^2) (p q) - 4*p*q) z
== c*( (p q)^3 - (p q)^2 (p q) - 4*n) z
当message已知时,即c已知,则:
( (p q)^3 - (p q)^2 (p q) - 4*n ) z//c == encry//c
bit_length(z) ≈ bit_length(c)
(p q)^3 - (p q)^2 (p q) ≈ encry//c 4*n
p q ≈ iroot(encry//c 4*n,3)
得到p q后,即可分解得到p和q,然后
encry(falg) == c*( (p q)^3 - (p q)^2 (p q) - 4*p q) z
encry(falg)//( (p q)^3 - (p q)^2 (p q) - 4*p q ) ≈ c
c ≈ encry(falg)//( (p q)^3 - (p q)^2 (p q) - 4*p q )
pow(flag,e,p*q) == c
flag = pow(c,d,p*q)
交互过程如图:
具体代码如下:
from gmpy2 import *
from libnum import *
import hashlib, string
import string
string.ascii_letters string.digits
def getHash(salt, result):
characters = string.ascii_letters string.digits
for c1 in characters:
for c2 in characters:
for c3 in characters:
for c4 in characters:
proof = (c1 c2 c3 c4)
if hashlib.sha256((proof salt).encode()).hexdigest() == result:
return proof
# print(getHash('22DTYHroGWCn', 'e4c9ef8db51891583283e46918102679b1a6c3dfe39fc03b6358dfc25a774b87'))
n = 85343149578176060673525681026723930359314280768242385609024815828556712907874238886300667543103765988586168603631056110828361309591875660584941941481131092974185146750844915150566700701092563758372252836639762879237827599338268809569117654436310368636789827651104134868900261762104527595991833761714901016029
e = 65537
m1s = b'123456'
cc1 = 105373287756342103942318018207056724895113233474538384206517559444291374325564458162829935057543845664205750932828630502829241312854079542426015944635674945007233226969286492255522761944177693783964402040849515814480732059253751703782424818957331522695828579625990399140552544980352436208260945967283728637409348330898050232258063842734314870654886700796338003597546732410884458751238829865847139778432136828226800897288424010979417923480250780864971811755934542620713460207847994035065574879421110368856772784757449082198034834405011617207370781985693178239051493374933415204965262530381690146459520225010213093464909483816574798355968626256136465430160720859598955776299806476466769412478819481700794165326427988495181589303730517671784092779839924300337807278823503948
flagcc = 454290573758015984361161126262811922788755078401937487579079634614218474633801258967721156564975754624859004052141021296088980113896281079737825700103991596426503507575094089473968746944563893361448273886607332373914110733362866368001364669002738540783848149392686860094417167606048872651224504789189640531484807929947408609762054624949645581390736093100707064204367843770956253500452956970787266407106360175299552284981057764308021200628000230080295901166574595815192713921576623749344127096235109866174624137703038268714280160476563698761263045817706939008171964455359487525305018326387123255659560601103557128168884398217553297448525018481589736937600226945431670247899467168039685000720178976703743528438795723822518269229648079592317649607172977245430485797171405656
m1 = s2n(m1s)
c1 = powmod(m1,e,n)
x = iroot(cc1//c1 4*n,3)[0]
while True:
t = iroot(x*x-4*n,2)
if t[1]:
p = (x t[0])//2
q = (x-t[0])//2
if p*q == n:
print(p,q)
break
x = x-1
d = invert(e,(p-1)*(q-1))
x = p**2 * (p 3*q - 1 ) q**2 * (q 3*p - 1)
y = 2*p*q p q
t = x y
flagc = flagcc//t 100
while True:
flag = powmod(flagc,d,n)
f = n2s(int(flag))
if b'ctf' in f or b'flag' in f or b'CTF' in f or b'FLAG' in f:
print(f)
break
flagc = flagc - 1
3、**Random_RSA**
python随机数相同的随机数种子产生的随机数序列相同,先用产生的随机数序列异或解密出dp,然后
https://blog.csdn.net/weixin_45369385/article/details/109208109该博客有dp泄露的原理和代码,直接用即可(python2运行)
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
import gmpy2
import libnum
import random
import binascii
import os
n=81196282992606113591233615204680597645208562279327854026981376917977843644855180528227037752692498558370026353244981467900057157997462760732019372185955846507977456657760125682125104309241802108853618468491463326268016450119817181368743376919334016359137566652069490881871670703767378496685419790016705210391
c=61505256223993349534474550877787675500827332878941621261477860880689799960938202020614342208518869582019307850789493701589309453566095881294166336673487909221860641809622524813959284722285069755310890972255545436989082654705098907006694780949725756312169019688455553997031840488852954588581160550377081811151
e = 65537
#rands=[[58, 53, 122],[145, 124, 244],[5, 19, 192],[255, 23, 64],[57, 113, 194],[246, 205, 162],[112, 87, 95],[215, 147, 105],[16, 131, 38],[234, 36, 46],[68, 61, 146],[148, 61, 9],[139, 77, 32],[96, 56, 160],[121, 76, 17],[114, 246, 92],[178, 206, 60],[168, 147, 26],[168, 41, 68],[24, 93, 84],[175, 43, 88],[147, 97, 153],[42, 94, 45],[150, 103, 127],[68, 163, 62],[165, 37, 89],[219, 248, 59],[241, 182, 8],[140, 211, 146],[88, 226, 2],[48, 150, 56],[87, 109, 255],[227, 216, 65],[23, 190, 10],[5, 25, 64],[6, 12, 124],[53, 113, 124],[255, 192, 158],[61, 239, 5],[62, 108, 86],[123, 44, 64],[195, 192, 30],[30, 82, 95],[56, 178, 165],[68, 77, 239],[106, 247, 226],[17, 46, 114],[91, 71, 156],[157, 43, 182],[146, 6, 42],[148, 143, 161],[108, 33, 139],[139, 169, 157],[71, 140, 25],[28, 153, 26],[241, 221, 235],[28, 131, 141],[159, 111, 184],[47, 206, 11],[220, 152, 157],[41, 213, 97],[4, 220, 10],[77, 13, 248],[94, 140, 110],[25, 250, 226],[218, 102, 109],[189, 238, 66],[91, 18, 131],[23, 239, 190],[159, 33, 72],[183, 78, 208],[209, 213, 101],[111, 50, 220],[166, 104, 233],[170, 144, 10],[187, 87, 175],[195, 59, 104],[165, 179, 179],[99, 247, 153],[195, 61, 100],[223, 159, 165],[230, 93, 184],[87, 28, 35],[35, 122, 38],[158, 188, 163],[229, 192, 222],[12, 12, 192],[207, 95, 224],[127, 113, 137],[22, 114, 143],[13, 45, 144],[70, 140, 211],[57, 101, 42],[132, 62, 129],[40, 128, 124],[1, 132, 161],[164, 33, 133],[252, 201, 32],[8, 18, 247],[1, 88, 55],[201, 135, 186],[101, 254, 125],[236, 196, 39],[148, 24, 103],[101, 29, 253],[97, 156, 64],[90, 103, 91],[50, 48, 80],[206, 22, 93],[11, 114, 174],[61, 132, 247],[215, 32, 232],[95, 128, 90],[57, 35, 228],[163, 143, 107],[178, 250, 28],[64, 107, 225],[106, 115, 207],[85, 134, 21],[118, 201, 76],[234, 34, 22],[241, 236, 122],[111, 185, 127],[1, 26, 164],[254, 57, 117],[243, 27, 32],[161, 88, 80],[50, 165, 93],[87, 182, 216],[184, 159, 63],[167, 166, 123],[37, 78, 33],[186, 81, 58],[48, 3, 239],[70, 186, 13],[56, 108, 178],[54, 55, 235],[105, 180, 105],[16, 194, 98],[136, 11, 41],[18, 203, 79],[185, 114, 170],[148, 181, 223],[118, 57, 160],[23, 250, 181],[235, 219, 228],[44, 151, 38],[185, 224, 134],[42, 162, 122],[3, 9, 158],[129, 245, 2],[66, 241, 92],[80, 124, 36]]
res=[55, 5, 183, 192, 103, 32, 211, 116, 102, 120, 118, 54, 120, 145, 185, 254, 77, 144, 70, 54, 193, 73, 64, 0, 79, 244, 190, 23, 215, 187, 53, 176, 27, 138, 42, 89, 158, 254, 159, 133, 78, 11, 155, 163, 145, 248, 14, 179, 23, 226, 220, 201, 5, 71, 241, 195, 75, 191, 237, 108, 141, 141, 185, 76, 7, 113, 191, 48, 135, 139, 100, 83, 212, 242, 21, 143, 255, 164, 146, 119, 173, 255, 140, 193, 173, 2, 224, 205, 68, 10, 77, 180, 24, 23, 196, 205, 108, 28, 243, 80, 140, 4, 98, 76, 217, 70, 208, 202, 78, 177, 124, 10, 168, 165, 223, 105, 157, 152, 48, 152, 51, 133, 190, 202, 136, 204, 44, 33, 58, 4, 196, 219, 71, 150, 68, 162, 175, 218, 173, 19, 201, 100, 100, 85, 201, 24, 59, 186, 46, 130, 147, 219, 22, 81]
# res = [48, 187, 242, 82, 159, 17, 153, 125, 154, 127, 74, 37, 162, 190, 27, 236, 201, 0, 209, 87, 74, 247, 218, 92, 206, 134, 60, 120, 132, 2, 221, 60, 98, 96, 120, 249, 18, 117, 107, 156, 207, 94, 141, 208, 78, 61, 192, 34, 121, 96, 212, 207, 82, 71, 7, 191, 207, 232, 38, 227, 98, 222, 222, 234, 84, 9, 180, 33, 22, 113, 154, 170, 231, 64, 44, 214, 164, 130, 197, 167, 70, 11, 241, 52, 145, 82, 42, 8, 214, 69, 98, 102, 122, 79, 91, 180, 146, 117, 29, 124, 21, 83, 125, 123, 251, 209, 191, 121, 212, 202, 244, 77, 136, 80, 224, 153, 181, 209, 50, 173, 62, 61, 5, 164, 209, 120, 75, 138, 47, 76, 196, 117, 199, 242, 211, 157, 85, 103, 243, 96, 16, 145, 157, 68, 25, 105, 109, 136, 11, 228, 36, 79, 115, 250]
seeds=[4827, 9522, 552, 880, 7467, 7742, 9425, 4803, 6146, 4366, 1126, 4707, 1138, 2367, 1081, 5577, 4592, 5897, 4565, 2012, 2700, 1331, 9638, 7741, 50, 824, 8321, 7411, 6145, 1271, 7637, 5481, 8474, 2085, 2421, 590, 7733, 9427, 3278, 5361, 1284, 2280, 7001, 8573, 5494, 7431, 2765, 827, 102, 1419, 6528, 735, 5653, 109, 4158, 5877, 5975, 1527, 3027, 9776, 5263, 5211, 1293, 5976, 7759, 3268, 1893, 6546, 4684, 419, 8334, 7621, 1649, 6840, 2975, 8605, 5714, 2709, 1109, 358, 2858, 6868, 2442, 8431, 8316, 5446, 9356, 2817, 2941, 3177, 7388, 4149, 4634, 4316, 5377, 4327, 1774, 6613, 5728, 1751, 8478, 3132, 4680, 3308, 9769, 8341, 1627, 3501, 1046, 2609, 7190, 5706, 3627, 8867, 2458, 607, 642, 5436, 6355, 6326, 1481, 9887, 205, 5511, 537, 8576, 6376, 3619, 6609, 8473, 2139, 3889, 1309, 9878, 2182, 8572, 9275, 5235, 6989, 6592, 4618, 7883, 5702, 3999, 925, 2419, 7838, 3073, 488, 21, 3280, 9915, 3672, 579]
ress = ""
dp = ''
for i in range(0,154):
random.seed(seeds[i])
rands = []
for j in range(0,4):
rands.append(random.randint(0,255))
# print(rands)
ress =chr((res[i]) ^ rands[i % 4])
# dp = str((res[i]) ^ rands[i % 4])
print(ress)
# print(dp)
dp = 5372007426161196154405640504110736659190183194052966723076041266610893158678092845450232508793279585163304918807656946147575280063208168816457346755227057
import gmpy2
for x in range(1, e):
if(e * dp % x == 1):
p = (e * dp - 1) // x 1
if(n % p != 0):
continue
q = n // p
fain = (p-1) * (q-1)
d = gmpy2.invert(e, fain)
m = pow(c, d, n)
if(len(hex(m)[2:]) % 2 == 1):
continue
print("m:", m)
print("flag:", binascii.a2b_hex(hex(m)[2:]))
###
pwn1、**note**scanf那里可以进行格式化字符串的利用,首先修改站上残留的stdout指针,可以泄露地址,之后可以任意地址写: