• 去年数安真没那么抽象,用的还是i春秋的平台,而且是线上CTF,线下不知道什么(当时0基础,签到题都写不出来,差点劝退我打CTF),之后还陷入了打基础的弯路(打的全是理论基础,对前期CTF感觉没太大帮助),导致大一下才找到方向开始狂赶进度。
  • 今年数安,安恒的平台,线上理论题,线下CTF。这次线下数据安全抽象的是,不收手机、赛后不用交wp、不用录屏、没有pwn题,集体顿悟(都不知道这比赛去年没那么抽象,今年怎么就这么抽象了)
  • 这场比赛收获最大的就是现场动态调试,在没文章的情况下坚持分析了一下go语言逆向(虽然最后没写出来,但是对go语言逆向稍微了解了一下)
  • 主要还是太菜了,要是我和队友各个方向全ak就好了(幻想时刻QAQ)

MISC

MISC1

  • 题目描述:一个人加密了一个压缩包,但是这个人忘记了密码,好在他将密码复制了下来。附件给了一个.raw的内存镜像文件
  • 我使用volatility先对内存镜像中的剪切板进行取证。
  • 先使用volatility查看一下内存镜像的操作系统信息,查看一下到底是什么操作系统,让后再进行后续的内促取证。
1
volatility -f easyraw.raw imageinfo

image-20241201221325349

  • 发现该内存镜像对应的Profile(s)Win7SP1x64

  • 然后接下来就对该内存镜像中的剪切板进行内存取证,利用volatility中的clipboard插件对剪切板进行取证。

1
volatility -f easyraw.raw --profile=Win7SP1x64 clipboard

image-20241201221655193

  • 取证后发现压缩包的密码Dki98misc@irR32df,原本以为压缩包的密码就是flag,但是把压缩包的密码当做flag交上去结果是错误的。
  • 这时思考了一下,然后猜想flag可能是存在压缩包里面。压缩包的密码是用来解密压缩包的。
  • 这时我就使用volatility尝试查看一下内存中是否有对应的压缩包文件。
1
volatility -f easyraw.raw --profile=Win7SP1x64 filescan
  • 查找后就发现内存中有zip压缩文件,恰好是本题的压缩文件。
1
0x000000007e79e450      2      0 -W-rwd \Device\HarddiskVolume1\Users\air\Desktop\flag.zipmp\vmware-air\VMwareDnD\1ae56e08\flag.zip
  • 然后继续使用volatility将这段内存给dump下来
1
volatility -f easyraw.raw --profile=Win7SP1x64 dumpfiles -Q  0x000000007e79e450  -D ./ -u
  • 之后就得到了下图的.dat文件

image-20241201222521949

  • 将该文件的后缀名修改为zip,然后再用上面取到的压缩包密码Dki98misc@irR32df,解压压缩包即可。解压后就会看到flag了
  • flag:DASCTF{584169a7074d6c8563512c76e3658bb3}

image-20241201222701707

MISC2

  • 单纯寻找flag文件,给了一个这个附件。

image-20241201222832810

  • 这个附件里面又给了俩个密码,一个真密码,一个假密码。真的密码是下面那个Th1$isP@ssW0rd!

image-20241201222918071

image-20241201223029927

  • 用这个真密码去解密,这个压缩包,解密之后将这个压缩包中的文件解压缩下来

image-20241201223214018

  • 解压后就会有一堆txt文件,随便打开看一个,说这是假密码。猜测这500个txt文件里面存在一个真的flag文件。

image-20241201223352894

  • 直接编写python脚本一把梭
1
2
3
4
5
for i in range(1,1001):
a = open("E:\CTF题目附件\\2024数据安全\misc\\findme的附件\\tempdir\MISC附件\\findme\{}.txt".format(i))
b = a.readline()
if 'true' in b:
print(b)
  • 直接得到正确的flag
1
this is true flag: DASCTF{b731d45d-7de4-4ae5-9eb2-ae6e889cc2ef}

Crypto

Crypto1

  • 简单的维纳攻击,题目如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Util.number import *
from gmpy2 import *
from libnum import *

flag = b'DASCTF{******}'

p = getPrime(512)
q = getPrime(512)
n = p*q
d = getPrime(256)
e = inverse(d, (p-1)*(q-1))
m = s2n(flag)
c = pow(m, e, n)

print('n = ' + str(n))
print('e = ' + str(e))
print('c = ' + str(c))

'''
n = 114566998957451783636756389276471274690612644037126335470456866443567982817002189902938330449132444558501556339080521014838959058380963759366933946623103869574657553262938223064086322963492884606713973124514306815995276393344755433548846003574038937940253826360659447735554684257197194046341849089254659225497
e = 35489734227210930185586918984451799765619374486784192218215354633053183935617953856556709715097294481614236703293033675674496036691242573294182072757562322996800390363453350727372642264982749305833933966045097125311467413670410802534093354414115267442785896373815076066721029449240889291057288090241124904705
c = 60503455347700500866544596012233537789678841391057706123172519773588895502922586197178148979273264437566411675346207472455036341903878112074983509557751805365618433536738111588239911292341288514123006967218545943520736254346030465088445419278775539026233686559207400401082452551955780877227801939191694370380
'''
  • 还好博客上存了维纳攻击的模版(24年打XYCTF写wp保存下来的),直接套用即可:
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
import libnum
import gmpy2
n = 114566998957451783636756389276471274690612644037126335470456866443567982817002189902938330449132444558501556339080521014838959058380963759366933946623103869574657553262938223064086322963492884606713973124514306815995276393344755433548846003574038937940253826360659447735554684257197194046341849089254659225497
e = 35489734227210930185586918984451799765619374486784192218215354633053183935617953856556709715097294481614236703293033675674496036691242573294182072757562322996800390363453350727372642264982749305833933966045097125311467413670410802534093354414115267442785896373815076066721029449240889291057288090241124904705
c = 60503455347700500866544596012233537789678841391057706123172519773588895502922586197178148979273264437566411675346207472455036341903878112074983509557751805365618433536738111588239911292341288514123006967218545943520736254346030465088445419278775539026233686559207400401082452551955780877227801939191694370380
d = 73063402529037322097118332383573632498272794119753822794611901750350495660289

def continuedFra(x, y):
"""计算连分数
:param x: 分子
:param y: 分母
:return: 连分数列表
"""
cf = []
while y:
cf.append(x // y)
x, y = y, x % y
return cf
def gradualFra(cf):
"""计算传入列表最后的渐进分数
:param cf: 连分数列表
:return: 该列表最后的渐近分数
"""
numerator = 0
denominator = 1
for x in cf[::-1]:
# 这里的渐进分数分子分母要分开
numerator, denominator = denominator, x * denominator + numerator
return numerator, denominator
def solve_pq(a, b, c):
"""使用韦达定理解出pq,x^2−(p+q)∗x+pq=0
:param a:x^2的系数
:param b:x的系数
:param c:pq
:return:p,q
"""
par = gmpy2.isqrt(b * b - 4 * a * c)
return (-b + par) // (2 * a), (-b - par) // (2 * a)
def getGradualFra(cf):
"""计算列表所有的渐近分数
:param cf: 连分数列表
:return: 该列表所有的渐近分数
"""
gf = []
for i in range(1, len(cf) + 1):
gf.append(gradualFra(cf[:i]))
return gf


def wienerAttack(e, n):
"""
:param e:
:param n:
:return: 私钥d
"""
cf = continuedFra(e, n)
gf = getGradualFra(cf)
for d, k in gf:
if k == 0: continue
if (e * d - 1) % k != 0:
continue
phi = (e * d - 1) // k
p, q = solve_pq(1, n - phi + 1, n)
if p * q == n:
return d


print(n)
d=wienerAttack(e, n)
print(d)
m = pow(c,d,n)
print(libnum.n2s(m))
# b'DASCTF{e694f0b4e9556021d1bc9e8deedba575}'

Crypto2

  • OpenRSA,听说这题还是个原题,一开始以为是考费马小定理,结果就单纯考一个数的奇偶性。而且题目还给了提示
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
from Crypto.Util.number import *
from gmpy2 import iroot
def getPrime(pp):
while True:
x=getPrime(512)
s=x**2+pp**2
if(isPrime(s)):
return s,x
flag = b''
m = bytes_to_long(flag)
e = 0x10001
pp = ???
assert isPrime(pp)
s,p=getPrime(pp)
assert iroot(s-pp**2,2)[0] == p
assert s%2 == 1
#注意观察一下数和数之间的关系,相信你一定可以猜到pp的值
q = getPrime(512)
n = p*q
c = pow(m,e,n)

print(f'n = {n}')
print(f'e = {e}')
print(f'c = {c}')
print(f's = {s}')
# n = 91332943043957251900549627486310189996740089685835683300621629110943492183477268072298084280915990633551010090925404931181501528744693585078837081210712114190987563470157519717774234682286443126927653309723270524901176734059185014688925211350678028031584074094348200320194354359517392064299266428589467651877
# e = 65537
# c = 56047741088808471978777825274508389592730927600153384445849570005499054151546904431595413241700524283982925340735997036959411123465509486474875805374561817710368400036617625285408296984445244211890678298780346979950633523883426046251122190772687200378680540970303449180211765041573634411303625986012155354363
# s = 85800895230491036216758530886003341168631461607188722404807814593592648170497231916924533123351386068154228324172747834362249217755009796485811038447281072462412691656306643440837354994979197958887259958930060878212841756145266179832110649310586242527945793993646330413532949285121357704413955480099382778653

  • 这题注意到,s是由关系式x**2 + pp**2
  • 同时给出了assert s%2==1。说明s是一个奇数。接下来利用数的奇偶性推理出pp的值、

已知assert isPrime(pp),即pp是一个素数,而x也是一个素数。除2以外的素数都是奇数。

x**2是俩个x相乘,而pp**2是俩个pp相乘,假设他们都是奇数,那么x**2p**2也都是奇数。

奇数+奇数=偶数,这与断言矛盾,故确定pp=2

  • exp:
1
2
3
4
5
6
7
8
9
10
11
12
13
import libnum
import gmpy2
n = 91332943043957251900549627486310189996740089685835683300621629110943492183477268072298084280915990633551010090925404931181501528744693585078837081210712114190987563470157519717774234682286443126927653309723270524901176734059185014688925211350678028031584074094348200320194354359517392064299266428589467651877
e = 65537
c = 56047741088808471978777825274508389592730927600153384445849570005499054151546904431595413241700524283982925340735997036959411123465509486474875805374561817710368400036617625285408296984445244211890678298780346979950633523883426046251122190772687200378680540970303449180211765041573634411303625986012155354363
s = 85800895230491036216758530886003341168631461607188722404807814593592648170497231916924533123351386068154228324172747834362249217755009796485811038447281072462412691656306643440837354994979197958887259958930060878212841756145266179832110649310586242527945793993646330413532949285121357704413955480099382778653
pp = 2
p = gmpy2.iroot(s-pp**2,2)[0]
q = n//p
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,n)
print(libnum.n2s(int(m)))

Reverse

go_bytes

+