关注公众号,后台回复“2022年江西省大学生信息安全技术大赛初赛附件”获取附件。writeup为火炬木攻防实验室复现。
Misc
av番号?
分离png得到压缩包
密码即为av号所对应的bv号,打开即可获得flag
DASCTF{2cf74144f7a6753b8ec5ef1a17bd6943}
b64
文件尾有rar,winhex手动分离另存为1.rar
打开rar提示文件损坏,尝试手动修复
将7A修改为74后有一个CMT文件
内部数据为375c24f24
WinRAR打开,直接拖出来就可以,会提示输入密码,直接点确定即可
获得flag.png
Mc25LaMdwVfSrAcTi5hUjdjZigLVtdfWj50Btbvat5YTtJjZiV7JXL==
直接使用常见base64表都无法解码,所以考虑还有密码表未找到
这个时候发现b64.png是有lsb隐写的
结合上面获取的375c24f24作为密钥,进行lsb隐写解密,获得密码表
换表获取flag
Reverse
just try
日常查壳
ida32打开抓住main函数,看到一串类似于base的加密
下面整体分析一下,加密完成对应汇编
动调一下了解加密的过程
输三出四abc->d7Jo
类base加密,表应该是
pc$LEQz=`J&x}Z1H[_#WY?7(d+beh9Rg%U.omaADIn/^r2qj"X8*SPiVT~,!@0lO
分析加密思路,发现和b64很相似基本判断就可以看成一个变表的base
刚好表也是64位,映证我的想法
尝试写写解密脚本
import base64
xx = "9zUnhP0nhP0U(i+Ubi?g+AXU+P0Vbz?8+?0nhP0Sbz?g9=JP+W@="
string1 = "pc$LEQz=`J&x}Z1H[_#WY?7(d+beh9Rg%U.omaADIn/^r2qj"X8*SPiVT~,!@0lO"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print(base64.b64decode(xx.translate(str.maketrans(string1, string2))))
发现得到的结果并不正确,回头继续看
找到有两个地方引用了DASCTF{}输出flag
第一个也就是对比9zUnhP0nhP0U(i+Ubi?g+AXU+P0Vbz?8+?0nhP0Sbz?g9=JP+W@=
现在找第二个,根据ida中的地址将断点下在这里动调,找到第二个加密字符串的储存位置对应的字符串
追踪到[ebp-54]0xD9F804的位置
找到加密之后的第二个字符串:bDYP9Q0S}Vag}(_gZz~m(Vm"9?0V}7Xr(ih*9Q0Ybz?g+AXp+8E=
出flag:DASCTF{ju5t_t3y_1t_4nd_y0u_w1ll_g3t_The_fl@g!}
Crypto
childRSA
题目给了两个hint,一个t,三个式子的关系式需要注意,除此之外没有给别的条件,要利用三个式子之间的关系将n给分解,从而解得RSA问题。
移位运算需要格外注意数据的大小,hint2为325位,即p+q有1025位
可以通过hint1求出中间未知的300位,coppersmith攻击可以得解,需要注意的是参数epsilon需要调解。
#sage
PR.<x> = PolynomialRing(Zmod(n))
f = (hint2 * 2 ** 300 + x) ** 5 - hint1
f = f.monic()
root = f.small_roots(X=2^300,epsilon=0.05)
print(root)
#[900264792430764766810468133825778807801191920823522836863083047162892866646875705320428414]
这样就得到了中间300位数据,也就得到了完整的t,t为p+q的高625位。尝试将t补齐末尾的400位后,将t当作p+q进行解方程求解p和q,得到的结果高位绝大部分(约625位)都是p的真实值,即又是一次coppersmith攻击。
本地调试代码为
from Crypto.Util.number import *
import gmpy2
p = getPrime(1024)
q = getPrime(1024)
n = p * q
print(bin(p))
print(bin(q))
t = (p + q) >> 400
tmp = t << 400
delta = (-tmp) ** 2 - 4 * n
root = (tmp + gmpy2.iroot(delta,2)[0]) // 2
print(bin(root))
print(bin((root >> 410) << 410))
观察真实的p和q的值,与用高位p+q计算出的p和q对比,发现高位约410左右的值均为真实值。
最终完整的exp为
#sage
from Crypto.Util.number import *
import gmpy2
e = 0x10001
hint1 = 6964268498224091442825901686661237530522347823219684563953066748773962088742241306677313317319854958214809420491702826564173355938490895331198923527667364391468907737301225088055694814054437257546623622938612408110705668176565380596339718060188913772054934639716087768201377510580527776620973849589493097834538277938095415499237738389824293807732943558864605374620352812654675340721179976350321686554346480366405041985305950214160057477895135264060509738709041302441896671041092913276009633345558000228385343666906746902900413558103089531391702625462756747693602826394235998376415996614904736368860948851904114759520
hint2 = 35165031790811266789276297244077421419318407075263158049499021955914590950991343652276232777908755
c = 1194117711433011441060134674606098070381155137570132814645921839615957597835342364752690350397111039680829661168950994677242133003831857753717267765730709950962838353493193313333861519610959115846772660808231021695226017063586411911884012906630417263646774337811587546018982857308444743074540232702175124483283963022003128128895028486075083457146101759085577311851691019744921491271824543561105936792223059552432601797275680969934801073929816816591461641917010862943585908913395097700239584604202024790346377492049803175414595521867623349879553627712654215740750111307350401014702090262981840327908865144781276319568
n = 8549553129556983264608088682144271656693794050112289425675496094026434817108494235711226667779521325697862914028343058066103508338456921605474038543206958948754257875152530897451832886150364719949419136810566809716512257764229488443939365856512970801159298226321696518457404725027861542259048326408205187101646347015821199955131581632322611062812545798546366651032754969448116265458489609498024105014804973782490072390302931423444439067883414987213231822019508606373773220271568649831375769401969720741032679413016192706592762550683257986177763209776366348327296666255389811197464163893141112673359393597787787992057
PR.<x> = PolynomialRing(Zmod(n))
f = (hint2 * 2 ** 300 + x) ** 5 - hint1
f = f.monic()
root = f.small_roots(X=2^300,epsilon=0.05)
print(root)
tmp = int(root[0])
t = int(hint2 * 2 ** 300 + tmp)
assert pow(t,5,n) == hint1
tmp = t << 400
delta = (-tmp) ** 2 - 4 * n
p = (tmp + gmpy2.iroot(delta,2)[0]) // 2
bits = 410
p = int((p >> bits) << bits)
PR.<x> = PolynomialRing(Zmod(n))
f = p + x
root = f.small_roots(X=2^bits,beta=0.4)
print(root)
p += int(root[0])
assert n % p == 0
q = n // p
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(int(m)))
#b'DASCTF{you_s0lve_the_double_c0pper_problem!}'
easylattice2
n=40,m = 256,q = ,泄露βi的高s=8位。
首先把问题换个符号表述,βi拆成泄露的高未和未知的低位相加:
观察一下,现在未知数有和,是m bits,是(m−s) bits,如果可以把的未知量转换成((m−s) bits以下或者消去的话是最好的(按以前的经验,如果有未知数和模数一样大的话问题大概率不能解,不过也要看具体问题)。
以下选择消去减小未知数的规模:首先选一组定义为第0组(只是一个定义,实际选出来后换个位置也行),需要满足gcd(A0,q)=1,即模q可逆,需要可逆的原因是想把移到一边:
然后对i=1,2,...的每一组就可以代入然后消去,最终得到:
令
展开模数q:
简单推算一下,+−大概(2m−s) bits,q是m bits,所以大概(m−s) bits,最终所有未知数都(m−s) bits。
令常数R=,接下来就是构造格L(B):
使得:
可算
算出若∥w∥≤σ(L(B))的话就是:
化简:
实际应用的时候还有一个技巧:在拆成的时候,是恒为正的,如果在中加上一个,就可以为负,的位数变为(比原来小一位),这时把R设成,就会:
算出若∥w∥≤σ(L(B))的话就是:
即开始所说的关系。计算出取组就可解,当然取越多越好。
exp:
#sage
from Crypto.Util.number import *
def matrix_overview(BB):
for ii in range(BB.dimensions()[0]):
a = ('%02d ' % ii)
for jj in range(BB.dimensions()[1]):
if BB[ii, jj] == 0:
a += ' '
else:
a += 'X'
if BB.dimensions()[0] < 60:
a += ' '
print(a)
m = 256
s = 8
A = [84545605098919357883342049785700230040968693996530839945990653400855504906802, 64318627050238621913856342658149309111953371364362248466973076501370171739866, 44833833707095656654503484256000993796921007419233493881691012114619868094560, 73232050050978729749876385355125922365994635840614577909712939078465889486927, 49705754343680217825731689069247222931464457288368278401756955216063821460713, 7773716507069077286176384328311704695943346186956011585647833650872546985704, 35367871748426097942891975752985612532178159522392487799137847162793844297259, 62764829622761591382777789741125592700340145715067712695838863315679297865421, 46935977121421979257863144003719821155118122728798766585021557461458554711048, 42939177889039484362479588720740991357365976148437177435101168045290359758410, 97121564005524888337068660871158366982592875907457306709790495639937090537232, 76886701253807415588943538291675931582703667239932988501427868196293288708454, 26135505377348779821008049265473415821466025876911023611852970773014088341697, 110995849442144940870427048133899156608419550927266942442877901533603266505363, 5044203606638773879637402874988459469968364471257924922588754307799172436111, 2665604848469247498374079779039877909487959491708401136315883984900023830087, 106082111880140350563516845222048616300919360816856986713701434503153473598272, 87595120997346701153771844173354962363505990024749960032323522802170210856998, 30735469834005371392098522683460862628728000563099737246414787689161654170005, 74359883667893599589405273462303347696610905658857136168118529986363407255898, 20204197780205297843081711648226294480448019326273455617021195999857044167942, 63096262783751516980983192186356065149841431907259395141910451383433704709184, 12152056244753544826439613524228624069728455796264166814352560273933151913592, 114889255822548504838278221664465176494052041487922417522436000874970493661674, 12697645037989154507748939749910714768436117428576511237333427290637745232352, 75299588851358924593106633315972752823613401831656849845776220971408926864757, 66252398829865053651294427099510477412334399373429337393371739360897428551080, 96532198311446483093375170979824934072692435507945852599941894677854324762234, 6139286263397899992951419178195053475916568135172144122694657112490581510300, 34376460022522877744382639064317171686750419881002499940120807593906622629919, 96501742323730881521910813296284942340349016330837155159335201986513386546858, 77138784030740465724716203856139754018741545301925742743136359127104441232992, 57759435811750287940649147535145228583155499038537697675728235258033065901677, 27297361883253038600939612200992657560439960674763420079462172997044428666986, 23401758127641977798857113971736125468419263857787075540336458711365758576497, 68532606512738331105309350681916480349485076493586056552769624280354609427017, 71959573997311126544920410961743015991934367773498267843192433783459395347384, 86568022924301252995070743709076133954812487027394051823868169701714096819788, 65483599135089201771470413647566590147384718070198959226794224092625758570289, 2353939170592029768060112909867989273389149830947499985690619642365711664985]
B = [231, 134, 184, 26, 1, 252, 141, 254, 219, 145, 192, 30, 211, 114, 242, 175, 180, 134, 76, 238, 3, 108, 164, 227, 220, 212, 197, 226, 147, 252, 241, 249, 89, 26, 98, 232, 213, 192, 145, 36]
AAA = [x for x in A]
BBB = [x for x in B]
while True:
A = [x for x in AAA]
B = [x for x in BBB]
#B = [x << (m-s) for x in B]
B = [(x << (m-s)) + (1 << (m-s-1)) for x in B]
assert len(A) == len(B)
q = 2^m
n = len(A)-1
AA = [x for x in A]
BB = [x for x in B]
for choice in range(n):
A = [x for x in AA]
B = [x for x in BB]
if A[choice] % 2 != 1:
continue
A0 = A[choice]
A0i = A0.inverse_mod(q)
B0 = B[choice]
del A[choice]
del B[choice]
assert gcd(A0, q) == 1
Mt = matrix(ZZ, n+2)
for i in range(n):
Mt[i, i] = -q
Mt[-2, i] = A0i*A[i] % q
Mt[-1, i] = A0i*(A[i]*B0 - A0*B[i]) % q
Mt[-2, -2] = 1
R = 2^(m-s-1)
Mt[-1, -1] = R
#print(det(Mt) == 0)
#matrix_overview(Mt)
L = Mt.BKZ()
for l in L:
if l[-1] == R:
b = vector(l)
b0 = b[-2]
#print(b0)
x0 = (B0+b0) * A0.inverse_mod(q) % q
test1 = [bi >> (m-s) for bi in B]
test2 = [(ai*x0 % q) >> (m-s) for ai in A]
print(long_to_bytes(x0))
print(test1)
print(test2)
print()
if test1 == test2:
print('get: %d' % x0)
exit(0)
#b'5f0552110ef8c3dbfb892697bf889bf6'
#[231, 134, 184, 1, 252, 141, 254, 219, 145, 192, 30, 211, 114, 242, 175, 180, 134, 76, 238, 3, 108, 164, 227, 220, 212, 197, 226, 147, 252, 241, 249, 89, 26, 98, 232, 213, 192, 145, 36]
#[231, 134, 184, 1, 252, 141, 254, 219, 145, 192, 30, 211, 114, 242, 175, 180, 134, 76, 238, 3, 108, 164, 227, 220, 212, 197, 226, 147, 252, 241, 249, 89, 26, 98, 232, 213, 192, 145, 36]
#get: 24153132093824532405578251214404236997470757161095572611640663666873489057334
原文始发于微信公众号(火炬木攻防实验室):2022年江西省大学生信息安全技术大赛初赛writeup——re、misc、crypto方向
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论