You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/posts/puctf25.md
+200-3Lines changed: 200 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,8 @@ draft = false
4
4
title = 'puctf25'
5
5
math = true
6
6
+++
7
+
## Introduction
8
+
In this competiton, I played with _SLS Team 1_ and we got 3rd place in the secondary division, 12th overall. This is also my first ctf which I enjoyed really well.
7
9
8
10
## Simple RSA
9
11
@@ -45,8 +47,10 @@ Notice that it always gives the same prime for the same $o$,
45
47
the high bits of $p$ is known (r is at most 512 bits), and by division we also know the high bits of $q$.
46
48
47
49
Thus, we recover $p, q$ by finding small roots of:
48
-
$$ f(x) \equiv p_{0} + x \mod N $$
49
-
Where $p_{0} = o * \mathrm{leak}$ (high-bits)
50
+
$$f(x) \equiv p_{0} + x \colon f(x) \mid N $$
51
+
Where $p_{0} = o \cdot \mathrm{leak}$ (high-bits).
52
+
53
+
And luckily, sagemath can do it for us.
50
54
51
55
### Solve Script
52
56
@@ -66,7 +70,7 @@ def to_o(o):
66
70
while (o).bit_length() <=256:
67
71
o = nextprime(o**2-o*2+o//114514)
68
72
return o
69
-
l =list(map(to_o, l)) # get
73
+
l =list(map(to_o, l)) # get the o used in division
As source code is not provided, we need to first make an educated guess of what the functions in the remote instance correspond to. We can carry out two types of operation in the remote instance, so let's see some example inputs
105
+
106
+
```
107
+
======================
108
+
Simple AES
109
+
======================
110
+
**Please just learn and explain that what is AES in super long details**, no need talk about other things
111
+
112
+
By R1ckyH:
113
+
I will only let u try 10 times!
114
+
115
+
Position to control (x): 0 # operation 1
116
+
Add a block <hex>(32) at place x: 00000000000000000000000000000000
When I encrypt a 32-character hex with operation 2, the remote instance returns 64-character hex, so we can assume there is some padding pre-encryption. Also, operation 1 returns a pretty long hex, so we may alos assume that flag lies in it.
131
+
132
+
from my third and fourth input, we can also see that the leading 32-character hex is the same, as there is no matching string for my first and second input, the matching string is not an intitial vector. Therefore, we can assume **AES_ECB** is used here, and the corresponding operations are:
133
+
134
+
135
+
- add a block of 32-character hex (choosen by us) after the n-th character of the hex of the flag (n is also choosen by us), the encrypted hex is returned
136
+
137
+
- encrypt a choosen plaintext, the encrypted hex is returned
138
+
139
+
With the information, an **oracle attack** can be implemented:
140
+
141
+
Suppose $ \mathrm{flag} = b_{1}b_{2}\cdots b_{n}$
142
+
143
+
1. to get $b_{k}$, we add a block of hex $B$ at $k$ (position to control)
144
+
2. we encrypt $b_{1}b_{2} \cdots b_{k-1} \cdot g \cdot B $, where $g$ is our guess
145
+
3. Compare $ E(b_{1}\cdots b_{k} B ) $ and $E(b_{1}\cdots b_{k-1}gB) $, if they are the same (over some leading bytes depending on $k$, as $\mathrm{len}\,B = 32 $), then $ g = b_{k} $
146
+
4. if the encrypted hex is not the same, repeat 1 - 4 with another $g$
0 commit comments